| Index: lib/abp2blocklist.js |
| =================================================================== |
| --- a/lib/abp2blocklist.js |
| +++ b/lib/abp2blocklist.js |
| @@ -271,20 +271,32 @@ |
| parseDomains(filter.domains, included, excluded); |
| if (exceptionDomains) |
| excluded = excluded.concat(exceptionDomains); |
| if (withResourceTypes) |
| { |
| - trigger["resource-type"] = getResourceTypes(filter); |
| + let resourceTypes = getResourceTypes(filter); |
| - if (trigger["resource-type"].length == 0) |
| + // Content blocker rules can't differentiate between sub-document requests |
| + // (iframes) and top-level document requests. To avoid too many false |
| + // positives, we prevent rules with no hostname part from blocking document |
| + // requests. |
| + // |
| + // Once Safari 11 becomes our minimum supported version, we could change |
| + // our approach here to use the new "unless-top-url" property instead. |
| + if (filter instanceof filterClasses.BlockingFilter && !parsed.hostname) |
| + resourceTypes = resourceTypes.filter(type => type != "document"); |
| + |
| + if (resourceTypes.length == 0) |
| return; |
| + |
| + trigger["resource-type"] = resourceTypes; |
| } |
| if (filter.thirdParty != null) |
| trigger["load-type"] = [filter.thirdParty ? "third-party" : "first-party"]; |
| if (included.length > 0) |
| { |
| trigger["if-domain"] = []; |
| @@ -310,18 +322,25 @@ |
| } |
| } |
| } |
| else if (excluded.length > 0) |
| { |
| trigger["unless-domain"] = excluded.map(name => "*" + name); |
| } |
| else if (filter instanceof filterClasses.BlockingFilter && |
| - filter.contentType & typeMap.SUBDOCUMENT) |
| + filter.contentType & typeMap.SUBDOCUMENT && parsed.hostname) |
| { |
| + // Rules with a hostname part are still allowed to block document requests, |
| + // but we add an exception for top-level documents. |
| + // |
| + // Note that we can only do this if there's no "unless-domain" property for |
| + // now. This also only works in Safari 11 onwards, while older versions |
| + // simply ignore this property. Once Safari 11 becomes our minimum |
| + // supported version, we can merge "unless-domain" into "unless-top-url". |
| trigger["unless-top-url"] = [trigger["url-filter"]]; |
| if (trigger["url-filter-is-case-sensitive"]) |
| trigger["top-url-filter-is-case-sensitive"] = true; |
| } |
| rules.push({trigger: trigger, action: {type: action}}); |
| } |