Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/contentFiltering.js

Issue 29737561: Issue 6539, 6782 - Implement support for snippets (Closed) Base URL: https://hg.adblockplus.org/adblockpluschrome/
Patch Set: Add explanatory comment in catch block Created July 19, 2018, 3:51 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include.preload.js ('k') | metadata.chrome » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/contentFiltering.js
===================================================================
rename from lib/cssInjection.js
rename to lib/contentFiltering.js
--- a/lib/cssInjection.js
+++ b/lib/contentFiltering.js
@@ -10,39 +10,43 @@
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.
*/
-/** @module cssInjection */
+/** @module contentFiltering */
"use strict";
const {RegExpFilter} = require("../adblockpluscore/lib/filterClasses");
const {ElemHide} = require("../adblockpluscore/lib/elemHide");
const {ElemHideEmulation} = require("../adblockpluscore/lib/elemHideEmulation");
+const {Snippets, compileScript} = require("../adblockpluscore/lib/snippets");
const {checkWhitelisted} = require("./whitelisting");
const {extractHostFromFrame} = require("./url");
const {port} = require("./messaging");
const {HitLogger} = require("./hitLogger");
const info = require("info");
// Chromium's support for tabs.removeCSS is still a work in progress and the
// API is likely to be different from Firefox's; for now we just don't use it
// at all, even if it's available.
// See https://crbug.com/608854
const styleSheetRemovalSupported = info.platform == "gecko";
const selectorGroupSize = 1024;
let userStyleSheetsSupported = true;
+let snippetsLibrarySource = "";
+let executableCode = 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
@@ -90,17 +94,17 @@
userStyleSheetsSupported = false;
// For other errors, we simply return false to indicate failure.
//
// One common error that occurs frequently is when a frame is not found
// (e.g. "Error: No frame with id 574 in tab 266"), which can happen when
// the code in the parent document has removed the frame before the
// background page has had a chance to respond to the content script's
- // "elemhide.getSelectors" message. We simply ignore such errors, because
+ // "content.applyFilters" message. We simply ignore such errors, because
// otherwise they show up in the log too often and make debugging
// difficult.
//
// Also note that the missing frame error is thrown synchronously on
// Firefox, while on Chromium it is an asychronous promise rejection. In
// the latter case, we cannot indicate failure to the caller, but we still
// explicitly ignore the error.
return false;
@@ -155,35 +159,86 @@
// style sheet now.
if (oldStyleSheet && oldStyleSheet != styleSheet)
removeStyleSheet(tabId, frameId, oldStyleSheet);
frame.injectedStyleSheets.set(groupName, styleSheet);
return true;
}
-port.on("elemhide.getSelectors", (message, sender) =>
+function getExecutableCode(script)
+{
+ let code = executableCode.get(script);
+ if (code)
+ return code;
+
+ code = compileScript(script, [snippetsLibrarySource]);
+
+ executableCode.set(script, code);
+ return code;
+}
+
+function executeScript(script, tabId, frameId)
+{
+ try
+ {
+ browser.tabs.executeScript(tabId, {
+ code: getExecutableCode(script),
+ frameId,
+ matchAboutBlank: true,
+ runAt: "document_start"
+ })
+ .catch(error =>
+ {
+ // Sometimes a frame is added and removed very quickly, in such cases we
+ // simply ignore the error.
+ if (error.message == "The frame was removed.")
+ return;
+
+ throw error;
+ });
+ }
+ catch (error)
+ {
+ // See the comment in the catch block associated with the call to
+ // tabs.insertCSS for why we catch and ignore any errors here.
+ }
+}
+
+port.on("content.applyFilters", (message, sender) =>
{
let selectors = [];
let emulatedPatterns = [];
let trace = HitLogger.hasListener(sender.page.id);
let inline = !userStyleSheetsSupported;
+ let {elemhide, snippets} = message.filterTypes ||
+ {elemhide: true, snippets: true};
+
if (!checkWhitelisted(sender.page, sender.frame, null,
- RegExpFilter.typeMap.DOCUMENT |
- RegExpFilter.typeMap.ELEMHIDE))
+ RegExpFilter.typeMap.DOCUMENT))
{
let hostname = extractHostFromFrame(sender.frame);
- let specificOnly = checkWhitelisted(sender.page, sender.frame, null,
- RegExpFilter.typeMap.GENERICHIDE);
+
+ if (snippets)
+ {
+ for (let script of Snippets.getScriptsForDomain(hostname))
+ executeScript(script, sender.page.id, sender.frame.id);
+ }
- selectors = ElemHide.getSelectorsForDomain(hostname, specificOnly);
+ if (elemhide && !checkWhitelisted(sender.page, sender.frame, null,
+ RegExpFilter.typeMap.ELEMHIDE))
+ {
+ let specificOnly = checkWhitelisted(sender.page, sender.frame, null,
+ RegExpFilter.typeMap.GENERICHIDE);
+ selectors = ElemHide.getSelectorsForDomain(hostname, specificOnly);
- for (let filter of ElemHideEmulation.getRulesForDomain(hostname))
- emulatedPatterns.push({selector: filter.selector, text: filter.text});
+ for (let filter of ElemHideEmulation.getRulesForDomain(hostname))
+ emulatedPatterns.push({selector: filter.selector, text: filter.text});
+ }
}
if (!inline && !updateFrameStyles(sender.page.id, sender.frame.id,
selectors, "standard"))
{
inline = true;
}
@@ -201,8 +256,15 @@
return response;
});
port.on("elemhide.injectSelectors", (message, sender) =>
{
updateFrameStyles(sender.page.id, sender.frame.id, message.selectors,
message.groupName, message.appendOnly);
});
+
+fetch(browser.extension.getURL("/snippets.js"), {cache: "no-cache"})
+.then(response => response.ok ? response.text() : "")
+.then(text =>
+{
+ snippetsLibrarySource = text;
+});
« no previous file with comments | « include.preload.js ('k') | metadata.chrome » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld