| 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 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 59  */ | 59  */ | 
| 60 let knownFilters = new Set(); | 60 let knownFilters = new Set(); | 
| 61 | 61 | 
| 62 /** | 62 /** | 
| 63  * Lookup table, lists of element hiding exceptions by selector | 63  * Lookup table, lists of element hiding exceptions by selector | 
| 64  * @type {Map.<string,Filter>} | 64  * @type {Map.<string,Filter>} | 
| 65  */ | 65  */ | 
| 66 let exceptions = new Map(); | 66 let exceptions = new Map(); | 
| 67 | 67 | 
| 68 /** | 68 /** | 
|  | 69  * Adds a filter to the lookup table of filters by domain. | 
|  | 70  * @param {Filter} | 
|  | 71  */ | 
|  | 72 function addToFiltersByDomain(filter) | 
|  | 73 { | 
|  | 74   let domains = filter.domains || defaultDomains; | 
|  | 75   for (let [domain, isIncluded] of domains) | 
|  | 76   { | 
|  | 77     // There's no need to note that a filter is generically disabled. | 
|  | 78     if (!isIncluded && domain == "") | 
|  | 79       continue; | 
|  | 80 | 
|  | 81     let filters = filtersByDomain.get(domain); | 
|  | 82     if (!filters) | 
|  | 83       filtersByDomain.set(domain, filters = new Map()); | 
|  | 84     filters.set(filter, isIncluded); | 
|  | 85   } | 
|  | 86 } | 
|  | 87 | 
|  | 88 /** | 
|  | 89  * Returns a list of selectors that apply on each website unconditionally. | 
|  | 90  * @returns {string[]} | 
|  | 91  */ | 
|  | 92 function getUnconditionalSelectors() | 
|  | 93 { | 
|  | 94   if (!unconditionalSelectors) | 
|  | 95     unconditionalSelectors = [...filterBySelector.keys()]; | 
|  | 96 | 
|  | 97   return unconditionalSelectors.slice(); | 
|  | 98 } | 
|  | 99 | 
|  | 100 /** | 
| 69  * Container for element hiding filters | 101  * Container for element hiding filters | 
| 70  * @class | 102  * @class | 
| 71  */ | 103  */ | 
| 72 let ElemHide = exports.ElemHide = { | 104 let ElemHide = exports.ElemHide = { | 
| 73   /** | 105   /** | 
| 74    * Removes all known filters | 106    * Removes all known filters | 
| 75    */ | 107    */ | 
| 76   clear() | 108   clear() | 
| 77   { | 109   { | 
| 78     for (let collection of [filtersByDomain, filterBySelector, | 110     for (let collection of [filtersByDomain, filterBySelector, | 
| 79                             knownFilters, exceptions]) | 111                             knownFilters, exceptions]) | 
| 80     { | 112     { | 
| 81       collection.clear(); | 113       collection.clear(); | 
| 82     } | 114     } | 
| 83     unconditionalSelectors = null; | 115     unconditionalSelectors = null; | 
| 84     FilterNotifier.emit("elemhideupdate"); | 116     FilterNotifier.emit("elemhideupdate"); | 
| 85   }, | 117   }, | 
| 86 | 118 | 
| 87   _addToFiltersByDomain(filter) |  | 
| 88   { |  | 
| 89     let domains = filter.domains || defaultDomains; |  | 
| 90     for (let [domain, isIncluded] of domains) |  | 
| 91     { |  | 
| 92       // There's no need to note that a filter is generically disabled. |  | 
| 93       if (!isIncluded && domain == "") |  | 
| 94         continue; |  | 
| 95 |  | 
| 96       let filters = filtersByDomain.get(domain); |  | 
| 97       if (!filters) |  | 
| 98         filtersByDomain.set(domain, filters = new Map()); |  | 
| 99       filters.set(filter, isIncluded); |  | 
| 100     } |  | 
| 101   }, |  | 
| 102 |  | 
| 103   /** | 119   /** | 
| 104    * Add a new element hiding filter | 120    * Add a new element hiding filter | 
| 105    * @param {ElemHideBase} filter | 121    * @param {ElemHideBase} filter | 
| 106    */ | 122    */ | 
| 107   add(filter) | 123   add(filter) | 
| 108   { | 124   { | 
| 109     if (knownFilters.has(filter)) | 125     if (knownFilters.has(filter)) | 
| 110       return; | 126       return; | 
| 111 | 127 | 
| 112     if (filter instanceof ElemHideException) | 128     if (filter instanceof ElemHideException) | 
| 113     { | 129     { | 
| 114       let {selector} = filter; | 130       let {selector} = filter; | 
| 115       let list = exceptions.get(selector); | 131       let list = exceptions.get(selector); | 
| 116       if (list) | 132       if (list) | 
| 117         list.push(filter); | 133         list.push(filter); | 
| 118       else | 134       else | 
| 119         exceptions.set(selector, [filter]); | 135         exceptions.set(selector, [filter]); | 
| 120 | 136 | 
| 121       // If this is the first exception for a previously unconditionally | 137       // If this is the first exception for a previously unconditionally | 
| 122       // applied element hiding selector we need to take care to update the | 138       // applied element hiding selector we need to take care to update the | 
| 123       // lookups. | 139       // lookups. | 
| 124       let unconditionalFilterForSelector = filterBySelector.get(selector); | 140       let unconditionalFilterForSelector = filterBySelector.get(selector); | 
| 125       if (unconditionalFilterForSelector) | 141       if (unconditionalFilterForSelector) | 
| 126       { | 142       { | 
| 127         this._addToFiltersByDomain(unconditionalFilterForSelector); | 143         addToFiltersByDomain(unconditionalFilterForSelector); | 
| 128         filterBySelector.delete(selector); | 144         filterBySelector.delete(selector); | 
| 129         unconditionalSelectors = null; | 145         unconditionalSelectors = null; | 
| 130       } | 146       } | 
| 131     } | 147     } | 
| 132     else if (!(filter.domains || exceptions.has(filter.selector))) | 148     else if (!(filter.domains || exceptions.has(filter.selector))) | 
| 133     { | 149     { | 
| 134       // The new filter's selector is unconditionally applied to all domains | 150       // The new filter's selector is unconditionally applied to all domains | 
| 135       filterBySelector.set(filter.selector, filter); | 151       filterBySelector.set(filter.selector, filter); | 
| 136       unconditionalSelectors = null; | 152       unconditionalSelectors = null; | 
| 137     } | 153     } | 
| 138     else | 154     else | 
| 139     { | 155     { | 
| 140       // The new filter's selector only applies to some domains | 156       // The new filter's selector only applies to some domains | 
| 141       this._addToFiltersByDomain(filter); | 157       addToFiltersByDomain(filter); | 
| 142     } | 158     } | 
| 143 | 159 | 
| 144     knownFilters.add(filter); | 160     knownFilters.add(filter); | 
| 145     FilterNotifier.emit("elemhideupdate"); | 161     FilterNotifier.emit("elemhideupdate"); | 
| 146   }, | 162   }, | 
| 147 | 163 | 
| 148   /** | 164   /** | 
| 149    * Removes an element hiding filter | 165    * Removes an element hiding filter | 
| 150    * @param {ElemHideBase} filter | 166    * @param {ElemHideBase} filter | 
| 151    */ | 167    */ | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 200     for (let i = list.length - 1; i >= 0; i--) | 216     for (let i = list.length - 1; i >= 0; i--) | 
| 201     { | 217     { | 
| 202       if (list[i].isActiveOnDomain(docDomain)) | 218       if (list[i].isActiveOnDomain(docDomain)) | 
| 203         return list[i]; | 219         return list[i]; | 
| 204     } | 220     } | 
| 205 | 221 | 
| 206     return null; | 222     return null; | 
| 207   }, | 223   }, | 
| 208 | 224 | 
| 209   /** | 225   /** | 
| 210    * Returns a list of selectors that apply on each website unconditionally. |  | 
| 211    * @returns {string[]} |  | 
| 212    */ |  | 
| 213   getUnconditionalSelectors() |  | 
| 214   { |  | 
| 215     if (!unconditionalSelectors) |  | 
| 216       unconditionalSelectors = [...filterBySelector.keys()]; |  | 
| 217     return unconditionalSelectors.slice(); |  | 
| 218   }, |  | 
| 219 |  | 
| 220   /** |  | 
| 221    * Constant used by getSelectorsForDomain to return all selectors applying to | 226    * Constant used by getSelectorsForDomain to return all selectors applying to | 
| 222    * a particular hostname. | 227    * a particular hostname. | 
| 223    * @type {number} | 228    * @type {number} | 
| 224    * @const | 229    * @const | 
| 225    */ | 230    */ | 
| 226   ALL_MATCHING: 0, | 231   ALL_MATCHING: 0, | 
| 227 | 232 | 
| 228   /** | 233   /** | 
| 229    * Constant used by getSelectorsForDomain to exclude selectors which apply to | 234    * Constant used by getSelectorsForDomain to exclude selectors which apply to | 
| 230    * all websites without exception. | 235    * all websites without exception. | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 249    *   One of the following: ElemHide.ALL_MATCHING, ElemHide.NO_UNCONDITIONAL or | 254    *   One of the following: ElemHide.ALL_MATCHING, ElemHide.NO_UNCONDITIONAL or | 
| 250    *                         ElemHide.SPECIFIC_ONLY. | 255    *                         ElemHide.SPECIFIC_ONLY. | 
| 251    * @returns {string[]} | 256    * @returns {string[]} | 
| 252    *   List of selectors. | 257    *   List of selectors. | 
| 253    */ | 258    */ | 
| 254   getSelectorsForDomain(domain, criteria = ElemHide.ALL_MATCHING) | 259   getSelectorsForDomain(domain, criteria = ElemHide.ALL_MATCHING) | 
| 255   { | 260   { | 
| 256     let selectors = []; | 261     let selectors = []; | 
| 257 | 262 | 
| 258     if (criteria < ElemHide.NO_UNCONDITIONAL) | 263     if (criteria < ElemHide.NO_UNCONDITIONAL) | 
| 259       selectors = this.getUnconditionalSelectors(); | 264       selectors = getUnconditionalSelectors(); | 
| 260 | 265 | 
| 261     let specificOnly = (criteria >= ElemHide.SPECIFIC_ONLY); | 266     let specificOnly = (criteria >= ElemHide.SPECIFIC_ONLY); | 
| 262     let excluded = new Set(); | 267     let excluded = new Set(); | 
| 263     let currentDomain = domain ? domain.toUpperCase() : ""; | 268     let currentDomain = domain ? domain.toUpperCase() : ""; | 
| 264 | 269 | 
| 265     // This code is a performance hot-spot, which is why we've made certain | 270     // This code is a performance hot-spot, which is why we've made certain | 
| 266     // micro-optimisations. Please be careful before making changes. | 271     // micro-optimisations. Please be careful before making changes. | 
| 267     while (true) | 272     while (true) | 
| 268     { | 273     { | 
| 269       if (specificOnly && currentDomain == "") | 274       if (specificOnly && currentDomain == "") | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 289       if (currentDomain == "") | 294       if (currentDomain == "") | 
| 290         break; | 295         break; | 
| 291 | 296 | 
| 292       let nextDot = currentDomain.indexOf("."); | 297       let nextDot = currentDomain.indexOf("."); | 
| 293       currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1); | 298       currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1); | 
| 294     } | 299     } | 
| 295 | 300 | 
| 296     return selectors; | 301     return selectors; | 
| 297   } | 302   } | 
| 298 }; | 303 }; | 
| OLD | NEW | 
|---|