Index: lib/elemHide.js |
=================================================================== |
--- a/lib/elemHide.js |
+++ b/lib/elemHide.js |
@@ -22,17 +22,17 @@ |
*/ |
const {ElemHideException} = require("./filterClasses"); |
const {FilterNotifier} = require("./filterNotifier"); |
/** |
* Lookup table, active flag, by filter by domain. |
* (Only contains filters that aren't unconditionally matched for all domains.) |
- * @type {Map.<string,Map.<Filter,boolean>>} |
+ * @type {Map.<string,Array.<Set.<Filter>>>} |
*/ |
let filtersByDomain = new Map(); |
/** |
* Lookup table, filter by selector. (Only used for selectors that are |
* unconditionally matched for all domains.) |
* @type {Map.<string,Filter>} |
*/ |
@@ -87,18 +87,23 @@ |
for (let [domain, isIncluded] of domains) |
{ |
// There's no need to note that a filter is generically disabled. |
if (!isIncluded && domain == "") |
continue; |
let filters = filtersByDomain.get(domain); |
if (!filters) |
- filtersByDomain.set(domain, filters = new Map()); |
- filters.set(filter, isIncluded); |
+ filtersByDomain.set(domain, filters = []); |
+ |
+ let setIndex = +isIncluded; |
+ if (!filters[setIndex]) |
+ filters[setIndex] = new Set(); |
+ |
+ filters[setIndex].add(filter); |
} |
}, |
/** |
* Add a new element hiding filter |
* @param {ElemHideBase} filter |
*/ |
add(filter) |
@@ -166,19 +171,27 @@ |
unconditionalSelectors = null; |
} |
// Conditionally applied element hiding filters |
else |
{ |
let domains = filter.domains || defaultDomains; |
for (let domain of domains.keys()) |
{ |
- let filters = filtersByDomain.get(domain); |
- if (filters) |
- filters.delete(filter); |
+ let filters = filtersByDomain.get(domain) || []; |
+ for (let i = 0; i < filters.length; i++) |
+ { |
+ if (!filters[i]) |
+ continue; |
+ |
+ filters[i].delete(filter); |
+ |
+ if (filters[i].size == 0) |
+ delete filters[i]; |
+ } |
} |
} |
knownFilters.delete(filter); |
FilterNotifier.emit("elemhideupdate"); |
}, |
/** |
@@ -247,43 +260,48 @@ |
let selectors = []; |
if (typeof criteria == "undefined") |
criteria = ElemHide.ALL_MATCHING; |
if (criteria < ElemHide.NO_UNCONDITIONAL) |
selectors = this.getUnconditionalSelectors(); |
let specificOnly = (criteria >= ElemHide.SPECIFIC_ONLY); |
- let excludedFilters = new Set(); |
+ let excludedFilters = []; |
let currentDomain = domain ? domain.toUpperCase() : ""; |
let currentDomainIsGeneric = currentDomain == ""; |
// This code is a performance hot-spot, which is why we've made certain |
// micro-optimisations. Please be careful before making changes. |
while (true) |
{ |
if (specificOnly && currentDomainIsGeneric) |
break; |
- let filters = filtersByDomain.get(currentDomain); |
- if (filters) |
- { |
- for (let [filter, isIncluded] of filters) |
- { |
- if (excludedFilters.size > 0 && excludedFilters.has(filter)) |
- continue; |
+ let [excluded, included] = filtersByDomain.get(currentDomain) || []; |
+ |
+ if (excluded) |
+ excludedFilters.push(excluded); |
- if (isIncluded) |
+ if (included) |
+ { |
+ for (let filter of included) |
+ { |
+ for (let i = 0; i < excludedFilters.length; i++) |
{ |
- if (!this.getException(filter, domain)) |
- selectors.push(filter.selector); |
+ if (excludedFilters[i].has(filter)) |
+ { |
+ filter = null; |
+ break; |
+ } |
} |
- else if (!currentDomainIsGeneric) |
- excludedFilters.add(filter); |
+ |
+ if (filter && !this.getException(filter, domain)) |
+ selectors.push(filter.selector); |
} |
} |
if (currentDomainIsGeneric) |
break; |
let nextDot = currentDomain.indexOf("."); |
if (nextDot == -1) |