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(); |