| 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 177 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  188   } |  188   } | 
|  189   // Just in case the getSelectors() generator above had to run some heavy |  189   // Just in case the getSelectors() generator above had to run some heavy | 
|  190   // document.querySelectorAll() call which didn't produce any results, make |  190   // document.querySelectorAll() call which didn't produce any results, make | 
|  191   // sure there is at least one point where execution can pause. |  191   // sure there is at least one point where execution can pause. | 
|  192   yield null; |  192   yield null; | 
|  193 } |  193 } | 
|  194  |  194  | 
|  195 function PlainSelector(selector) |  195 function PlainSelector(selector) | 
|  196 { |  196 { | 
|  197   this._selector = selector; |  197   this._selector = selector; | 
 |  198   this.maybeDependsOnAttributes = /[#.]|\[.+\]/.test(selector); | 
|  198 } |  199 } | 
|  199  |  200  | 
|  200 PlainSelector.prototype = { |  201 PlainSelector.prototype = { | 
|  201   /** |  202   /** | 
|  202    * Generator function returning a pair of selector |  203    * Generator function returning a pair of selector | 
|  203    * string and subtree. |  204    * string and subtree. | 
|  204    * @param {string} prefix the prefix for the selector. |  205    * @param {string} prefix the prefix for the selector. | 
|  205    * @param {Node} subtree the subtree we work on. |  206    * @param {Node} subtree the subtree we work on. | 
|  206    * @param {StringifiedStyle[]} styles the stringified style objects. |  207    * @param {StringifiedStyle[]} styles the stringified style objects. | 
|  207    */ |  208    */ | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
|  219 } |  220 } | 
|  220  |  221  | 
|  221 HasSelector.prototype = { |  222 HasSelector.prototype = { | 
|  222   requiresHiding: true, |  223   requiresHiding: true, | 
|  223  |  224  | 
|  224   get dependsOnStyles() |  225   get dependsOnStyles() | 
|  225   { |  226   { | 
|  226     return this._innerSelectors.some(selector => selector.dependsOnStyles); |  227     return this._innerSelectors.some(selector => selector.dependsOnStyles); | 
|  227   }, |  228   }, | 
|  228  |  229  | 
 |  230   get dependsOnCharacterData() | 
 |  231   { | 
 |  232     return this._innerSelectors.some( | 
 |  233       selector => selector.dependsOnCharacterData | 
 |  234     ); | 
 |  235   }, | 
 |  236  | 
 |  237   get maybeDependsOnAttributes() | 
 |  238   { | 
 |  239     return this._innerSelectors.some( | 
 |  240       selector => selector.maybeDependsOnAttributes | 
 |  241     ); | 
 |  242   }, | 
 |  243  | 
|  229   *getSelectors(prefix, subtree, styles) |  244   *getSelectors(prefix, subtree, styles) | 
|  230   { |  245   { | 
|  231     for (let element of this.getElements(prefix, subtree, styles)) |  246     for (let element of this.getElements(prefix, subtree, styles)) | 
|  232       yield [makeSelector(element, ""), element]; |  247       yield [makeSelector(element, ""), element]; | 
|  233   }, |  248   }, | 
|  234  |  249  | 
|  235   /** |  250   /** | 
|  236    * Generator function returning selected elements. |  251    * Generator function returning selected elements. | 
|  237    * @param {string} prefix the prefix for the selector. |  252    * @param {string} prefix the prefix for the selector. | 
|  238    * @param {Node} subtree the subtree we work on. |  253    * @param {Node} subtree the subtree we work on. | 
| (...skipping 22 matching lines...) Expand all  Loading... | 
|  261   } |  276   } | 
|  262 }; |  277 }; | 
|  263  |  278  | 
|  264 function ContainsSelector(textContent) |  279 function ContainsSelector(textContent) | 
|  265 { |  280 { | 
|  266   this._text = textContent; |  281   this._text = textContent; | 
|  267 } |  282 } | 
|  268  |  283  | 
|  269 ContainsSelector.prototype = { |  284 ContainsSelector.prototype = { | 
|  270   requiresHiding: true, |  285   requiresHiding: true, | 
 |  286   dependsOnCharacterData: true, | 
|  271  |  287  | 
|  272   *getSelectors(prefix, subtree, stylesheet) |  288   *getSelectors(prefix, subtree, stylesheet) | 
|  273   { |  289   { | 
|  274     for (let element of this.getElements(prefix, subtree, stylesheet)) |  290     for (let element of this.getElements(prefix, subtree, stylesheet)) | 
|  275       yield [makeSelector(element, ""), subtree]; |  291       yield [makeSelector(element, ""), subtree]; | 
|  276   }, |  292   }, | 
|  277  |  293  | 
|  278   *getElements(prefix, subtree, stylesheet) |  294   *getElements(prefix, subtree, stylesheet) | 
|  279   { |  295   { | 
|  280     let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ? |  296     let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ? | 
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  337       yield [selector, subtree]; |  353       yield [selector, subtree]; | 
|  338   } |  354   } | 
|  339 }; |  355 }; | 
|  340  |  356  | 
|  341 function isSelectorHidingOnlyPattern(pattern) |  357 function isSelectorHidingOnlyPattern(pattern) | 
|  342 { |  358 { | 
|  343   return pattern.selectors.some(s => s.preferHideWithSelector) && |  359   return pattern.selectors.some(s => s.preferHideWithSelector) && | 
|  344     !pattern.selectors.some(s => s.requiresHiding); |  360     !pattern.selectors.some(s => s.requiresHiding); | 
|  345 } |  361 } | 
|  346  |  362  | 
 |  363 function shouldObserveAttributes(patterns) | 
 |  364 { | 
 |  365   // Observe changes to attributes if either there's a plain selector that | 
 |  366   // looks like an ID selector, class selector, or attribute selector in one of | 
 |  367   // the patterns (e.g. "a[href='https://example.com/']") | 
 |  368   // or there's a properties selector nested inside a has selector | 
 |  369   // (e.g. "div:-abp-has(:-abp-properties(color: blue))") | 
 |  370   return patterns.some( | 
 |  371     pattern => pattern.selectors.some( | 
 |  372       selector => selector.maybeDependsOnAttributes || | 
 |  373                   (selector instanceof HasSelector && | 
 |  374                    selector.dependsOnStyles) | 
 |  375     ) | 
 |  376   ); | 
 |  377 } | 
 |  378  | 
 |  379 function shouldObserveCharacterData(patterns) | 
 |  380 { | 
 |  381   // Observe changes to character data only if there's a contains selector in | 
 |  382   // one of the patterns. | 
 |  383   return patterns.some( | 
 |  384     pattern => pattern.selectors.some( | 
 |  385       selector => selector.dependsOnCharacterData | 
 |  386     ) | 
 |  387   ); | 
 |  388 } | 
 |  389  | 
|  347 function ElemHideEmulation(addSelectorsFunc, hideElemsFunc) |  390 function ElemHideEmulation(addSelectorsFunc, hideElemsFunc) | 
|  348 { |  391 { | 
|  349   this.document = document; |  392   this.document = document; | 
|  350   this.addSelectorsFunc = addSelectorsFunc; |  393   this.addSelectorsFunc = addSelectorsFunc; | 
|  351   this.hideElemsFunc = hideElemsFunc; |  394   this.hideElemsFunc = hideElemsFunc; | 
|  352   this.observer = new MutationObserver(this.observe.bind(this)); |  395   this.observer = new MutationObserver(this.observe.bind(this)); | 
|  353 } |  396 } | 
|  354  |  397  | 
|  355 ElemHideEmulation.prototype = { |  398 ElemHideEmulation.prototype = { | 
|  356   isSameOrigin(stylesheet) |  399   isSameOrigin(stylesheet) | 
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  635         this.patterns.push({selectors, text: pattern.text}); |  678         this.patterns.push({selectors, text: pattern.text}); | 
|  636     } |  679     } | 
|  637  |  680  | 
|  638     if (this.patterns.length > 0) |  681     if (this.patterns.length > 0) | 
|  639     { |  682     { | 
|  640       this.queueFiltering(); |  683       this.queueFiltering(); | 
|  641       this.observer.observe( |  684       this.observer.observe( | 
|  642         this.document, |  685         this.document, | 
|  643         { |  686         { | 
|  644           childList: true, |  687           childList: true, | 
|  645           attributes: true, |  688           attributes: shouldObserveAttributes(this.patterns), | 
|  646           characterData: true, |  689           characterData: shouldObserveCharacterData(this.patterns), | 
|  647           subtree: true |  690           subtree: true | 
|  648         } |  691         } | 
|  649       ); |  692       ); | 
|  650       this.document.addEventListener("load", this.onLoad.bind(this), true); |  693       this.document.addEventListener("load", this.onLoad.bind(this), true); | 
|  651     } |  694     } | 
|  652   } |  695   } | 
|  653 }; |  696 }; | 
|  654  |  697  | 
|  655 exports.ElemHideEmulation = ElemHideEmulation; |  698 exports.ElemHideEmulation = ElemHideEmulation; | 
| OLD | NEW |