Index: lib/abp2blocklist.js |
=================================================================== |
--- a/lib/abp2blocklist.js |
+++ b/lib/abp2blocklist.js |
@@ -209,17 +209,18 @@ |
typeMap.OTHER)) |
types.push("raw"); |
if (filter.contentType & typeMap.SUBDOCUMENT) |
types.push("document"); |
return types; |
} |
-function convertFilterAddRules(rules, filter, action, withResourceTypes) |
+function convertFilterAddRules(rules, filter, action, withResourceTypes, |
+ exceptionDomains) |
{ |
let parsed = parseFilterRegexpSource(filter.regexpSource); |
// For the special case of $document whitelisting filters with just a domain |
// we can generate an equivalent blocking rule exception using if-domain. |
if (filter instanceof filterClasses.WhitelistFilter && |
filter.contentType & typeMap.DOCUMENT && |
parsed.justHostname) |
@@ -251,16 +252,19 @@ |
if (parsed.canSafelyMatchAsLowercase || filter.matchCase) |
trigger["url-filter-is-case-sensitive"] = true; |
let included = []; |
let excluded = []; |
parseDomains(filter.domains, included, excluded); |
+ if (exceptionDomains) |
+ excluded = excluded.concat(exceptionDomains); |
+ |
if (withResourceTypes) |
{ |
trigger["resource-type"] = getResourceTypes(filter); |
if (trigger["resource-type"].length == 0) |
return; |
} |
@@ -376,16 +380,17 @@ |
* @constructor |
*/ |
exports.ContentBlockerList = function () |
{ |
this.requestFilters = []; |
this.requestExceptions = []; |
this.elemhideFilters = []; |
this.elemhideExceptions = []; |
+ this.genericblockExceptions = []; |
this.generichideExceptions = []; |
this.elemhideSelectorExceptions = new Map(); |
}; |
/** |
* Add Adblock Plus filter to be converted |
* |
* @param {Filter} filter Filter to convert |
@@ -401,16 +406,19 @@ |
if (filter instanceof filterClasses.BlockingFilter) |
this.requestFilters.push(filter); |
if (filter instanceof filterClasses.WhitelistFilter) |
{ |
if (filter.contentType & (typeMap.DOCUMENT | whitelistableRequestTypes)) |
this.requestExceptions.push(filter); |
+ if (filter.contentType & typeMap.GENERICBLOCK) |
+ this.genericblockExceptions.push(filter); |
+ |
if (filter.contentType & typeMap.ELEMHIDE) |
this.elemhideExceptions.push(filter); |
else if (filter.contentType & typeMap.GENERICHIDE) |
this.generichideExceptions.push(filter); |
} |
if (filter instanceof filterClasses.ElemHideFilter) |
this.elemhideFilters.push(filter); |
@@ -467,15 +475,28 @@ |
groupedElemhideFilters.forEach((selectors, matchDomain) => |
{ |
addCSSRules(rules, selectors, matchDomain); |
}); |
for (let filter of this.elemhideExceptions) |
convertFilterAddRules(rules, filter, "ignore-previous-rules", false); |
+ |
+ let requestFilterExceptionDomains = []; |
+ for (let filter of this.genericblockExceptions) |
+ { |
+ let parsed = parseFilterRegexpSource(filter.regexpSource); |
+ if (parsed.hostname) |
+ requestFilterExceptionDomains.push(parsed.hostname); |
+ } |
+ |
for (let filter of this.requestFilters) |
- convertFilterAddRules(rules, filter, "block", true); |
+ { |
+ convertFilterAddRules(rules, filter, "block", true, |
+ requestFilterExceptionDomains); |
+ } |
+ |
for (let filter of this.requestExceptions) |
convertFilterAddRules(rules, filter, "ignore-previous-rules", true); |
return rules.filter(rule => !hasNonASCI(rule)); |
}; |