| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -493,20 +493,20 @@ | 
| * @type {?Map.<string,boolean>} | 
| */ | 
| get domains() | 
| { | 
| let domains = null; | 
|  | 
| if (this.domainSource) | 
| { | 
| -      // For some filter types this property is accessed only rarely, | 
| +      // For most 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; | 
| +      // caching by default. | 
| +      let cacheDomains = this._cacheDomains; | 
|  | 
| let source = this.domainSource.toLowerCase(); | 
|  | 
| let knownMap = knownDomainMaps.get(source); | 
| if (knownMap) | 
| { | 
| domains = knownMap; | 
| } | 
| @@ -555,27 +555,27 @@ | 
|  | 
| if (!domains || cacheDomains) | 
| { | 
| this.domainSource = null; | 
| Object.defineProperty(this, "domains", {value: domains}); | 
| } | 
| } | 
|  | 
| +    this._cacheDomains = true; | 
| + | 
| 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 | 
| +   * @private | 
| */ | 
| -  cacheDomains: true, | 
| +  _cacheDomains: false, | 
|  | 
| /** | 
| * Array containing public keys of websites that this filter should apply to | 
| * @type {?string[]} | 
| */ | 
| sitekeys: null, | 
|  | 
| /** | 
| @@ -759,16 +759,17 @@ | 
| } | 
| exports.RegExpFilter = RegExpFilter; | 
|  | 
| RegExpFilter.prototype = extend(ActiveFilter, { | 
| /** | 
| * Number of filters contained, will always be 1 (required to | 
| * optimize {@link Matcher}). | 
| * @type {number} | 
| +   * @package | 
| */ | 
| size: 1, | 
|  | 
| /** | 
| * @see ActiveFilter.domainSeparator | 
| */ | 
| domainSeparator: "|", | 
|  | 
| @@ -872,16 +873,35 @@ | 
| (this.thirdParty == null || this.thirdParty == thirdParty) && | 
| (this.regexp ? (this.isActiveOnDomain(docDomain, sitekey) && | 
| this.matchesLocation(location)) : | 
| (this.matchesLocation(location) && | 
| this.isActiveOnDomain(docDomain, sitekey))); | 
| }, | 
|  | 
| /** | 
| +   * Checks whether the given URL matches this filter without checking the | 
| +   * filter's domains. | 
| +   * @param {string} location | 
| +   * @param {number} typeMask | 
| +   * @param {boolean} [thirdParty] | 
| +   * @param {string} [sitekey] | 
| +   * @return {boolean} | 
| +   * @package | 
| +   */ | 
| +  matchesWithoutDomain(location, typeMask, thirdParty, sitekey) | 
| +  { | 
| +    return (this.contentType & typeMask) != 0 && | 
| +           (this.thirdParty == null || this.thirdParty == thirdParty) && | 
| +           this.matchesLocation(location) && | 
| +           (!this.sitekeys || | 
| +            (sitekey && this.sitekeys.includes(sitekey.toUpperCase()))); | 
| +  }, | 
| + | 
| +  /** | 
| * Checks whether the given URL matches this filter's pattern. | 
| * @param {string} location The URL to check. | 
| * @param {?string} [lowerCaseLocation] The lower-case version of the URL to | 
| *   check, for case-insensitive matching. | 
| * @returns {boolean} <code>true</code> if the URL matches. | 
| * @package | 
| */ | 
| matchesLocation(location, lowerCaseLocation) | 
| @@ -928,23 +948,35 @@ | 
| !this.domainSource && !this.sitekeySource && | 
| !this.domains && !this.sitekeys; | 
| } | 
| }); | 
|  | 
| /** | 
| * Yields the filter itself (required to optimize {@link Matcher}). | 
| * @yields {RegExpFilter} | 
| + * @package | 
| */ | 
| RegExpFilter.prototype[Symbol.iterator] = function*() | 
| { | 
| yield this; | 
| }; | 
|  | 
| /** | 
| + * Yields a key-value pair consisting of the filter itself and the value | 
| + * <code>true</code> (required to optimize {@link Matcher}). | 
| + * @yields {Array} | 
| + * @package | 
| + */ | 
| +RegExpFilter.prototype.entries = function*() | 
| +{ | 
| +  yield [this, true]; | 
| +}; | 
| + | 
| +/** | 
| * Creates a RegExp filter from its text representation | 
| * @param {string} text   same as in Filter() | 
| * @return {Filter} | 
| */ | 
| RegExpFilter.fromText = function(text) | 
| { | 
| let blocking = true; | 
| let origText = text; | 
| @@ -1326,38 +1358,16 @@ | 
| 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 "); | 
| } | 
|  |