[Pkg-mozext-commits] [adblock-plus] 49/87: Issue 2401 - Integrate CSS property rule handling in Firefox
David Prévot
taffit at moszumanska.debian.org
Sat Apr 30 17:59:07 UTC 2016
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit 284f8b9868ac06944ac71a35235bcec95d9af15d
Author: Wladimir Palant <trev at adblockplus.org>
Date: Wed Mar 30 20:38:48 2016 +0200
Issue 2401 - Integrate CSS property rule handling in Firefox
---
lib/child/cssProperties.js | 97 +++++++++++++++++++++++++++++++++++++
lib/child/main.js | 1 +
lib/contentPolicy.js | 116 +++++++++++++++++++++++++++------------------
lib/cssProperties.js | 47 ++++++++++++++++++
lib/main.js | 1 +
lib/whitelisting.js | 46 ++++++++++++++++++
6 files changed, 263 insertions(+), 45 deletions(-)
diff --git a/lib/child/cssProperties.js b/lib/child/cssProperties.js
new file mode 100644
index 0000000..2a27655
--- /dev/null
+++ b/lib/child/cssProperties.js
@@ -0,0 +1,97 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2016 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * 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/>.
+ */
+
+"use strict";
+
+(function()
+{
+ let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
+
+ let {port} = require("messaging");
+ let {getFrames} = require("child/utils");
+
+ let senderWindow = null;
+
+ let scope = {
+ ext: {
+ backgroundPage: {
+ sendMessage: function(data, callback)
+ {
+ data = {payload: data, frames: getFrames(senderWindow)};
+ if (typeof callback == "function")
+ port.emitWithResponse("cssPropertiesRequest", data).then(callback);
+ else
+ port.emit("cssPropertiesRequest", data);
+ }
+ }
+ }
+ };
+
+ function addUserCSS(window, cssCode)
+ {
+ let uri = Services.io.newURI("data:text/css," + encodeURIComponent(cssCode),
+ null, null);
+ let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindowUtils);
+ utils.loadSheet(uri, Ci.nsIDOMWindowUtils.USER_SHEET);
+ }
+
+ function initCSSPropertyFilters()
+ {
+ Services.scriptloader.loadSubScript(
+ "chrome://adblockplus/content/cssProperties.js", scope);
+
+ let onContentWindow = (subject, topic, data) =>
+ {
+ if (!(subject instanceof Ci.nsIDOMWindow))
+ return;
+
+ let onReady = event =>
+ {
+ subject.removeEventListener("DOMContentLoaded", onReady);
+ let handler = new scope.CSSPropertyFilters(subject, selectors =>
+ {
+ if (selectors.length == 0)
+ return;
+
+ addUserCSS(subject, selectors.map(
+ selector => selector + "{display: none !important;}"
+ ).join("\n"));
+ });
+
+ // HACK: The content script just calls ext.backgroundPage.sendMessage
+ // without indicating which window this is about. We'll store the window
+ // here because we know that messaging happens synchronously.
+ senderWindow = subject;
+ handler.load(() => handler.apply());
+ senderWindow = null;
+ };
+
+ subject.addEventListener("DOMContentLoaded", onReady);
+ };
+
+ Services.obs.addObserver(onContentWindow, "content-document-global-created",
+ false);
+ onShutdown.add(() =>
+ {
+ Services.obs.removeObserver(onContentWindow,
+ "content-document-global-created");
+ });
+ }
+
+ initCSSPropertyFilters();
+})();
diff --git a/lib/child/main.js b/lib/child/main.js
index 7065464..f971968 100644
--- a/lib/child/main.js
+++ b/lib/child/main.js
@@ -19,3 +19,4 @@ require("child/elemHide");
require("child/contentPolicy");
require("child/contextMenu");
require("child/dataCollector");
+require("child/cssProperties");
diff --git a/lib/contentPolicy.js b/lib/contentPolicy.js
index e416634..b5e506a 100644
--- a/lib/contentPolicy.js
+++ b/lib/contentPolicy.js
@@ -145,50 +145,27 @@ var Policy = exports.Policy =
// Interpret unknown types as "other"
contentType = this.contentTypes.get(contentType) || "OTHER";
- let wndLocation = frames[0].location;
- let docDomain = getHostname(wndLocation);
- let match = null;
- let [sitekey, sitekeyFrame] = getSitekey(frames);
let nogeneric = false;
- if (!match && Prefs.enabled)
+ if (Prefs.enabled)
{
- let testSitekey = sitekey;
- let testSitekeyFrame = sitekeyFrame;
- for (let i = 0; i < frames.length; i++)
+ let whitelistHit =
+ this.isFrameWhitelisted(frames, contentType == "ELEMHIDE");
+ if (whitelistHit)
{
- let frame = frames[i];
- let testWndLocation = frame.location;
- let parentWndLocation = frames[Math.min(i + 1, frames.length - 1)].location;
- let parentDocDomain = getHostname(parentWndLocation);
-
- let typeMap = RegExpFilter.typeMap.DOCUMENT;
- if (contentType == "ELEMHIDE")
- typeMap = typeMap | RegExpFilter.typeMap.ELEMHIDE;
- let whitelistMatch = defaultMatcher.matchesAny(testWndLocation, typeMap, parentDocDomain, false, testSitekey);
- if (whitelistMatch instanceof WhitelistFilter)
- {
- let whitelistType = (whitelistMatch.contentType & RegExpFilter.typeMap.DOCUMENT) ? "DOCUMENT" : "ELEMHIDE";
- addHit(i, whitelistType, parentDocDomain, false, testWndLocation,
- whitelistMatch);
+ let [frameIndex, matchType, docDomain, thirdParty, location, filter] = whitelistHit;
+ addHit(frameIndex, matchType, docDomain, thirdParty, location, filter);
+ if (matchType == "DOCUMENT" || matchType == "ELEMHIDE")
return response(true, false);
- }
-
- let genericType = (contentType == "ELEMHIDE" ? "GENERICHIDE" : "GENERICBLOCK");
- let nogenericMatch = defaultMatcher.matchesAny(testWndLocation,
- RegExpFilter.typeMap[genericType], parentDocDomain, false, testSitekey);
- if (nogenericMatch instanceof WhitelistFilter)
- {
+ else
nogeneric = true;
- addHit(i, genericType, parentDocDomain, false, testWndLocation,
- nogenericMatch);
- }
-
- if (frame == testSitekeyFrame)
- [testSitekey, testSitekeyFrame] = getSitekey(frames.slice(i + 1));
}
}
- if (!match && contentType == "ELEMHIDE")
+ let match = null;
+ let wndLocation = frames[0].location;
+ let docDomain = getHostname(wndLocation);
+ let [sitekey, sitekeyFrame] = getSitekey(frames);
+ if (contentType == "ELEMHIDE")
{
match = ElemHide.getFilterByKey(location);
location = match.text.replace(/^.*?#/, '#');
@@ -240,13 +217,13 @@ var Policy = exports.Policy =
},
/**
- * Checks whether a page is whitelisted.
+ * Checks whether a top-level window is whitelisted.
* @param {String} url
- * @param {String} [parentUrl] location of the parent page
- * @param {String} [sitekey] public key provided on the page
- * @return {Filter} filter that matched the URL or null if not whitelisted
+ * URL of the document loaded into the window
+ * @return {?WhitelistFilter}
+ * exception rule that matched the URL if any
*/
- isWhitelisted: function(url, parentUrl, sitekey)
+ isWhitelisted: function(url)
{
if (!url)
return null;
@@ -255,19 +232,68 @@ var Policy = exports.Policy =
if (!this.isBlockableScheme(url))
return null;
- if (!parentUrl)
- parentUrl = url;
-
// Ignore fragment identifier
let index = url.indexOf("#");
if (index >= 0)
url = url.substring(0, index);
- let result = defaultMatcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT, getHostname(parentUrl), false, sitekey);
+ let result = defaultMatcher.matchesAny(url, RegExpFilter.typeMap.DOCUMENT,
+ getHostname(url), false, null);
return (result instanceof WhitelistFilter ? result : null);
},
/**
+ * Checks whether a frame is whitelisted.
+ * @param {Array} frames
+ * frame structure as returned by getFrames() in child/utils module.
+ * @param {boolean} isElemHide
+ * true if element hiding whitelisting should be considered
+ * @return {?Array}
+ * An array with the hit parameters: frameIndex, contentType, docDomain,
+ * thirdParty, location, filter. Note that the filter could be a
+ * genericblock/generichide exception rule. If nothing matched null is
+ * returned.
+ */
+ isFrameWhitelisted: function(frames, isElemHide)
+ {
+ let [sitekey, sitekeyFrame] = getSitekey(frames);
+ let nogenericHit = null;
+
+ let typeMap = RegExpFilter.typeMap.DOCUMENT;
+ if (isElemHide)
+ typeMap = typeMap | RegExpFilter.typeMap.ELEMHIDE;
+ let genericType = (isElemHide ? "GENERICHIDE" : "GENERICBLOCK");
+
+ for (let i = 0; i < frames.length; i++)
+ {
+ let frame = frames[i];
+ let wndLocation = frame.location;
+ let parentWndLocation = frames[Math.min(i + 1, frames.length - 1)].location;
+ let parentDocDomain = getHostname(parentWndLocation);
+
+ let match = defaultMatcher.matchesAny(wndLocation, typeMap, parentDocDomain, false, sitekey);
+ if (match instanceof WhitelistFilter)
+ {
+ let whitelistType = (whitelistMatch.contentType & RegExpFilter.typeMap.DOCUMENT) ? "DOCUMENT" : "ELEMHIDE";
+ return [i, whitelistType, parentDocDomain, false, wndLocation, match];
+ }
+
+ if (!nogenericHit)
+ {
+ match = defaultMatcher.matchesAny(wndLocation,
+ RegExpFilter.typeMap[genericType], parentDocDomain, false, sitekey);
+ if (match instanceof WhitelistFilter)
+ nogenericHit = [i, genericType, parentDocDomain, false, wndLocation, match];
+ }
+
+ if (frame == sitekeyFrame)
+ [sitekey, sitekeyFrame] = getSitekey(frames.slice(i + 1));
+ }
+
+ return nogenericHit;
+ },
+
+ /**
* Deletes nodes that were previously stored with a
* RequestNotifier.storeNodesForEntries() call or similar.
* @param {string} id unique ID of the nodes
diff --git a/lib/cssProperties.js b/lib/cssProperties.js
new file mode 100644
index 0000000..b0e878b
--- /dev/null
+++ b/lib/cssProperties.js
@@ -0,0 +1,47 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2016 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * 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/>.
+ */
+
+/**
+ * @fileOverview This is merely forwarding messages from the content script to
+ * message responder, these will hopefully be received directly soon.
+ */
+
+"use strict";
+
+let {port} = require("messaging");
+let {onMessage} = require("ext_background");
+
+port.on("cssPropertiesRequest", ({payload, frames}) =>
+{
+ let result = undefined;
+
+ // HACK: Message responder doesn't care about sender.page but it passes
+ // sender.frame to whitelisting.checkWhitelisted(). Instead of converting
+ // our frame list into the format used in Chrome we keep it as is, then our
+ // whitelisting.checkWhitelisted() implementation won't need to convert it
+ // back. We merely have to set frames.url, message responder needs it.
+ frames.url = new URL(frames[0].location);
+ let sender = {
+ page: null,
+ frame: frames
+ };
+
+ onMessage._dispatch(payload, sender, data => {
+ result = data;
+ });
+ return result;
+});
diff --git a/lib/main.js b/lib/main.js
index 742a9fb..dadca3a 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -32,6 +32,7 @@ require("sync");
require("messageResponder");
require("ui");
require("objectTabs");
+require("cssProperties");
function bootstrapChildProcesses()
{
diff --git a/lib/whitelisting.js b/lib/whitelisting.js
new file mode 100644
index 0000000..518f31e
--- /dev/null
+++ b/lib/whitelisting.js
@@ -0,0 +1,46 @@
+/*
+ * This file is part of Adblock Plus <https://adblockplus.org/>,
+ * Copyright (C) 2006-2016 Eyeo GmbH
+ *
+ * Adblock Plus is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * Adblock Plus is distributed in the hope that it will be useful,
+ * 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/>.
+ */
+
+/**
+ * @fileOverview This is a dummy to provide a function needed by message
+ * responder.
+ */
+
+"use strict";
+
+let {Policy} = require("contentPolicy");
+let {RegExpFilter} = require("filterClasses");
+
+// NOTE: The function interface is supposed to be compatible with
+// checkWhitelisted in adblockpluschrome. That's why there is a typeMask
+// parameter here. However, this parameter is only used to decide whether
+// elemhide whitelisting should be considered, so only supported values for this
+// parameter are RegExpFilter.typeMap.DOCUMENT and
+// RegExpFilter.typeMap.DOCUMENT | RegExpFilter.typeMap.ELEMHIDE.
+exports.checkWhitelisted = function(page, frames, typeMask)
+{
+ let match =
+ Policy.isFrameWhitelisted(frames, typeMask & RegExpFilter.typeMap.ELEMHIDE);
+ if (match)
+ {
+ let [frameIndex, matchType, docDomain, thirdParty, location, filter] = match;
+ if (matchType == "DOCUMENT" || matchType == "ELEMHIDE")
+ return filter;
+ }
+
+ return null;
+};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-mozext/adblock-plus.git
More information about the Pkg-mozext-commits
mailing list