Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Delta Between Two Patch Sets: include.postload.js

Issue 4935175632846848: Issue 1527 - Properly escape generated CSS selectors (Closed)
Left Patch Set: Addressed comments Created Nov. 5, 2014, 6:08 p.m.
Right Patch Set: Addressed comments Created Nov. 10, 2014, 12:10 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | qunit/index.html » ('j') | qunit/tests/cssEscaping.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2014 Eyeo GmbH 3 * Copyright (C) 2006-2014 Eyeo GmbH
4 * 4 *
5 * Adblock Plus is free software: you can redistribute it and/or modify 5 * Adblock Plus is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 3 as 6 * it under the terms of the GNU General Public License version 3 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 * Adblock Plus is distributed in the hope that it will be useful, 9 * Adblock Plus is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details. 12 * GNU General Public License for more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License 14 * You should have received a copy of the GNU General Public License
15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18 // Click-to-hide stuff 18 // Click-to-hide stuff
19 var clickHide_activated = false; 19 var clickHide_activated = false;
20 var clickHide_filters = null; 20 var clickHide_filters = null;
21 var currentElement = null; 21 var currentElement = null;
22 var clickHideFilters = null; 22 var clickHideFilters = null;
23 var highlightedElementsSelector = null; 23 var highlightedElementsSelector = null;
24 var clickHideFiltersDialog = null; 24 var clickHideFiltersDialog = null;
25 var lastRightClickEvent = null; 25 var lastRightClickEvent = null;
26 26
27 var ctrlChar = /[\x00-\x1F\x7F]/g; 27 function escapeChar(chr)
28 28 {
29 function escapeLiteral(chr) 29 var code = chr.charCodeAt(0);
30 { 30
31 if (code <= 0x1F || code == 0x7F || /\d/.test(chr))
32 return "\\" + code.toString(16) + " ";
33
31 return "\\" + chr; 34 return "\\" + chr;
32 } 35 }
33 36
34 function escapeWithCharCode(chr)
35 {
36 return "\\" + chr.charCodeAt(0).toString(16) + " ";
37 }
38
39 function quote(value) 37 function quote(value)
40 { 38 {
41 value = value.replace(/["\\]/g, escapeLiteral); 39 return '"' + value.replace(/["\\\x00-\x1F\x7F]/g, escapeChar) + '"';
42 value = value.replace(ctrlChar, escapeWithCharCode); 40 }
43 41
44 return '"' + value + '"'; 42 function escapeCSS(s)
45 } 43 {
46 44 return s.replace(/^[\d\-]|[^\w\-\u0080-\uFFFF]/g, escapeChar);
47 function escapeToken(s)
48 {
49 return s.replace(
50 /^\d|^-(?![^\d-])|[^\w-\u0080-\uFFFF]/g,
Wladimir Palant 2014/11/05 19:56:52 Constructing character classes that deal with larg
Sebastian Noack 2014/11/06 08:25:14 You forgot to run the regex, but there still isn't
Wladimir Palant 2014/11/06 14:13:59 No, I didn't intend to run it - the slowdown I kno
51
52 function(chr)
53 {
54 if (ctrlChar.test(chr) || /\d/.test(chr))
55 return escapeWithCharCode(chr);
56
57 return escapeLiteral(chr);
58 }
59 );
60 } 45 }
61 46
62 function supportsShadowRoot(element) 47 function supportsShadowRoot(element)
63 { 48 {
64 if (!("createShadowRoot" in element)) 49 if (!("createShadowRoot" in element))
65 return false; 50 return false;
66 51
67 // There are some elements (e.g. <textarea>), which don't 52 // There are some elements (e.g. <textarea>), which don't
68 // support author created shadow roots and throw an exception. 53 // support author created shadow roots and throw an exception.
69 var clone = element.cloneNode(false); 54 var clone = element.cloneNode(false);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 clickHideFilters = new Array(); 394 clickHideFilters = new Array();
410 selectorList = new Array(); 395 selectorList = new Array();
411 396
412 var addSelector = function(selector) 397 var addSelector = function(selector)
413 { 398 {
414 clickHideFilters.push(document.domain + "##" + selector); 399 clickHideFilters.push(document.domain + "##" + selector);
415 selectorList.push(selector); 400 selectorList.push(selector);
416 }; 401 };
417 402
418 if (elt.id) 403 if (elt.id)
419 addSelector("#" + escapeToken(elt.id)); 404 addSelector("#" + escapeCSS(elt.id));
420 405
421 if (elt.classList.length > 0) 406 if (elt.classList.length > 0)
422 { 407 {
423 var selector = ""; 408 var selector = "";
424 409
425 for (var i = 0; i < elt.classList.length; i++) 410 for (var i = 0; i < elt.classList.length; i++)
426 selector += "." + escapeToken(elt.classList[i]); 411 selector += "." + escapeCSS(elt.classList[i]);
427 412
428 addSelector(selector); 413 addSelector(selector);
429 } 414 }
430 415
431 if (url) 416 if (url)
432 { 417 {
433 var src = elt.getAttribute("src"); 418 var src = elt.getAttribute("src");
434 var selector = src && escapeToken(elt.localName) + '[src=' + quote(src) + '] '; 419 var selector = src && escapeCSS(elt.localName) + '[src=' + quote(src) + ']';
435 420
436 if (/^https?:/i.test(url)) 421 if (/^https?:/i.test(url))
437 { 422 {
438 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||")); 423 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"));
439 424
440 if (selector) 425 if (selector)
441 selectorList.push(selector); 426 selectorList.push(selector);
442 } 427 }
443 else if (selector) 428 else if (selector)
444 addSelector(selector); 429 addSelector(selector);
445 } 430 }
446 431
447 // restore the original style, before generating the fallback filter that 432 // restore the original style, before generating the fallback filter that
448 // will include the style, and to prevent highlightElements from saving those 433 // will include the style, and to prevent highlightElements from saving those
449 unhighlightElement(currentElement); 434 unhighlightElement(currentElement);
450 435
451 // as last resort, create a filter based on inline styles 436 // as last resort, create a filter based on inline styles
452 if (clickHideFilters.length == 0) 437 if (clickHideFilters.length == 0)
453 { 438 {
454 var style = elt.getAttribute("style"); 439 var style = elt.getAttribute("style");
455 if (style) 440 if (style)
456 addSelector(escapeToken(elt.localName) + '[style=' + quote(style) + ']'); 441 addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']');
457 } 442 }
458 443
459 // Show popup 444 // Show popup
460 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); 445 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters);
461 446
462 // Highlight the elements specified by selector in yellow 447 // Highlight the elements specified by selector in yellow
463 highlightElements(selectorList.join(",")); 448 highlightElements(selectorList.join(","));
464 // Now, actually highlight the element the user clicked on in red 449 // Now, actually highlight the element the user clicked on in red
465 highlightElement(currentElement, "#fd1708", "#f6a1b5"); 450 highlightElement(currentElement, "#fd1708", "#f6a1b5");
466 451
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
685 break; 670 break;
686 default: 671 default:
687 sendResponse({}); 672 sendResponse({});
688 break; 673 break;
689 } 674 }
690 }); 675 });
691 676
692 if (window == window.top) 677 if (window == window.top)
693 ext.backgroundPage.sendMessage({type: "report-html-page"}); 678 ext.backgroundPage.sendMessage({type: "report-html-page"});
694 } 679 }
LEFTRIGHT
« no previous file | qunit/index.html » ('j') | Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Toggle Comments ('s')

Powered by Google App Engine
This is Rietveld