OLD | NEW |
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 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
393 function patternDependsOnDOM(pattern) | 393 function patternDependsOnDOM(pattern) |
394 { | 394 { |
395 return pattern.selectors.some(s => s.dependsOnDOM); | 395 return pattern.selectors.some(s => s.dependsOnDOM); |
396 } | 396 } |
397 | 397 |
398 function patternDependsOnStylesAndDOM(pattern) | 398 function patternDependsOnStylesAndDOM(pattern) |
399 { | 399 { |
400 return pattern.selectors.some(s => s.dependsOnStyles && s.dependsOnDOM); | 400 return pattern.selectors.some(s => s.dependsOnStyles && s.dependsOnDOM); |
401 } | 401 } |
402 | 402 |
403 function filterPatterns(patterns, {stylesheets, mutations}) | 403 function patternMaybeDependsOnAttributes(pattern) |
404 { | |
405 if (stylesheets && !mutations) | |
406 return patterns.filter(patternDependsOnStyles); | |
407 | |
408 if (!stylesheets && mutations) | |
409 return patterns.filter(patternDependsOnDOM); | |
410 | |
411 return patterns.slice(); | |
412 } | |
413 | |
414 function shouldObserveAttributes(patterns) | |
415 { | 404 { |
416 // Observe changes to attributes if either there's a plain selector that | 405 // Observe changes to attributes if either there's a plain selector that |
417 // looks like an ID selector, class selector, or attribute selector in one of | 406 // looks like an ID selector, class selector, or attribute selector in one of |
418 // the patterns (e.g. "a[href='https://example.com/']") | 407 // the patterns (e.g. "a[href='https://example.com/']") |
419 // or there's a properties selector nested inside a has selector | 408 // or there's a properties selector nested inside a has selector |
420 // (e.g. "div:-abp-has(:-abp-properties(color: blue))") | 409 // (e.g. "div:-abp-has(:-abp-properties(color: blue))") |
421 return patterns.some( | 410 return pattern.selectors.some( |
422 pattern => pattern.selectors.some( | 411 selector => selector.maybeDependsOnAttributes || |
423 selector => selector.maybeDependsOnAttributes || | 412 (selector instanceof HasSelector && |
424 (selector instanceof HasSelector && | 413 selector.dependsOnStyles) |
425 selector.dependsOnStyles) | |
426 ) | |
427 ); | 414 ); |
428 } | 415 } |
429 | 416 |
| 417 function patternDependsOnCharacterData(pattern) |
| 418 { |
| 419 // Observe changes to character data only if there's a contains selector in |
| 420 // one of the patterns. |
| 421 return pattern.selectors.some(selector => selector.dependsOnCharacterData); |
| 422 } |
| 423 |
| 424 function patternMatchesMutationTypes(pattern, mutationTypes) |
| 425 { |
| 426 return mutationTypes.has("childList") || |
| 427 (mutationTypes.has("attributes") && |
| 428 patternMaybeDependsOnAttributes(pattern)) || |
| 429 (mutationTypes.has("characterData") && |
| 430 patternDependsOnCharacterData(pattern)); |
| 431 } |
| 432 |
| 433 function extractMutationTypes(mutations) |
| 434 { |
| 435 let types = new Set(); |
| 436 |
| 437 for (let mutation of mutations) |
| 438 { |
| 439 types.add(mutation.type); |
| 440 |
| 441 // There are only 3 types of mutations: "attributes", "characterData", and |
| 442 // "childList". |
| 443 if (types.size == 3) |
| 444 break; |
| 445 } |
| 446 |
| 447 return types; |
| 448 } |
| 449 |
| 450 function filterPatterns(patterns, {stylesheets, mutations}) |
| 451 { |
| 452 if (!stylesheets && !mutations) |
| 453 return patterns.slice(); |
| 454 |
| 455 let mutationTypes = mutations ? extractMutationTypes(mutations) : null; |
| 456 |
| 457 return patterns.filter( |
| 458 pattern => (stylesheets && patternDependsOnStyles(pattern)) || |
| 459 (mutations && patternDependsOnDOM(pattern) && |
| 460 patternMatchesMutationTypes(pattern, mutationTypes)) |
| 461 ); |
| 462 } |
| 463 |
| 464 function shouldObserveAttributes(patterns) |
| 465 { |
| 466 return patterns.some(patternMaybeDependsOnAttributes); |
| 467 } |
| 468 |
430 function shouldObserveCharacterData(patterns) | 469 function shouldObserveCharacterData(patterns) |
431 { | 470 { |
432 // Observe changes to character data only if there's a contains selector in | 471 return patterns.some(patternDependsOnCharacterData); |
433 // one of the patterns. | |
434 return patterns.some( | |
435 pattern => pattern.selectors.some( | |
436 selector => selector.dependsOnCharacterData | |
437 ) | |
438 ); | |
439 } | 472 } |
440 | 473 |
441 function ElemHideEmulation(addSelectorsFunc, hideElemsFunc) | 474 function ElemHideEmulation(addSelectorsFunc, hideElemsFunc) |
442 { | 475 { |
443 this.document = document; | 476 this.document = document; |
444 this.addSelectorsFunc = addSelectorsFunc; | 477 this.addSelectorsFunc = addSelectorsFunc; |
445 this.hideElemsFunc = hideElemsFunc; | 478 this.hideElemsFunc = hideElemsFunc; |
446 this.observer = new MutationObserver(this.observe.bind(this)); | 479 this.observer = new MutationObserver(this.observe.bind(this)); |
447 } | 480 } |
448 | 481 |
(...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
768 characterData: shouldObserveCharacterData(this.patterns), | 801 characterData: shouldObserveCharacterData(this.patterns), |
769 subtree: true | 802 subtree: true |
770 } | 803 } |
771 ); | 804 ); |
772 this.document.addEventListener("load", this.onLoad.bind(this), true); | 805 this.document.addEventListener("load", this.onLoad.bind(this), true); |
773 } | 806 } |
774 } | 807 } |
775 }; | 808 }; |
776 | 809 |
777 exports.ElemHideEmulation = ElemHideEmulation; | 810 exports.ElemHideEmulation = ElemHideEmulation; |
OLD | NEW |