| Index: lib/filterClasses.js |
| =================================================================== |
| --- a/lib/filterClasses.js |
| +++ b/lib/filterClasses.js |
| @@ -452,16 +452,21 @@ |
| * @type {?Map.<string,boolean>} |
| */ |
| get domains() |
| { |
| let domains = null; |
| if (this.domainSource) |
| { |
| + // For some filter types this property is accessed only rarely, |
| + // especially when the subscriptions are initially loaded. We defer any |
| + // caching for such filters. |
| + let {cacheDomains} = this; |
| + |
| let source = this.domainSource.toLowerCase(); |
| let knownMap = knownDomainMaps.get(source); |
| if (knownMap) |
| { |
| domains = knownMap; |
| } |
| else |
| @@ -498,28 +503,40 @@ |
| domains.set(domain, include); |
| } |
| if (domains) |
| domains.set("", !hasIncludes); |
| } |
| - if (domains) |
| + if (!domains || cacheDomains) |
| knownDomainMaps.set(source, domains); |
| } |
| - this.domainSource = null; |
| + if (!domains || cacheDomains) |
| + { |
| + this.domainSource = null; |
| + Object.defineProperty(this, "domains", {value: domains}); |
| + } |
| } |
| - Object.defineProperty(this, "domains", {value: domains}); |
| - return this.domains; |
| + return domains; |
| }, |
| /** |
| + * Whether the value of {@link ActiveFilter#domains} should be cached. |
| + * Defaults to <code>true</code>, but may be overridden by subclasses that |
| + * don't want the value to be cached (for better memory usage). |
| + * @type {boolean} |
| + * @protected |
| + */ |
| + cacheDomains: true, |
| + |
| + /** |
| * Array containing public keys of websites that this filter should apply to |
| * @type {?string[]} |
| */ |
| sitekeys: null, |
| /** |
| * Checks whether this filter is active on a domain. |
| * @param {string} [docDomain] domain name of the document that loads the URL |
| @@ -1149,16 +1166,38 @@ |
| function ElemHideBase(text, domains, selector) |
| { |
| ContentFilter.call(this, text, domains, selector); |
| } |
| exports.ElemHideBase = ElemHideBase; |
| ElemHideBase.prototype = extend(ContentFilter, { |
| /** |
| + * @see ActiveFilter#domains |
| + * @type {?Map.<string,boolean>} |
| + */ |
| + get domains() |
| + { |
| + let {get} = Object.getOwnPropertyDescriptor(ActiveFilter.prototype, |
| + "domains"); |
| + let value = get.call(this); |
| + this.cacheDomains = true; |
| + return value; |
| + }, |
| + |
| + /** |
| + * Initially <code>false</code>, but set to <code>true</code> after |
| + * {@link ActiveFilter#domains} has been accessed once. |
| + * @see ActiveFilter#cacheDomains |
| + * @type {boolean} |
| + * @protected |
| + */ |
| + cacheDomains: false, |
| + |
| + /** |
| * CSS selector for the HTML elements that should be hidden |
| * @type {string} |
| */ |
| get selector() |
| { |
| // Braces are being escaped to prevent CSS rule injection. |
| return this.body.replace("{", "\\7B ").replace("}", "\\7D "); |
| } |