summaryrefslogtreecommitdiff
path: root/data/extensions/spyblock@gnu.org/lib/child
diff options
context:
space:
mode:
authorRuben Rodriguez <ruben@gnu.org>2018-09-13 20:39:48 -0400
committerRuben Rodriguez <ruben@gnu.org>2018-09-13 21:02:13 -0400
commitd26b319fd6f98517cc3421f10bf18698b953e4d2 (patch)
treebc70c4e472a2eaf514d411dba5067d530e5bbea9 /data/extensions/spyblock@gnu.org/lib/child
parentc3b304c51a3386ea09527a479a883253ea35243a (diff)
Updated extensions list for v60
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/child')
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/bootstrap.js97
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/contentPolicy.js518
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/contextMenu.js137
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/dataCollector.js108
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/elemHide.js403
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/elemHideEmulation.js118
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/flasher.js99
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/main.js31
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/objectTabs.js405
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js444
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/subscribeLinks.js118
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/utils.js141
12 files changed, 0 insertions, 2619 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/child/bootstrap.js b/data/extensions/spyblock@gnu.org/lib/child/bootstrap.js
deleted file mode 100644
index 477ca44..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/bootstrap.js
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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()
-{
- const Cc = Components.classes;
- const Ci = Components.interfaces;
- const Cr = Components.results;
- const Cu = Components.utils;
-
- let {Loader, main, unload} = Cu.import("resource://gre/modules/commonjs/toolkit/loader.js", {});
- let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
- Cu.importGlobalProperties(["atob", "btoa", "File", "URL", "URLSearchParams",
- "TextDecoder", "TextEncoder"]);
-
- let shutdownHandlers = [];
- let onShutdown =
- {
- done: false,
- add: function(handler)
- {
- if (shutdownHandlers.indexOf(handler) < 0)
- shutdownHandlers.push(handler);
- },
- remove: function(handler)
- {
- let index = shutdownHandlers.indexOf(handler);
- if (index >= 0)
- shutdownHandlers.splice(index, 1);
- }
- };
-
- function init()
- {
- let url = new URL(Components.stack.filename);
- let params = new URLSearchParams(url.search.substr(1));
- let info = JSON.parse(params.get("info"));
-
- let loader = Loader({
- paths: {
- "": info.addonRoot + "lib/"
- },
- globals: {
- Components, Cc, Ci, Cu, Cr, atob, btoa, File, URL, URLSearchParams,
- TextDecoder, TextEncoder, onShutdown
- },
- modules: {"info": info, "messageManager": this},
- id: info.addonID
- });
- onShutdown.add(() => unload(loader, "disable"))
-
- main(loader, "child/main");
- }
-
- function shutdown(message)
- {
- if (message.data == Components.stack.filename)
- {
- onShutdown.done = true;
- for (let i = shutdownHandlers.length - 1; i >= 0; i --)
- {
- try
- {
- shutdownHandlers[i]();
- }
- catch (e)
- {
- Cu.reportError(e);
- }
- }
- shutdownHandlers = null;
- }
- }
-
- addMessageListener("AdblockPlus:Shutdown", shutdown);
- onShutdown.add(() =>
- {
- removeMessageListener("AdblockPlus:Shutdown", shutdown);
- });
-
- init();
-})();
diff --git a/data/extensions/spyblock@gnu.org/lib/child/contentPolicy.js b/data/extensions/spyblock@gnu.org/lib/child/contentPolicy.js
deleted file mode 100644
index 97ea7b1..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/contentPolicy.js
+++ /dev/null
@@ -1,518 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Content policy implementation, responsible for blocking things.
- */
-
-"use strict";
-
-try
-{
- // Hack: SDK loader masks our Components object with a getter.
- let proto = Object.getPrototypeOf(this);
- let property = Object.getOwnPropertyDescriptor(proto, "Components");
- if (property && property.get)
- delete proto.Components;
-}
-catch (e)
-{
- Cu.reportError(e);
-}
-
-let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-let {port} = require("messaging");
-let {Utils} = require("utils");
-let {getFrames, isPrivate, getRequestWindow} = require("child/utils");
-let {objectMouseEventHander} = require("child/objectTabs");
-let {RequestNotifier} = require("child/requestNotifier");
-
-/**
- * Randomly generated class name, to be applied to collapsed nodes.
- * @type Promise.<string>
- */
-let collapsedClass = port.emitWithResponse("getCollapsedClass");
-
-/**
- * Maps numerical content type IDs to strings.
- * @type Map.<number,string>
- */
-let types = new Map();
-
-/**
- * Contains nodes stored by storeNodes() mapped by their IDs.
- * @type Map.<string,DOMNode[]>
- */
-let storedNodes = new Map();
-
-/**
- * Process-dependent prefix to be used for unique nodes identifiers returned
- * by storeNodes().
- * @type string
- */
-let nodesIDPrefix = Services.appinfo.processID + " ";
-
-/**
- * Counter used to generate unique nodes identifiers in storeNodes().
- * @type number
- */
-let maxNodesID = 0;
-
-port.on("deleteNodes", onDeleteNodes);
-port.on("refilterNodes", onRefilterNodes);
-
-/**
- * Processes parent's response to the ShouldAllow message.
- * @param {nsIDOMWindow} window window that the request is associated with
- * @param {nsIDOMElement} node DOM element that the request is associated with
- * @param {Object|undefined} response object received as response
- * @return {Boolean} false if the request should be blocked
- */
-function processPolicyResponse(window, node, response)
-{
- if (typeof response == "undefined")
- return true;
-
- let {allow, collapse, hits} = response;
- let isObject = false;
- for (let hit of hits)
- {
- if (hit.contentType == "OBJECT")
- isObject = true;
-
- let context = node;
- if (typeof hit.frameIndex == "number")
- {
- context = window;
- for (let i = 0; i < hit.frameIndex; i++)
- context = context.parent;
- context = context.document;
- }
- RequestNotifier.addNodeData(context, window.top, hit);
- }
-
- if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- {
- // Track mouse events for objects
- if (allow && isObject)
- {
- node.addEventListener("mouseover", objectMouseEventHander, true);
- node.addEventListener("mouseout", objectMouseEventHander, true);
- }
-
- if (collapse)
- schedulePostProcess(node);
- }
- return allow;
-}
-
-/**
- * Checks whether a request should be allowed, hides it if necessary
- * @param {nsIDOMWindow} window
- * @param {nsIDOMElement} node
- * @param {String} contentType
- * @param {String} location location of the request, filter key if contentType is ELEMHIDE
- * @return {Boolean} false if the request should be blocked
- */
-let shouldAllow = exports.shouldAllow = function(window, node, contentType, location)
-{
- return processPolicyResponse(window, node, port.emitSync("shouldAllow", {
- contentType,
- location,
- frames: getFrames(window),
- isPrivate: isPrivate(window)
- }));
-};
-
-/**
- * Asynchronously checks whether a request should be allowed.
- * @param {nsIDOMWindow} window
- * @param {nsIDOMElement} node
- * @param {String} contentType
- * @param {String} location location of the request, filter key if contentType is ELEMHIDE
- * @param {Function} callback callback to be called with a boolean value, if
- * false the request should be blocked
- */
-let shouldAllowAsync = exports.shouldAllowAsync = function(window, node, contentType, location, callback)
-{
- port.emitWithResponse("shouldAllow", {
- contentType,
- location,
- frames: getFrames(window),
- isPrivate: isPrivate(window)
- }).then(response =>
- {
- callback(processPolicyResponse(window, node, response));
- });
-};
-
-/**
- * Stores nodes and generates a unique ID for them that can be used for
- * Policy.refilterNodes() later. It's important that Policy.deleteNodes() is
- * called later, otherwise the nodes will be leaked.
- * @param {DOMNode[]} nodes list of nodes to be stored
- * @return {string} unique ID for the nodes
- */
-let storeNodes = exports.storeNodes = function(nodes)
-{
- let id = nodesIDPrefix + (++maxNodesID);
- storedNodes.set(id, nodes);
- return id;
-};
-
-/**
- * Called via message whenever Policy.deleteNodes() is called in the parent.
- */
-function onDeleteNodes(id, sender)
-{
- storedNodes.delete(id);
-}
-
-/**
- * Called via message whenever Policy.refilterNodes() is called in the parent.
- */
-function onRefilterNodes({nodesID, entry}, sender)
-{
- let nodes = storedNodes.get(nodesID);
- if (nodes)
- for (let node of nodes)
- if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- Utils.runAsync(refilterNode.bind(this, node, entry));
-}
-
-/**
- * Re-checks filters on an element.
- */
-function refilterNode(/**Node*/ node, /**Object*/ entry)
-{
- let wnd = Utils.getWindow(node);
- if (!wnd || wnd.closed)
- return;
-
- if (entry.type == "OBJECT")
- {
- node.removeEventListener("mouseover", objectMouseEventHander, true);
- node.removeEventListener("mouseout", objectMouseEventHander, true);
- }
-
- shouldAllow(wnd, node, entry.type, entry.location, (allow) => {
- // Force node to be collapsed
- if (!allow)
- schedulePostProcess(node)
- });
-}
-
-/**
- * Actual nsIContentPolicy and nsIChannelEventSink implementation
- * @class
- */
-var PolicyImplementation =
-{
- classDescription: "Adblock Plus content policy",
- classID: Components.ID("cfeaabe6-1dd1-11b2-a0c6-cb5c268894c9"),
- contractID: "@adblockplus.org/abp/policy;1",
- xpcom_categories: ["content-policy", "net-channel-event-sinks"],
-
- /**
- * Registers the content policy on startup.
- */
- init: function()
- {
- // Populate types map
- let iface = Ci.nsIContentPolicy;
- for (let name in iface)
- if (name.indexOf("TYPE_") == 0 && name != "TYPE_DATAREQUEST")
- types.set(iface[name], name.substr(5));
-
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.registerFactory(this.classID, this.classDescription, this.contractID, this);
-
- let catMan = Utils.categoryManager;
- for (let category of this.xpcom_categories)
- catMan.addCategoryEntry(category, this.contractID, this.contractID, false, true);
-
- Services.obs.addObserver(this, "document-element-inserted", true);
-
- onShutdown.add(() =>
- {
- Services.obs.removeObserver(this, "document-element-inserted");
-
- for (let category of this.xpcom_categories)
- catMan.deleteCategoryEntry(category, this.contractID, false);
-
- registrar.unregisterFactory(this.classID, this);
- });
- },
-
- //
- // nsISupports interface implementation
- //
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPolicy, Ci.nsIObserver,
- Ci.nsIChannelEventSink, Ci.nsIFactory, Ci.nsISupportsWeakReference]),
-
- //
- // nsIContentPolicy interface implementation
- //
-
- shouldLoad: function(contentType, contentLocation, requestOrigin, node, mimeTypeGuess, extra)
- {
- // Ignore requests without context and top-level documents
- if (!node || contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT)
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Bail out early for chrome: an resource: URLs, this is a work-around for
- // https://bugzil.la/1127744 and https://bugzil.la/1247640
- let location = Utils.unwrapURL(contentLocation);
- if (location.schemeIs("chrome") || location.schemeIs("resource"))
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Ignore standalone objects
- if (contentType == Ci.nsIContentPolicy.TYPE_OBJECT && node.ownerDocument && !/^text\/|[+\/]xml$/.test(node.ownerDocument.contentType))
- return Ci.nsIContentPolicy.ACCEPT;
-
- let wnd = Utils.getWindow(node);
- if (!wnd)
- return Ci.nsIContentPolicy.ACCEPT;
-
- // Data loaded by plugins should be associated with the document
- if (contentType == Ci.nsIContentPolicy.TYPE_OBJECT_SUBREQUEST && node instanceof Ci.nsIDOMElement)
- node = node.ownerDocument;
-
- // Fix type for objects misrepresented as frames or images
- if (contentType != Ci.nsIContentPolicy.TYPE_OBJECT && (node instanceof Ci.nsIDOMHTMLObjectElement || node instanceof Ci.nsIDOMHTMLEmbedElement))
- contentType = Ci.nsIContentPolicy.TYPE_OBJECT;
-
- let result = shouldAllow(wnd, node, types.get(contentType), location.spec);
- return (result ? Ci.nsIContentPolicy.ACCEPT : Ci.nsIContentPolicy.REJECT_REQUEST);
- },
-
- shouldProcess: function(contentType, contentLocation, requestOrigin, insecNode, mimeType, extra)
- {
- return Ci.nsIContentPolicy.ACCEPT;
- },
-
- //
- // nsIObserver interface implementation
- //
- _openers: new WeakMap(),
- _alreadyLoaded: Symbol(),
-
- observe: function(subject, topic, data, uri)
- {
- switch (topic)
- {
- case "document-element-inserted":
- {
- let window = subject.defaultView;
- if (!window)
- return;
-
- let type = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .itemType;
- if (type != Ci.nsIDocShellTreeItem.typeContent)
- return;
-
- let opener = this._openers.get(window);
- if (opener == this._alreadyLoaded)
- {
- // This window has loaded already, ignore it regardless of whether
- // window.opener is still set.
- return;
- }
-
- if (opener && Cu.isDeadWrapper(opener))
- opener = null;
-
- if (!opener)
- {
- // We don't know the opener for this window yet, try to find it
- opener = window.opener;
- if (!opener)
- return;
-
- // The opener might be an intermediate window, get the real one
- while (opener.location == "about:blank" && opener.opener)
- opener = opener.opener;
-
- this._openers.set(window, opener);
-
- let forgetPopup = event =>
- {
- subject.removeEventListener("DOMContentLoaded", forgetPopup);
- this._openers.set(window, this._alreadyLoaded);
- };
- subject.addEventListener("DOMContentLoaded", forgetPopup);
- }
-
- if (!uri)
- uri = window.location.href;
- if (!shouldAllow(opener, opener.document, "POPUP", uri))
- {
- window.stop();
- Utils.runAsync(() => window.close());
- }
- else if (uri == "about:blank")
- {
- // An about:blank pop-up most likely means that a load will be
- // initiated asynchronously. Wait for that.
- Utils.runAsync(() =>
- {
- let channel = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDocShell)
- .QueryInterface(Ci.nsIDocumentLoader)
- .documentChannel;
- if (channel)
- this.observe(subject, topic, data, channel.URI.spec);
- });
- }
- break;
- }
- }
- },
-
- //
- // nsIChannelEventSink interface implementation
- //
-
- asyncOnChannelRedirect: function(oldChannel, newChannel, flags, callback)
- {
- let async = false;
- try
- {
- // nsILoadInfo.contentPolicyType was introduced in Gecko 35, then
- // renamed to nsILoadInfo.externalContentPolicyType in Gecko 44.
- let loadInfo = oldChannel.loadInfo;
- let contentType = ("externalContentPolicyType" in loadInfo ?
- loadInfo.externalContentPolicyType : loadInfo.contentPolicyType);
- if (!contentType)
- return;
-
- let wnd = getRequestWindow(newChannel);
- if (!wnd)
- return;
-
- if (contentType == Ci.nsIContentPolicy.TYPE_DOCUMENT)
- {
- if (wnd.history.length <= 1 && wnd.opener)
- {
- // Special treatment for pop-up windows - this will close the window
- // rather than preventing the redirect. Note that we might not have
- // seen the original channel yet because the redirect happened before
- // the async code in observe() had a chance to run.
- this.observe(wnd.document, "document-element-inserted", null, oldChannel.URI.spec);
- this.observe(wnd.document, "document-element-inserted", null, newChannel.URI.spec);
- }
- return;
- }
-
- shouldAllowAsync(wnd, wnd.document, types.get(contentType), newChannel.URI.spec, function(allow)
- {
- callback.onRedirectVerifyCallback(allow ? Cr.NS_OK : Cr.NS_BINDING_ABORTED);
- });
- async = true;
- }
- catch (e)
- {
- // We shouldn't throw exceptions here - this will prevent the redirect.
- Cu.reportError(e);
- }
- finally
- {
- if (!async)
- callback.onRedirectVerifyCallback(Cr.NS_OK);
- }
- },
-
- //
- // nsIFactory interface implementation
- //
-
- createInstance: function(outer, iid)
- {
- if (outer)
- throw Cr.NS_ERROR_NO_AGGREGATION;
- return this.QueryInterface(iid);
- }
-};
-PolicyImplementation.init();
-
-/**
- * Nodes scheduled for post-processing (might be null).
- * @type Node[]
- */
-let scheduledNodes = null;
-
-/**
- * Schedules a node for post-processing.
- */
-function schedulePostProcess(/**Element*/ node)
-{
- if (scheduledNodes)
- scheduledNodes.push(node);
- else
- {
- scheduledNodes = [node];
- Utils.runAsync(postProcessNodes);
- }
-}
-
-/**
- * Processes nodes scheduled for post-processing (typically hides them).
- */
-function postProcessNodes()
-{
- collapsedClass.then(cls =>
- {
- let nodes = scheduledNodes;
- scheduledNodes = null;
-
- // Resolving class is async initially so the nodes might have already been
- // processed in the meantime.
- if (!nodes)
- return;
-
- for (let node of nodes)
- {
- // adjust frameset's cols/rows for frames
- let parentNode = node.parentNode;
- if (parentNode && parentNode instanceof Ci.nsIDOMHTMLFrameSetElement)
- {
- let hasCols = (parentNode.cols && parentNode.cols.indexOf(",") > 0);
- let hasRows = (parentNode.rows && parentNode.rows.indexOf(",") > 0);
- if ((hasCols || hasRows) && !(hasCols && hasRows))
- {
- let index = -1;
- for (let frame = node; frame; frame = frame.previousSibling)
- if (frame instanceof Ci.nsIDOMHTMLFrameElement || frame instanceof Ci.nsIDOMHTMLFrameSetElement)
- index++;
-
- let property = (hasCols ? "cols" : "rows");
- let weights = parentNode[property].split(",");
- weights[index] = "0";
- parentNode[property] = weights.join(",");
- }
- }
- else
- node.classList.add(cls);
- }
- });
-}
diff --git a/data/extensions/spyblock@gnu.org/lib/child/contextMenu.js b/data/extensions/spyblock@gnu.org/lib/child/contextMenu.js
deleted file mode 100644
index 297ef3e..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/contextMenu.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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";
-
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-
-let {Utils} = require("utils");
-let {RequestNotifier} = require("child/requestNotifier");
-let {storeNodes} = require("child/contentPolicy");
-
-/**
- * Determines the context menu entries to be shown for a contextmenu event.
- * @param {Event} event
- * @return {Array}
- */
-function getContextInfo(event)
-{
- let items = [];
- let target = event.target;
- if (target.localName == "menupopup" && target.triggerNode)
- {
- // SeaMonkey gives us the context menu's popupshowing event
- target = target.triggerNode;
- }
- if (target instanceof Ci.nsIDOMHTMLMapElement || target instanceof Ci.nsIDOMHTMLAreaElement)
- {
- // HTML image maps will usually receive events when the mouse pointer is
- // over a different element, get the real event target.
- let rect = target.getClientRects()[0];
- target = target.ownerDocument.elementFromPoint(Math.max(rect.left, 0), Math.max(rect.top, 0));
- }
-
- if (!target)
- return items;
-
- let addMenuItem = function([node, nodeData])
- {
- let nodeID = null;
- if (node && node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- nodeID = storeNodes([node]);
- items.push([nodeID, nodeData]);
- }.bind(this);
-
- // Look up data that we have for the node
- let data = RequestNotifier.getDataForNode(target);
- let hadImage = false;
- if (data && !data[1].filter)
- {
- addMenuItem(data);
- hadImage = (data[1].type == "IMAGE");
- }
-
- // Look for frame data
- let wnd = Utils.getWindow(target);
- if (wnd.frameElement)
- {
- let data = RequestNotifier.getDataForNode(wnd.frameElement, true);
- if (data && !data[1].filter)
- addMenuItem(data);
- }
-
- // Look for a background image
- if (!hadImage)
- {
- let extractImageURL = function(computedStyle, property)
- {
- let value = computedStyle.getPropertyCSSValue(property);
- // CSSValueList
- if ("length" in value && value.length >= 1)
- value = value[0];
- // CSSValuePrimitiveType
- if ("primitiveType" in value && value.primitiveType == value.CSS_URI)
- return Utils.unwrapURL(value.getStringValue()).spec;
-
- return null;
- };
-
- let node = target;
- while (node)
- {
- if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- {
- let style = wnd.getComputedStyle(node, "");
- let bgImage = extractImageURL(style, "background-image") || extractImageURL(style, "list-style-image");
- if (bgImage)
- {
- let data = RequestNotifier.getDataForNode(wnd.document, true, "IMAGE", bgImage);
- if (data && !data[1].filter)
- {
- addMenuItem(data);
- break;
- }
- }
- }
-
- node = node.parentNode;
- }
- }
-
- return items;
-};
-
-let ContextMenuObserver =
-{
- observe: function(subject, topic, data)
- {
- if (subject.wrappedJSObject)
- subject = subject.wrappedJSObject;
-
- if (subject.addonInfo)
- subject.addonInfo.adblockplus = getContextInfo(subject.event);
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference, Ci.nsIObserver])
-};
-
-Services.obs.addObserver(ContextMenuObserver, "content-contextmenu", true);
-Services.obs.addObserver(ContextMenuObserver, "AdblockPlus:content-contextmenu", true);
-onShutdown.add(() => {
- Services.obs.removeObserver(ContextMenuObserver, "content-contextmenu");
- Services.obs.removeObserver(ContextMenuObserver, "AdblockPlus:content-contextmenu");
-});
diff --git a/data/extensions/spyblock@gnu.org/lib/child/dataCollector.js b/data/extensions/spyblock@gnu.org/lib/child/dataCollector.js
deleted file mode 100644
index 09c334a..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/dataCollector.js
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Collects some data for a content window, to be attached to
- * issue reports.
- */
-
-"use strict";
-
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-let {Task} = Cu.import("resource://gre/modules/Task.jsm", {});
-let {PrivateBrowsingUtils} = Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm", {});
-
-let {port} = require("messaging");
-let {Utils} = require("utils");
-
-port.on("collectData", onCollectData);
-
-function onCollectData({outerWindowID, screenshotWidth}, sender)
-{
- let window = Services.wm.getOuterWindowWithId(outerWindowID);
- if (window)
- {
- return Task.spawn(function*()
- {
- let data = {};
- data.isPrivate = PrivateBrowsingUtils.isContentWindowPrivate(window);
- data.opener = window.opener ? window.opener.location.href : null;
- data.referrer = window.document.referrer;
- data.frames = yield scanFrames(window);
- data.screenshot = yield createScreenshot(window, screenshotWidth);
- return data;
- });
- }
-}
-
-function scanFrames(window)
-{
- let frames = [];
- for (let i = 0; i < window.frames.length; i++)
- {
- let frame = window.frames[i];
- frames.push({
- url: frame.location.href,
- frames: scanFrames(frame)
- });
- }
- return frames;
-}
-
-function* createScreenshot(window, screenshotWidth)
-{
- let canvas = window.document.createElement("canvas");
- canvas.width = screenshotWidth;
-
- let context = canvas.getContext("2d");
- let wndWidth = window.document.documentElement.scrollWidth;
- let wndHeight = window.document.documentElement.scrollHeight;
-
- // Copy scaled screenshot of the webpage, according to the specified width.
-
- // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe side.
- // Also, make sure height is at most five times the width to keep image size down.
- let copyWidth = Math.min(wndWidth, 30000);
- let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5);
- let copyX = Math.max(Math.min(window.scrollX - copyWidth / 2, wndWidth - copyWidth), 0);
- let copyY = Math.max(Math.min(window.scrollY - copyHeight / 2, wndHeight - copyHeight), 0);
-
- let scalingFactor = screenshotWidth / copyWidth;
- canvas.height = copyHeight * scalingFactor;
-
- context.save();
- context.scale(scalingFactor, scalingFactor);
- context.drawWindow(window, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,255)");
- context.restore();
-
- // Reduce colors
- let pixelData = context.getImageData(0, 0, canvas.width, canvas.height);
- let data = pixelData.data;
- let mapping = [0x00, 0x55, 0xAA, 0xFF];
- for (let i = 0; i < data.length; i++)
- {
- data[i] = mapping[data[i] >> 6];
-
- if (i % 5000 == 0)
- {
- // Take a break every 5000 bytes to prevent browser hangs
- yield new Promise((resolve, reject) => Utils.runAsync(resolve));
- }
- }
-
- return pixelData;
-}
diff --git a/data/extensions/spyblock@gnu.org/lib/child/elemHide.js b/data/extensions/spyblock@gnu.org/lib/child/elemHide.js
deleted file mode 100644
index 988adee..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/elemHide.js
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Serves CSS for element hiding and processes hits.
- */
-
-try
-{
- // Hack: SDK loader masks our Components object with a getter.
- let proto = Object.getPrototypeOf(this);
- let property = Object.getOwnPropertyDescriptor(proto, "Components");
- if (property && property.get)
- delete proto.Components;
-}
-catch (e)
-{
- Cu.reportError(e);
-}
-
-let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-let {shouldAllowAsync} = require("child/contentPolicy");
-let {getFrames, isPrivate, getRequestWindow} = require("child/utils");
-let {RequestNotifier} = require("child/requestNotifier");
-let {port} = require("messaging");
-let {Utils} = require("utils");
-
-const notImplemented = () => Cr.NS_ERROR_NOT_IMPLEMENTED;
-
-/**
- * about: URL module used to count hits.
- * @class
- */
-let AboutHandler =
-{
- classID: Components.ID("{55fb7be0-1dd2-11b2-98e6-9e97caf8ba67}"),
- classDescription: "Element hiding hit registration protocol handler",
- aboutPrefix: "abp-elemhide",
-
- /**
- * Registers handler on startup.
- */
- init: function()
- {
- let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
- registrar.registerFactory(this.classID, this.classDescription,
- "@mozilla.org/network/protocol/about;1?what=" + this.aboutPrefix, this);
- onShutdown.add(function()
- {
- registrar.unregisterFactory(this.classID, this);
- }.bind(this));
- },
-
- //
- // Factory implementation
- //
-
- createInstance: function(outer, iid)
- {
- if (outer != null)
- throw Cr.NS_ERROR_NO_AGGREGATION;
-
- return this.QueryInterface(iid);
- },
-
- //
- // About module implementation
- //
-
- getURIFlags: function(uri)
- {
- return Ci.nsIAboutModule.HIDE_FROM_ABOUTABOUT;
- },
-
- newChannel: function(uri, loadInfo)
- {
- let match = /\?hit(\d+)$/.exec(uri.path);
- if (match)
- return new HitRegistrationChannel(uri, loadInfo, match[1]);
-
- match = /\?css(?:=(.*?))?(&specificonly)?$/.exec(uri.path);
- if (match)
- {
- return new StyleDataChannel(uri, loadInfo,
- match[1] ? decodeURIComponent(match[1]) : null, !!match[2]);
- }
-
- throw Cr.NS_ERROR_FAILURE;
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIFactory, Ci.nsIAboutModule])
-};
-AboutHandler.init();
-
-/**
- * Base class for channel implementations, subclasses usually only need to
- * override BaseChannel._getResponse() method.
- * @constructor
- */
-function BaseChannel(uri, loadInfo)
-{
- this.URI = this.originalURI = uri;
- this.loadInfo = loadInfo;
-}
-BaseChannel.prototype = {
- URI: null,
- originalURI: null,
- contentCharset: "utf-8",
- contentLength: 0,
- contentType: null,
- owner: Utils.systemPrincipal,
- securityInfo: null,
- notificationCallbacks: null,
- loadFlags: 0,
- loadGroup: null,
- name: null,
- status: Cr.NS_OK,
-
- _getResponse: notImplemented,
-
- _checkSecurity: function()
- {
- if (!this.loadInfo.triggeringPrincipal.equals(Utils.systemPrincipal))
- throw Cr.NS_ERROR_FAILURE;
- },
-
- asyncOpen: function(listener, context)
- {
- Promise.resolve(this._getResponse()).then(data =>
- {
- let stream = Cc["@mozilla.org/io/string-input-stream;1"]
- .createInstance(Ci.nsIStringInputStream);
- stream.setData(data, data.length);
-
- try
- {
- listener.onStartRequest(this, context);
- }
- catch(e)
- {
- // Listener failing isn't our problem
- }
-
- try
- {
- listener.onDataAvailable(this, context, stream, 0, stream.available());
- }
- catch(e)
- {
- // Listener failing isn't our problem
- }
-
- try
- {
- listener.onStopRequest(this, context, Cr.NS_OK);
- }
- catch(e)
- {
- // Listener failing isn't our problem
- }
- });
- },
-
- asyncOpen2: function(listener)
- {
- this._checkSecurity();
- this.asyncOpen(listener, null);
- },
-
- open: function()
- {
- let data = this._getResponse();
- if (typeof data.then == "function")
- throw Cr.NS_ERROR_NOT_IMPLEMENTED;
-
- let stream = Cc["@mozilla.org/io/string-input-stream;1"]
- .createInstance(Ci.nsIStringInputStream);
- stream.setData(data, data.length);
- return stream;
- },
-
- open2: function()
- {
- this._checkSecurity();
- return this.open();
- },
-
- isPending: () => false,
- cancel: notImplemented,
- suspend: notImplemented,
- resume: notImplemented,
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIChannel, Ci.nsIRequest])
-};
-
-/**
- * Channel returning CSS data for the global as well as site-specific stylesheet.
- * @constructor
- */
-function StyleDataChannel(uri, loadInfo, domain, specificOnly)
-{
- BaseChannel.call(this, uri, loadInfo);
- this._domain = domain;
- this._specificOnly = specificOnly;
-}
-StyleDataChannel.prototype = {
- __proto__: BaseChannel.prototype,
- contentType: "text/css",
- _domain: null,
-
- _getResponse: function()
- {
- function escapeChar(match)
- {
- return "\\" + match.charCodeAt(0).toString(16) + " ";
- }
-
- // Would be great to avoid sync messaging here but nsIStyleSheetService
- // insists on opening channels synchronously.
- let [selectors, keys] = (this._domain ?
- port.emitSync("getSelectorsForDomain", [this._domain, this._specificOnly]) :
- port.emitSync("getUnconditionalSelectors"));
-
- let cssPrefix = "{-moz-binding: url(about:abp-elemhide?hit";
- let cssSuffix = "#dummy) !important;}\n";
- let result = [];
-
- for (let i = 0; i < selectors.length; i++)
- {
- let selector = selectors[i];
- let key = keys[i];
- result.push(selector.replace(/[^\x01-\x7F]/g, escapeChar),
- cssPrefix, key, cssSuffix);
- }
-
- return result.join("");
- }
-};
-
-/**
- * Channel returning data for element hiding hits.
- * @constructor
- */
-function HitRegistrationChannel(uri, loadInfo, key)
-{
- BaseChannel.call(this, uri, loadInfo);
- this.key = key;
-}
-HitRegistrationChannel.prototype = {
- __proto__: BaseChannel.prototype,
- key: null,
- contentType: "text/xml",
-
- _getResponse: function()
- {
- let window = getRequestWindow(this);
- port.emitWithResponse("registerElemHideHit", {
- key: this.key,
- frames: getFrames(window),
- isPrivate: isPrivate(window)
- }).then(hit =>
- {
- if (hit)
- RequestNotifier.addNodeData(window.document, window.top, hit);
- });
- return "<bindings xmlns='http://www.mozilla.org/xbl'/>";
- }
-};
-
-let observer = {
- QueryInterface: XPCOMUtils.generateQI([
- Ci.nsIObserver, Ci.nsISupportsWeakReference
- ]),
-
- topic: "document-element-inserted",
- styleURL: Utils.makeURI("about:abp-elemhide?css"),
- sheet: null,
-
- init: function()
- {
- Services.obs.addObserver(this, this.topic, true);
- onShutdown.add(() =>
- {
- Services.obs.removeObserver(this, this.topic);
- });
-
- port.on("elemhideupdate", () =>
- {
- this.sheet = null;
- });
- },
-
- observe: function(subject, topic, data)
- {
- if (topic != this.topic)
- return;
-
- let window = subject.defaultView;
- if (!window)
- {
- // This is typically XBL bindings and SVG images, but also real
- // documents occasionally - probably due to speculative loading?
- return;
- }
- let type = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .itemType;
- if (type != Ci.nsIDocShellTreeItem.typeContent)
- return;
-
- port.emitWithResponse("elemhideEnabled", {
- frames: getFrames(window),
- isPrivate: isPrivate(window)
- }).then(({
- enabled, contentType, docDomain, thirdParty, location, filter,
- filterType
- }) =>
- {
- if (Cu.isDeadWrapper(window))
- {
- // We are too late, the window is gone already.
- return;
- }
-
- if (enabled)
- {
- let utils = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindowUtils);
-
- // If we have a filter hit at this point then it must be a $generichide
- // filter - apply only specific element hiding filters.
- let specificOnly = !!filter;
- if (!specificOnly)
- {
- if (!this.sheet)
- {
- this.sheet = Utils.styleService.preloadSheet(this.styleURL,
- Ci.nsIStyleSheetService.USER_SHEET);
- }
-
- try
- {
- utils.addSheet(this.sheet, Ci.nsIStyleSheetService.USER_SHEET);
- }
- catch (e)
- {
- // Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add
- // the stylesheet multiple times to the same document (the observer
- // will be notified twice for some documents).
- if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE)
- throw e;
- }
- }
-
- let host = window.location.hostname;
- if (host)
- {
- try
- {
- let suffix = "=" + encodeURIComponent(host);
- if (specificOnly)
- suffix += "&specificonly";
- utils.loadSheetUsingURIString(this.styleURL.spec + suffix,
- Ci.nsIStyleSheetService.USER_SHEET);
- }
- catch (e)
- {
- // Ignore NS_ERROR_ILLEGAL_VALUE - it will be thrown if we try to add
- // the stylesheet multiple times to the same document (the observer
- // will be notified twice for some documents).
- if (e.result != Cr.NS_ERROR_ILLEGAL_VALUE)
- throw e;
- }
- }
- }
-
- if (filter)
- {
- RequestNotifier.addNodeData(window.document, window.top, {
- contentType, docDomain, thirdParty, location, filter, filterType
- });
- }
- });
- }
-};
-observer.init();
diff --git a/data/extensions/spyblock@gnu.org/lib/child/elemHideEmulation.js b/data/extensions/spyblock@gnu.org/lib/child/elemHideEmulation.js
deleted file mode 100644
index 7c4ee17..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/elemHideEmulation.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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, isPrivate} = require("child/utils");
- let {RequestNotifier} = require("child/requestNotifier");
-
- function getFilters(window, callback)
- {
- let message = {
- frames: getFrames(window),
- payload: {
- type: "filters.get",
- what: "elemhideemulation"
- }
- };
- port.emitWithResponse("ext_message", message).then(callback);
- }
-
- 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 initElemHideEmulation()
- {
- let scope = Object.assign({}, require("common"));
- Services.scriptloader.loadSubScript(
- "chrome://adblockplus/content/elemHideEmulation.js", scope);
-
- let onContentWindow = (subject, topic, data) =>
- {
- if (!(subject instanceof Ci.nsIDOMWindow))
- return;
-
- let onReady = event =>
- {
- subject.removeEventListener("load", onReady);
- let handler = new scope.ElemHideEmulation(
- subject, getFilters.bind(null, subject), (selectors, filters) =>
- {
- if (selectors.length == 0)
- return;
-
- addUserCSS(subject, selectors.map(
- selector => selector + "{display: none !important;}"
- ).join("\n"));
-
- if (!isPrivate(subject))
- port.emit("addHits", filters);
-
- let docDomain = null;
- try
- {
- // We are calling getFrames() here because it will consider
- // "inheritance" for about:blank and data: frames.
- docDomain = new URL(getFrames(subject)[0].location).hostname;
- }
- catch (e)
- {
- // Invalid URL?
- }
-
- for (let i = 0; i < filters.length; i++)
- {
- RequestNotifier.addNodeData(subject.document, subject.top, {
- contentType: "ELEMHIDE",
- docDomain: docDomain,
- thirdParty: false,
- location: "##" + selectors[i],
- filter: filters[i],
- filterType: "elemhideemulation"
- });
- }
- }
- );
-
- handler.apply();
- };
-
- subject.addEventListener("load", onReady);
- };
-
- Services.obs.addObserver(onContentWindow, "content-document-global-created",
- false);
- onShutdown.add(() =>
- {
- Services.obs.removeObserver(onContentWindow,
- "content-document-global-created");
- });
- }
-
- initElemHideEmulation();
-})();
diff --git a/data/extensions/spyblock@gnu.org/lib/child/flasher.js b/data/extensions/spyblock@gnu.org/lib/child/flasher.js
deleted file mode 100644
index 492f4e0..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/flasher.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Draws a blinking border for a list of matching elements.
- */
-
-function Flasher(elements, scrollToItem)
-{
- if (scrollToItem && elements[0].ownerDocument)
- {
- // Ensure that at least one element is visible when flashing
- elements[0].scrollIntoView();
- }
-
- this.elements = elements;
- this.count = 0;
-
- this.doFlash();
-
-}
-Flasher.prototype =
-{
- elements: null,
- count: 0,
- timer: null,
-
- doFlash: function()
- {
- if (this.count >= 12)
- {
- this.stop();
- return;
- }
-
- if (this.count % 2)
- this.switchOff();
- else
- this.switchOn();
-
- this.count++;
-
- this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.timer.initWithCallback(() => this.doFlash(), 300, Ci.nsITimer.TYPE_ONE_SHOT);
- },
-
- stop: function()
- {
- if (this.timer)
- {
- this.timer.cancel();
- this.timer = null;
- }
-
- if (this.elements)
- {
- this.switchOff();
- this.elements = null;
- }
- },
-
- setOutline: function(outline, offset)
- {
- for (let element of this.elements)
- {
- if (!Cu.isDeadWrapper(element) && "style" in element)
- {
- element.style.outline = outline;
- element.style.outlineOffset = offset;
- }
- }
- },
-
- switchOn: function()
- {
- this.setOutline("#CC0000 dotted 2px", "-2px");
- },
-
- switchOff: function()
- {
- this.setOutline("", "");
- }
-};
-
-exports.Flasher = Flasher;
diff --git a/data/extensions/spyblock@gnu.org/lib/child/main.js b/data/extensions/spyblock@gnu.org/lib/child/main.js
deleted file mode 100644
index bc21e9a..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/main.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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/>.
- */
-
-let {port} = require("messaging");
-
-// Only initialize after receiving a "response" to a dummy message - this makes
-// sure that on update the old version has enough time to receive and process
-// the shutdown message.
-port.emitWithResponse("ping").then(() =>
-{
- require("child/elemHide");
- require("child/contentPolicy");
- require("child/contextMenu");
- require("child/dataCollector");
- require("child/elemHideEmulation");
- require("child/subscribeLinks");
-}).catch(e => Cu.reportError(e));
diff --git a/data/extensions/spyblock@gnu.org/lib/child/objectTabs.js b/data/extensions/spyblock@gnu.org/lib/child/objectTabs.js
deleted file mode 100644
index 74e7387..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/objectTabs.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Code responsible for showing and hiding object tabs.
- */
-
-let {port} = require("messaging");
-
-/**
- * Class responsible for showing and hiding object tabs.
- * @class
- */
-var objTabs =
-{
- /**
- * Number of milliseconds to wait until hiding tab after the mouse moves away.
- * @type Integer
- */
- HIDE_DELAY: 1000,
-
- /**
- * Document element the object tab is currently being displayed for.
- * @type Element
- */
- currentElement: null,
-
- /**
- * Windows that the window event handler is currently registered for.
- * @type Window[]
- */
- windowListeners: null,
-
- /**
- * Panel element currently used as object tab.
- * @type Element
- */
- objtabElement: null,
-
- /**
- * Time of previous position update.
- * @type Integer
- */
- prevPositionUpdate: 0,
-
- /**
- * Timer used to update position of the object tab.
- * @type nsITimer
- */
- positionTimer: null,
-
- /**
- * Timer used to delay hiding of the object tab.
- * @type nsITimer
- */
- hideTimer: null,
-
- /**
- * Used when hideTimer is running, time when the tab should be hidden.
- * @type Integer
- */
- hideTargetTime: 0,
-
- /**
- * Localized texts and class names to be used for the tab. This will be set
- * when showTabFor is called for the first time.
- * @type Object
- */
- texts: null,
-
- /**
- * Called to show object tab for an element.
- */
- showTabFor: function(/**Element*/ element)
- {
- // Object tabs aren't usable in Fennec
- let {application} = require("info");
- if (application == "fennec" || application == "fennec2" ||
- application == "adblockbrowser")
- return;
-
- if (!this.texts)
- this.texts = port.emitWithResponse("getObjectTabsTexts");
- Promise.all([port.emitWithResponse("getObjectTabsStatus"), this.texts])
- .then(([status, texts]) =>
- {
- this.texts = texts;
- if (!status)
- return;
-
- if (this.hideTimer)
- {
- this.hideTimer.cancel();
- this.hideTimer = null;
- }
-
- if (this.objtabElement)
- this.objtabElement.style.setProperty("opacity", "1", "important");
-
- if (this.currentElement != element)
- {
- this._hideTab();
-
- let {RequestNotifier} = require("child/requestNotifier");
- let data = RequestNotifier.getDataForNode(element, true, "OBJECT");
- if (data)
- this._showTab(element, data[1]);
- }
- });
- },
-
- /**
- * Called to hide object tab for an element (actual hiding happens delayed).
- */
- hideTabFor: function(/**Element*/ element)
- {
- if (element != this.currentElement || this.hideTimer)
- return;
-
- this.hideTargetTime = Date.now() + this.HIDE_DELAY;
- this.hideTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.hideTimer.init(this, 40, Ci.nsITimer.TYPE_REPEATING_SLACK);
- },
-
- /**
- * Makes the tab element visible.
- * @param {Element} element
- * @param {RequestEntry} data
- */
- _showTab: function(element, data)
- {
- let doc = element.ownerDocument.defaultView.top.document;
-
- this.objtabElement = doc.createElementNS("http://www.w3.org/1999/xhtml", "a");
- this.objtabElement.textContent = this.texts.label;
- this.objtabElement.setAttribute("title", this.texts.tooltip);
- this.objtabElement.setAttribute("href", data.location);
- this.objtabElement.setAttribute("class", this.texts.classHidden);
- this.objtabElement.style.setProperty("opacity", "1", "important");
- this.objtabElement.nodeData = data;
-
- this.currentElement = element;
-
- // Register paint listeners for the relevant windows
- this.windowListeners = [];
- let wnd = element.ownerDocument.defaultView;
- while (wnd)
- {
- wnd.addEventListener("MozAfterPaint", objectWindowEventHandler, false);
- this.windowListeners.push(wnd);
- wnd = (wnd.parent != wnd ? wnd.parent : null);
- }
-
- // Register mouse listeners on the object tab
- this.objtabElement.addEventListener("mouseover", objectTabEventHander, false);
- this.objtabElement.addEventListener("mouseout", objectTabEventHander, false);
- this.objtabElement.addEventListener("click", objectTabEventHander, true);
-
- // Insert the tab into the document and adjust its position
- doc.documentElement.appendChild(this.objtabElement);
- if (!this.positionTimer)
- {
- this.positionTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.positionTimer.init(this, 200, Ci.nsITimer.TYPE_REPEATING_SLACK);
- }
- this._positionTab();
- },
-
- /**
- * Hides the tab element.
- */
- _hideTab: function()
- {
- if (this.objtabElement)
- {
- // Prevent recursive calls via popuphidden handler
- let objtab = this.objtabElement;
- this.objtabElement = null;
- this.currentElement = null;
-
- if (this.hideTimer)
- {
- this.hideTimer.cancel();
- this.hideTimer = null;
- }
-
- if (this.positionTimer)
- {
- this.positionTimer.cancel();
- this.positionTimer = null;
- }
-
- try {
- objtab.parentNode.removeChild(objtab);
- } catch (e) {}
- objtab.removeEventListener("mouseover", objectTabEventHander, false);
- objtab.removeEventListener("mouseout", objectTabEventHander, false);
- objtab.nodeData = null;
-
- for (let wnd of this.windowListeners)
- wnd.removeEventListener("MozAfterPaint", objectWindowEventHandler, false);
- this.windowListeners = null;
- }
- },
-
- /**
- * Updates position of the tab element.
- */
- _positionTab: function()
- {
- // Test whether element is still in document
- let elementDoc = null;
- try
- {
- elementDoc = this.currentElement.ownerDocument;
- } catch (e) {} // Ignore "can't access dead object" error
- if (!elementDoc || !this.currentElement.offsetWidth || !this.currentElement.offsetHeight ||
- !elementDoc.defaultView || !elementDoc.documentElement)
- {
- this._hideTab();
- return;
- }
-
- let objRect = this._getElementPosition(this.currentElement);
-
- let className = this.texts.classVisibleTop;
- let left = objRect.right - this.objtabElement.offsetWidth;
- let top = objRect.top - this.objtabElement.offsetHeight;
- if (top < 0)
- {
- top = objRect.bottom;
- className = this.texts.classVisibleBottom;
- }
-
- if (this.objtabElement.style.left != left + "px")
- this.objtabElement.style.setProperty("left", left + "px", "important");
- if (this.objtabElement.style.top != top + "px")
- this.objtabElement.style.setProperty("top", top + "px", "important");
-
- if (this.objtabElement.getAttribute("class") != className)
- this.objtabElement.setAttribute("class", className);
-
- this.prevPositionUpdate = Date.now();
- },
-
- /**
- * Calculates element's position relative to the top frame and considering
- * clipping due to scrolling.
- * @return {{left: Number, top: Number, right: Number, bottom: Number}}
- */
- _getElementPosition: function(/**Element*/ element)
- {
- // Restrict rectangle coordinates by the boundaries of a window's client area
- function intersectRect(rect, wnd)
- {
- // Cannot use wnd.innerWidth/Height because they won't account for scrollbars
- let doc = wnd.document;
- let wndWidth = doc.documentElement.clientWidth;
- let wndHeight = doc.documentElement.clientHeight;
- if (doc.compatMode == "BackCompat") // clientHeight will be bogus in quirks mode
- wndHeight = Math.max(doc.documentElement.offsetHeight, doc.body.offsetHeight) - wnd.scrollMaxY - 1;
-
- rect.left = Math.max(rect.left, 0);
- rect.top = Math.max(rect.top, 0);
- rect.right = Math.min(rect.right, wndWidth);
- rect.bottom = Math.min(rect.bottom, wndHeight);
- }
-
- let rect = element.getBoundingClientRect();
- let wnd = element.ownerDocument.defaultView;
-
- let style = wnd.getComputedStyle(element, null);
- let offsets = [
- parseFloat(style.borderLeftWidth) + parseFloat(style.paddingLeft),
- parseFloat(style.borderTopWidth) + parseFloat(style.paddingTop),
- parseFloat(style.borderRightWidth) + parseFloat(style.paddingRight),
- parseFloat(style.borderBottomWidth) + parseFloat(style.paddingBottom)
- ];
-
- rect = {left: rect.left + offsets[0], top: rect.top + offsets[1],
- right: rect.right - offsets[2], bottom: rect.bottom - offsets[3]};
- while (true)
- {
- intersectRect(rect, wnd);
-
- if (!wnd.frameElement)
- break;
-
- // Recalculate coordinates to be relative to frame's parent window
- let frameElement = wnd.frameElement;
- wnd = frameElement.ownerDocument.defaultView;
-
- let frameRect = frameElement.getBoundingClientRect();
- let frameStyle = wnd.getComputedStyle(frameElement, null);
- let relLeft = frameRect.left + parseFloat(frameStyle.borderLeftWidth) + parseFloat(frameStyle.paddingLeft);
- let relTop = frameRect.top + parseFloat(frameStyle.borderTopWidth) + parseFloat(frameStyle.paddingTop);
-
- rect.left += relLeft;
- rect.right += relLeft;
- rect.top += relTop;
- rect.bottom += relTop;
- }
-
- return rect;
- },
-
- doBlock: function()
- {
- let {storeNodes} = require("child/contentPolicy");
- let nodesID = storeNodes([this.currentElement]);
- port.emit("blockItem", {
- request: this.objtabElement.nodeData,
- nodesID
- });
- },
-
- /**
- * Called whenever a timer fires.
- * @param {nsISupport} subject
- * @param {string} topic
- * @param {string} data
- */
- observe: function(subject, topic, data)
- {
- if (subject == this.positionTimer)
- {
- // Don't update position if it was already updated recently (via MozAfterPaint)
- if (Date.now() - this.prevPositionUpdate > 100)
- this._positionTab();
- }
- else if (subject == this.hideTimer)
- {
- let now = Date.now();
- if (now >= this.hideTargetTime)
- this._hideTab();
- else if (this.hideTargetTime - now < this.HIDE_DELAY / 2)
- this.objtabElement.style.setProperty("opacity", (this.hideTargetTime - now) * 2 / this.HIDE_DELAY, "important");
- }
- }
-};
-
-onShutdown.add(objTabs._hideTab.bind(objTabs));
-
-/**
- * Function called whenever the mouse enters or leaves an object.
- */
-function objectMouseEventHander(/**Event*/ event)
-{
- if (!event.isTrusted)
- return;
-
- if (event.type == "mouseover")
- objTabs.showTabFor(event.target);
- else if (event.type == "mouseout")
- objTabs.hideTabFor(event.target);
-}
-
-/**
- * Function called for paint events of the object tab window.
- */
-function objectWindowEventHandler(/**Event*/ event)
-{
- if (!event.isTrusted)
- return;
-
- // Don't trigger update too often, avoid overusing CPU on frequent page updates
- if (event.type == "MozAfterPaint" && Date.now() - objTabs.prevPositionUpdate > 20)
- objTabs._positionTab();
-}
-
-/**
- * Function called whenever the mouse enters or leaves an object tab.
- */
-function objectTabEventHander(/**Event*/ event)
-{
- if (onShutdown.done || !event.isTrusted)
- return;
-
- if (event.type == "click" && event.button == 0)
- {
- event.preventDefault();
- event.stopPropagation();
-
- objTabs.doBlock();
- }
- else if (event.type == "mouseover")
- objTabs.showTabFor(objTabs.currentElement);
- else if (event.type == "mouseout")
- objTabs.hideTabFor(objTabs.currentElement);
-}
-exports.objectMouseEventHander = objectMouseEventHander;
diff --git a/data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js b/data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js
deleted file mode 100644
index fc6d314..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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 Stores Adblock Plus data to be attached to a window.
- */
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-let {port} = require("messaging");
-let {Utils} = require("utils");
-let {Flasher} = require("child/flasher");
-
-let nodeData = new WeakMap();
-let windowStats = new WeakMap();
-let windowData = new WeakMap();
-let requestEntryMaxId = 0;
-
-/**
- * Active RequestNotifier instances by their ID
- * @type Map.<number,RequestNotifier>
- */
-let notifiers = new Map();
-
-port.on("startWindowScan", onStartScan);
-port.on("shutdownNotifier", onNotifierShutdown);
-port.on("flashNodes", onFlashNodes);
-port.on("retrieveNodeSize", onRetrieveNodeSize);
-port.on("storeNodesForEntries", onStoreNodes);
-port.on("retrieveWindowStats", onRetrieveWindowStats);
-port.on("storeWindowData", onStoreWindowData);
-port.on("retrieveWindowData", onRetrieveWindowData);
-
-function onStartScan({notifierID, outerWindowID})
-{
- let window = Services.wm.getOuterWindowWithId(outerWindowID);
- if (window)
- new RequestNotifier(window, notifierID);
-}
-
-function onNotifierShutdown(notifierID)
-{
- let notifier = notifiers.get(notifierID);
- if (notifier)
- notifier.shutdown();
-}
-
-function onFlashNodes({notifierID, requests, scrollToItem})
-{
- let notifier = notifiers.get(notifierID);
- if (notifier)
- notifier.flashNodes(requests, scrollToItem);
-}
-
-function onRetrieveNodeSize({notifierID, requests})
-{
- let notifier = notifiers.get(notifierID);
- if (notifier)
- return notifier.retrieveNodeSize(requests);
-}
-
-function onStoreNodes({notifierID, requests})
-{
- let notifier = notifiers.get(notifierID);
- if (notifier)
- return notifier.storeNodesForEntries(requests);
-}
-
-function onRetrieveWindowStats(outerWindowID)
-{
- let window = Services.wm.getOuterWindowWithId(outerWindowID);
- if (window)
- return RequestNotifier.getWindowStatistics(window);
-}
-
-function onStoreWindowData({outerWindowID, data})
-{
- let window = Services.wm.getOuterWindowWithId(outerWindowID);
- if (window)
- windowData.set(window.document, data);
-};
-
-function onRetrieveWindowData(outerWindowID)
-{
- let window = Services.wm.getOuterWindowWithId(outerWindowID);
- if (window)
- return windowData.get(window.document) || null;
-};
-
-/**
- * Creates a notifier object for a particular window. After creation the window
- * will first be scanned for previously saved requests. Once that scan is
- * complete only new requests for this window will be reported.
- * @param {Window} window window to attach the notifier to
- * @param {Integer} notifierID Parent notifier ID to be messaged
- */
-function RequestNotifier(window, notifierID)
-{
- this.window = window;
- this.id = notifierID;
- notifiers.set(this.id, this);
- this.nodes = new Map();
- this.startScan(window);
-}
-exports.RequestNotifier = RequestNotifier;
-
-RequestNotifier.prototype =
-{
- /**
- * Parent notifier ID to be messaged
- * @type Integer
- */
- id: null,
-
- /**
- * The window this notifier is associated with.
- * @type Window
- */
- window: null,
-
- /**
- * Nodes associated with a particular request ID.
- * @type Map.<number,Node>
- */
- nodes: null,
-
- /**
- * Shuts down the notifier once it is no longer used. The listener
- * will no longer be called after that.
- */
- shutdown: function()
- {
- delete this.window;
- delete this.nodes;
- this.stopFlashing();
- notifiers.delete(this.id);
- },
-
- /**
- * Notifies the parent about a new request.
- * @param {Node} node DOM node that the request is associated with
- * @param {Object} entry
- */
- notifyListener: function(node, entry)
- {
- if (this.nodes)
- this.nodes.set(entry.id, node);
- port.emit("foundNodeData", {
- notifierID: this.id,
- data: entry
- });
- },
-
- onComplete: function()
- {
- port.emit("scanComplete", this.id);
- },
-
- /**
- * Number of currently posted scan events (will be 0 when the scan finishes
- * running).
- */
- eventsPosted: 0,
-
- /**
- * Starts the initial scan of the window (will recurse into frames).
- * @param {Window} wnd the window to be scanned
- */
- startScan: function(wnd)
- {
- let doc = wnd.document;
- let walker = doc.createTreeWalker(doc, Ci.nsIDOMNodeFilter.SHOW_ELEMENT, null, false);
-
- let process = function()
- {
- // Don't do anything if the notifier was shut down already.
- if (!this.window)
- return;
-
- let node = walker.currentNode;
- let data = nodeData.get(node);
- if (typeof data != "undefined")
- for (let k in data)
- this.notifyListener(node, data[k]);
-
- if (walker.nextNode())
- Utils.runAsync(process);
- else
- {
- // Done with the current window, start the scan for its frames
- for (let i = 0; i < wnd.frames.length; i++)
- this.startScan(wnd.frames[i]);
-
- this.eventsPosted--;
- if (!this.eventsPosted)
- {
- this.scanComplete = true;
- this.onComplete();
- }
- }
- }.bind(this);
-
- // Process each node in a separate event to allow other events to process
- this.eventsPosted++;
- Utils.runAsync(process);
- },
-
- /**
- * Makes the nodes associated with the given requests blink.
- * @param {number[]} requests list of request IDs that were previously
- * reported by this notifier.
- * @param {boolean} scrollToItem if true, scroll to first node
- */
- flashNodes: function(requests, scrollToItem)
- {
- this.stopFlashing();
-
- let nodes = [];
- for (let id of requests)
- {
- if (!this.nodes.has(id))
- continue;
-
- let node = this.nodes.get(id);
- if (Cu.isDeadWrapper(node))
- this.nodes.delete(node);
- else if (node.nodeType == Ci.nsIDOMNode.ELEMENT_NODE)
- nodes.push(node);
- }
- if (nodes.length)
- this.flasher = new Flasher(nodes, scrollToItem);
- },
-
- /**
- * Stops flashing nodes after a previous flashNodes() call.
- */
- stopFlashing: function()
- {
- if (this.flasher)
- this.flasher.stop();
- this.flasher = null;
- },
-
- /**
- * Attempts to calculate the size of the nodes associated with the requests.
- * @param {number[]} requests list of request IDs that were previously
- * reported by this notifier.
- * @return {number[]|null} either an array containing width and height or
- * null if the size could not be calculated.
- */
- retrieveNodeSize: function(requests)
- {
- function getNodeSize(node)
- {
- if (node instanceof Ci.nsIDOMHTMLImageElement && (node.naturalWidth || node.naturalHeight))
- return [node.naturalWidth, node.naturalHeight];
- else if (node instanceof Ci.nsIDOMHTMLElement && (node.offsetWidth || node.offsetHeight))
- return [node.offsetWidth, node.offsetHeight];
- else
- return null;
- }
-
- let size = null;
- for (let id of requests)
- {
- if (!this.nodes.has(id))
- continue;
-
- let node = this.nodes.get(id);
- if (Cu.isDeadWrapper(node))
- this.nodes.delete(node);
- else
- {
- size = getNodeSize(node);
- if (size)
- break;
- }
- }
- return size;
- },
-
- /**
- * Stores the nodes associated with the requests and generates a unique ID
- * for them that can be used with Policy.refilterNodes().
- * @param {number[]} requests list of request IDs that were previously
- * reported by this notifier.
- * @return {string} unique identifiers associated with the nodes.
- */
- storeNodesForEntries: function(requests)
- {
- let nodes = [];
- for (let id of requests)
- {
- if (!this.nodes.has(id))
- continue;
-
- let node = this.nodes.get(id);
- if (Cu.isDeadWrapper(node))
- this.nodes.delete(node);
- else
- nodes.push(node);
- }
-
- let {storeNodes} = require("child/contentPolicy");
- return storeNodes(nodes);
- }
-};
-
-/**
- * Attaches request data to a DOM node.
- * @param {Node} node node to attach data to
- * @param {Window} topWnd top-level window the node belongs to
- * @param {Object} hitData
- * @param {String} hitData.contentType request type, e.g. "IMAGE"
- * @param {String} hitData.docDomain domain of the document that initiated the request
- * @param {Boolean} hitData.thirdParty will be true if a third-party server has been requested
- * @param {String} hitData.location the address that has been requested
- * @param {String} hitData.filter filter applied to the request or null if none
- * @param {String} hitData.filterType type of filter applied to the request
- */
-RequestNotifier.addNodeData = function(node, topWnd, {contentType, docDomain, thirdParty, location, filter, filterType})
-{
- let entry = {
- id: ++requestEntryMaxId,
- type: contentType,
- docDomain, thirdParty, location, filter
- };
-
- let existingData = nodeData.get(node);
- if (typeof existingData == "undefined")
- {
- existingData = {};
- nodeData.set(node, existingData);
- }
-
- // Add this request to the node data
- existingData[contentType + " " + location] = entry;
-
- // Update window statistics
- if (!windowStats.has(topWnd.document))
- {
- windowStats.set(topWnd.document, {
- items: 0,
- hidden: 0,
- blocked: 0,
- whitelisted: 0,
- filters: {}
- });
- }
-
- let stats = windowStats.get(topWnd.document);
- if (filterType != "elemhide" && filterType != "elemhideexception" && filterType != "elemhideemulation")
- stats.items++;
- if (filter)
- {
- if (filterType == "blocking")
- stats.blocked++;
- else if (filterType == "whitelist" || filterType == "elemhideexception")
- stats.whitelisted++;
- else if (filterType == "elemhide" || filterType == "elemhideemulation")
- stats.hidden++;
-
- if (filter in stats.filters)
- stats.filters[filter]++;
- else
- stats.filters[filter] = 1;
- }
-
- // Notify listeners
- for (let notifier of notifiers.values())
- if (!notifier.window || notifier.window == topWnd)
- notifier.notifyListener(node, entry);
-}
-
-/**
- * Retrieves the statistics for a window.
- * @return {Object} Object with the properties items, blocked, whitelisted, hidden, filters containing statistics for the window (might be null)
- */
-RequestNotifier.getWindowStatistics = function(/**Window*/ wnd)
-{
- if (windowStats.has(wnd.document))
- return windowStats.get(wnd.document);
- else
- return null;
-}
-
-/**
- * Retrieves the request data associated with a DOM node.
- * @param {Node} node
- * @param {Boolean} noParent if missing or false, the search will extend to the parent nodes until one is found that has data associated with it
- * @param {Integer} [type] request type to be looking for
- * @param {String} [location] request location to be looking for
- * @result {[Node, Object]}
- * @static
- */
-RequestNotifier.getDataForNode = function(node, noParent, type, location)
-{
- while (node)
- {
- let data = nodeData.get(node);
- if (typeof data != "undefined")
- {
- let entry = null;
- // Look for matching entry
- for (let k in data)
- {
- if ((!entry || entry.id < data[k].id) &&
- (typeof type == "undefined" || data[k].type == type) &&
- (typeof location == "undefined" || data[k].location == location))
- {
- entry = data[k];
- }
- }
- if (entry)
- return [node, entry];
- }
-
- // If we don't have any match on this node then maybe its parent will do
- if ((typeof noParent != "boolean" || !noParent) &&
- node.parentNode instanceof Ci.nsIDOMElement)
- {
- node = node.parentNode;
- }
- else
- {
- node = null;
- }
- }
-
- return null;
-};
diff --git a/data/extensions/spyblock@gnu.org/lib/child/subscribeLinks.js b/data/extensions/spyblock@gnu.org/lib/child/subscribeLinks.js
deleted file mode 100644
index a2e729d..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/subscribeLinks.js
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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/>.
- */
-
-let {Services} = Cu.import("resource://gre/modules/Services.jsm", {});
-
-let {port} = require("messaging");
-
-Services.obs.addObserver(onContentWindow, "content-document-global-created",
- false);
-onShutdown.add(() =>
-{
- Services.obs.removeObserver(onContentWindow,
- "content-document-global-created");
-});
-
-function onContentWindow(subject, topic, data)
-{
- if (subject instanceof Ci.nsIDOMWindow && subject.top == subject)
- {
- let eventTarget = subject.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .chromeEventHandler;
- if (eventTarget)
- eventTarget.addEventListener("click", onClick, true);
- }
-}
-
-function onClick(event)
-{
- if (onShutdown.done)
- return;
-
- // Ignore right-clicks
- if (event.button == 2)
- return;
-
- // Search the link associated with the click
- let link = event.target;
- while (!(link instanceof Ci.nsIDOMHTMLAnchorElement))
- {
- link = link.parentNode;
-
- if (!link)
- return;
- }
-
- let queryString = null;
- if (link.protocol == "http:" || link.protocol == "https:")
- {
- if (link.host == "subscribe.adblockplus.org" && link.pathname == "/")
- queryString = link.search.substr(1);
- }
- else
- {
- // Firefox doesn't populate the "search" property for links with
- // non-standard URL schemes so we need to extract the query string
- // manually
- let match = /^abp:\/*subscribe\/*\?(.*)/i.exec(link.href);
- if (match)
- queryString = match[1];
- }
-
- if (!queryString)
- return;
-
- // This is our link - make sure the browser doesn't handle it
- event.preventDefault();
- event.stopPropagation();
-
- // Decode URL parameters
- let title = null;
- let url = null;
- let mainSubscriptionTitle = null;
- let mainSubscriptionURL = null;
- for (let param of queryString.split("&"))
- {
- let parts = param.split("=", 2);
- if (parts.length != 2 || !/\S/.test(parts[1]))
- continue;
- switch (parts[0])
- {
- case "title":
- title = decodeURIComponent(parts[1]);
- break;
- case "location":
- url = decodeURIComponent(parts[1]);
- break;
- case "requiresTitle":
- mainSubscriptionTitle = decodeURIComponent(parts[1]);
- break;
- case "requiresLocation":
- mainSubscriptionURL = decodeURIComponent(parts[1]);
- break;
- }
- }
-
- port.emit("subscribeLinkClick", {
- title: title,
- url: url,
- mainSubscriptionTitle: mainSubscriptionTitle,
- mainSubscriptionURL: mainSubscriptionURL
- });
-}
diff --git a/data/extensions/spyblock@gnu.org/lib/child/utils.js b/data/extensions/spyblock@gnu.org/lib/child/utils.js
deleted file mode 100644
index fde649f..0000000
--- a/data/extensions/spyblock@gnu.org/lib/child/utils.js
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * This file is part of Adblock Plus <https://adblockplus.org/>,
- * Copyright (C) 2006-2017 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";
-
-let {PrivateBrowsingUtils} = Cu.import("resource://gre/modules/PrivateBrowsingUtils.jsm", {});
-
-let {Utils} = require("utils");
-
-/**
- * Retrieves the effective location of a window.
- */
-let getWindowLocation = exports.getWindowLocation = function(/**Window*/ window) /**String*/
-{
- let result = null;
-
- // Crazy Thunderbird stuff
- if ("name" in window && window.name == "messagepane")
- {
- try
- {
- let mailWnd = window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShellTreeItem)
- .rootTreeItem
- .QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
-
- // Typically we get a wrapped mail window here, need to unwrap
- try
- {
- mailWnd = mailWnd.wrappedJSObject;
- } catch(e) {}
-
- if ("currentHeaderData" in mailWnd && "content-base" in mailWnd.currentHeaderData)
- {
- result = mailWnd.currentHeaderData["content-base"].headerValue;
- }
- else if ("currentHeaderData" in mailWnd && "from" in mailWnd.currentHeaderData)
- {
- let emailAddress = Utils.headerParser.extractHeaderAddressMailboxes(mailWnd.currentHeaderData.from.headerValue);
- if (emailAddress)
- result = 'mailto:' + emailAddress.replace(/^[\s"]+/, "").replace(/[\s"]+$/, "").replace(/\s/g, '%20');
- }
- } catch(e) {}
- }
-
- // Sane branch
- if (!result)
- result = window.location.href;
-
- // Remove the anchor if any
- let index = result.indexOf("#");
- if (index >= 0)
- result = result.substring(0, index);
-
- return result;
-}
-
-/**
- * Retrieves the frame hierarchy for a window. Returns an array containing
- * the information for all frames, starting with the window itself up to its
- * top-level window. Each entry has a location and a sitekey entry.
- * @return {Array}
- */
-let getFrames = exports.getFrames = function(/**Window*/ window)
-{
- let frames = [];
- while (window)
- {
- let frame = {
- location: getWindowLocation(window),
- sitekey: null
- };
-
- let documentElement = window.document && window.document.documentElement;
- if (documentElement)
- frame.sitekey = documentElement.getAttribute("data-adblockkey")
-
- frames.push(frame);
- window = (window != window.parent ? window.parent : null);
- }
-
- // URLs like about:blank inherit their security context from upper-level
- // frames, resolve their URLs accordingly.
- for (let i = frames.length - 2; i >= 0; i--)
- {
- let frame = frames[i];
- if (frame.location == "about:blank" || frame.location == "moz-safe-about:blank" ||
- frame.location == "about:srcdoc" ||
- Utils.netUtils.URIChainHasFlags(Utils.makeURI(frame.location), Ci.nsIProtocolHandler.URI_INHERITS_SECURITY_CONTEXT))
- {
- frame.location = frames[i + 1].location;
- }
- }
-
- return frames;
-};
-
-/**
- * Checks whether Private Browsing mode is enabled for a content window.
- * @return {Boolean}
- */
-let isPrivate = exports.isPrivate = function(/**Window*/ window)
-{
- return PrivateBrowsingUtils.isContentWindowPrivate(window);
-};
-
-/**
- * Gets the DOM window associated with a particular request (if any).
- */
-let getRequestWindow = exports.getRequestWindow = function(/**nsIChannel*/ channel) /**nsIDOMWindow*/
-{
- try
- {
- if (channel.notificationCallbacks)
- return channel.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch(e) {}
-
- try
- {
- if (channel.loadGroup && channel.loadGroup.notificationCallbacks)
- return channel.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext).associatedWindow;
- } catch(e) {}
-
- return null;
-};