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

Side by Side Diff: chrome/content/elemHideEmulation.js

Issue 29464703: Issue 5313 - Make error reporting more robust. (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created June 14, 2017, 2:50 a.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 | « no previous file | no next file » | 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-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
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 if (parens == 0) 123 if (parens == 0)
124 break; 124 break;
125 } 125 }
126 } 126 }
127 127
128 if (parens > 0) 128 if (parens > 0)
129 return null; 129 return null;
130 return {text: content.substring(startIndex, i), end: i}; 130 return {text: content.substring(startIndex, i), end: i};
131 } 131 }
132 132
133 /** Parse the selector
134 * @param {string} selector the selector to parse
135 * @return {Object} selectors is an array of objects,
136 * or null in case of errors. hide is true if we'll hide
137 * elements instead of styles..
138 */
139 function parseSelector(selector)
140 {
141 if (selector.length == 0)
142 return [];
143
144 let match = abpSelectorRegexp.exec(selector);
145 if (!match)
146 return [new PlainSelector(selector)];
147
148 let selectors = [];
149 if (match.index > 0)
150 selectors.push(new PlainSelector(selector.substr(0, match.index)));
151
152 let startIndex = match.index + match[0].length;
153 let content = parseSelectorContent(selector, startIndex);
154 if (!content)
155 {
156 reportError(new SyntaxError("Failed to parse Adblock Plus " +
157 `selector ${selector}, ` +
158 "due to unmatched parentheses."));
159 return null;
160 }
161 if (match[1] == "properties")
162 selectors.push(new PropsSelector(content.text));
163 else if (match[1] == "has")
164 {
165 let hasSelector = new HasSelector(content.text);
166 if (!hasSelector.valid())
167 return null;
168 selectors.push(hasSelector);
169 }
170 else
171 {
172 // this is an error, can't parse selector.
173 reportError(new SyntaxError("Failed to parse Adblock Plus " +
174 `selector ${selector}, invalid ` +
175 `pseudo-class :-abp-${match[1]}().`));
176 return null;
177 }
178
179 let suffix = parseSelector(selector.substr(content.end + 1));
180 if (suffix == null)
181 return null;
182
183 selectors.push(...suffix);
184
185 return selectors;
186 }
187
188 /** Stringified style objects 133 /** Stringified style objects
189 * @typedef {Object} StringifiedStyle 134 * @typedef {Object} StringifiedStyle
190 * @property {string} style CSS style represented by a string. 135 * @property {string} style CSS style represented by a string.
191 * @property {string[]} subSelectors selectors the CSS properties apply to. 136 * @property {string[]} subSelectors selectors the CSS properties apply to.
192 */ 137 */
193 138
194 /** 139 /**
195 * Produce a string representation of the stylesheet entry. 140 * Produce a string representation of the stylesheet entry.
196 * @param {CSSStyleRule} rule the CSS style rule. 141 * @param {CSSStyleRule} rule the CSS style rule.
197 * @return {StringifiedStyle} the stringified style. 142 * @return {StringifiedStyle} the stringified style.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 * @param {StringifiedStyle[]} styles the stringified style objects. 184 * @param {StringifiedStyle[]} styles the stringified style objects.
240 */ 185 */
241 *getSelectors(prefix, subtree, styles) 186 *getSelectors(prefix, subtree, styles)
242 { 187 {
243 yield [prefix + this._selector, subtree]; 188 yield [prefix + this._selector, subtree];
244 } 189 }
245 }; 190 };
246 191
247 const incompletePrefixRegexp = /[\s>+~]$/; 192 const incompletePrefixRegexp = /[\s>+~]$/;
248 193
249 function HasSelector(selector) 194 function HasSelector(selectors)
250 { 195 {
251 this._innerSelectors = parseSelector(selector); 196 this._innerSelectors = selectors;
252 } 197 }
253 198
254 HasSelector.prototype = { 199 HasSelector.prototype = {
255 requiresHiding: true, 200 requiresHiding: true,
256 201
257 valid()
258 {
259 return this._innerSelectors != null;
260 },
261
262 *getSelectors(prefix, subtree, styles) 202 *getSelectors(prefix, subtree, styles)
263 { 203 {
264 for (let element of this.getElements(prefix, subtree, styles)) 204 for (let element of this.getElements(prefix, subtree, styles))
265 yield [makeSelector(element, ""), element]; 205 yield [makeSelector(element, ""), element];
266 }, 206 },
267 207
268 /** 208 /**
269 * Generator function returning selected elements. 209 * Generator function returning selected elements.
270 * @param {string} prefix the prefix for the selector. 210 * @param {string} prefix the prefix for the selector.
271 * @param {Node} subtree the subtree we work on. 211 * @param {Node} subtree the subtree we work on.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 { 277 {
338 return new URL(stylesheet.href).origin == this.window.location.origin; 278 return new URL(stylesheet.href).origin == this.window.location.origin;
339 } 279 }
340 catch (e) 280 catch (e)
341 { 281 {
342 // Invalid URL, assume that it is first-party. 282 // Invalid URL, assume that it is first-party.
343 return true; 283 return true;
344 } 284 }
345 }, 285 },
346 286
287 /** Parse the selector
288 * @param {string} selector the selector to parse
289 * @return {Object} selectors is an array of objects,
290 * or null in case of errors. hide is true if we'll hide
291 * elements instead of styles..
292 */
293 parseSelector(selector)
294 {
295 if (selector.length == 0)
296 return [];
297
298 let match = abpSelectorRegexp.exec(selector);
299 if (!match)
300 return [new PlainSelector(selector)];
301
302 let selectors = [];
303 if (match.index > 0)
304 selectors.push(new PlainSelector(selector.substr(0, match.index)));
305
306 let startIndex = match.index + match[0].length;
307 let content = parseSelectorContent(selector, startIndex);
308 if (!content)
309 {
310 this.window.console.error(
311 new SyntaxError("Failed to parse Adblock Plus " +
312 `selector ${selector}, ` +
313 "due to unmatched parentheses."));
314 return null;
315 }
316 if (match[1] == "properties")
317 selectors.push(new PropsSelector(content.text));
318 else if (match[1] == "has")
319 {
320 let hasSelectors = this.parseSelector(content.text);
321 if (hasSelectors == null)
322 return null;
323 let hasSelector = new HasSelector(hasSelectors);
324 selectors.push(hasSelector);
325 }
326 else
327 {
328 // this is an error, can't parse selector.
329 this.window.console.error(
330 new SyntaxError("Failed to parse Adblock Plus " +
331 `selector ${selector}, invalid ` +
332 `pseudo-class :-abp-${match[1]}().`));
333 return null;
334 }
335
336 let suffix = this.parseSelector(selector.substr(content.end + 1));
337 if (suffix == null)
338 return null;
339
340 selectors.push(...suffix);
341
342 return selectors;
343 },
344
347 addSelectors(stylesheets) 345 addSelectors(stylesheets)
348 { 346 {
349 let selectors = []; 347 let selectors = [];
350 let selectorFilters = []; 348 let selectorFilters = [];
351 349
352 let elements = []; 350 let elements = [];
353 let elementFilters = []; 351 let elementFilters = [];
354 352
355 let cssStyles = []; 353 let cssStyles = [];
356 354
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 { 402 {
405 let stylesheet = event.target.sheet; 403 let stylesheet = event.target.sheet;
406 if (stylesheet) 404 if (stylesheet)
407 this.addSelectors([stylesheet]); 405 this.addSelectors([stylesheet]);
408 }, 406 },
409 407
410 apply() 408 apply()
411 { 409 {
412 this.getFiltersFunc(patterns => 410 this.getFiltersFunc(patterns =>
413 { 411 {
414 let oldReportError = reportError;
415 reportError = error => this.window.console.error(error);
416
417 this.patterns = []; 412 this.patterns = [];
418 for (let pattern of patterns) 413 for (let pattern of patterns)
419 { 414 {
420 let selectors = parseSelector(pattern.selector); 415 let selectors = this.parseSelector(pattern.selector);
421 if (selectors != null && selectors.length > 0) 416 if (selectors != null && selectors.length > 0)
422 this.patterns.push({selectors, text: pattern.text}); 417 this.patterns.push({selectors, text: pattern.text});
423 } 418 }
424 419
425 if (this.patterns.length > 0) 420 if (this.patterns.length > 0)
426 { 421 {
427 let {document} = this.window; 422 let {document} = this.window;
428 this.addSelectors(document.styleSheets); 423 this.addSelectors(document.styleSheets);
429 document.addEventListener("load", this.onLoad.bind(this), true); 424 document.addEventListener("load", this.onLoad.bind(this), true);
430 } 425 }
431 reportError = oldReportError;
432 }); 426 });
433 } 427 }
434 }; 428 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld