summaryrefslogtreecommitdiff
path: root/data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js')
-rw-r--r--data/extensions/spyblock@gnu.org/lib/child/requestNotifier.js444
1 files changed, 0 insertions, 444 deletions
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;
-};