| Index: lib/matcher.js |
| diff --git a/lib/matcher.js b/lib/matcher.js |
| index 69a8e2543e115a982eefcd9883b728c2589d2845..c96cab214dd2a20ca33057c3ce45ca579571f02f 100644 |
| --- a/lib/matcher.js |
| +++ b/lib/matcher.js |
| @@ -15,11 +15,14 @@ |
| * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| */ |
| +"use strict"; |
| + |
| /** |
| - * @fileOverview Matcher class implementing matching addresses against a list of filters. |
| + * @fileOverview Matcher class implementing matching addresses against |
| + * a list of filters. |
| */ |
| -let {Filter, RegExpFilter, WhitelistFilter} = require("filterClasses"); |
| +const {Filter, WhitelistFilter} = require("filterClasses"); |
| /** |
| * Blacklist/whitelist filter matching |
| @@ -34,20 +37,20 @@ exports.Matcher = Matcher; |
| Matcher.prototype = { |
| /** |
| * Lookup table for filters by their associated keyword |
| - * @type Object |
| + * @type {Object} |
| */ |
| filterByKeyword: null, |
| /** |
| * Lookup table for keywords by the filter text |
| - * @type Object |
| + * @type {Object} |
| */ |
| keywordByFilter: null, |
| /** |
| * Removes all known filters |
| */ |
| - clear: function() |
| + clear() |
| { |
| this.filterByKeyword = Object.create(null); |
| this.keywordByFilter = Object.create(null); |
| @@ -57,7 +60,7 @@ Matcher.prototype = { |
| * Adds a filter to the matcher |
| * @param {RegExpFilter} filter |
| */ |
| - add: function(filter) |
| + add(filter) |
| { |
| if (filter.text in this.keywordByFilter) |
| return; |
| @@ -78,7 +81,7 @@ Matcher.prototype = { |
| * Removes a filter from the matcher |
| * @param {RegExpFilter} filter |
| */ |
| - remove: function(filter) |
| + remove(filter) |
| { |
| if (!(filter.text in this.keywordByFilter)) |
| return; |
| @@ -103,13 +106,13 @@ Matcher.prototype = { |
| /** |
| * Chooses a keyword to be associated with the filter |
| - * @param {String} text text representation of the filter |
| - * @return {String} keyword (might be empty string) |
| + * @param {Filter} filter |
| + * @return {string} keyword or an empty string if no keyword could be found |
| */ |
| - findKeyword: function(filter) |
| + findKeyword(filter) |
| { |
| let result = ""; |
| - let text = filter.text; |
| + let {text} = filter; |
| if (Filter.regexpRegExp.test(text)) |
| return result; |
| @@ -122,7 +125,9 @@ Matcher.prototype = { |
| if (text.substr(0, 2) == "@@") |
| text = text.substr(2); |
| - let candidates = text.toLowerCase().match(/[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g); |
| + let candidates = text.toLowerCase().match( |
| + /[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/g |
| + ); |
| if (!candidates) |
| return result; |
| @@ -133,7 +138,8 @@ Matcher.prototype = { |
| { |
| let candidate = candidates[i].substr(1); |
| let count = (candidate in hash ? hash[candidate].length : 0); |
| - if (count < resultCount || (count == resultCount && candidate.length > resultLength)) |
| + if (count < resultCount || |
| + (count == resultCount && candidate.length > resultLength)) |
| { |
| result = candidate; |
| resultCount = count; |
| @@ -145,27 +151,39 @@ Matcher.prototype = { |
| /** |
| * Checks whether a particular filter is being matched against. |
| + * @param {RegExpFilter} filter |
| + * @return {boolean} |
| */ |
| - hasFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ |
| + hasFilter(filter) |
| { |
| return (filter.text in this.keywordByFilter); |
| }, |
| /** |
| * Returns the keyword used for a filter, null for unknown filters. |
| + * @param {RegExpFilter} filter |
| + * @return {string} |
| */ |
| - getKeywordForFilter: function(/**RegExpFilter*/ filter) /**String*/ |
| + getKeywordForFilter(filter) |
| { |
| if (filter.text in this.keywordByFilter) |
| return this.keywordByFilter[filter.text]; |
| - else |
| - return null; |
| + return null; |
| }, |
| /** |
| * Checks whether the entries for a particular keyword match a URL |
| + * @param {string} keyword |
| + * @param {string} location |
| + * @param {number} typeMask |
| + * @param {string} docDomain |
| + * @param {boolean} thirdParty |
| + * @param {string} sitekey |
| + * @param {boolean} specificOnly |
| + * @return {?Filter} |
| */ |
| - _checkEntryMatch: function(keyword, location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| + _checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey, |
| + specificOnly) |
| { |
| let list = this.filterByKeyword[keyword]; |
| for (let i = 0; i < list.length; i++) |
| @@ -184,15 +202,22 @@ Matcher.prototype = { |
| /** |
| * Tests whether the URL matches any of the known filters |
| - * @param {String} location URL to be tested |
| - * @param {number} typeMask bitmask of content / request types to match |
| - * @param {String} docDomain domain name of the document that loads the URL |
| - * @param {Boolean} thirdParty should be true if the URL is a third-party request |
| - * @param {String} sitekey public key provided by the document |
| - * @param {Boolean} specificOnly should be true if generic matches should be ignored |
| - * @return {RegExpFilter} matching filter or null |
| + * @param {string} location |
| + * URL to be tested |
| + * @param {number} typeMask |
| + * bitmask of content / request types to match |
| + * @param {string} docDomain |
| + * domain name of the document that loads the URL |
| + * @param {boolean} thirdParty |
| + * should be true if the URL is a third-party request |
| + * @param {string} sitekey |
| + * public key provided by the document |
| + * @param {boolean} specificOnly |
| + * should be true if generic matches should be ignored |
| + * @return {?RegExpFilter} |
| + * matching filter or null |
| */ |
| - matchesAny: function(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| + matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| { |
| let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |
| if (candidates === null) |
| @@ -203,7 +228,9 @@ Matcher.prototype = { |
| let substr = candidates[i]; |
| if (substr in this.filterByKeyword) |
| { |
| - let result = this._checkEntryMatch(substr, location, typeMask, docDomain, thirdParty, sitekey, specificOnly); |
| + let result = this._checkEntryMatch(substr, location, typeMask, |
| + docDomain, thirdParty, sitekey, |
| + specificOnly); |
| if (result) |
| return result; |
| } |
| @@ -217,6 +244,7 @@ Matcher.prototype = { |
| * Combines a matcher for blocking and exception rules, automatically sorts |
| * rules into two Matcher instances. |
| * @constructor |
| + * @augments Matcher |
| */ |
| function CombinedMatcher() |
| { |
| @@ -228,7 +256,7 @@ exports.CombinedMatcher = CombinedMatcher; |
| /** |
| * Maximal number of matching cache entries to be kept |
| - * @type Number |
| + * @type {number} |
| */ |
| CombinedMatcher.maxCacheEntries = 1000; |
| @@ -236,32 +264,32 @@ CombinedMatcher.prototype = |
| { |
| /** |
| * Matcher for blocking rules. |
| - * @type Matcher |
| + * @type {Matcher} |
| */ |
| blacklist: null, |
| /** |
| * Matcher for exception rules. |
| - * @type Matcher |
| + * @type {Matcher} |
| */ |
| whitelist: null, |
| /** |
| * Lookup table of previous matchesAny results |
| - * @type Object |
| + * @type {Object} |
| */ |
| resultCache: null, |
| /** |
| * Number of entries in resultCache |
| - * @type Number |
| + * @type {number} |
| */ |
| cacheEntries: 0, |
| /** |
| * @see Matcher#clear |
| */ |
| - clear: function() |
| + clear() |
| { |
| this.blacklist.clear(); |
| this.whitelist.clear(); |
| @@ -271,8 +299,9 @@ CombinedMatcher.prototype = |
| /** |
| * @see Matcher#add |
| + * @param {Filter} filter |
| */ |
| - add: function(filter) |
| + add(filter) |
| { |
| if (filter instanceof WhitelistFilter) |
| this.whitelist.add(filter); |
| @@ -288,8 +317,9 @@ CombinedMatcher.prototype = |
| /** |
| * @see Matcher#remove |
| + * @param {Filter} filter |
| */ |
| - remove: function(filter) |
| + remove(filter) |
| { |
| if (filter instanceof WhitelistFilter) |
| this.whitelist.remove(filter); |
| @@ -305,55 +335,63 @@ CombinedMatcher.prototype = |
| /** |
| * @see Matcher#findKeyword |
| + * @param {Filter} filter |
| + * @return {string} keyword |
| */ |
| - findKeyword: function(filter) |
| + findKeyword(filter) |
| { |
| if (filter instanceof WhitelistFilter) |
| return this.whitelist.findKeyword(filter); |
| - else |
| - return this.blacklist.findKeyword(filter); |
| + return this.blacklist.findKeyword(filter); |
| }, |
| /** |
| * @see Matcher#hasFilter |
| + * @param {Filter} filter |
| + * @return {boolean} |
| */ |
| - hasFilter: function(filter) |
| + hasFilter(filter) |
| { |
| if (filter instanceof WhitelistFilter) |
| return this.whitelist.hasFilter(filter); |
| - else |
| - return this.blacklist.hasFilter(filter); |
| + return this.blacklist.hasFilter(filter); |
| }, |
| /** |
| * @see Matcher#getKeywordForFilter |
| + * @param {Filter} filter |
| + * @return {string} keyword |
| */ |
| - getKeywordForFilter: function(filter) |
| + getKeywordForFilter(filter) |
| { |
| if (filter instanceof WhitelistFilter) |
| return this.whitelist.getKeywordForFilter(filter); |
| - else |
| - return this.blacklist.getKeywordForFilter(filter); |
| + return this.blacklist.getKeywordForFilter(filter); |
| }, |
| /** |
| * Checks whether a particular filter is slow |
| + * @param {RegExpFilter} filter |
| + * @return {boolean} |
| */ |
| - isSlowFilter: function(/**RegExpFilter*/ filter) /**Boolean*/ |
| + isSlowFilter(filter) |
| { |
| - let matcher = (filter instanceof WhitelistFilter ? this.whitelist : this.blacklist); |
| + let matcher = ( |
| + filter instanceof WhitelistFilter ? this.whitelist : this.blacklist |
| + ); |
| if (matcher.hasFilter(filter)) |
| return !matcher.getKeywordForFilter(filter); |
| - else |
| - return !matcher.findKeyword(filter); |
| + return !matcher.findKeyword(filter); |
| }, |
| /** |
| * Optimized filter matching testing both whitelist and blacklist matchers |
| * simultaneously. For parameters see Matcher.matchesAny(). |
| * @see Matcher#matchesAny |
| + * @inheritdoc |
| */ |
| - matchesAnyInternal: function(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| + matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey, |
| + specificOnly) |
| { |
| let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |
| if (candidates === null) |
| @@ -366,26 +404,36 @@ CombinedMatcher.prototype = |
| let substr = candidates[i]; |
| if (substr in this.whitelist.filterByKeyword) |
| { |
| - let result = this.whitelist._checkEntryMatch(substr, location, typeMask, docDomain, thirdParty, sitekey); |
| + let result = this.whitelist._checkEntryMatch( |
| + substr, location, typeMask, docDomain, thirdParty, sitekey |
| + ); |
| if (result) |
| return result; |
| } |
| if (substr in this.blacklist.filterByKeyword && blacklistHit === null) |
| - blacklistHit = this.blacklist._checkEntryMatch(substr, location, typeMask, docDomain, thirdParty, sitekey, specificOnly); |
| + { |
| + blacklistHit = this.blacklist._checkEntryMatch( |
| + substr, location, typeMask, docDomain, thirdParty, sitekey, |
| + specificOnly |
| + ); |
| + } |
| } |
| return blacklistHit; |
| }, |
| /** |
| * @see Matcher#matchesAny |
| + * @inheritdoc |
| */ |
| - matchesAny: function(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| + matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
| { |
| - let key = location + " " + typeMask + " " + docDomain + " " + thirdParty + " " + sitekey + " " + specificOnly; |
| + let key = location + " " + typeMask + " " + docDomain + " " + thirdParty + |
| + " " + sitekey + " " + specificOnly; |
| if (key in this.resultCache) |
| return this.resultCache[key]; |
| - let result = this.matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey, specificOnly); |
| + let result = this.matchesAnyInternal(location, typeMask, docDomain, |
| + thirdParty, sitekey, specificOnly); |
| if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) |
| { |
| @@ -398,10 +446,10 @@ CombinedMatcher.prototype = |
| return result; |
| } |
| -} |
| +}; |
| /** |
| * Shared CombinedMatcher instance that should usually be used. |
| - * @type CombinedMatcher |
| + * @type {CombinedMatcher} |
| */ |
| -let defaultMatcher = exports.defaultMatcher = new CombinedMatcher(); |
| +exports.defaultMatcher = new CombinedMatcher(); |