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

Delta Between Two Patch Sets: chrome/content/elemHideEmulation.js

Issue 29383960: Issue 3143 - Filter elements with :-abp-has() (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore
Left Patch Set: Last comments. Created June 8, 2017, 12:15 a.m.
Right Patch Set: Fix reportError and the error message Created June 13, 2017, 1:52 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 | « chrome/content/.eslintrc.json ('k') | test/browser/elemHideEmulation.js » ('j') | no next file with change/comment »
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 <https://adblockplus.org/>, 2 * This file is part of Adblock Plus <https://adblockplus.org/>,
3 * Copyright (C) 2006-2017 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 *
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 /* globals filterToRegExp */ 18 /* globals filterToRegExp */
19 19
20 "use strict"; 20 "use strict";
21 21
22 const abpSelectorRegexp = /:-abp-([\w-]+)\(/i; 22 const abpSelectorRegexp = /:-abp-([\w-]+)\(/i;
23 23
24 let reportError = () => {};
25
24 function splitSelector(selector) 26 function splitSelector(selector)
25 { 27 {
26 if (selector.indexOf(",") == -1) 28 if (selector.indexOf(",") == -1)
27 return [selector]; 29 return [selector];
28 30
29 let selectors = []; 31 let selectors = [];
30 let start = 0; 32 let start = 0;
31 let level = 0; 33 let level = 0;
32 let sep = ""; 34 let sep = "";
33 35
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 let match = abpSelectorRegexp.exec(selector); 144 let match = abpSelectorRegexp.exec(selector);
143 if (!match) 145 if (!match)
144 return [new PlainSelector(selector)]; 146 return [new PlainSelector(selector)];
145 147
146 let selectors = []; 148 let selectors = [];
147 if (match.index > 0) 149 if (match.index > 0)
148 selectors.push(new PlainSelector(selector.substr(0, match.index))); 150 selectors.push(new PlainSelector(selector.substr(0, match.index)));
149 151
150 let startIndex = match.index + match[0].length; 152 let startIndex = match.index + match[0].length;
151 let content = parseSelectorContent(selector, startIndex); 153 let content = parseSelectorContent(selector, startIndex);
152 if (content == null) 154 if (!content)
Sebastian Noack 2017/06/08 08:28:47 Nit: Given that parseSelectorContent() either retu
hub 2017/06/08 15:45:47 Done.
153 { 155 {
154 console.error(new SyntaxError("Failed parsing AdBlock Plus " + 156 reportError(new SyntaxError("Failed to parse Adblock Plus " +
Sebastian Noack 2017/06/08 08:28:48 Nit: It's Adblock Plus (with lower case "B"). But
hub 2017/06/08 15:45:48 Maybe we could change this to "Failed parsing cont
Felix Dahlke 2017/06/09 09:02:33 Well, we're actually parsing what we call an "ABP
155 `selector ${selector}, didn't ` + 157 `selector ${selector}, ` +
156 "find closing parenthesis.")); 158 "due to unmatched parentheses."));
157 return null; 159 return null;
158 } 160 }
159 if (match[1] == "properties") 161 if (match[1] == "properties")
160 selectors.push(new PropsSelector(content.text)); 162 selectors.push(new PropsSelector(content.text));
161 else if (match[1] == "has") 163 else if (match[1] == "has")
162 { 164 {
163 let hasSelector = new HasSelector(content.text); 165 let hasSelector = new HasSelector(content.text);
164 if (!hasSelector.valid()) 166 if (!hasSelector.valid())
165 return null; 167 return null;
166 selectors.push(hasSelector); 168 selectors.push(hasSelector);
167 } 169 }
168 else 170 else
169 { 171 {
170 // this is an error, can't parse selector. 172 // this is an error, can't parse selector.
171 console.error(new SyntaxError("Failed parsing AdBlock Plus " + 173 reportError(new SyntaxError("Failed to parse Adblock Plus " +
172 `selector ${selector}, invalid ` + 174 `selector ${selector}, invalid ` +
173 `pseudo-class -abp-${match[1]}().`)); 175 `pseudo-class :-abp-${match[1]}().`));
174 return null; 176 return null;
175 } 177 }
176 178
177 let suffix = parseSelector(selector.substr(content.end + 1)); 179 let suffix = parseSelector(selector.substr(content.end + 1));
178 if (suffix == null) 180 if (suffix == null)
179 return null; 181 return null;
180 182
181 selectors.push(...suffix); 183 selectors.push(...suffix);
182 184
183 return selectors; 185 return selectors;
184 } 186 }
185 187
186 /** Stringified style objects 188 /** Stringified style objects
187 * @typedef {Object} StringifiedStyle 189 * @typedef {Object} StringifiedStyle
188 * @property {string} style CSS style represented a string. 190 * @property {string} style CSS style represented by a string.
Wladimir Palant 2017/06/08 13:12:40 This doesn't seem to be quite English to me, also
hub 2017/06/08 15:45:47 Acknowledged.
189 * @property {string[]} subSelectors selectors for the rule. 191 * @property {string[]} subSelectors selectors the CSS properties apply to.
Wladimir Palant 2017/06/08 13:12:39 "selectors that the CSS properties apply to"?
hub 2017/06/08 15:45:46 Acknowledged.
190 */ 192 */
191 193
192 /** 194 /**
193 * Turn a CSSStyleRule into a StringifiedStyle 195 * Produce a string representation of the stylesheet entry.
Wladimir Palant 2017/06/08 13:12:39 You have the types listed below, no need to repeat
hub 2017/06/08 15:45:47 Acknowledged.
194 * @param {CSSStyleRule} rule the CSS style rule. 196 * @param {CSSStyleRule} rule the CSS style rule.
195 * @return {StringifiedStyle} the stringified style. 197 * @return {StringifiedStyle} the stringified style.
196 */ 198 */
197 function stringifyStyle(rule) 199 function stringifyStyle(rule)
198 { 200 {
199 let styles = []; 201 let styles = [];
200 for (let i = 0; i < rule.style.length; i++) 202 for (let i = 0; i < rule.style.length; i++)
201 { 203 {
202 let property = rule.style.item(i); 204 let property = rule.style.item(i);
203 let value = rule.style.getPropertyValue(property); 205 let value = rule.style.getPropertyValue(property);
204 let priority = rule.style.getPropertyPriority(property); 206 let priority = rule.style.getPropertyPriority(property);
205 styles.push(property + ": " + value + (priority ? " !" + priority : "") + 207 styles.push(`${property}: ${value}${priority ? " !" + priority : ""};`);
Sebastian Noack 2017/06/08 08:28:47 Nit: If you'd use a template literal here you woud
hub 2017/06/08 15:45:46 This code was simply moved and written pre-ES6. I'
206 ";");
207 } 208 }
208 styles.sort(); 209 styles.sort();
209 return { 210 return {
210 style: styles.join(" "), 211 style: styles.join(" "),
211 subSelectors: splitSelector(rule.selectorText) 212 subSelectors: splitSelector(rule.selectorText)
212 }; 213 };
213 } 214 }
214 215
215 function* evaluate(chain, index, prefix, subtree, styles) 216 function* evaluate(chain, index, prefix, subtree, styles)
216 { 217 {
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 367
367 for (let rule of rules) 368 for (let rule of rules)
368 { 369 {
369 if (rule.type != rule.STYLE_RULE) 370 if (rule.type != rule.STYLE_RULE)
370 continue; 371 continue;
371 372
372 cssStyles.push(stringifyStyle(rule)); 373 cssStyles.push(stringifyStyle(rule));
373 } 374 }
374 } 375 }
375 376
377 let {document} = this.window;
376 for (let pattern of this.patterns) 378 for (let pattern of this.patterns)
377 { 379 {
378 for (let selector of evaluate(pattern.selectors, 380 for (let selector of evaluate(pattern.selectors,
379 0, "", document, cssStyles)) 381 0, "", document, cssStyles))
380 { 382 {
381 if (!pattern.selectors.some(s => s.requiresHiding)) 383 if (!pattern.selectors.some(s => s.requiresHiding))
382 { 384 {
383 selectors.push(selector); 385 selectors.push(selector);
384 selectorFilters.push(pattern.text); 386 selectorFilters.push(pattern.text);
385 } 387 }
(...skipping 16 matching lines...) Expand all
402 { 404 {
403 let stylesheet = event.target.sheet; 405 let stylesheet = event.target.sheet;
404 if (stylesheet) 406 if (stylesheet)
405 this.addSelectors([stylesheet]); 407 this.addSelectors([stylesheet]);
406 }, 408 },
407 409
408 apply() 410 apply()
409 { 411 {
410 this.getFiltersFunc(patterns => 412 this.getFiltersFunc(patterns =>
411 { 413 {
414 let oldReportError = reportError;
415 reportError = error => this.window.console.error(error);
416
412 this.patterns = []; 417 this.patterns = [];
413 for (let pattern of patterns) 418 for (let pattern of patterns)
414 { 419 {
415 let selectors = parseSelector(pattern.selector); 420 let selectors = parseSelector(pattern.selector);
416 if (selectors != null && selectors.length > 0) 421 if (selectors != null && selectors.length > 0)
417 this.patterns.push({selectors, text: pattern.text}); 422 this.patterns.push({selectors, text: pattern.text});
418 } 423 }
419 424
420 if (this.patterns.length > 0) 425 if (this.patterns.length > 0)
421 { 426 {
422 let {document} = this.window; 427 let {document} = this.window;
423 this.addSelectors(document.styleSheets); 428 this.addSelectors(document.styleSheets);
424 document.addEventListener("load", this.onLoad.bind(this), true); 429 document.addEventListener("load", this.onLoad.bind(this), true);
425 } 430 }
431 reportError = oldReportError;
426 }); 432 });
427 } 433 }
428 }; 434 };
LEFTRIGHT

Powered by Google App Engine
This is Rietveld