Index: lib/contentFiltering.js |
=================================================================== |
--- a/lib/contentFiltering.js |
+++ b/lib/contentFiltering.js |
@@ -37,16 +37,18 @@ |
const selectorGroupSize = 1024; |
let userStyleSheetsSupported = true; |
let snippetsLibrarySource = ""; |
let executableCode = new Map(); |
+let registeredContentScripts = new Map(); |
+ |
function* splitSelectors(selectors) |
{ |
// Chromium's Blink engine supports only up to 8,192 simple selectors, and |
// even fewer compound selectors, in a rule. The exact number of selectors |
// that would work depends on their sizes (e.g. "#foo .bar" has a size of 2). |
// Since we don't know the sizes of the selectors here, we simply split them |
// into groups of 1,024, based on the reasonable assumption that the average |
// selector won't have a size greater than 8. The alternative would be to |
@@ -224,17 +226,17 @@ |
let {elemhide, snippets} = message.filterTypes || |
{elemhide: true, snippets: true}; |
if (!checkWhitelisted(sender.page, sender.frame, null, |
RegExpFilter.typeMap.DOCUMENT)) |
{ |
let hostname = extractHostFromFrame(sender.frame); |
- if (snippets) |
+ if (snippets && !browser.contentScripts) |
{ |
for (let script of Snippets.getScriptsForDomain(hostname)) |
executeScript(script, sender.page.id, sender.frame.id); |
} |
if (elemhide && !checkWhitelisted(sender.page, sender.frame, null, |
RegExpFilter.typeMap.ELEMHIDE)) |
{ |
@@ -274,8 +276,59 @@ |
}); |
fetch(browser.extension.getURL("/snippets.js"), {cache: "no-cache"}) |
.then(response => response.ok ? response.text() : "") |
.then(text => |
{ |
snippetsLibrarySource = text; |
}); |
+ |
+if (browser.contentScripts) |
+{ |
+ Snippets.on("snippets.filterAdded", ({script, domains, text}) => |
+ { |
+ let details = { |
+ js: [{code: getExecutableCode(script)}], |
+ allFrames: true, |
+ matchAboutBlank: true, |
+ runAt: "document_start", |
+ matches: [] |
+ }; |
+ |
+ for (let [domain, include] of domains) |
+ { |
+ if (domain == "") |
+ continue; |
+ |
+ if (!include && !details.excludeMatches) |
+ details.excludeMatches = []; |
+ |
+ let matches = include ? details.matches : details.excludeMatches; |
+ |
+ matches.push(`http://*.${domain}/*`); |
+ matches.push(`https://*.${domain}/*`); |
+ } |
+ |
+ browser.contentScripts.register(details).then(contentScript => |
+ { |
+ registeredContentScripts.set(text, contentScript); |
+ }); |
+ }); |
+ |
+ Snippets.on("snippets.filterRemoved", ({text}) => |
+ { |
+ let contentScript = registeredContentScripts.get(text); |
+ if (contentScript) |
+ { |
+ contentScript.unregister(); |
+ registeredContentScripts.delete(text); |
+ } |
+ }); |
+ |
+ Snippets.on("snippets.filtersCleared", () => |
+ { |
+ for (let contentScript of registeredContentScripts.values()) |
+ contentScript.unregister(); |
+ |
+ registeredContentScripts.clear(); |
+ }); |
+} |