Index: lib/elemHide.js |
=================================================================== |
--- a/lib/elemHide.js |
+++ b/lib/elemHide.js |
@@ -16,17 +16,17 @@ |
*/ |
"use strict"; |
/** |
* @fileOverview Element hiding implementation. |
*/ |
-const {ElemHideException} = require("./filterClasses"); |
+const {ElemHideExceptions} = require("./elemHideExceptions"); |
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>>} |
*/ |
let filtersByDomain = new Map(); |
@@ -49,28 +49,22 @@ |
/** |
* Map to be used instead when a filter has a blank domains property. |
* @type {Map.<string,boolean>} |
* @const |
*/ |
let defaultDomains = new Map([["", true]]); |
/** |
- * Set containing known element hiding and exception filters |
- * @type {Set.<ElemHideBase>} |
+ * Set containing known element hiding filters |
+ * @type {Set.<ElemHideFilter>} |
*/ |
let knownFilters = new Set(); |
/** |
- * Lookup table, lists of element hiding exceptions by selector |
- * @type {Map.<string,Filter[]>} |
- */ |
-let exceptions = new Map(); |
- |
-/** |
* Adds a filter to the lookup table of filters by domain. |
* @param {Filter} filter |
*/ |
function addToFiltersByDomain(filter) |
{ |
let domains = filter.domains || defaultDomains; |
for (let [domain, isIncluded] of domains) |
{ |
@@ -92,66 +86,58 @@ |
function getUnconditionalSelectors() |
{ |
if (!unconditionalSelectors) |
unconditionalSelectors = [...filterBySelector.keys()]; |
return unconditionalSelectors; |
} |
+ElemHideExceptions.on("added", ({selector}) => |
+{ |
+ // If this is the first exception for a previously unconditionally applied |
+ // element hiding selector we need to take care to update the lookups. |
+ let unconditionalFilterForSelector = filterBySelector.get(selector); |
+ if (unconditionalFilterForSelector) |
+ { |
+ addToFiltersByDomain(unconditionalFilterForSelector); |
+ filterBySelector.delete(selector); |
+ unconditionalSelectors = null; |
+ } |
+}); |
+ |
/** |
* Container for element hiding filters |
* @class |
*/ |
exports.ElemHide = { |
/** |
* Removes all known filters |
*/ |
clear() |
{ |
- for (let collection of [filtersByDomain, filterBySelector, |
- knownFilters, exceptions]) |
- { |
+ for (let collection of [filtersByDomain, filterBySelector, knownFilters]) |
collection.clear(); |
- } |
+ |
unconditionalSelectors = null; |
FilterNotifier.emit("elemhideupdate"); |
}, |
/** |
* Add a new element hiding filter |
- * @param {ElemHideBase} filter |
+ * @param {ElemHideFilter} filter |
*/ |
add(filter) |
{ |
if (knownFilters.has(filter)) |
return; |
let {selector} = filter; |
- if (filter instanceof ElemHideException) |
- { |
- let list = exceptions.get(selector); |
- if (list) |
- list.push(filter); |
- else |
- exceptions.set(selector, [filter]); |
- |
- // If this is the first exception for a previously unconditionally |
- // applied element hiding selector we need to take care to update the |
- // lookups. |
- let unconditionalFilterForSelector = filterBySelector.get(selector); |
- if (unconditionalFilterForSelector) |
- { |
- addToFiltersByDomain(unconditionalFilterForSelector); |
- filterBySelector.delete(selector); |
- unconditionalSelectors = null; |
- } |
- } |
- else if (!(filter.domains || exceptions.has(selector))) |
+ if (!(filter.domains || ElemHideExceptions.hasExceptions(selector))) |
{ |
// The new filter's selector is unconditionally applied to all domains |
filterBySelector.set(selector, filter); |
unconditionalSelectors = null; |
} |
else |
{ |
// The new filter's selector only applies to some domains |
@@ -159,35 +145,27 @@ |
} |
knownFilters.add(filter); |
FilterNotifier.emit("elemhideupdate"); |
}, |
/** |
* Removes an element hiding filter |
- * @param {ElemHideBase} filter |
+ * @param {ElemHideFilter} filter |
*/ |
remove(filter) |
{ |
if (!knownFilters.has(filter)) |
return; |
let {selector} = filter; |
- // Whitelisting filters |
- if (filter instanceof ElemHideException) |
- { |
- let list = exceptions.get(selector); |
- let index = list.indexOf(filter); |
- if (index >= 0) |
- list.splice(index, 1); |
- } |
// Unconditially applied element hiding filters |
- else if (filterBySelector.get(selector) == filter) |
+ if (filterBySelector.get(selector) == filter) |
{ |
filterBySelector.delete(selector); |
unconditionalSelectors = null; |
} |
// Conditionally applied element hiding filters |
else |
{ |
let domains = filter.domains || defaultDomains; |
@@ -199,38 +177,16 @@ |
} |
} |
knownFilters.delete(filter); |
FilterNotifier.emit("elemhideupdate"); |
}, |
/** |
- * Checks whether an exception rule is registered for a selector on a |
- * particular domain. |
- * @param {string} selector |
- * @param {?string} docDomain |
- * @return {?ElemHideException} |
- */ |
- getException(selector, docDomain) |
- { |
- let list = exceptions.get(selector); |
- if (!list) |
- return null; |
- |
- for (let i = list.length - 1; i >= 0; i--) |
- { |
- if (list[i].isActiveOnDomain(docDomain)) |
- return list[i]; |
- } |
- |
- return null; |
- }, |
- |
- /** |
* Determines from the current filter list which selectors should be applied |
* on a particular host name. |
* @param {string} domain |
* @param {boolean} [specificOnly] true if generic filters should not apply. |
* @returns {string[]} List of selectors. |
*/ |
getSelectorsForDomain(domain, specificOnly = false) |
{ |
@@ -254,17 +210,17 @@ |
if (!isIncluded) |
{ |
excluded.add(filter); |
} |
else |
{ |
let {selector} = filter; |
if ((excluded.size == 0 || !excluded.has(filter)) && |
- !this.getException(selector, domain)) |
+ !ElemHideExceptions.getException(selector, domain)) |
{ |
selectors.push(selector); |
} |
} |
} |
} |
if (currentDomain == "") |