| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -76,16 +76,26 @@ | 
| * @type {string} | 
| */ | 
| get type() | 
| { | 
| throw new Error("Please define filter type in the subclass"); | 
| }, | 
| /** | 
| + * Whether this object is discarded after use. If <code>false</code>, the | 
| + * object is retained in memory once created and every call to | 
| + * {@link Filter#fromText} returns the same instance. Defaults to | 
| + * <code>false</code>. | 
| + * @type {boolean} | 
| + * @package | 
| + */ | 
| + ephemeral: false, | 
| + | 
| + /** | 
| * Subscriptions to which this filter belongs. | 
| * @type {?(Subscription|Set.<Subscription>)} | 
| * @private | 
| */ | 
| _subscriptions: null, | 
| /** | 
| * Whether the filter's subscriptions have already been added to the filter. | 
| @@ -223,19 +233,21 @@ | 
| */ | 
| Filter.invalidCSPRegExp = /(;|^) ?(base-uri|referrer|report-to|report-uri|upgrade-insecure-requests)\b/i; | 
| /** | 
| * Creates a filter of correct type from its text representation - does the | 
| * basic parsing and calls the right constructor then. | 
| * | 
| * @param {string} text as in Filter() | 
| + * @param {boolean} persistent Whether the filter object should be persisted in | 
| + * memory. | 
| * @return {Filter} | 
| */ | 
| -Filter.fromText = function(text) | 
| +Filter.fromText = function(text, persistent = true) | 
| 
 
Manish Jethani
2018/11/18 06:19:14
The idea here is that internally we'll always pass
 
 | 
| { | 
| let filter = Filter.knownFilters.get(text); | 
| if (filter) | 
| return filter; | 
| if (text[0] == "!") | 
| { | 
| filter = new CommentFilter(text); | 
| @@ -244,17 +256,22 @@ | 
| { | 
| let match = text.includes("#") ? Filter.contentRegExp.exec(text) : null; | 
| if (match) | 
| filter = ContentFilter.fromText(text, match[1], match[2], match[3]); | 
| else | 
| filter = RegExpFilter.fromText(text); | 
| } | 
| - Filter.knownFilters.set(filter.text, filter); | 
| + if (persistent) | 
| + filter.ephemeral = false; | 
| + | 
| + if (!filter.ephemeral) | 
| + Filter.knownFilters.set(filter.text, filter); | 
| + | 
| return filter; | 
| }; | 
| /** | 
| * Deserializes a filter | 
| * | 
| * @param {Object} obj map of serialized properties and their values | 
| * @return {Filter} filter or null if the filter couldn't be created | 
| @@ -1311,17 +1328,23 @@ | 
| */ | 
| function ElemHideFilter(text, domains, selector) | 
| { | 
| ElemHideBase.call(this, text, domains, selector); | 
| } | 
| exports.ElemHideFilter = ElemHideFilter; | 
| ElemHideFilter.prototype = extend(ElemHideBase, { | 
| - type: "elemhide" | 
| + type: "elemhide", | 
| + | 
| + /** | 
| + * See Filter.ephemeral | 
| + * @inheritdoc | 
| + */ | 
| + ephemeral: true | 
| }); | 
| /** | 
| * Class for element hiding exceptions | 
| * @param {string} text see {@link Filter Filter()} | 
| * @param {string} [domains] see {@link ElemHideBase ElemHideBase()} | 
| * @param {string} selector see {@link ElemHideBase ElemHideBase()} | 
| * @constructor |