Index: lib/abp2blocklist.js |
=================================================================== |
--- a/lib/abp2blocklist.js |
+++ b/lib/abp2blocklist.js |
@@ -345,28 +345,48 @@ |
newSelector.push('[id=', selector.substring(pos.start + 1, pos.end), ']'); |
i = pos.end; |
} |
newSelector.push(selector.substring(i)); |
return newSelector.join(""); |
} |
+function addCSSRules(rules, selectors, matchDomain) |
+{ |
+ while (selectors.length) |
+ { |
+ let selector = selectors.splice(0, selectorLimit).join(", "); |
+ |
+ // As of Safari 9.0 element IDs are matched as lowercase. We work around |
+ // this by converting to the attribute format [id="elementID"] |
+ selector = convertIDSelectorsToAttributeSelectors(selector); |
+ |
+ rules.push({ |
+ trigger: {"url-filter": matchDomain, |
+ "url-filter-is-case-sensitive": true}, |
+ action: {type: "css-display-none", |
+ selector: selector} |
+ }); |
+ } |
+} |
+ |
let ContentBlockerList = |
/** |
* Create a new Adblock Plus filter to content blocker list converter |
* |
* @constructor |
*/ |
exports.ContentBlockerList = function () |
{ |
this.requestFilters = []; |
this.requestExceptions = []; |
this.elemhideFilters = []; |
this.elemhideExceptions = []; |
+ this.generichideExceptions = []; |
this.elemhideSelectorExceptions = new Map(); |
}; |
/** |
* Add Adblock Plus filter to be converted |
* |
* @param {Filter} filter Filter to convert |
*/ |
@@ -383,16 +403,18 @@ |
if (filter instanceof filterClasses.WhitelistFilter) |
{ |
if (filter.contentType & (typeMap.DOCUMENT | whitelistableRequestTypes)) |
this.requestExceptions.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); |
if (filter instanceof filterClasses.ElemHideException) |
{ |
let domains = this.elemhideSelectorExceptions[filter.selector]; |
@@ -407,51 +429,50 @@ |
* Generate content blocker list for all filters that were added |
* |
* @returns {Filter} filter Filter to convert |
*/ |
ContentBlockerList.prototype.generateRules = function(filter) |
{ |
let rules = []; |
+ let genericSelectors = []; |
let groupedElemhideFilters = new Map(); |
+ |
for (let filter of this.elemhideFilters) |
{ |
let result = convertElemHideFilter(filter, this.elemhideSelectorExceptions); |
if (!result) |
continue; |
if (result.matchDomains.length == 0) |
- result.matchDomains = ["^https?://"]; |
- |
- for (let matchDomain of result.matchDomains) |
+ { |
+ genericSelectors.push(result.selector); |
+ } |
+ else |
{ |
- let group = groupedElemhideFilters.get(matchDomain) || []; |
- group.push(result.selector); |
- groupedElemhideFilters.set(matchDomain, group); |
+ for (let matchDomain of result.matchDomains) |
+ { |
+ let group = groupedElemhideFilters.get(matchDomain) || []; |
+ group.push(result.selector); |
+ groupedElemhideFilters.set(matchDomain, group); |
+ } |
} |
} |
+ addCSSRules(rules, genericSelectors, "^https?://"); |
+ |
+ // Right after the generic element hiding filters, add the exceptions that |
+ // should apply only to those filters. |
+ for (let filter of this.generichideExceptions) |
+ convertFilterAddRules(rules, filter, "ignore-previous-rules", false); |
+ |
groupedElemhideFilters.forEach((selectors, matchDomain) => |
{ |
- while (selectors.length) |
- { |
- let selector = selectors.splice(0, selectorLimit).join(", "); |
- |
- // As of Safari 9.0 element IDs are matched as lowercase. We work around |
- // this by converting to the attribute format [id="elementID"] |
- selector = convertIDSelectorsToAttributeSelectors(selector); |
- |
- rules.push({ |
- trigger: {"url-filter": matchDomain, |
- "url-filter-is-case-sensitive": true}, |
- action: {type: "css-display-none", |
- selector: selector} |
- }); |
- } |
+ addCSSRules(rules, selectors, matchDomain); |
}); |
for (let filter of this.elemhideExceptions) |
convertFilterAddRules(rules, filter, "ignore-previous-rules", false); |
for (let filter of this.requestFilters) |
convertFilterAddRules(rules, filter, "block", true); |
for (let filter of this.requestExceptions) |
convertFilterAddRules(rules, filter, "ignore-previous-rules", true); |