| Index: lib/filterClasses.js | 
| =================================================================== | 
| --- a/lib/filterClasses.js | 
| +++ b/lib/filterClasses.js | 
| @@ -18,17 +18,18 @@ | 
| "use strict"; | 
|  | 
| /** | 
| * @fileOverview Definition of Filter class and its subclasses. | 
| */ | 
|  | 
| const {filterNotifier} = require("./filterNotifier"); | 
| const {extend} = require("./coreUtils"); | 
| -const {filterToRegExp} = require("./common"); | 
| +const {filterToRegExp, isLiteralPattern, | 
| +       locationMatchesPattern} = require("./common"); | 
|  | 
| /** | 
| * All known unique domain sources mapped to their parsed values. | 
| * @type {Map.<string,Map.<string,boolean>>} | 
| */ | 
| let knownDomainMaps = new Map(); | 
|  | 
| /** | 
| @@ -688,16 +689,19 @@ | 
| // The filter is a regular expression - convert it immediately to | 
| // catch syntax errors | 
| let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), | 
| this.matchCase ? "" : "i"); | 
| Object.defineProperty(this, "regexp", {value: regexp}); | 
| } | 
| else | 
| { | 
| +    if (!this.matchCase && isLiteralPattern(regexpSource)) | 
| +      regexpSource = regexpSource.toLowerCase(); | 
| + | 
| // No need to convert this filter to regular expression yet, do it on demand | 
| this.pattern = regexpSource; | 
| } | 
| } | 
| exports.RegExpFilter = RegExpFilter; | 
|  | 
| RegExpFilter.prototype = extend(ActiveFilter, { | 
| /** | 
| @@ -719,20 +723,27 @@ | 
| */ | 
| pattern: null, | 
| /** | 
| * Regular expression to be used when testing against this filter | 
| * @type {RegExp} | 
| */ | 
| get regexp() | 
| { | 
| -    let source = filterToRegExp(this.pattern, this.rewrite != null); | 
| -    let regexp = new RegExp(source, this.matchCase ? "" : "i"); | 
| -    Object.defineProperty(this, "regexp", {value: regexp}); | 
| -    return regexp; | 
| +    let value = null; | 
| + | 
| +    let {pattern, rewrite} = this; | 
| +    if (rewrite != null || !isLiteralPattern(pattern)) | 
| +    { | 
| +      value = new RegExp(filterToRegExp(pattern, rewrite != null), | 
| +                         this.matchCase ? "" : "i"); | 
| +    } | 
| + | 
| +    Object.defineProperty(this, "regexp", {value}); | 
| +    return value; | 
| }, | 
| /** | 
| * Content types the filter applies to, combination of values from | 
| * RegExpFilter.typeMap | 
| * @type {number} | 
| */ | 
| contentType: 0x7FFFFFFF, | 
| /** | 
| @@ -783,17 +794,33 @@ | 
| * @param {string} [sitekey] public key provided by the document | 
| * @return {boolean} true in case of a match | 
| */ | 
| matches(location, typeMask, docDomain, thirdParty, sitekey) | 
| { | 
| return (this.contentType & typeMask) != 0 && | 
| (this.thirdParty == null || this.thirdParty == thirdParty) && | 
| this.isActiveOnDomain(docDomain, sitekey) && | 
| -           this.regexp.test(location); | 
| +           this.matchesLocation(location); | 
| +  }, | 
| + | 
| +  /** | 
| +   * Checks whether the given URL matches this filter's pattern. | 
| +   * @param {string} location The URL to check. | 
| +   * @returns {boolean} <code>true</code> if the URL matches. | 
| +   */ | 
| +  matchesLocation(location) | 
| +  { | 
| +    if (this.regexp) | 
| +      return this.regexp.test(location); | 
| + | 
| +    if (!this.matchCase) | 
| +      location = location.toLowerCase(); | 
| + | 
| +    return locationMatchesPattern(location, this.pattern); | 
| } | 
| }); | 
|  | 
| /** | 
| * Yields the filter itself (required to optimize {@link Matcher}). | 
| * @yields {RegExpFilter} | 
| */ | 
| RegExpFilter.prototype[Symbol.iterator] = function*() | 
|  |