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

Delta Between Two Patch Sets: lib/filterComposer.js

Issue 5225119261655040: Issue 1282 - Don't generate filters conflicting with existing exception rules (Closed)
Left Patch Set: Created Dec. 15, 2014, 2:47 p.m.
Right Patch Set: Addressed comment Created March 3, 2015, 2:59 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « include.preload.js ('k') | no next file » | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 /* 1 /*
2 * This file is part of Adblock Plus <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2015 Eyeo GmbH 3 * Copyright (C) 2006-2015 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 let {getDecodedHostname, stringifyURL} = require("url"); 18 let {extractHostFromFrame, stringifyURL, isThirdParty} = require("url");
19 let {getKey, isFrameWhitelisted} = require("whitelisting");
20 let {defaultMatcher} = require("matcher");
21 let {WhitelistFilter} = require("filterClasses");
19 22
20 function escapeChar(chr) 23 function escapeChar(chr)
21 { 24 {
22 let code = chr.charCodeAt(0); 25 let code = chr.charCodeAt(0);
23 26
24 // Control characters and leading digits must be escaped based on 27 // Control characters and leading digits must be escaped based on
25 // their char code in CSS. Moreover, curly brackets aren't allowed 28 // their char code in CSS. Moreover, curly brackets aren't allowed
26 // in elemhide filters, and therefore must be escaped based on their 29 // in elemhide filters, and therefore must be escaped based on their
27 // char code as well. 30 // char code as well.
28 if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr)) 31 if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr))
(...skipping 21 matching lines...) Expand all
50 * @return {string} 53 * @return {string}
51 */ 54 */
52 function quoteCSS(value) 55 function quoteCSS(value)
53 { 56 {
54 return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"'; 57 return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"';
55 } 58 }
56 exports.quoteCSS = quoteCSS; 59 exports.quoteCSS = quoteCSS;
57 60
58 /** 61 /**
59 * Generates filters to block an element. 62 * Generates filters to block an element.
60 * 63 * @param {Object} details
61 * @param {string} tagName The element's tag name 64 * @param {string} details.tagName The element's tag name
62 * @param {string} [src] The element's "src" attribute 65 * @param {string} detials.id The element's "id" attribute
63 * @param {string} [id] The element's "id" attribute 66 * @param {string} details.src The element's "src" attribute
64 * @param {string} [style] The element's "style" attribute 67 * @param {string} details.style The element's "style" attribute
65 * @param {string[]} classes The classes given by the element's "class" attribu te 68 * @param {string[]} details.classes The classes given by the element's "class" attribute
66 * @param {string[]} urls The URLs considered when loading the element 69 * @param {string[]} details.urls The URLs considered when loading the eleme nt
67 * @param {URL} baseURL The URL of the document containing the element 70 * @param {string} details.type The request type (will be ignored if there are no URLs)
71 * @param {string} details.baseURL The URL of the document containing the ele ment
72 * @param {Page} details.page The page containing the element
73 * @param {Frame} details.frame The frame containing the element
Wladimir Palant 2015/03/03 19:17:01 I wonder whether JsDoc Toolkit will actually accep
Sebastian Noack 2015/03/03 19:18:54 Why not? This is official JSDoc syntax: http://use
Wladimir Palant 2015/03/03 20:11:47 Yes, seems to be supported by our version as well:
68 * 74 *
69 * @return {object} An object holding the list of generated filters and 75 * @return {object} An object holding the list of generated filters and
70 * the list of CSS selectors for the included element 76 * the list of CSS selectors for the included element
71 * hiding filters: {filters: [...], selectors: [...]} 77 * hiding filters: {filters: [...], selectors: [...]}
72 */ 78 */
73 function composeFilters(tagName, id, src, style, classes, urls, baseURL) 79 function composeFilters(details)
74 { 80 {
75 // Add a blocking filter for each HTTP(S) URL associated with the element
76 let filters = []; 81 let filters = [];
77 for (let url of urls) 82 let selectors = [];
83
84 let page = details.page;
85 let frame = details.frame;
86
87 if (!isFrameWhitelisted(page, frame, "DOCUMENT"))
78 { 88 {
79 let urlObj = new URL(url, baseURL); 89 let docDomain = extractHostFromFrame(frame);
80 if (urlObj.protocol == "http:" || urlObj.protocol == "https:") 90
91 // Add a blocking filter for each URL of the element that can be blocked
92 for (let url of details.urls)
81 { 93 {
82 let filter = stringifyURL(urlObj).replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); 94 let urlObj = new URL(url, details.baseURL);
83 95
84 if (filters.indexOf(filter) == -1) 96 if (urlObj.protocol == "http:" || urlObj.protocol == "https:")
85 filters.push(filter); 97 {
98 url = stringifyURL(urlObj);
99
100 let filter = defaultMatcher.matchesAny(
101 url, details.type, docDomain,
102 isThirdParty(urlObj, docDomain),
103 getKey(page, frame)
104 );
105
106 if (!(filter instanceof WhitelistFilter))
107 {
108 let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||");
109
110 if (filters.indexOf(filterText) == -1)
111 filters.push(filterText);
112 }
113 }
86 } 114 }
87 }
88 115
89 // If we couldn't generate any blocking filters, fallback to element hiding 116 // If we couldn't generate any blocking filters, fallback to element hiding
90 let selectors = []; 117 let selectors = [];
91 if (filters.length == 0) 118 if (filters.length == 0 && !isFrameWhitelisted(page, frame, "ELEMHIDE"))
92 { 119 {
93 // Generate CSS selectors based on the element's "id" and "class" attribute 120 // Generate CSS selectors based on the element's "id" and "class" attribut e
94 if (id) 121 if (details.id)
95 selectors.push("#" + escapeCSS(id)); 122 selectors.push("#" + escapeCSS(details.id));
96 if (classes.length > 0) 123 if (details.classes.length > 0)
97 selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); 124 selectors.push(details.classes.map(c => "." + escapeCSS(c)).join(""));
98 125
99 // If there is a "src" attribute, specifiying a URL that we can't block, 126 // If there is a "src" attribute, specifiying a URL that we can't block,
100 // generate a CSS selector matching the "src" attribute 127 // generate a CSS selector matching the "src" attribute
101 if (src) 128 if (details.src)
102 selectors.push(escapeCSS(tagName) + "[src=" + quoteCSS(src) + "]"); 129 selectors.push(escapeCSS(details.tagName) + "[src=" + quoteCSS(details.s rc) + "]");
103 130
104 // As last resort, if there is a "style" attribute, and we couldn't generate 131 // As last resort, if there is a "style" attribute, and we couldn't genera te
105 // any filters so far, generate a CSS selector matching the "style" attribut e 132 // any filters so far, generate a CSS selector matching the "style" attrib ute
106 if (style && selectors.length == 0 && filters.length == 0) 133 if (details.style && selectors.length == 0 && filters.length == 0)
107 selectors.push(escapeCSS(tagName) + "[style=" + quoteCSS(style) + "]"); 134 selectors.push(escapeCSS(details.tagName) + "[style=" + quoteCSS(details .style) + "]");
108 135
109 // Add an element hiding filter for each generated CSS selector 136 // Add an element hiding filter for each generated CSS selector
110 if (selectors.length > 0)
111 {
112 let domain = getDecodedHostname(baseURL).replace(/^www\./, "");
113
114 for (let selector of selectors) 137 for (let selector of selectors)
115 filters.push(domain + "##" + selector); 138 filters.push(docDomain.replace(/^www\./, "") + "##" + selector);
116 } 139 }
117 } 140 }
118 141
119 return {filters: filters, selectors: selectors}; 142 return {filters: filters, selectors: selectors};
120 } 143 }
121 exports.composeFilters = composeFilters; 144 exports.composeFilters = composeFilters;
LEFTRIGHT

Powered by Google App Engine
This is Rietveld