| 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,35 @@ |
| * @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) |
| + { |
| + let {regexp} = this; |
| + |
| + if (regexp) |
| + return 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*() |