| Index: lib/abp2blocklist.js |
| =================================================================== |
| --- a/lib/abp2blocklist.js |
| +++ b/lib/abp2blocklist.js |
| @@ -66,16 +66,19 @@ |
| function escapeRegExp(s) |
| { |
| return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); |
| } |
| function matchDomain(domain) |
| { |
| + if (!domain) |
| + return "^https?://"; |
| + |
| return "^https?://([^/:]*\\.)?" + escapeRegExp(domain).toLowerCase() + "[/:]"; |
| } |
| function getURLSchemes(contentType) |
| { |
| // If the given content type includes all supported URL schemes, simply |
| // return a single generic URL scheme pattern. This minimizes the size of the |
| // generated rule set. The downside to this is that it will also match |
| @@ -124,22 +127,21 @@ |
| } |
| return domains; |
| } |
| function convertElemHideFilter(filter, elemhideSelectorExceptions) |
| { |
| let included = []; |
| let excluded = []; |
| - let rules = []; |
| parseDomains(filter.domains, included, excluded); |
| if (excluded.length == 0 && !(filter.selector in elemhideSelectorExceptions)) |
| - return {matchDomains: included.map(matchDomain), selector: filter.selector}; |
| + return {matchDomains: included, selector: filter.selector}; |
| } |
| /** |
| * Parse the given filter "regexpSource" string. Producing a regular expression, |
| * extracting the hostname (if any), deciding if the regular expression is safe |
| * to be converted + matched as lower case and noting if the source contains |
| * anything after the hostname.) |
| * |
| @@ -581,32 +583,38 @@ |
| 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, exceptionDomains) |
| +function addCSSRules(rules, selectors, domain, exceptionDomains) |
| { |
| let unlessDomain = exceptionDomains.size > 0 ? [] : null; |
| - exceptionDomains.forEach(name => unlessDomain.push("*" + name)); |
| + exceptionDomains.forEach(name => |
| + { |
| + // For domain-specific filters, include the exception domains only if |
| + // they're subdomains of the given domain. |
| + if (!domain || name.substr(-domain.length - 1) == "." + domain) |
| + unlessDomain.push("*" + name); |
| + }); |
| 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); |
| let rule = { |
| - trigger: {"url-filter": matchDomain, |
| + trigger: {"url-filter": matchDomain(domain), |
| "url-filter-is-case-sensitive": true}, |
| action: {type: "css-display-none", |
| selector: selector} |
| }; |
| if (unlessDomain) |
| rule.trigger["unless-domain"] = unlessDomain; |
| @@ -723,18 +731,21 @@ |
| let genericSelectorExceptionDomains = |
| extractFilterDomains(this.generichideExceptions); |
| elemhideExceptionDomains.forEach(name => |
| { |
| genericSelectorExceptionDomains.add(name); |
| }); |
| - addCSSRules(rules, genericSelectors, "^https?://", |
| - genericSelectorExceptionDomains); |
| + addCSSRules(rules, genericSelectors, null, genericSelectorExceptionDomains); |
| + |
| + // Filter out whitelisted domains. |
| + elemhideExceptionDomains.forEach(domain => |
| + groupedElemhideFilters.delete(domain)); |
| groupedElemhideFilters.forEach((selectors, matchDomain) => |
| { |
| addCSSRules(rules, selectors, matchDomain, elemhideExceptionDomains); |
| }); |
| let requestFilterExceptionDomains = []; |
| for (let filter of this.genericblockExceptions) |