[Pkg-mozext-commits] [adblock-plus] 18/52: Implemented fake background page and proper message responder there
David Prévot
taffit at moszumanska.debian.org
Thu Jan 22 21:43:45 UTC 2015
This is an automated email from the git hooks/post-receive script.
taffit pushed a commit to branch master
in repository adblock-plus.
commit 87a7c25f4fd3b187818229b552a2260c599ade42
Author: Wladimir Palant <trev at adblockplus.org>
Date: Fri Dec 19 18:44:23 2014 +0100
Implemented fake background page and proper message responder there
--HG--
extra : rebase_source : 494b7c6396a8407c1f04ed56d483401cc41fb3b7
extra : amend_source : da2ea4e0a3b286300bd7d825065ce135b22ca2ed
extra : histedit_source : 0d9e01408727890bce9d2a0b4146e30caa537d59%2C7bc4cdd24122f3d436c03418b213b402f23c2cbc
---
README.md | 10 ++-
background.html | 29 +++++++++
background.js | 172 ++++++++++++++++++++++++++++++++++++++++++++++++++++
ext/background.js | 78 ++++++++++++++++++++++++
ext/common.js | 60 +++++++++++++++++-
ext/content.js | 148 +++++++++++---------------------------------
firstRun.js | 5 +-
messageResponder.js | 160 ++++++++++++++++++++++++++++++++++++++++++++++++
8 files changed, 542 insertions(+), 120 deletions(-)
diff --git a/README.md b/README.md
index 18716d4..c31d070 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,14 @@ as they will do in the final product.
Directory structure
-------------------
-* Top-level files: HTML pages and scripts meant to be imported into the
- respective products.
+* Top-level files:
+ * `firstRun.html` and `firstRun.js`: First-run page, see below
+ * `i18n.js`: Localization functions, should be included by all pages.
+ * `utils.js`: Utility functions, to be removed soon.
+ * `messageResponder.js`: Script to be used on the background page to respond
+ to messages sent by UI code.
+ * `background.html`, `background.js`: Test implementation of the background
+ page, should *not be imported*.
* `locale` directory: Localized strings, with one directory per locale. The
Firefox format for locale identifiers is used (xx-YY where xx is the language
code and YY the optional region code). The localization strings themselves are
diff --git a/background.html b/background.html
new file mode 100644
index 0000000..1f2d2d1
--- /dev/null
+++ b/background.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!--
+ - This file is part of Adblock Plus <http://adblockplus.org/>,
+ - Copyright (C) 2006-2014 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/>.
+ -->
+
+<html>
+ <head>
+ <meta charset="utf-8">
+ <script type="text/javascript" src="ext/common.js"></script>
+ <script type="text/javascript" src="ext/background.js"></script>
+ <script type="text/javascript" src="background.js"></script>
+ <script type="text/javascript" src="messageResponder.js"></script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/background.js b/background.js
new file mode 100644
index 0000000..93f4896
--- /dev/null
+++ b/background.js
@@ -0,0 +1,172 @@
+/*
+ * This file is part of Adblock Plus <http://adblockplus.org/>,
+ * Copyright (C) 2006-2014 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/>.
+ */
+
+(function(global)
+{
+ function updateFromURL(data)
+ {
+ if (window.location.search)
+ {
+ var params = window.location.search.substr(1).split("&");
+ for (var i = 0; i < params.length; i++)
+ {
+ var parts = params[i].split("=", 2);
+ if (parts.length == 2 && parts[0] in data)
+ data[parts[0]] = decodeURIComponent(parts[1]);
+ }
+ }
+ }
+
+ var subscriptions =[
+ "https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt",
+ "https://easylist-downloads.adblockplus.org/exceptionrules.txt",
+ "https://easylist-downloads.adblockplus.org/fanboy-social.txt"
+ ];
+
+ global.Utils = {
+ getDocLink: function(link)
+ {
+ return "https://adblockplus.org/redirect?link=" + encodeURIComponent(link);
+ }
+ };
+
+ global.Subscription = function(url)
+ {
+ this.url = url;
+ this.title = "Subscription " + url;
+ this.disabled = false;
+ this.lastDownload = 1234;
+ };
+
+ global.Subscription.fromURL = function(url)
+ {
+ return new global.Subscription(url);
+ };
+
+ global.DownloadableSubscription = global.Subscription;
+ global.SpecialSubscription = function() {};
+
+ global.FilterStorage = {
+ get subscriptions()
+ {
+ return subscriptions.map(global.Subscription.fromURL);
+ },
+
+ get knownSubscriptions()
+ {
+ var result = {};
+ for (var i = 0; i < subscriptions.length; i++)
+ result[subscriptions[i]] = global.Subscription.fromURL(subscriptions[i]);
+ return result;
+ },
+
+ addSubscription: function(subscription)
+ {
+ var index = subscriptions.indexOf(subscription.url);
+ if (index < 0)
+ {
+ subscriptions.push(subscription.url);
+ global.FilterNotifier.triggerListeners("subscription.added", subscription);
+ }
+ },
+
+ removeSubscription: function(subscription)
+ {
+ var index = subscriptions.indexOf(subscription.url);
+ if (index >= 0)
+ {
+ subscriptions.splice(index, 1);
+ global.FilterNotifier.triggerListeners("subscription.removed", subscription);
+ }
+ }
+ };
+
+ global.BlockingFilter = function() {};
+
+ global.defaultMatcher = {
+ matchesAny: function(url, requestType, docDomain, thirdParty)
+ {
+ var params = {blockedURLs: ""};
+ updateFromURL(params);
+ var blocked = params.blockedURLs.split(",");
+ if (blocked.indexOf(url) >= 0)
+ return new global.BlockingFilter();
+ else
+ return null;
+ }
+ };
+
+ var notifierListeners = [];
+ global.FilterNotifier = {
+ addListener: function(listener)
+ {
+ if (notifierListeners.indexOf(listener) < 0)
+ notifierListeners.push(listener);
+ },
+
+ removeListener: function(listener)
+ {
+ var index = notifierListeners.indexOf(listener);
+ if (index >= 0)
+ notifierListeners.splice(index, 1);
+ },
+
+ triggerListeners: function()
+ {
+ var args = Array.prototype.slice.apply(arguments);
+ var listeners = notifierListeners.slice();
+ for (var i = 0; i < listeners.length; i++)
+ listeners[i].apply(null, args);
+ }
+ };
+
+ global.require = function(module)
+ {
+ if (module == "info")
+ {
+ var result = {
+ platform: "gecko",
+ platformVersion: "34.0",
+ application: "firefox",
+ applicationVersion: "34.0"
+ };
+ updateFromURL(result);
+ return result;
+ }
+ else
+ return undefined;
+ }
+
+ global.openOptions = function()
+ {
+ window.open("http://example.com/options.html", "_blank");
+ };
+
+ global.Services = {
+ vc: {
+ compare: function(v1, v2)
+ {
+ return parseFloat(v1) - parseFloat(v2);
+ }
+ }
+ };
+
+ var issues = {seenDataCorruption: false, filterlistsReinitialized: false};
+ updateFromURL(issues);
+ global.seenDataCorruption = issues.seenDataCorruption;
+ global.filterlistsReinitialized = issues.filterlistsReinitialized;
+})(this);
diff --git a/ext/background.js b/ext/background.js
new file mode 100644
index 0000000..f0a7361
--- /dev/null
+++ b/ext/background.js
@@ -0,0 +1,78 @@
+/*
+ * This file is part of Adblock Plus <http://adblockplus.org/>,
+ * Copyright (C) 2006-2014 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/>.
+ */
+
+(function(global)
+{
+ if (!global.ext)
+ global.ext = {};
+
+ window.addEventListener("load", function()
+ {
+ parent.postMessage({
+ type: "backgroundPageLoaded"
+ }, "*");
+ }, false)
+
+ function PageMap()
+ {
+ this._keys = [];
+ this._values = [];
+ }
+ PageMap.prototype = {
+ keys: function()
+ {
+ return this._keys.map(function(source)
+ {
+ return new global.ext.Page(source);
+ });
+ },
+
+ get: function(page)
+ {
+ return this._values[this._keys.indexOf(page._source)];
+ },
+
+ set: function(page, value)
+ {
+ var index = this._keys.indexOf(page._source);
+ if (index < 0)
+ {
+ index = this._keys.push(page._source) - 1;
+
+ var callback = function()
+ {
+ page._source.removeEventListener("unload", callback, false);
+ this.delete(page);
+ }.bind(this);
+ page._source.addEventListener("unload", callback, false);
+ }
+ this._values[index] = value;
+ },
+
+ delete: function(page)
+ {
+ var index = this._keys.indexOf(page._source);
+ if (index >= 0)
+ {
+ this._keys.splice(index, 1);
+ this._values.splice(index, 1);
+ }
+ }
+ };
+
+ global.ext.PageMap = PageMap;
+})(this);
diff --git a/ext/common.js b/ext/common.js
index 434b476..1104062 100644
--- a/ext/common.js
+++ b/ext/common.js
@@ -17,6 +17,63 @@
(function(global)
{
+ if (!global.ext)
+ global.ext = {};
+
+ function Page(source)
+ {
+ this._source = source;
+ }
+ Page.prototype =
+ {
+ sendMessage: function(message)
+ {
+ this._source.postMessage({
+ type: "message",
+ messageId: -1,
+ payload: message
+ }, "*");
+ }
+ };
+
+ global.ext.Page = Page;
+
+ /* Message passing */
+
+ global.ext.onMessage =
+ {
+ addListener: function(listener)
+ {
+ listener._extWrapper = function(event)
+ {
+ if (event.data.type != "message")
+ return;
+
+ var message = event.data.payload;
+ var messageId = event.data.messageId;
+ var sender = {
+ page: new Page(event.source)
+ };
+ var callback = function(message)
+ {
+ event.source.postMessage({
+ type: "response",
+ messageId: messageId,
+ payload: message
+ }, "*");
+ };
+ listener(message, sender, callback);
+ };
+ window.addEventListener("message", listener._extWrapper, false);
+ },
+
+ removeListener: function(listener)
+ {
+ if ("_extWrapper" in listener)
+ window.removeEventListener("message", listener._extWrapper, false);
+ }
+ };
+
/* I18n */
var getLocaleCandidates = function(selectedLocale)
@@ -110,9 +167,6 @@
}
};
- if (!global.ext)
- global.ext = {};
-
global.ext.i18n = {
getMessage: function(msgId, substitutions)
{
diff --git a/ext/content.js b/ext/content.js
index a62f0c5..ad8d0f0 100644
--- a/ext/content.js
+++ b/ext/content.js
@@ -20,135 +20,55 @@
if (!global.ext)
global.ext = {};
- function updateFromURL(data)
+ var backgroundFrame = document.createElement("iframe");
+ backgroundFrame.setAttribute("src", "background.html" + window.location.search);
+ backgroundFrame.style.display = "none";
+ window.addEventListener("DOMContentLoaded", function()
{
- if (window.location.search)
+ document.body.appendChild(backgroundFrame);
+ }, false);
+
+ var messageQueue = [];
+ var maxMessageId = -1;
+ var loadHandler = function(event)
+ {
+ if (event.data.type == "backgroundPageLoaded")
{
- var params = window.location.search.substr(1).split("&");
- for (var i = 0; i < params.length; i++)
- {
- var parts = params[i].split("=", 2);
- if (parts.length == 2 && parts[0] in data)
- data[parts[0]] = decodeURIComponent(parts[1]);
- }
+ var queue = messageQueue;
+ messageQueue = null;
+ if (queue)
+ for (var i = 0; i < queue.length; i++)
+ backgroundFrame.contentWindow.postMessage(queue[i], "*");
+ window.removeEventListener("message", loadHandler, false);
}
}
-
- var subscriptions =[
- "https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt",
- "https://easylist-downloads.adblockplus.org/exceptionrules.txt",
- "https://easylist-downloads.adblockplus.org/fanboy-social.txt"
- ];
-
- var listenerFilter = null;
+ window.addEventListener("message", loadHandler, false);
global.ext.backgroundPage = {
sendMessage: function(message, responseCallback)
{
- var respond = function(response)
- {
- setTimeout(responseCallback.bind(responseCallback, response), 0);
+ var rawMessage = {
+ type: "message",
+ messageId: ++maxMessageId,
+ payload: message
};
+ if (messageQueue)
+ messageQueue.push(rawMessage);
+ else
+ backgroundFrame.contentWindow.postMessage(rawMessage, "*");
- var dispatchListenerNotification = function(action)
+ if (responseCallback)
{
- var match = /^subscription\.(.*)/.exec(action);
- if (match && listenerFilter && listenerFilter.indexOf(match[1]) >= 0)
+ var callbackWrapper = function(event)
{
- global.ext.onMessage._dispatch({
- type: "subscriptions.listen",
- action: match[1],
- args: Array.prototype.slice.call(arguments, 1)
- });
- }
- };
-
- switch (message.type)
- {
- case "app.get":
- if (message.what == "issues")
+ if (event.data.type == "response" && event.data.messageId == rawMessage.messageId)
{
- var response = {seenDataCorruption: false, filterlistsReinitialized: false};
- updateFromURL(response);
-
- var info = {platform: "gecko", platformVersion: "34.0", application: "firefox", applicationVersion: "34.0"};
- updateFromURL(info);
- response.legacySafariVersion = (info.platform == "safari" && (
- parseInt(info.platformVersion, 10) < 6 || // beforeload breaks websites in Safari 5
- info.platformVersion == "6.1" || // extensions are broken in 6.1 and 7.0
- info.platformVersion == "7.0"));
-
- respond(response);
+ window.removeEventListener("message", callbackWrapper, false);
+ responseCallback(event.data.payload);
}
- else if (message.what == "doclink")
- respond("https://adblockplus.org/redirect?link=" + encodeURIComponent(message.link));
- else
- respond(null);
- break;
- case "app.open":
- if (message.what == "options")
- window.open("http://example.com/options.html", "_blank");
- break;
- case "subscriptions.get":
- respond(subscriptions);
- break;
- case "filters.blocked":
- var params = {blockedURLs: ""};
- updateFromURL(params);
- var blocked = params.blockedURLs.split(",");
- respond(blocked.indexOf(message.url) >= 0);
- break;
- case "subscriptions.toggle":
- var index = subscriptions.indexOf(message.url);
- if (index >= 0)
- {
- subscriptions.splice(index, 1);
- dispatchListenerNotification("subscription.removed", message.url);
- }
- else
- {
- subscriptions.push(message.url);
- dispatchListenerNotification("subscription.added", message.url);
- }
- break;
- case "subscriptions.listen":
- listenerFilter = message.filter;
- break;
- }
- }
- };
-
- var EventTarget = function(cancelable)
- {
- this._listeners = [];
- this._cancelable = cancelable;
- };
- EventTarget.prototype = {
- addListener: function(listener)
- {
- if (this._listeners.indexOf(listener) == -1)
- this._listeners.push(listener);
- },
- removeListener: function(listener)
- {
- var idx = this._listeners.indexOf(listener);
- if (idx != -1)
- this._listeners.splice(idx, 1);
- },
- _dispatch: function()
- {
- var result = null;
-
- for (var i = 0; i < this._listeners.length; i++)
- {
- result = this._listeners[i].apply(null, arguments);
-
- if (this._cancelable && result === false)
- break;
+ };
+ window.addEventListener("message", callbackWrapper, false);
}
-
- return result;
}
};
- global.ext.onMessage = new EventTarget();
})(this);
diff --git a/firstRun.js b/firstRun.js
index 1819805..fc40eda 100644
--- a/firstRun.js
+++ b/firstRun.js
@@ -256,10 +256,13 @@
ignoreDisabled: true
}, function(subscriptions)
{
+ var known = Object.create(null);
+ for (var i = 0; i < subscriptions.length; i++)
+ known[subscriptions[i].url] = true;
for (var i = 0; i < featureSubscriptions.length; i++)
{
var featureSubscription = featureSubscriptions[i];
- updateToggleButton(featureSubscription.feature, subscriptions.indexOf(featureSubscription.url) >= 0);
+ updateToggleButton(featureSubscription.feature, featureSubscription.url in known);
}
});
}
diff --git a/messageResponder.js b/messageResponder.js
new file mode 100644
index 0000000..9a4b310
--- /dev/null
+++ b/messageResponder.js
@@ -0,0 +1,160 @@
+/*
+ * This file is part of Adblock Plus <http://adblockplus.org/>,
+ * Copyright (C) 2006-2014 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/>.
+ */
+
+(function(global)
+{
+ var subscriptionKeys = ["disabled", "homepage", "lastSuccess", "title", "url", "downloadStatus"];
+ function convertSubscription(subscription)
+ {
+ var result = {};
+ for (var i = 0; i < subscriptionKeys.length; i++)
+ result[subscriptionKeys[i]] = subscription[subscriptionKeys[i]]
+ return result;
+ }
+
+ var changeListeners = null;
+ var messageTypes = {
+ "app": "app.listen",
+ "filter": "filters.listen",
+ "subscription": "subscriptions.listen"
+ };
+
+ function onFilterChange(action)
+ {
+ var parts = action.split(".", 2);
+ var type;
+ if (parts.length == 1)
+ {
+ type = "app";
+ action = parts[0];
+ }
+ else
+ {
+ type = parts[0];
+ action = parts[1];
+ }
+
+ if (!messageTypes.hasOwnProperty(type))
+ return;
+
+ var args = Array.prototype.slice.call(arguments, 1).map(function(arg)
+ {
+ if (arg instanceof Subscription)
+ return convertSubscription(arg);
+ else
+ return arg;
+ });
+
+ var pages = changeListeners.keys();
+ for (var i = 0; i < pages.length; i++)
+ {
+ var filters = changeListeners.get(pages[i]);
+ if (filters[type] && filters[type].indexOf(action) >= 0)
+ {
+ pages[i].sendMessage({
+ type: messageTypes[type],
+ action: action,
+ args: args
+ });
+ }
+ }
+ };
+
+ ext.onMessage.addListener(function(message, sender, callback)
+ {
+ switch (message.type)
+ {
+ case "app.get":
+ if (message.what == "issues")
+ {
+ var info = require("info");
+ callback({
+ seenDataCorruption: "seenDataCorruption" in global ? global.seenDataCorruption : false,
+ filterlistsReinitialized: "filterlistsReinitialized" in global ? global.filterlistsReinitialized : false,
+ legacySafariVersion: (info.platform == "safari" && (
+ Services.vc.compare(info.platformVersion, "6.0") < 0 || // beforeload breaks websites in Safari 5
+ Services.vc.compare(info.platformVersion, "6.1") == 0 || // extensions are broken in 6.1 and 7.0
+ Services.vc.compare(info.platformVersion, "7.0") == 0))
+ });
+ }
+ else if (message.what == "doclink")
+ callback(Utils.getDocLink(message.link));
+ else
+ callback(null);
+ break;
+ case "app.open":
+ if (message.what == "options")
+ {
+ if (typeof UI != "undefined")
+ UI.openFiltersDialog();
+ else
+ global.openOptions();
+ }
+ break;
+ case "subscriptions.get":
+ var subscriptions = FilterStorage.subscriptions.filter(function(s)
+ {
+ if (message.ignoreDisabled && s.disabled)
+ return false;
+ if (s instanceof DownloadableSubscription && message.downloadable)
+ return true;
+ if (s instanceof SpecialSubscription && message.special)
+ return true;
+ return false;
+ });
+ callback(subscriptions.map(convertSubscription));
+ break;
+ case "filters.blocked":
+ var filter = defaultMatcher.matchesAny(message.url, message.requestType, message.docDomain, message.thirdParty);
+ callback(filter instanceof BlockingFilter);
+ break;
+ case "subscriptions.toggle":
+ var subscription = Subscription.fromURL(message.url);
+ if (subscription.url in FilterStorage.knownSubscriptions && !subscription.disabled)
+ FilterStorage.removeSubscription(subscription);
+ else
+ {
+ subscription.disabled = false;
+ subscription.title = message.title;
+ subscription.homepage = message.homepage;
+ FilterStorage.addSubscription(subscription);
+ if (!subscription.lastDownload)
+ Synchronizer.execute(subscription);
+ }
+ break;
+ case "subscriptions.listen":
+ if (!changeListeners)
+ {
+ changeListeners = new global.ext.PageMap();
+ FilterNotifier.addListener(onFilterChange);
+ }
+
+ var filters = changeListeners.get(sender.page);
+ if (!filters)
+ {
+ filters = Object.create(null);
+ changeListeners.set(sender.page, filters);
+ }
+
+ if (message.filter)
+ filters.subscription = message.filter;
+ else
+ delete filters.subscription;
+ break;
+ }
+ });
+})(this);
--
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