Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/matcher.js

Issue 29990555: Issue 7179 - Add function to return all matching filters (Closed) Base URL: https://hg.adblockplus.org/adblockpluscore/
Patch Set: Fix typo Created Jan. 28, 2019, 5:35 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | test/matcher.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/matcher.js
===================================================================
--- a/lib/matcher.js
+++ b/lib/matcher.js
@@ -295,36 +295,45 @@
* 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]
+ * @param {?Array.<Filter>} [collection] An optional list of filters to which
+ * to append any results. If specified, the function adds <em>all</em>
+ * matching filters to the list; if omitted, the function directly returns
+ * the first matching filter.
* @returns {?Filter}
* @protected
*/
checkEntryMatch(keyword, location, typeMask, docDomain, thirdParty, sitekey,
- specificOnly)
+ specificOnly, collection)
{
// We need to skip the simple (location-only) filters if the type mask does
// not contain any default content types.
if ((typeMask & DEFAULT_TYPES) != 0)
{
let simpleSet = this._simpleFiltersByKeyword.get(keyword);
if (simpleSet)
{
for (let filter of simpleSet)
{
if (specificOnly && !(filter instanceof WhitelistFilter))
continue;
if (filter.matchesLocation(location))
- return filter;
+ {
+ if (!collection)
+ return filter;
+
+ collection.push(filter);
+ }
}
}
}
let complexSet = null;
// If the type mask contains a non-default type (first condition) and it is
// the only type in the mask (second condition), we can use the
@@ -346,17 +355,22 @@
{
for (let filter of complexSet)
{
if (specificOnly && filter.isGeneric() &&
!(filter instanceof WhitelistFilter))
continue;
if (filter.matches(location, typeMask, docDomain, thirdParty, sitekey))
- return filter;
+ {
+ if (!collection)
+ return filter;
+
+ collection.push(filter);
+ }
}
}
return null;
}
/**
* Tests whether the URL matches any of the known filters
@@ -525,16 +539,60 @@
typeMask, docDomain,
thirdParty, sitekey);
}
}
return whitelistHit || blacklistHit;
}
+ _searchInternal(location, typeMask, docDomain, thirdParty, sitekey,
+ specificOnly, filterType)
+ {
+ let hits = {};
+
+ let searchBlocking = filterType == "blocking" || filterType == "all";
+ let searchWhitelist = filterType == "whitelist" || filterType == "all";
+
+ if (searchBlocking)
+ hits.blocking = [];
+
+ if (searchWhitelist)
+ hits.whitelist = [];
+
+ // If the type mask includes no types other than whitelist-only types, we
+ // can skip the blacklist.
+ if ((typeMask & ~WHITELIST_ONLY_TYPES) == 0)
+ searchBlocking = false;
+
+ 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++)
+ {
+ if (searchBlocking)
+ {
+ this._blacklist.checkEntryMatch(candidates[i], location, typeMask,
+ docDomain, thirdParty, sitekey,
+ specificOnly, hits.blocking);
+ }
+
+ if (searchWhitelist)
+ {
+ this._whitelist.checkEntryMatch(candidates[i], location, typeMask,
+ docDomain, thirdParty, sitekey,
+ false, hits.whitelist);
+ }
+ }
+
+ return hits;
+ }
+
/**
* @see Matcher#matchesAny
* @inheritdoc
*/
matchesAny(location, typeMask, docDomain, thirdParty, sitekey, specificOnly)
{
let key = location + " " + typeMask + " " + docDomain + " " + thirdParty +
" " + sitekey + " " + specificOnly;
@@ -550,16 +608,62 @@
this._resultCache.clear();
this._resultCache.set(key, result);
return result;
}
/**
+ * @typedef {object} MatcherSearchResults
+ * @property {Array.<BlockingFilter>} [blocking] List of blocking filters
+ * found.
+ * @property {Array.<WhitelistFilter>} [whitelist] List of whitelist filters
+ * found.
+ */
+
+ /**
+ * Searches all blocking and whitelist filters and returns results matching
+ * the given parameters.
+ *
+ * @param {string} location
+ * @param {number} typeMask
+ * @param {string} [docDomain]
+ * @param {boolean} [thirdParty]
+ * @param {string} [sitekey]
+ * @param {boolean} [specificOnly]
+ * @param {string} [filterType] The types of filters to look for. This can be
+ * <code>"blocking"</code>, <code>"whitelist"</code>, or
+ * <code>"all"</code> (default).
+ *
+ * @returns {MatcherSearchResults}
+ */
+ search(location, typeMask, docDomain, thirdParty, sitekey, specificOnly,
+ filterType = "all")
+ {
+ let key = "* " + location + " " + typeMask + " " + docDomain + " " +
+ thirdParty + " " + sitekey + " " + specificOnly + " " +
+ filterType;
+
+ let result = this._resultCache.get(key);
+ if (typeof result != "undefined")
+ return result;
+
+ result = this._searchInternal(location, typeMask, docDomain, thirdParty,
+ sitekey, specificOnly, filterType);
+
+ if (this._resultCache.size >= this.maxCacheEntries)
+ this._resultCache.clear();
+
+ this._resultCache.set(key, result);
+
+ return result;
+ }
+
+ /**
* Tests whether the URL is whitelisted
* @see Matcher#matchesAny
* @inheritdoc
* @returns {boolean}
*/
isWhitelisted(location, typeMask, docDomain, thirdParty, sitekey,
specificOnly)
{
« no previous file with comments | « no previous file | test/matcher.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld