Index: lib/matcher.js |
=================================================================== |
--- a/lib/matcher.js |
+++ b/lib/matcher.js |
@@ -53,94 +53,96 @@ |
*/ |
class Matcher |
{ |
constructor() |
{ |
/** |
* Lookup table for filters by their associated keyword |
* @type {Map.<string,(Filter|Set.<Filter>)>} |
+ * @private |
*/ |
- this.filterByKeyword = new Map(); |
+ this._filterByKeyword = new Map(); |
} |
/** |
* Removes all known filters |
*/ |
clear() |
{ |
- this.filterByKeyword.clear(); |
+ this._filterByKeyword.clear(); |
} |
/** |
* Adds a filter to the matcher |
* @param {RegExpFilter} filter |
*/ |
add(filter) |
{ |
// Look for a suitable keyword |
let keyword = this.findKeyword(filter); |
- let set = this.filterByKeyword.get(keyword); |
+ let set = this._filterByKeyword.get(keyword); |
if (typeof set == "undefined") |
{ |
- this.filterByKeyword.set(keyword, filter); |
+ this._filterByKeyword.set(keyword, filter); |
} |
else if (set.size == 1) |
{ |
if (filter != set) |
- this.filterByKeyword.set(keyword, new Set([set, filter])); |
+ this._filterByKeyword.set(keyword, new Set([set, filter])); |
} |
else |
{ |
set.add(filter); |
} |
} |
/** |
* Removes a filter from the matcher |
* @param {RegExpFilter} filter |
*/ |
remove(filter) |
{ |
let keyword = this.findKeyword(filter); |
- let set = this.filterByKeyword.get(keyword); |
+ let set = this._filterByKeyword.get(keyword); |
if (typeof set == "undefined") |
return; |
if (set.size == 1) |
{ |
if (filter == set) |
- this.filterByKeyword.delete(keyword); |
+ this._filterByKeyword.delete(keyword); |
} |
else |
{ |
set.delete(filter); |
if (set.size == 1) |
- this.filterByKeyword.set(keyword, [...set][0]); |
+ this._filterByKeyword.set(keyword, [...set][0]); |
} |
} |
/** |
* Chooses a keyword to be associated with the filter |
* @param {Filter} filter |
* @returns {string} keyword or an empty string if no keyword could be found |
+ * @protected |
*/ |
findKeyword(filter) |
{ |
let result = ""; |
let {pattern} = filter; |
if (pattern == null) |
return result; |
let candidates = pattern.toLowerCase().match(allKeywordsRegExp); |
if (!candidates) |
return result; |
- let hash = this.filterByKeyword; |
+ let hash = this._filterByKeyword; |
let resultCount = 0xFFFFFF; |
let resultLength = 0; |
for (let i = 0, l = candidates.length; i < l; i++) |
{ |
let candidate = candidates[i].substr(1); |
let filters = hash.get(candidate); |
let count = typeof filters != "undefined" ? filters.size : 0; |
if (count < resultCount || |
@@ -159,21 +161,22 @@ |
* @param {string} keyword |
* @param {string} location |
* @param {number} typeMask |
* @param {string} [docDomain] |
* @param {boolean} [thirdParty] |
* @param {string} [sitekey] |
* @param {boolean} [specificOnly] |
* @returns {?Filter} |
+ * @protected |
*/ |
- _checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey, |
+ checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey, |
specificOnly) |
{ |
- let set = this.filterByKeyword.get(keyword); |
+ let set = this._filterByKeyword.get(keyword); |
if (typeof set == "undefined") |
return null; |
for (let filter of set) |
{ |
if (specificOnly && filter.isGeneric() && |
!(filter instanceof WhitelistFilter)) |
continue; |
@@ -204,17 +207,17 @@ |
matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
{ |
let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |
if (candidates === null) |
candidates = []; |
candidates.push(""); |
for (let i = 0, l = candidates.length; i < l; i++) |
{ |
- let result = this._checkEntryMatch(candidates[i], location, typeMask, |
+ let result = this.checkEntryMatch(candidates[i], location, typeMask, |
docDomain, thirdParty, sitekey, |
specificOnly); |
if (result) |
return result; |
} |
return null; |
} |
@@ -234,109 +237,114 @@ |
* Maximal number of matching cache entries to be kept |
* @type {number} |
*/ |
this.maxCacheEntries = 1000; |
/** |
* Matcher for blocking rules. |
* @type {Matcher} |
+ * @protected |
*/ |
this.blacklist = new Matcher(); |
/** |
* Matcher for exception rules. |
* @type {Matcher} |
+ * @protected |
*/ |
this.whitelist = new Matcher(); |
/** |
* Lookup table of previous {@link Matcher#matchesAny} results |
* @type {Map.<string,Filter>} |
+ * @private |
*/ |
- this.resultCache = new Map(); |
+ this._resultCache = new Map(); |
} |
/** |
* @see Matcher#clear |
*/ |
clear() |
{ |
this.blacklist.clear(); |
this.whitelist.clear(); |
- this.resultCache.clear(); |
+ this._resultCache.clear(); |
} |
/** |
* @see Matcher#add |
* @param {Filter} filter |
*/ |
add(filter) |
{ |
if (filter instanceof WhitelistFilter) |
this.whitelist.add(filter); |
else |
this.blacklist.add(filter); |
- this.resultCache.clear(); |
+ this._resultCache.clear(); |
} |
/** |
* @see Matcher#remove |
* @param {Filter} filter |
*/ |
remove(filter) |
{ |
if (filter instanceof WhitelistFilter) |
this.whitelist.remove(filter); |
else |
this.blacklist.remove(filter); |
- this.resultCache.clear(); |
+ this._resultCache.clear(); |
} |
/** |
* @see Matcher#findKeyword |
* @param {Filter} filter |
* @returns {string} keyword |
+ * @protected |
*/ |
findKeyword(filter) |
{ |
if (filter instanceof WhitelistFilter) |
return this.whitelist.findKeyword(filter); |
return this.blacklist.findKeyword(filter); |
} |
/** |
* Optimized filter matching testing both whitelist and blacklist matchers |
* simultaneously. For parameters see |
{@link Matcher#matchesAny Matcher.matchesAny()}. |
* @see Matcher#matchesAny |
* @inheritdoc |
+ * @private |
*/ |
- matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey, |
+ _matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey, |
specificOnly) |
{ |
let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |
if (candidates === null) |
candidates = []; |
candidates.push(""); |
let blacklistHit = null; |
for (let i = 0, l = candidates.length; i < l; i++) |
{ |
let substr = candidates[i]; |
- let result = this.whitelist._checkEntryMatch( |
+ let result = this.whitelist.checkEntryMatch( |
substr, location, typeMask, docDomain, thirdParty, sitekey |
); |
if (result) |
return result; |
if (blacklistHit === null) |
{ |
- blacklistHit = this.blacklist._checkEntryMatch( |
+ blacklistHit = this.blacklist.checkEntryMatch( |
substr, location, typeMask, docDomain, thirdParty, sitekey, |
specificOnly |
); |
} |
} |
return blacklistHit; |
} |
@@ -344,27 +352,27 @@ |
* @see Matcher#matchesAny |
* @inheritdoc |
*/ |
matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
{ |
let key = location + " " + typeMask + " " + docDomain + " " + thirdParty + |
" " + sitekey + " " + specificOnly; |
- let result = this.resultCache.get(key); |
+ let result = this._resultCache.get(key); |
if (typeof result != "undefined") |
return result; |
- result = this.matchesAnyInternal(location, typeMask, docDomain, |
+ result = this._matchesAnyInternal(location, typeMask, docDomain, |
thirdParty, sitekey, specificOnly); |
- if (this.resultCache.size >= this.maxCacheEntries) |
- this.resultCache.clear(); |
+ if (this._resultCache.size >= this.maxCacheEntries) |
+ this._resultCache.clear(); |
- this.resultCache.set(key, result); |
+ this._resultCache.set(key, result); |
return result; |
} |
} |
exports.CombinedMatcher = CombinedMatcher; |
/** |