| 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 | 
|   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the |   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|   12  * GNU General Public License for more details. |   12  * GNU General Public License for more details. | 
|   13  * |   13  * | 
|   14  * You should have received a copy of the GNU General Public License |   14  * You should have received a copy of the GNU General Public License | 
|   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. |   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
|   16  */ |   16  */ | 
|   17  |   17  | 
|   18 "use strict"; |   18 "use strict"; | 
|   19  |   19  | 
|   20 /** |   20 /** | 
|   21  * @fileOverview Element hiding emulation implementation. |   21  * @fileOverview Element hiding emulation implementation. | 
|   22  */ |   22  */ | 
|   23  |   23  | 
|   24 const {ElemHide} = require("./elemHide"); |   24 const {ElemHide} = require("./elemHide"); | 
|   25 const {Filter} = require("./filterClasses"); |   25 const {filterIt, mapIt, flattenIt, regExpIt} = require("./coreUtils"); | 
|   26  |   26  | 
|   27 let filters = new Set(); |   27 /** | 
 |   28  * Map of element hiding emulation filters by domain | 
 |   29  * @type {Map.<string,Set.<ElemHideEmulationFilter>>} | 
 |   30  */ | 
 |   31 let filtersByDomain = new Map(); | 
 |   32  | 
 |   33 /** | 
 |   34  * Set containing known element hiding emulation filters | 
 |   35  * @type {Set.<ElemHideEmulation>} | 
 |   36  */ | 
 |   37 let knownFilters = new Set(); | 
 |   38  | 
 |   39 function* filterDomains(filter) | 
 |   40 { | 
 |   41   yield* mapIt(filterIt(filter.domains || [], ([domain]) => domain != ""), | 
 |   42                ([domain, include]) => [domain, include, | 
 |   43                                        filtersByDomain.get(domain)]); | 
 |   44 } | 
 |   45  | 
 |   46 function* filtersForDomain(domain) | 
 |   47 { | 
 |   48   yield* filtersByDomain.get(domain) || []; | 
 |   49  | 
 |   50   let subdomainIt = | 
 |   51     mapIt(regExpIt(/([^|]*)\|/g, domain.replace(/([^.]+\.)/g, "$'|")), | 
 |   52           ([, subdomain]) => filtersByDomain.get(subdomain) || []); | 
 |   53   yield* flattenIt(subdomainIt); | 
 |   54 } | 
|   28  |   55  | 
|   29 /** |   56 /** | 
|   30  * Container for element hiding emulation filters |   57  * Container for element hiding emulation filters | 
|   31  * @class |   58  * @class | 
|   32  */ |   59  */ | 
|   33 let ElemHideEmulation = { |   60 let ElemHideEmulation = { | 
|   34   /** |   61   /** | 
|   35    * Removes all known filters |   62    * Removes all known filters | 
|   36    */ |   63    */ | 
|   37   clear() |   64   clear() | 
|   38   { |   65   { | 
|   39     filters.clear(); |   66     filtersByDomain.clear(); | 
|   40   }, |   67   }, | 
|   41  |   68  | 
|   42   /** |   69   /** | 
|   43    * Add a new element hiding emulation filter |   70    * Add a new element hiding emulation filter | 
|   44    * @param {ElemHideEmulationFilter} filter |   71    * @param {ElemHideEmulationFilter} filter | 
|   45    */ |   72    */ | 
|   46   add(filter) |   73   add(filter) | 
|   47   { |   74   { | 
|   48     filters.add(filter.text); |   75     if (knownFilters.has(filter)) | 
 |   76       return; | 
 |   77  | 
 |   78     for (let [domain, include, filters] of filterDomains(filter)) | 
 |   79     { | 
 |   80       if (filters) | 
 |   81         filters.set(filter, include); | 
 |   82       else | 
 |   83         filtersByDomain.set(domain, new Map([[filter, include]])); | 
 |   84     } | 
 |   85  | 
 |   86     knownFilters.add(filter); | 
|   49   }, |   87   }, | 
|   50  |   88  | 
|   51   /** |   89   /** | 
|   52    * Removes an element hiding emulation filter |   90    * Removes an element hiding emulation filter | 
|   53    * @param {ElemHideEmulationFilter} filter |   91    * @param {ElemHideEmulationFilter} filter | 
|   54    */ |   92    */ | 
|   55   remove(filter) |   93   remove(filter) | 
|   56   { |   94   { | 
|   57     filters.delete(filter.text); |   95     if (!knownFilters.has(filter)) | 
 |   96       return; | 
 |   97  | 
 |   98     for (let [domain, , filters] of filterDomains(filter)) | 
 |   99     { | 
 |  100       if (filters) | 
 |  101       { | 
 |  102         filters.delete(filter); | 
 |  103  | 
 |  104         if (filters.size == 0) | 
 |  105           filtersByDomain.delete(domain); | 
 |  106       } | 
 |  107     } | 
 |  108  | 
 |  109     knownFilters.delete(filter); | 
|   58   }, |  110   }, | 
|   59  |  111  | 
|   60   /** |  112   /** | 
|   61    * Returns a list of all rules active on a particular domain |  113    * Returns a list of all rules active on a particular domain | 
|   62    * @param {string} domain |  114    * @param {string} domain | 
|   63    * @return {ElemHideEmulationFilter[]} |  115    * @return {ElemHideEmulationFilter[]} | 
|   64    */ |  116    */ | 
|   65   getRulesForDomain(domain) |  117   getRulesForDomain(domain) | 
|   66   { |  118   { | 
|   67     let result = []; |  119     let result = []; | 
|   68     for (let text of filters.values()) |  120  | 
 |  121     let excludeSet = new Set(); | 
 |  122     for (let [filter, include] of filtersForDomain(domain.toUpperCase())) | 
|   69     { |  123     { | 
|   70       let filter = Filter.fromText(text); |  124       if (!include) | 
|   71       if (filter.isActiveOnDomain(domain) && |  125       { | 
|   72           !ElemHide.getException(filter, domain)) |  126         excludeSet.add(filter); | 
 |  127       } | 
 |  128       else if ((excludeSet.size == 0 || !excludeSet.has(filter)) && | 
 |  129                !ElemHide.getException(filter, domain)) | 
|   73       { |  130       { | 
|   74         result.push(filter); |  131         result.push(filter); | 
|   75       } |  132       } | 
|   76     } |  133     } | 
 |  134  | 
|   77     return result; |  135     return result; | 
|   78   } |  136   } | 
|   79 }; |  137 }; | 
|   80 exports.ElemHideEmulation = ElemHideEmulation; |  138 exports.ElemHideEmulation = ElemHideEmulation; | 
| OLD | NEW |