| Index: lib/elemHideExceptions.js | 
| =================================================================== | 
| --- a/lib/elemHideExceptions.js | 
| +++ b/lib/elemHideExceptions.js | 
| @@ -26,32 +26,39 @@ | 
| /** | 
| * Lookup table, lists of element hiding exceptions by selector | 
| * @type {Map.<string,ElemHideException[]>} | 
| */ | 
| let exceptions = new Map(); | 
| /** | 
| + * Number of element hiding exceptions per domain. | 
| + * @type {Map.<string,number>} | 
| + */ | 
| +let exceptionCountByDomain = new Map(); | 
| + | 
| +/** | 
| * Set containing known element exceptions | 
| * @type {Set.<ElemHideException>} | 
| */ | 
| let knownExceptions = new Set(); | 
| /** | 
| * Container for element hiding exceptions | 
| * @class | 
| */ | 
| exports.ElemHideExceptions = Object.assign(Object.create(new EventEmitter()), { | 
| /** | 
| * Removes all known exceptions | 
| */ | 
| clear() | 
| { | 
| exceptions.clear(); | 
| + exceptionCountByDomain.clear(); | 
| knownExceptions.clear(); | 
| filterNotifier.emit("elemhideupdate"); | 
| }, | 
| /** | 
| * Add a new element hiding exception | 
| * @param {ElemHideException} exception | 
| @@ -63,16 +70,25 @@ | 
| let {selector} = exception; | 
| let list = exceptions.get(selector); | 
| if (list) | 
| list.push(exception); | 
| else | 
| exceptions.set(selector, [exception]); | 
| + for (let [domain] of exception.domains || []) | 
| + { | 
| + if (domain == "") | 
| + continue; | 
| + | 
| + let count = exceptionCountByDomain.get(domain) || 0; | 
| + exceptionCountByDomain.set(domain, count + 1); | 
| + } | 
| + | 
| knownExceptions.add(exception); | 
| this.emit("added", exception); | 
| filterNotifier.emit("elemhideupdate"); | 
| }, | 
| /** | 
| @@ -84,16 +100,28 @@ | 
| if (!knownExceptions.has(exception)) | 
| return; | 
| let list = exceptions.get(exception.selector); | 
| let index = list.indexOf(exception); | 
| if (index >= 0) | 
| list.splice(index, 1); | 
| + for (let [domain] of exception.domains || []) | 
| + { | 
| + if (domain == "") | 
| + continue; | 
| + | 
| + let count = exceptionCountByDomain.get(domain) || 0; | 
| + if (count == 1) | 
| + exceptionCountByDomain.delete(domain); | 
| + else if (count > 1) | 
| + exceptionCountByDomain.set(domain, count - 1); | 
| + } | 
| + | 
| knownExceptions.delete(exception); | 
| this.emit("removed", exception); | 
| filterNotifier.emit("elemhideupdate"); | 
| }, | 
| /** | 
| @@ -102,16 +130,26 @@ | 
| * @returns {boolean} | 
| */ | 
| hasExceptions(selector) | 
| { | 
| return exceptions.has(selector); | 
| }, | 
| /** | 
| + * Checks whether any exception rules are registered for a domain | 
| + * @param {string} domain | 
| + * @returns {boolean} | 
| + */ | 
| + domainHasExceptions(domain) | 
| + { | 
| + return exceptionCountByDomain.has(domain); | 
| + }, | 
| + | 
| + /** | 
| * 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) | 
| { |