| 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 |