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: Created Nov. 5, 2014, 2:21 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 function escapeChar(chr, pos, s) { 27 function escapeChar(chr)
28 var code = chr.charCodeAt(0); 28 {
29 29 var code = chr.charCodeAt(0);
30 // non-ascii, needs no escaping 30
31 if (code >= 128) 31 if (code <= 0x1F || code == 0x7F || /\d/.test(chr))
Sebastian Noack 2014/11/05 18:09:04 I just realized that I can easily check in the reg
32 return chr; 32 return "\\" + code.toString(16) + " ";
33 33
34 // control characters and numbers, must be escaped based on their code point 34 return "\\" + chr;
35 if ((code >= 0 && code <= 31) || (code >= 48 && code <= 57) || code == 127)
Wladimir Palant 2014/11/05 15:14:41 How about: if (code <= 0x1F || /\d/.test(chr) |
Sebastian Noack 2014/11/05 18:09:04 I already considered using that regex to check for
36 return "\\" + code.toString(16) + (pos + 1 < s.length ? " " : "");
Wladimir Palant 2014/11/05 15:14:41 Why create a special case for end of string? That
Sebastian Noack 2014/11/05 18:09:04 I find the extra space in the end confusing. It ca
37
38 // others, can be escaped by prepending a backslash
39 return "\\" + chr;
40 } 35 }
41 36
42 function quote(value) 37 function quote(value)
43 { 38 {
44 return '"' + value.replace(/["\\\r\n\f\0]/g, escapeChar) + '"'; 39 return '"' + value.replace(/["\\\x00-\x1F\x7F]/g, escapeChar) + '"';
Wladimir Palant 2014/11/05 15:14:41 How about generally escaping all non-printable cha
Sebastian Noack 2014/11/05 18:09:04 Yeah, un-escaped control characters make quoted st
45 } 40 }
46 41
47 function escapeToken(s) { 42 function escapeCSS(s)
48 return s.replace(/^\d|^-(?![^\d-])|[^\w-]/g, escapeChar); 43 {
Wladimir Palant 2014/11/05 15:14:41 How about always escaping leading dashes? These ar
Sebastian Noack 2014/11/05 18:09:04 I'd prefer to keep the logic for escaping dashes.
Wladimir Palant 2014/11/05 19:56:52 I'll leave the decision on whether that branch in
44 return s.replace(/^[\d\-]|[^\w\-\u0080-\uFFFF]/g, escapeChar);
49 } 45 }
50 46
51 function supportsShadowRoot(element) 47 function supportsShadowRoot(element)
52 { 48 {
53 if (!("createShadowRoot" in element)) 49 if (!("createShadowRoot" in element))
54 return false; 50 return false;
55 51
56 // There are some elements (e.g. <textarea>), which don't 52 // There are some elements (e.g. <textarea>), which don't
57 // support author created shadow roots and throw an exception. 53 // support author created shadow roots and throw an exception.
58 var clone = element.cloneNode(false); 54 var clone = element.cloneNode(false);
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
398 clickHideFilters = new Array(); 394 clickHideFilters = new Array();
399 selectorList = new Array(); 395 selectorList = new Array();
400 396
401 var addSelector = function(selector) 397 var addSelector = function(selector)
402 { 398 {
403 clickHideFilters.push(document.domain + "##" + selector); 399 clickHideFilters.push(document.domain + "##" + selector);
404 selectorList.push(selector); 400 selectorList.push(selector);
405 }; 401 };
406 402
407 if (elt.id) 403 if (elt.id)
408 addSelector("#" + escapeToken(elt.id)); 404 addSelector("#" + escapeCSS(elt.id));
409 405
410 if (elt.classList.length > 0) 406 if (elt.classList.length > 0)
411 { 407 {
412 var selector = ""; 408 var selector = "";
413 409
414 for (var i = 0; i < elt.classList.length; i++) 410 for (var i = 0; i < elt.classList.length; i++)
415 selector += "." + escapeToken(elt.classList[i]); 411 selector += "." + escapeCSS(elt.classList[i]);
416 412
417 addSelector(selector); 413 addSelector(selector);
418 } 414 }
419 415
420 if (url) 416 if (url)
421 { 417 {
422 var src = elt.getAttribute("src"); 418 var src = elt.getAttribute("src");
423 var selector = src && escapeToken(elt.localName) + '[src=' + quote(src) + '] '; 419 var selector = src && escapeCSS(elt.localName) + '[src=' + quote(src) + ']';
424 420
425 if (/^https?:/i.test(url)) 421 if (/^https?:/i.test(url))
426 { 422 {
427 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||")); 423 clickHideFilters.push(url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"));
428 424
429 if (selector) 425 if (selector)
430 selectorList.push(selector); 426 selectorList.push(selector);
431 } 427 }
432 else if (selector) 428 else if (selector)
433 addSelector(selector); 429 addSelector(selector);
434 } 430 }
435 431
436 // restore the original style, before generating the fallback filter that 432 // restore the original style, before generating the fallback filter that
437 // will include the style, and to prevent highlightElements from saving those 433 // will include the style, and to prevent highlightElements from saving those
438 unhighlightElement(currentElement); 434 unhighlightElement(currentElement);
439 435
440 // as last resort, create a filter based on inline styles 436 // as last resort, create a filter based on inline styles
441 if (clickHideFilters.length == 0) 437 if (clickHideFilters.length == 0)
442 { 438 {
443 var style = elt.getAttribute("style"); 439 var style = elt.getAttribute("style");
444 if (style) 440 if (style)
445 addSelector(escapeToken(elt.localName) + '[style=' + quote(style) + ']'); 441 addSelector(escapeCSS(elt.localName) + '[style=' + quote(style) + ']');
446 } 442 }
447 443
448 // Show popup 444 // Show popup
449 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters); 445 clickHide_showDialog(e.clientX, e.clientY, clickHideFilters);
450 446
451 // Highlight the elements specified by selector in yellow 447 // Highlight the elements specified by selector in yellow
452 highlightElements(selectorList.join(",")); 448 highlightElements(selectorList.join(","));
453 // Now, actually highlight the element the user clicked on in red 449 // Now, actually highlight the element the user clicked on in red
454 highlightElement(currentElement, "#fd1708", "#f6a1b5"); 450 highlightElement(currentElement, "#fd1708", "#f6a1b5");
455 451
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 break; 670 break;
675 default: 671 default:
676 sendResponse({}); 672 sendResponse({});
677 break; 673 break;
678 } 674 }
679 }); 675 });
680 676
681 if (window == window.top) 677 if (window == window.top)
682 ext.backgroundPage.sendMessage({type: "report-html-page"}); 678 ext.backgroundPage.sendMessage({type: "report-html-page"});
683 } 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