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

Side by Side Diff: lib/filterComposer.js

Issue 29452181: Noissue - Merge current tip to Edge bookmark (Closed)
Patch Set: Created May 30, 2017, 3:49 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « lib/devtools.js ('k') | lib/filterValidation.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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-2016 Eyeo GmbH 3 * Copyright (C) 2006-2017 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 *
(...skipping 19 matching lines...) Expand all
33 * Checks whether the given page is ready to use the filter composer 33 * Checks whether the given page is ready to use the filter composer
34 * 34 *
35 * @param {Page} page 35 * @param {Page} page
36 * @return {boolean} 36 * @return {boolean}
37 */ 37 */
38 exports.isPageReady = page => 38 exports.isPageReady = page =>
39 { 39 {
40 return readyPages.has(page); 40 return readyPages.has(page);
41 }; 41 };
42 42
43 function isValidString(s) { 43 function isValidString(s)
44 {
44 return s && s.indexOf("\0") == -1; 45 return s && s.indexOf("\0") == -1;
45 } 46 }
46 47
47 function escapeChar(chr) 48 function escapeChar(chr)
48 { 49 {
49 let code = chr.charCodeAt(0); 50 let code = chr.charCodeAt(0);
50 51
51 // Control characters and leading digits must be escaped based on 52 // Control characters and leading digits must be escaped based on
52 // their char code in CSS. Moreover, curly brackets aren't allowed 53 // their char code in CSS. Moreover, curly brackets aren't allowed
53 // in elemhide filters, and therefore must be escaped based on their 54 // in elemhide filters, and therefore must be escaped based on their
54 // char code as well. 55 // char code as well.
55 if (code <= 0x1F || code == 0x7F || /[\d\{\}]/.test(chr)) 56 if (code <= 0x1F || code == 0x7F || /[\d{}]/.test(chr))
56 return "\\" + code.toString(16) + " "; 57 return "\\" + code.toString(16) + " ";
57 58
58 return "\\" + chr; 59 return "\\" + chr;
59 } 60 }
60 61
61 let escapeCSS = 62 let escapeCSS =
62 /** 63 /**
63 * Escapes a token (e.g. tag, id, class or attribute) to be used in CSS selector s. 64 * Escapes a token (e.g. tag, id, class or attribute) to be used in
65 * CSS selectors.
64 * 66 *
65 * @param {string} s 67 * @param {string} s
66 * @return {string} 68 * @return {string}
67 * @static 69 * @static
68 */ 70 */
69 exports.escapeCSS = s => 71 exports.escapeCSS = s =>
70 { 72 {
71 return s.replace(/^[\d\-]|[^\w\-\u0080-\uFFFF]/g, escapeChar); 73 return s.replace(/^[\d-]|[^\w\-\u0080-\uFFFF]/g, escapeChar);
72 }; 74 };
73 75
74 let quoteCSS = 76 let quoteCSS =
75 /** 77 /**
76 * Quotes a string to be used as attribute value in CSS selectors. 78 * Quotes a string to be used as attribute value in CSS selectors.
77 * 79 *
78 * @param {string} value 80 * @param {string} value
79 * @return {string} 81 * @return {string}
80 * @static 82 * @static
81 */ 83 */
82 exports.quoteCSS = value => 84 exports.quoteCSS = value =>
83 { 85 {
84 return '"' + value.replace(/["\\\{\}\x00-\x1F\x7F]/g, escapeChar) + '"'; 86 return '"' + value.replace(/["\\{}\x00-\x1F\x7F]/g, escapeChar) + '"';
85 }; 87 };
86 88
87 function composeFilters(details) 89 function composeFilters(details)
88 { 90 {
91 let {page, frame} = details;
89 let filters = []; 92 let filters = [];
90 let selectors = []; 93 let selectors = [];
91 94
92 let page = details.page;
93 let frame = details.frame;
94
95 if (!checkWhitelisted(page, frame)) 95 if (!checkWhitelisted(page, frame))
96 { 96 {
97 let typeMask = RegExpFilter.typeMap[details.type]; 97 let typeMask = RegExpFilter.typeMap[details.type];
98 let docDomain = extractHostFromFrame(frame); 98 let docDomain = extractHostFromFrame(frame);
99 let specificOnly = checkWhitelisted(page, frame, RegExpFilter.typeMap.GENERI CBLOCK); 99 let specificOnly = checkWhitelisted(page, frame,
100 RegExpFilter.typeMap.GENERICBLOCK);
100 101
101 // Add a blocking filter for each URL of the element that can be blocked 102 // Add a blocking filter for each URL of the element that can be blocked
102 for (let url of details.urls) 103 for (let url of details.urls)
103 { 104 {
104 let urlObj = new URL(url, details.baseURL); 105 let urlObj = new URL(url, details.baseURL);
105 url = stringifyURL(urlObj); 106 url = stringifyURL(urlObj);
106 107
107 let filter = defaultMatcher.whitelist.matchesAny( 108 let filter = defaultMatcher.whitelist.matchesAny(
108 url, typeMask, docDomain, 109 url, typeMask, docDomain,
109 isThirdParty(urlObj, docDomain), 110 isThirdParty(urlObj, docDomain),
110 getKey(page, frame), specificOnly 111 getKey(page, frame), specificOnly
111 ); 112 );
112 113
113 if (!filter) 114 if (!filter)
114 { 115 {
115 let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||"); 116 let filterText = url.replace(/^[\w-]+:\/+(?:www\.)?/, "||");
116 117
117 if (specificOnly) 118 if (specificOnly)
118 filterText += "$domain=" + docDomain; 119 filterText += "$domain=" + docDomain;
119 120
120 if (filters.indexOf(filterText) == -1) 121 if (filters.indexOf(filterText) == -1)
121 filters.push(filterText); 122 filters.push(filterText);
122 } 123 }
123 } 124 }
124 125
125 // If we couldn't generate any blocking filters, fallback to element hiding 126 // If we couldn't generate any blocking filters, fallback to element hiding
126 let selectors = []; 127 if (filters.length == 0 && !checkWhitelisted(page, frame,
127 if (filters.length == 0 && !checkWhitelisted(page, frame, RegExpFilter.typeM ap.ELEMHIDE)) 128 RegExpFilter.typeMap.ELEMHIDE))
128 { 129 {
129 // Generate CSS selectors based on the element's "id" and "class" attribut e 130 // Generate CSS selectors based on the element's "id" and
131 // "class" attribute.
130 if (isValidString(details.id)) 132 if (isValidString(details.id))
131 selectors.push("#" + escapeCSS(details.id)); 133 selectors.push("#" + escapeCSS(details.id));
132 134
133 let classes = details.classes.filter(isValidString); 135 let classes = details.classes.filter(isValidString);
134 if (classes.length > 0) 136 if (classes.length > 0)
135 selectors.push(classes.map(c => "." + escapeCSS(c)).join("")); 137 selectors.push(classes.map(c => "." + escapeCSS(c)).join(""));
136 138
137 // If there is a "src" attribute, specifiying a URL that we can't block, 139 // If there is a "src" attribute, specifiying a URL that we can't block,
138 // generate a CSS selector matching the "src" attribute 140 // generate a CSS selector matching the "src" attribute
139 if (isValidString(details.src)) 141 if (isValidString(details.src))
140 selectors.push(escapeCSS(details.tagName) + "[src=" + quoteCSS(details.s rc) + "]"); 142 {
143 selectors.push(
144 escapeCSS(details.tagName) + "[src=" + quoteCSS(details.src) + "]"
145 );
146 }
141 147
142 // As last resort, if there is a "style" attribute, and we couldn't genera te 148 // As last resort, if there is a "style" attribute, and we
143 // any filters so far, generate a CSS selector matching the "style" attrib ute 149 // couldn't generate any filters so far, generate a CSS selector
144 if (isValidString(details.style) && selectors.length == 0 && filters.lengt h == 0) 150 // matching the "style" attribute
145 selectors.push(escapeCSS(details.tagName) + "[style=" + quoteCSS(details .style) + "]"); 151 if (isValidString(details.style) && selectors.length == 0 &&
152 filters.length == 0)
153 {
154 selectors.push(
155 escapeCSS(details.tagName) + "[style=" + quoteCSS(details.style) + "]"
156 );
157 }
146 158
147 // Add an element hiding filter for each generated CSS selector 159 // Add an element hiding filter for each generated CSS selector
148 for (let selector of selectors) 160 for (let selector of selectors)
149 filters.push(docDomain.replace(/^www\./, "") + "##" + selector); 161 filters.push(docDomain.replace(/^www\./, "") + "##" + selector);
150 } 162 }
151 } 163 }
152 164
153 return {filters: filters, selectors: selectors}; 165 return {filters, selectors};
154 } 166 }
155 167
156 let contextMenuItem = { 168 let contextMenuItem = {
157 title: ext.i18n.getMessage("block_element"), 169 title: ext.i18n.getMessage("block_element"),
158 contexts: ["image", "video", "audio"], 170 contexts: ["image", "video", "audio"],
159 onclick(page) 171 onclick(page)
160 { 172 {
161 page.sendMessage({type: "composer.content.contextMenuClicked"}); 173 page.sendMessage({type: "composer.content.contextMenuClicked"});
162 } 174 }
163 }; 175 };
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 ext.pages.onRemoved.addListener(onRemoved); 230 ext.pages.onRemoved.addListener(onRemoved);
219 resolve(popupPageId); 231 resolve(popupPageId);
220 }); 232 });
221 }); 233 });
222 }); 234 });
223 235
224 port.on("composer.getFilters", (message, sender) => 236 port.on("composer.getFilters", (message, sender) =>
225 { 237 {
226 return composeFilters({ 238 return composeFilters({
227 tagName: message.tagName, 239 tagName: message.tagName,
228 id: message.id, 240 id: message.id,
229 src: message.src, 241 src: message.src,
230 style: message.style, 242 style: message.style,
231 classes: message.classes, 243 classes: message.classes,
232 urls: message.urls, 244 urls: message.urls,
233 type: message.mediatype, 245 type: message.mediatype,
234 baseURL: message.baseURL, 246 baseURL: message.baseURL,
235 page: sender.page, 247 page: sender.page,
236 frame: sender.frame 248 frame: sender.frame
237 }); 249 });
238 }); 250 });
239 251
240 ext.pages.onLoading.addListener(page => 252 ext.pages.onLoading.addListener(page =>
241 { 253 {
242 page.sendMessage({type: "composer.content.finished"}); 254 page.sendMessage({type: "composer.content.finished"});
243 }); 255 });
OLDNEW
« no previous file with comments | « lib/devtools.js ('k') | lib/filterValidation.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld