Index: lib/matcher.js |
=================================================================== |
--- a/lib/matcher.js |
+++ b/lib/matcher.js |
@@ -17,31 +17,41 @@ |
"use strict"; |
/** |
* @fileOverview Matcher class implementing matching addresses against |
* a list of filters. |
*/ |
-const {WhitelistFilter} = require("./filterClasses"); |
+const {RegExpFilter, WhitelistFilter} = require("./filterClasses"); |
/** |
* Regular expression for matching a keyword in a filter. |
* @type {RegExp} |
*/ |
const keywordRegExp = /[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/; |
/** |
* Regular expression for matching all keywords in a filter. |
* @type {RegExp} |
*/ |
const allKeywordsRegExp = new RegExp(keywordRegExp, "g"); |
/** |
+ * Bitmask for "types" that are for exception rules only, like |
+ * <code>$document</code>, <code>$elemhide</code>, and so on. |
+ * @type {number} |
+ */ |
+const WHITELIST_ONLY_TYPES = RegExpFilter.typeMap.DOCUMENT | |
+ RegExpFilter.typeMap.ELEMHIDE | |
+ RegExpFilter.typeMap.GENERICHIDE | |
+ RegExpFilter.typeMap.GENERICBLOCK; |
+ |
+/** |
* Checks whether a particular filter is slow. |
* @param {RegExpFilter} filter |
* @returns {boolean} |
*/ |
function isSlowFilter(filter) |
{ |
return !filter.pattern || !keywordRegExp.test(filter.pattern); |
} |
@@ -315,34 +325,43 @@ |
matchesAnyInternal(location, typeMask, docDomain, thirdParty, sitekey, |
specificOnly) |
{ |
let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); |
if (candidates === null) |
candidates = []; |
candidates.push(""); |
+ let whitelistHit = null; |
let blacklistHit = null; |
- for (let i = 0, l = candidates.length; i < l; i++) |
+ |
+ let {blacklist, whitelist} = this; |
+ |
+ if ((typeMask & ~WHITELIST_ONLY_TYPES) != 0) |
{ |
- let substr = candidates[i]; |
- let result = this.whitelist._checkEntryMatch( |
- substr, location, typeMask, docDomain, thirdParty, sitekey |
- ); |
- if (result) |
- return result; |
- if (blacklistHit === null) |
+ for (let i = 0, l = candidates.length; !blacklistHit && i < l; i++) |
{ |
- blacklistHit = this.blacklist._checkEntryMatch( |
- substr, location, typeMask, docDomain, thirdParty, sitekey, |
- specificOnly |
- ); |
+ blacklistHit = blacklist._checkEntryMatch(candidates[i], location, |
+ typeMask, docDomain, |
+ thirdParty, sitekey, |
+ specificOnly); |
} |
} |
- return blacklistHit; |
+ |
+ if (blacklistHit || (typeMask & WHITELIST_ONLY_TYPES) != 0) |
+ { |
+ for (let i = 0, l = candidates.length; !whitelistHit && i < l; i++) |
+ { |
+ whitelistHit = whitelist._checkEntryMatch(candidates[i], location, |
+ typeMask, docDomain, |
+ thirdParty, sitekey); |
+ } |
+ } |
+ |
+ return whitelistHit || blacklistHit; |
} |
/** |
* @see Matcher#matchesAny |
* @inheritdoc |
*/ |
matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly) |
{ |