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

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

Issue 29859558: Issue 6741 - Use ES2015 classes in lib/content/elemHideEmulation.js (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Created Aug. 20, 2018, 5:55 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 | « 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-present eyeo GmbH 3 * Copyright (C) 2006-present 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 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
232 yield null; 232 yield null;
233 else 233 else
234 yield* evaluate(chain, index + 1, selector, element, styles, targets); 234 yield* evaluate(chain, index + 1, selector, element, styles, targets);
235 } 235 }
236 // Just in case the getSelectors() generator above had to run some heavy 236 // Just in case the getSelectors() generator above had to run some heavy
237 // document.querySelectorAll() call which didn't produce any results, make 237 // document.querySelectorAll() call which didn't produce any results, make
238 // sure there is at least one point where execution can pause. 238 // sure there is at least one point where execution can pause.
239 yield null; 239 yield null;
240 } 240 }
241 241
242 function PlainSelector(selector) 242 class PlainSelector
243 { 243 {
244 this._selector = selector; 244 constructor(selector)
245 this.maybeDependsOnAttributes = /[#.]|\[.+\]/.test(selector); 245 {
246 this.dependsOnDOM = this.maybeDependsOnAttributes; 246 this._selector = selector;
247 this.maybeContainsSiblingCombinators = /[~+]/.test(selector); 247 this.maybeDependsOnAttributes = /[#.]|\[.+\]/.test(selector);
248 } 248 this.dependsOnDOM = this.maybeDependsOnAttributes;
249 this.maybeContainsSiblingCombinators = /[~+]/.test(selector);
250 }
249 251
250 PlainSelector.prototype = {
251 /** 252 /**
252 * Generator function returning a pair of selector 253 * Generator function returning a pair of selector
253 * string and subtree. 254 * string and subtree.
254 * @param {string} prefix the prefix for the selector. 255 * @param {string} prefix the prefix for the selector.
255 * @param {Node} subtree the subtree we work on. 256 * @param {Node} subtree the subtree we work on.
256 * @param {StringifiedStyle[]} styles the stringified style objects. 257 * @param {StringifiedStyle[]} styles the stringified style objects.
257 * @param {Node[]} [targets] the nodes we are interested in. 258 * @param {Node[]} [targets] the nodes we are interested in.
258 */ 259 */
259 *getSelectors(prefix, subtree, styles, targets) 260 *getSelectors(prefix, subtree, styles, targets)
260 { 261 {
261 yield [prefix + this._selector, subtree]; 262 yield [prefix + this._selector, subtree];
262 } 263 }
263 }; 264 }
264 265
265 const incompletePrefixRegexp = /[\s>+~]$/; 266 const incompletePrefixRegexp = /[\s>+~]$/;
266 267
267 function HasSelector(selectors) 268 class HasSelector
268 { 269 {
269 this._innerSelectors = selectors; 270 constructor(selectors)
270 } 271 {
271 272 this._innerSelectors = selectors;
272 HasSelector.prototype = { 273 this.dependsOnDOM = true;
hub 2018/08/20 19:51:21 I'd feel better if the properties that have a defa
Manish Jethani 2018/08/21 03:45:30 OK, that makes sense. Done.
273 dependsOnDOM: true, 274 }
274 275
275 get dependsOnStyles() 276 get dependsOnStyles()
276 { 277 {
277 return this._innerSelectors.some(selector => selector.dependsOnStyles); 278 return this._innerSelectors.some(selector => selector.dependsOnStyles);
278 }, 279 }
279 280
280 get dependsOnCharacterData() 281 get dependsOnCharacterData()
281 { 282 {
282 return this._innerSelectors.some( 283 return this._innerSelectors.some(
283 selector => selector.dependsOnCharacterData 284 selector => selector.dependsOnCharacterData
284 ); 285 );
285 }, 286 }
286 287
287 get maybeDependsOnAttributes() 288 get maybeDependsOnAttributes()
288 { 289 {
289 return this._innerSelectors.some( 290 return this._innerSelectors.some(
290 selector => selector.maybeDependsOnAttributes 291 selector => selector.maybeDependsOnAttributes
291 ); 292 );
292 }, 293 }
293 294
294 *getSelectors(prefix, subtree, styles, targets) 295 *getSelectors(prefix, subtree, styles, targets)
295 { 296 {
296 for (let element of this.getElements(prefix, subtree, styles, targets)) 297 for (let element of this.getElements(prefix, subtree, styles, targets))
297 yield [makeSelector(element), element]; 298 yield [makeSelector(element), element];
298 }, 299 }
299 300
300 /** 301 /**
301 * Generator function returning selected elements. 302 * Generator function returning selected elements.
302 * @param {string} prefix the prefix for the selector. 303 * @param {string} prefix the prefix for the selector.
303 * @param {Node} subtree the subtree we work on. 304 * @param {Node} subtree the subtree we work on.
304 * @param {StringifiedStyle[]} styles the stringified style objects. 305 * @param {StringifiedStyle[]} styles the stringified style objects.
305 * @param {Node[]} [targets] the nodes we are interested in. 306 * @param {Node[]} [targets] the nodes we are interested in.
306 */ 307 */
307 *getElements(prefix, subtree, styles, targets) 308 *getElements(prefix, subtree, styles, targets)
308 { 309 {
(...skipping 22 matching lines...) Expand all
331 else if (scopedQuerySelector(element, selector)) 332 else if (scopedQuerySelector(element, selector))
332 yield element; 333 yield element;
333 } 334 }
334 yield null; 335 yield null;
335 336
336 if (testInfo) 337 if (testInfo)
337 testInfo.lastProcessedElements.add(element); 338 testInfo.lastProcessedElements.add(element);
338 } 339 }
339 } 340 }
340 } 341 }
341 };
342
343 function ContainsSelector(textContent)
344 {
345 this._regexp = makeRegExpParameter(textContent);
346 } 342 }
347 343
348 ContainsSelector.prototype = { 344 class ContainsSelector
349 dependsOnDOM: true, 345 {
350 dependsOnCharacterData: true, 346 constructor(textContent)
347 {
348 this._regexp = makeRegExpParameter(textContent);
349 this.dependsOnDOM = true;
350 this.dependsOnCharacterData = true;
hub 2018/08/20 19:51:21 same here.
Manish Jethani 2018/08/21 03:45:30 Done.
351 }
351 352
352 *getSelectors(prefix, subtree, styles, targets) 353 *getSelectors(prefix, subtree, styles, targets)
353 { 354 {
354 for (let element of this.getElements(prefix, subtree, styles, targets)) 355 for (let element of this.getElements(prefix, subtree, styles, targets))
355 yield [makeSelector(element), subtree]; 356 yield [makeSelector(element), subtree];
356 }, 357 }
357 358
358 *getElements(prefix, subtree, styles, targets) 359 *getElements(prefix, subtree, styles, targets)
359 { 360 {
360 let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ? 361 let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?
361 prefix + "*" : prefix; 362 prefix + "*" : prefix;
362 363
363 let elements = scopedQuerySelectorAll(subtree, actualPrefix); 364 let elements = scopedQuerySelectorAll(subtree, actualPrefix);
364 365
365 if (elements) 366 if (elements)
366 { 367 {
(...skipping 21 matching lines...) Expand all
388 if (this._regexp && this._regexp.test(element.textContent)) 389 if (this._regexp && this._regexp.test(element.textContent))
389 yield element; 390 yield element;
390 else 391 else
391 yield null; 392 yield null;
392 393
393 if (testInfo) 394 if (testInfo)
394 testInfo.lastProcessedElements.add(element); 395 testInfo.lastProcessedElements.add(element);
395 } 396 }
396 } 397 }
397 } 398 }
398 };
399
400 function PropsSelector(propertyExpression)
401 {
402 let regexpString;
403 if (propertyExpression.length >= 2 && propertyExpression[0] == "/" &&
404 propertyExpression[propertyExpression.length - 1] == "/")
405 {
406 regexpString = propertyExpression.slice(1, -1)
407 .replace("\\7B ", "{").replace("\\7D ", "}");
408 }
409 else
410 regexpString = filterToRegExp(propertyExpression);
411
412 this._regexp = new RegExp(regexpString, "i");
413 } 399 }
414 400
415 PropsSelector.prototype = { 401 class PropsSelector
416 dependsOnStyles: true, 402 {
417 dependsOnDOM: true, 403 constructor(propertyExpression)
404 {
405 let regexpString;
406 if (propertyExpression.length >= 2 && propertyExpression[0] == "/" &&
407 propertyExpression[propertyExpression.length - 1] == "/")
408 {
409 regexpString = propertyExpression.slice(1, -1)
410 .replace("\\7B ", "{").replace("\\7D ", "}");
411 }
412 else
413 regexpString = filterToRegExp(propertyExpression);
414
415 this._regexp = new RegExp(regexpString, "i");
416
417 this.dependsOnStyles = true;
418 this.dependsOnDOM = true;
hub 2018/08/20 19:51:21 and here.
Manish Jethani 2018/08/21 03:45:30 Done.
419 }
418 420
419 *findPropsSelectors(styles, prefix, regexp) 421 *findPropsSelectors(styles, prefix, regexp)
420 { 422 {
421 for (let style of styles) 423 for (let style of styles)
422 if (regexp.test(style.style)) 424 if (regexp.test(style.style))
423 for (let subSelector of style.subSelectors) 425 for (let subSelector of style.subSelectors)
424 { 426 {
425 if (subSelector.startsWith("*") && 427 if (subSelector.startsWith("*") &&
426 !incompletePrefixRegexp.test(prefix)) 428 !incompletePrefixRegexp.test(prefix))
427 { 429 {
428 subSelector = subSelector.substr(1); 430 subSelector = subSelector.substr(1);
429 } 431 }
430 let idx = subSelector.lastIndexOf("::"); 432 let idx = subSelector.lastIndexOf("::");
431 if (idx != -1) 433 if (idx != -1)
432 subSelector = subSelector.substr(0, idx); 434 subSelector = subSelector.substr(0, idx);
433 yield qualifySelector(subSelector, prefix); 435 yield qualifySelector(subSelector, prefix);
434 } 436 }
435 }, 437 }
436 438
437 *getSelectors(prefix, subtree, styles, targets) 439 *getSelectors(prefix, subtree, styles, targets)
438 { 440 {
439 for (let selector of this.findPropsSelectors(styles, prefix, this._regexp)) 441 for (let selector of this.findPropsSelectors(styles, prefix, this._regexp))
440 yield [selector, subtree]; 442 yield [selector, subtree];
441 } 443 }
442 };
443
444 function Pattern(selectors, text)
445 {
446 this.selectors = selectors;
447 this.text = text;
448 } 444 }
449 445
450 Pattern.prototype = { 446 class Pattern
447 {
448 constructor(selectors, text)
449 {
450 this.selectors = selectors;
451 this.text = text;
452 }
453
451 get dependsOnStyles() 454 get dependsOnStyles()
452 { 455 {
453 return getCachedPropertyValue( 456 return getCachedPropertyValue(
454 this, "_dependsOnStyles", 457 this, "_dependsOnStyles",
455 () => this.selectors.some(selector => selector.dependsOnStyles) 458 () => this.selectors.some(selector => selector.dependsOnStyles)
456 ); 459 );
457 }, 460 }
458 461
459 get dependsOnDOM() 462 get dependsOnDOM()
460 { 463 {
461 return getCachedPropertyValue( 464 return getCachedPropertyValue(
462 this, "_dependsOnDOM", 465 this, "_dependsOnDOM",
463 () => this.selectors.some(selector => selector.dependsOnDOM) 466 () => this.selectors.some(selector => selector.dependsOnDOM)
464 ); 467 );
465 }, 468 }
466 469
467 get dependsOnStylesAndDOM() 470 get dependsOnStylesAndDOM()
468 { 471 {
469 return getCachedPropertyValue( 472 return getCachedPropertyValue(
470 this, "_dependsOnStylesAndDOM", 473 this, "_dependsOnStylesAndDOM",
471 () => this.selectors.some(selector => selector.dependsOnStyles && 474 () => this.selectors.some(selector => selector.dependsOnStyles &&
472 selector.dependsOnDOM) 475 selector.dependsOnDOM)
473 ); 476 );
474 }, 477 }
475 478
476 get maybeDependsOnAttributes() 479 get maybeDependsOnAttributes()
477 { 480 {
478 // Observe changes to attributes if either there's a plain selector that 481 // Observe changes to attributes if either there's a plain selector that
479 // looks like an ID selector, class selector, or attribute selector in one 482 // looks like an ID selector, class selector, or attribute selector in one
480 // of the patterns (e.g. "a[href='https://example.com/']") 483 // of the patterns (e.g. "a[href='https://example.com/']")
481 // or there's a properties selector nested inside a has selector 484 // or there's a properties selector nested inside a has selector
482 // (e.g. "div:-abp-has(:-abp-properties(color: blue))") 485 // (e.g. "div:-abp-has(:-abp-properties(color: blue))")
483 return getCachedPropertyValue( 486 return getCachedPropertyValue(
484 this, "_maybeDependsOnAttributes", 487 this, "_maybeDependsOnAttributes",
485 () => this.selectors.some( 488 () => this.selectors.some(
486 selector => selector.maybeDependsOnAttributes || 489 selector => selector.maybeDependsOnAttributes ||
487 (selector instanceof HasSelector && 490 (selector instanceof HasSelector &&
488 selector.dependsOnStyles) 491 selector.dependsOnStyles)
489 ) 492 )
490 ); 493 );
491 }, 494 }
492 495
493 get dependsOnCharacterData() 496 get dependsOnCharacterData()
494 { 497 {
495 // Observe changes to character data only if there's a contains selector in 498 // Observe changes to character data only if there's a contains selector in
496 // one of the patterns. 499 // one of the patterns.
497 return getCachedPropertyValue( 500 return getCachedPropertyValue(
498 this, "_dependsOnCharacterData", 501 this, "_dependsOnCharacterData",
499 () => this.selectors.some(selector => selector.dependsOnCharacterData) 502 () => this.selectors.some(selector => selector.dependsOnCharacterData)
500 ); 503 );
501 }, 504 }
502 505
503 get maybeContainsSiblingCombinators() 506 get maybeContainsSiblingCombinators()
504 { 507 {
505 return getCachedPropertyValue( 508 return getCachedPropertyValue(
506 this, "_maybeContainsSiblingCombinators", 509 this, "_maybeContainsSiblingCombinators",
507 () => this.selectors.some(selector => 510 () => this.selectors.some(selector =>
508 selector.maybeContainsSiblingCombinators) 511 selector.maybeContainsSiblingCombinators)
509 ); 512 );
510 }, 513 }
511 514
512 matchesMutationTypes(mutationTypes) 515 matchesMutationTypes(mutationTypes)
513 { 516 {
514 let mutationTypeMatchMap = getCachedPropertyValue( 517 let mutationTypeMatchMap = getCachedPropertyValue(
515 this, "_mutationTypeMatchMap", 518 this, "_mutationTypeMatchMap",
516 () => new Map([ 519 () => new Map([
517 // All types of DOM-dependent patterns are affected by mutations of 520 // All types of DOM-dependent patterns are affected by mutations of
518 // type "childList". 521 // type "childList".
519 ["childList", true], 522 ["childList", true],
520 ["attributes", this.maybeDependsOnAttributes], 523 ["attributes", this.maybeDependsOnAttributes],
521 ["characterData", this.dependsOnCharacterData] 524 ["characterData", this.dependsOnCharacterData]
522 ]) 525 ])
523 ); 526 );
524 527
525 for (let mutationType of mutationTypes) 528 for (let mutationType of mutationTypes)
526 { 529 {
527 if (mutationTypeMatchMap.get(mutationType)) 530 if (mutationTypeMatchMap.get(mutationType))
528 return true; 531 return true;
529 } 532 }
530 533
531 return false; 534 return false;
532 } 535 }
533 }; 536 }
534 537
535 function extractMutationTypes(mutations) 538 function extractMutationTypes(mutations)
536 { 539 {
537 let types = new Set(); 540 let types = new Set();
538 541
539 for (let mutation of mutations) 542 for (let mutation of mutations)
540 { 543 {
541 types.add(mutation.type); 544 types.add(mutation.type);
542 545
543 // There are only 3 types of mutations: "attributes", "characterData", and 546 // There are only 3 types of mutations: "attributes", "characterData", and
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 function shouldObserveAttributes(patterns) 594 function shouldObserveAttributes(patterns)
592 { 595 {
593 return patterns.some(pattern => pattern.maybeDependsOnAttributes); 596 return patterns.some(pattern => pattern.maybeDependsOnAttributes);
594 } 597 }
595 598
596 function shouldObserveCharacterData(patterns) 599 function shouldObserveCharacterData(patterns)
597 { 600 {
598 return patterns.some(pattern => pattern.dependsOnCharacterData); 601 return patterns.some(pattern => pattern.dependsOnCharacterData);
599 } 602 }
600 603
601 function ElemHideEmulation(addSelectorsFunc, hideElemsFunc) 604 class ElemHideEmulation
602 { 605 {
603 this.document = document; 606 constructor(addSelectorsFunc, hideElemsFunc)
604 this.addSelectorsFunc = addSelectorsFunc; 607 {
605 this.hideElemsFunc = hideElemsFunc; 608 this._filteringInProgress = false;
606 this.observer = new MutationObserver(this.observe.bind(this)); 609 this._lastInvocation = -MIN_INVOCATION_INTERVAL;
607 } 610 this._scheduledProcessing = null;
608 611
609 ElemHideEmulation.prototype = { 612 this.document = document;
613 this.addSelectorsFunc = addSelectorsFunc;
614 this.hideElemsFunc = hideElemsFunc;
615 this.observer = new MutationObserver(this.observe.bind(this));
616 }
617
610 isSameOrigin(stylesheet) 618 isSameOrigin(stylesheet)
611 { 619 {
612 try 620 try
613 { 621 {
614 return new URL(stylesheet.href).origin == this.document.location.origin; 622 return new URL(stylesheet.href).origin == this.document.location.origin;
615 } 623 }
616 catch (e) 624 catch (e)
617 { 625 {
618 // Invalid URL, assume that it is first-party. 626 // Invalid URL, assume that it is first-party.
619 return true; 627 return true;
620 } 628 }
621 }, 629 }
622 630
623 /** Parse the selector 631 /** Parse the selector
624 * @param {string} selector the selector to parse 632 * @param {string} selector the selector to parse
625 * @return {Array} selectors is an array of objects, 633 * @return {Array} selectors is an array of objects,
626 * or null in case of errors. 634 * or null in case of errors.
627 */ 635 */
628 parseSelector(selector) 636 parseSelector(selector)
629 { 637 {
630 if (selector.length == 0) 638 if (selector.length == 0)
631 return []; 639 return [];
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 selectors.push(...suffix); 682 selectors.push(...suffix);
675 683
676 if (selectors.length == 1 && selectors[0] instanceof ContainsSelector) 684 if (selectors.length == 1 && selectors[0] instanceof ContainsSelector)
677 { 685 {
678 console.error(new SyntaxError("Failed to parse Adblock Plus " + 686 console.error(new SyntaxError("Failed to parse Adblock Plus " +
679 `selector ${selector}, can't ` + 687 `selector ${selector}, can't ` +
680 "have a lonely :-abp-contains().")); 688 "have a lonely :-abp-contains()."));
681 return null; 689 return null;
682 } 690 }
683 return selectors; 691 return selectors;
684 }, 692 }
685 693
686 /** 694 /**
687 * Processes the current document and applies all rules to it. 695 * Processes the current document and applies all rules to it.
688 * @param {CSSStyleSheet[]} [stylesheets] 696 * @param {CSSStyleSheet[]} [stylesheets]
689 * The list of new stylesheets that have been added to the document and 697 * The list of new stylesheets that have been added to the document and
690 * made reprocessing necessary. This parameter shouldn't be passed in for 698 * made reprocessing necessary. This parameter shouldn't be passed in for
691 * the initial processing, all of document's stylesheets will be considered 699 * the initial processing, all of document's stylesheets will be considered
692 * then and all rules, including the ones not dependent on styles. 700 * then and all rules, including the ones not dependent on styles.
693 * @param {MutationRecord[]} [mutations] 701 * @param {MutationRecord[]} [mutations]
694 * The list of DOM mutations that have been applied to the document and 702 * The list of DOM mutations that have been applied to the document and
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
810 { 818 {
811 setTimeout(processPatterns, 0); 819 setTimeout(processPatterns, 0);
812 return; 820 return;
813 } 821 }
814 } 822 }
815 pattern = null; 823 pattern = null;
816 return processPatterns(); 824 return processPatterns();
817 }; 825 };
818 826
819 processPatterns(); 827 processPatterns();
820 }, 828 }
821 829
822 // This property is only used in the tests 830 // This property is only used in the tests
823 // to shorten the invocation interval 831 // to shorten the invocation interval
824 get MIN_INVOCATION_INTERVAL() 832 get MIN_INVOCATION_INTERVAL()
825 { 833 {
826 return MIN_INVOCATION_INTERVAL; 834 return MIN_INVOCATION_INTERVAL;
827 }, 835 }
828 836
829 set MIN_INVOCATION_INTERVAL(interval) 837 set MIN_INVOCATION_INTERVAL(interval)
830 { 838 {
831 MIN_INVOCATION_INTERVAL = interval; 839 MIN_INVOCATION_INTERVAL = interval;
832 }, 840 }
833
834 _filteringInProgress: false,
835 _lastInvocation: -MIN_INVOCATION_INTERVAL,
836 _scheduledProcessing: null,
837 841
838 /** 842 /**
839 * Re-run filtering either immediately or queued. 843 * Re-run filtering either immediately or queued.
840 * @param {CSSStyleSheet[]} [stylesheets] 844 * @param {CSSStyleSheet[]} [stylesheets]
841 * new stylesheets to be processed. This parameter should be omitted 845 * new stylesheets to be processed. This parameter should be omitted
842 * for full reprocessing. 846 * for full reprocessing.
843 * @param {MutationRecord[]} [mutations] 847 * @param {MutationRecord[]} [mutations]
844 * new DOM mutations to be processed. This parameter should be omitted 848 * new DOM mutations to be processed. This parameter should be omitted
845 * for full reprocessing. 849 * for full reprocessing.
846 */ 850 */
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 this._scheduledProcessing = null; 912 this._scheduledProcessing = null;
909 this._addSelectors(params.stylesheets, params.mutations, completion); 913 this._addSelectors(params.stylesheets, params.mutations, completion);
910 }; 914 };
911 this.document.addEventListener("DOMContentLoaded", handler); 915 this.document.addEventListener("DOMContentLoaded", handler);
912 } 916 }
913 else 917 else
914 { 918 {
915 this._filteringInProgress = true; 919 this._filteringInProgress = true;
916 this._addSelectors(stylesheets, mutations, completion); 920 this._addSelectors(stylesheets, mutations, completion);
917 } 921 }
918 }, 922 }
919 923
920 onLoad(event) 924 onLoad(event)
921 { 925 {
922 let stylesheet = event.target.sheet; 926 let stylesheet = event.target.sheet;
923 if (stylesheet) 927 if (stylesheet)
924 this.queueFiltering([stylesheet]); 928 this.queueFiltering([stylesheet]);
925 }, 929 }
926 930
927 observe(mutations) 931 observe(mutations)
928 { 932 {
929 if (testInfo) 933 if (testInfo)
930 { 934 {
931 // In test mode, filter out any mutations likely done by us 935 // In test mode, filter out any mutations likely done by us
932 // (i.e. style="display: none !important"). This makes it easier to 936 // (i.e. style="display: none !important"). This makes it easier to
933 // observe how the code responds to DOM mutations. 937 // observe how the code responds to DOM mutations.
934 mutations = mutations.filter( 938 mutations = mutations.filter(
935 ({type, attributeName, target: {style: newValue}, oldValue}) => 939 ({type, attributeName, target: {style: newValue}, oldValue}) =>
936 !(type == "attributes" && attributeName == "style" && 940 !(type == "attributes" && attributeName == "style" &&
937 newValue.display == "none" && oldValue.display != "none") 941 newValue.display == "none" && oldValue.display != "none")
938 ); 942 );
939 943
940 if (mutations.length == 0) 944 if (mutations.length == 0)
941 return; 945 return;
942 } 946 }
943 947
944 this.queueFiltering(null, mutations); 948 this.queueFiltering(null, mutations);
945 }, 949 }
946 950
947 apply(patterns) 951 apply(patterns)
948 { 952 {
949 this.patterns = []; 953 this.patterns = [];
950 for (let pattern of patterns) 954 for (let pattern of patterns)
951 { 955 {
952 let selectors = this.parseSelector(pattern.selector); 956 let selectors = this.parseSelector(pattern.selector);
953 if (selectors != null && selectors.length > 0) 957 if (selectors != null && selectors.length > 0)
954 this.patterns.push(new Pattern(selectors, pattern.text)); 958 this.patterns.push(new Pattern(selectors, pattern.text));
955 } 959 }
956 960
957 if (this.patterns.length > 0) 961 if (this.patterns.length > 0)
958 { 962 {
959 this.queueFiltering(); 963 this.queueFiltering();
960 this.observer.observe( 964 this.observer.observe(
961 this.document, 965 this.document,
962 { 966 {
963 childList: true, 967 childList: true,
964 attributes: shouldObserveAttributes(this.patterns), 968 attributes: shouldObserveAttributes(this.patterns),
965 characterData: shouldObserveCharacterData(this.patterns), 969 characterData: shouldObserveCharacterData(this.patterns),
966 subtree: true 970 subtree: true
967 } 971 }
968 ); 972 );
969 this.document.addEventListener("load", this.onLoad.bind(this), true); 973 this.document.addEventListener("load", this.onLoad.bind(this), true);
970 } 974 }
971 } 975 }
972 }; 976 }
973 977
974 exports.ElemHideEmulation = ElemHideEmulation; 978 exports.ElemHideEmulation = ElemHideEmulation;
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