| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -19,16 +19,18 @@ | 
|  | 
| /** | 
| * @fileOverview Definition of Filter class and its subclasses. | 
| */ | 
|  | 
| const {filterNotifier} = require("./filterNotifier"); | 
| const {extend} = require("./coreUtils"); | 
| const {filterToRegExp} = require("./common"); | 
| +const {optimizeContentFilterText, | 
| +       optimizeRegExpFilterText} = require("./filterText"); | 
|  | 
| /** | 
| * All known unique domain sources mapped to their parsed values. | 
| * @type {Map.<string,Map.<string,boolean>>} | 
| */ | 
| let knownDomainMaps = new Map(); | 
|  | 
| /** | 
| @@ -890,16 +892,22 @@ | 
| if (contentType == null) | 
| ({contentType} = RegExpFilter.prototype); | 
| contentType &= ~(RegExpFilter.typeMap.SCRIPT | | 
| RegExpFilter.typeMap.SUBDOCUMENT | | 
| RegExpFilter.typeMap.OBJECT | | 
| RegExpFilter.typeMap.OBJECT_SUBREQUEST); | 
| } | 
|  | 
| +  if (domains) | 
| +  { | 
| +    [origText, text, domains, sitekeys, csp, rewrite] = | 
| +      optimizeRegExpFilterText(origText, text, domains, sitekeys, csp, rewrite); | 
| +  } | 
| + | 
| try | 
| { | 
| if (blocking) | 
| { | 
| if (csp && Filter.invalidCSPRegExp.test(csp)) | 
| return new InvalidFilter(origText, "filter_invalid_csp"); | 
|  | 
| return new BlockingFilter(origText, text, contentType, matchCase, domains, | 
| @@ -1108,16 +1116,22 @@ | 
| ContentFilter.fromText = function(text, domains, type, body) | 
| { | 
| // We don't allow content filters which have any empty domains. | 
| // Note: The ContentFilter.prototype.domainSeparator is duplicated here, if | 
| // that changes this must be changed too. | 
| if (domains && /(^|,)~?(,|$)/.test(domains)) | 
| return new InvalidFilter(text, "filter_invalid_domain"); | 
|  | 
| +  if (domains) | 
| +  { | 
| +    [text, domains, type, body] = | 
| +      optimizeContentFilterText(text, domains, type, body); | 
| +  } | 
| + | 
| if (type == "@") | 
| return new ElemHideException(text, domains, body); | 
|  | 
| if (type == "?" || type == "$") | 
| { | 
| // Element hiding emulation and snippet filters are inefficient so we need | 
| // to make sure that they're only applied if they specify active domains | 
| if (!(/,[^~][^,.]*\.[^,]/.test("," + domains) || | 
|  |