summaryrefslogtreecommitdiff
path: root/data/extensions/spyblock@gnu.org/lib/ui.js
diff options
context:
space:
mode:
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib/ui.js')
-rw-r--r--data/extensions/spyblock@gnu.org/lib/ui.js1906
1 files changed, 0 insertions, 1906 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/ui.js b/data/extensions/spyblock@gnu.org/lib/ui.js
deleted file mode 100644
index 1941a97..0000000
--- a/data/extensions/spyblock@gnu.org/lib/ui.js
+++ /dev/null
@@ -1,1906 +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/>.
- */
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-let {Utils} = require("utils");
-let {port} = require("messaging");
-let {Prefs} = require("prefs");
-let {Policy} = require("contentPolicy");
-let {FilterStorage} = require("filterStorage");
-let {FilterNotifier} = require("filterNotifier");
-let {RequestNotifier} = require("requestNotifier");
-let {Filter} = require("filterClasses");
-let {Subscription, SpecialSubscription, DownloadableSubscription} = require("subscriptionClasses");
-let {Synchronizer} = require("synchronizer");
-let {KeySelector} = require("keySelector");
-let {Notification} = require("notification");
-let {initAntiAdblockNotification} = require("antiadblockInit");
-
-let CustomizableUI = null;
-
-/**
- * Filter corresponding with "disable on site" menu item (set in fillIconMent()).
- * @type Filter
- */
-let siteWhitelist = null;
-/**
- * Filter corresponding with "disable on site" menu item (set in fillIconMenu()).
- * @type Filter
- */
-let pageWhitelist = null;
-
-/**
- * Window containing the detached list of blockable items.
- * @type Window
- */
-let detachedBottombar = null;
-
-/**
- * Object initializing add-on options, observes add-on manager notifications
- * about add-on options being opened.
- * @type nsIObserver
- */
-let optionsObserver =
-{
- init: function()
- {
- Services.obs.addObserver(this, "addon-options-displayed", true);
- onShutdown.add(function()
- {
- Services.obs.removeObserver(this, "addon-options-displayed");
- }.bind(this));
- },
-
- /**
- * Initializes options in add-on manager when they show up.
- */
- initOptionsDoc: function(/**Document*/ doc)
- {
- function hideElement(id, hide)
- {
- let element = doc.getElementById(id);
- if (element)
- element.collapsed = hide;
- }
- function setChecked(id, checked)
- {
- let element = doc.getElementById(id);
- if (element)
- element.value = checked;
- }
- function addCommandHandler(id, handler)
- {
- let element = doc.getElementById(id);
- if (element)
- element.addEventListener("command", handler, false);
- }
-
- Utils.splitAllLabels(doc);
-
- addCommandHandler("adblockplus-filters", UI.openFiltersDialog.bind(UI));
-
- let {Sync} = require("sync");
- let syncEngine = Sync.getEngine();
- hideElement("adblockplus-sync", !syncEngine);
-
- let {defaultToolbarPosition, statusbarPosition} = require("appSupport");
- let hasToolbar = defaultToolbarPosition;
- let hasStatusBar = statusbarPosition;
-
- hideElement("adblockplus-showintoolbar", !hasToolbar);
- hideElement("adblockplus-showinstatusbar", !hasStatusBar);
-
- let checkbox = doc.querySelector("setting[type=bool]");
- if (checkbox)
- initCheckboxes();
-
- function initCheckboxes()
- {
- if (!("value" in checkbox))
- {
- // XBL bindings didn't apply yet (bug 708397), try later
- Utils.runAsync(initCheckboxes);
- return;
- }
-
- setChecked("adblockplus-savestats", Prefs.savestats);
- addCommandHandler("adblockplus-savestats", function()
- {
- UI.toggleSaveStats(doc.defaultView);
- this.value = Prefs.savestats;
- });
-
- hideElement("adblockplus-shownotifications", !Prefs.notifications_showui);
- setChecked("adblockplus-shownotifications", Prefs.notifications_ignoredcategories.indexOf("*") == -1);
- addCommandHandler("adblockplus-shownotifications", function()
- {
- Notification.toggleIgnoreCategory("*");
- this.value = (Prefs.notifications_ignoredcategories.indexOf("*") == -1);
- });
-
- let hasAcceptableAds = FilterStorage.subscriptions.some((subscription) => subscription instanceof DownloadableSubscription &&
- subscription.url == Prefs.subscriptions_exceptionsurl);
- setChecked("adblockplus-acceptableAds", hasAcceptableAds);
- addCommandHandler("adblockplus-acceptableAds", function()
- {
- this.value = UI.toggleAcceptableAds();
- });
-
- setChecked("adblockplus-sync", syncEngine && syncEngine.enabled);
- addCommandHandler("adblockplus-sync", function()
- {
- this.value = UI.toggleSync();
- });
-
- setChecked("adblockplus-showintoolbar", UI.isToolbarIconVisible());
- addCommandHandler("adblockplus-showintoolbar", function()
- {
- UI.toggleToolbarIcon();
- this.value = UI.isToolbarIconVisible();
- });
-
- let list = doc.getElementById("adblockplus-subscription-list");
- if (list)
- {
- // Load subscriptions data
- let request = new XMLHttpRequest();
- request.mozBackgroundRequest = true;
- request.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml");
- request.addEventListener("load", function()
- {
- if (onShutdown.done)
- return;
-
- let currentSubscription = FilterStorage.subscriptions.filter((subscription) => subscription instanceof DownloadableSubscription &&
- subscription.url != Prefs.subscriptions_exceptionsurl &&
- subscription.url != Prefs.subscriptions_antiadblockurl);
- currentSubscription = (currentSubscription.length ? currentSubscription[0] : null);
-
- let subscriptions =request.responseXML.getElementsByTagName("subscription");
- for (let i = 0; i < subscriptions.length; i++)
- {
- let item = subscriptions[i];
- let url = item.getAttribute("url");
- if (!url)
- continue;
-
- list.appendItem(item.getAttribute("title"), url, null);
- if (currentSubscription && url == currentSubscription.url)
- list.selectedIndex = list.itemCount - 1;
-
- if (currentSubscription && list.selectedIndex < 0)
- {
- list.appendItem(currentSubscription.title, currentSubscription.url, null);
- list.selectedIndex = list.itemCount - 1;
- }
- }
-
- var listener = function()
- {
- if (list.value)
- UI.setSubscription(list.value, list.label);
- }
- list.addEventListener("command", listener, false);
-
- // xul:menulist in Fennec is broken and doesn't trigger any events
- // on selection. Have to detect selectIndex changes instead.
- // See https://bugzilla.mozilla.org/show_bug.cgi?id=891736
- list.watch("selectedIndex", function(prop, oldval, newval)
- {
- Utils.runAsync(listener);
- return newval;
- });
- }, false);
- request.send();
- }
- }
- },
-
- observe: function(subject, topic, data)
- {
- let {addonID} = require("info")
- if (data != addonID)
- return;
-
- this.initOptionsDoc(subject.QueryInterface(Ci.nsIDOMDocument));
- },
-
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference])
-};
-optionsObserver.init();
-
-/**
- * Session restore observer instance, stored to prevent it from being garbage
- * collected.
- * @type SessionRestoreObserver
- */
-let sessionRestoreObserver = null;
-
-/**
- * Observer waiting for the browsing session to be restored on startup.
- */
-function SessionRestoreObserver(/**function*/ callback)
-{
- sessionRestoreObserver = this;
-
- this.callback = callback;
- Services.obs.addObserver(this, "sessionstore-windows-restored", true);
-
- // Just in case, don't wait longer than 5 seconds
- this.timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
- this.timer.init(this, 5000, Ci.nsITimer.TYPE_ONE_SHOT);
-}
-SessionRestoreObserver.prototype =
-{
- callback: null,
- timer: null,
- observe: function(subject, topic, data)
- {
- Services.obs.removeObserver(this, "sessionstore-windows-restored");
- sessionRestoreObserver = null;
-
- this.timer.cancel();
- this.timer = null;
-
- if (!onShutdown.done)
- this.callback();
- },
- QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference])
-}
-
-/**
- * Timer used to delay notification handling.
- * @type nsITimer
- */
-let notificationTimer = null;
-
-let UI = exports.UI =
-{
- /**
- * Gets called on startup, initializes UI integration.
- */
- init: function()
- {
- // We have to wait for multiple events before running start-up actions
- let prerequisites = [];
-
- // Start loading overlay
- prerequisites.push(new Promise((resolve, reject) =>
- {
- let request = new XMLHttpRequest();
- request.mozBackgroundRequest = true;
- request.open("GET", "chrome://adblockplus/content/ui/overlay.xul");
- request.channel.owner = Utils.systemPrincipal;
- request.addEventListener("load", event =>
- {
- if (onShutdown.done)
- return;
-
- this.processOverlay(request.responseXML.documentElement);
-
- // Don't wait for the rest of the startup sequence, add icon already
- this.addToolbarButton();
-
- resolve();
- }, false);
-
- request.addEventListener("error", event =>
- {
- reject(new Error("Unexpected: Failed to load overlay.xul"));
- });
-
- request.send(null);
- }));
-
- // Wait for filters to load
- if (!FilterStorage.initialized)
- prerequisites.push(FilterNotifier.once("load"));
-
- // Wait for session to be restored
- prerequisites.push(new Promise((resolve, reject) =>
- {
- let window = this.currentWindow;
- if (!window && "nsISessionStore" in Ci)
- {
- // No application windows yet, the application must be starting up. Wait
- // for session to be restored before initializing our UI.
- new SessionRestoreObserver(resolve);
- }
- else
- resolve();
- }));
-
- Promise.all(prerequisites).then(() => this.initDone())
- .catch(e => Cu.reportError(e));
- },
-
- /**
- * Provesses overlay document data and initializes overlay property.
- */
- processOverlay: function(/**Element*/ root)
- {
- Utils.splitAllLabels(root);
-
- let specialElements = {"abp-status-popup": true, "abp-status": true, "abp-toolbarbutton": true, "abp-menuitem": true, "abp-bottombar-container": true};
-
- this.overlay = {all: []};
-
- // Remove whitespace text nodes
- let walker = root.ownerDocument.createTreeWalker(
- root, Ci.nsIDOMNodeFilter.SHOW_TEXT,
- (node) => !/\S/.test(node.nodeValue), false
- );
- let whitespaceNodes = [];
- while (walker.nextNode())
- whitespaceNodes.push(walker.currentNode);
-
- for (let i = 0; i < whitespaceNodes.length; i++)
- whitespaceNodes[i].parentNode.removeChild(whitespaceNodes[i]);
-
- // Put overlay elements into appropriate fields
- while (root.firstElementChild)
- {
- let child = root.firstElementChild;
- if (child.getAttribute("id") in specialElements)
- this.overlay[child.getAttribute("id")] = child;
- else
- this.overlay.all.push(child);
- root.removeChild(child);
- }
-
- // Read overlay attributes
- this.overlay.attributes = {};
- for (let i = 0; i < root.attributes.length; i++)
- this.overlay.attributes[root.attributes[i].name] = root.attributes[i].value;
-
- // Copy context menu into the toolbar icon and Tools menu item
- function fixId(element, newId)
- {
- if (element.hasAttribute("id"))
- element.setAttribute("id", element.getAttribute("id").replace("abp-status", newId));
-
- for (let i = 0, len = element.children.length; i < len; i++)
- fixId(element.children[i], newId);
-
- return element;
- }
-
- if ("abp-status-popup" in this.overlay)
- {
- let menuSource = this.overlay["abp-status-popup"];
- delete this.overlay["abp-status-popup"];
-
- if (this.overlay.all.length)
- this.overlay.all[0].appendChild(menuSource);
- if ("abp-toolbarbutton" in this.overlay)
- this.overlay["abp-toolbarbutton"].appendChild(fixId(menuSource.cloneNode(true), "abp-toolbar"));
- if ("abp-menuitem" in this.overlay)
- this.overlay["abp-menuitem"].appendChild(fixId(menuSource.cloneNode(true), "abp-menuitem"));
- }
- },
-
- /**
- * Gets called once the initialization is finished and Adblock Plus elements
- * can be added to the UI.
- */
- initDone: function()
- {
- // The icon might be added already, make sure its state is correct
- this.updateState();
-
- // Listen for pref and filters changes
- Prefs.addListener(name =>
- {
- if (name == "enabled" || name == "defaulttoolbaraction" || name == "defaultstatusbaraction")
- this.updateState();
- else if (name == "showinstatusbar")
- {
- for (let window of this.applicationWindows)
- this.updateStatusbarIcon(window);
- }
- });
-
- for (let eventName of [
- "filter.added", "filter.removed", "filter.disabled",
- "subscription.added", "subscription.removed", "subscription.disabled",
- "subscription.updated", "load"
- ])
- {
- FilterNotifier.on(eventName, () => this.updateState());
- }
-
- Notification.addShowListener(notification =>
- {
- let window = this.currentWindow;
- if (!window)
- return;
-
- let button = window.document.getElementById("abp-toolbarbutton")
- || window.document.getElementById("abp-status");
- if (!button)
- return;
-
- this._showNotification(window, button, notification);
- });
-
- // Add "anti-adblock messages" notification
- initAntiAdblockNotification();
-
- // Initialize subscribe link handling
- port.on("subscribeLinkClick", data => this.subscribeLinkClicked(data));
-
- // Execute first-run actions if a window is open already, otherwise it
- // will happen in applyToWindow() when a window is opened.
- this.firstRunActions(this.currentWindow);
- },
-
- addToolbarButton: function()
- {
- let {WindowObserver} = require("windowObserver");
- new WindowObserver(this);
-
- let {defaultToolbarPosition} = require("appSupport");
- if ("abp-toolbarbutton" in this.overlay && defaultToolbarPosition)
- {
- try
- {
- ({CustomizableUI} = Cu.import("resource:///modules/CustomizableUI.jsm", null));
- }
- catch (e)
- {
- // No built-in CustomizableUI API, use our own implementation.
- ({CustomizableUI} = require("customizableUI"));
- }
-
- CustomizableUI.createWidget({
- id: "abp-toolbarbutton",
- type: "custom",
- positionAttribute: "abp-iconposition", // For emulation only
- defaultArea: defaultToolbarPosition.parent,
- defaultBefore: defaultToolbarPosition.before, // For emulation only
- defaultAfter: defaultToolbarPosition.after, // For emulation only
- removable: true,
- onBuild: function(document)
- {
- let node = document.importNode(this.overlay["abp-toolbarbutton"], true);
- node.addEventListener("click", this.onIconClick, false);
- node.addEventListener("command", this.onIconClick, false);
- this.updateIconState(document.defaultView, node);
- return node;
- }.bind(this),
- onAdded: function(node)
- {
- // For emulation only, this callback isn't part of the official
- // CustomizableUI API.
- this.updateIconState(node.ownerDocument.defaultView, node);
- }.bind(this),
- });
- onShutdown.add(CustomizableUI.destroyWidget.bind(CustomizableUI, "abp-toolbarbutton"));
- }
- },
-
- firstRunActions: function(window)
- {
- if (this.firstRunDone || !window || !FilterStorage.initialized)
- return;
-
- this.firstRunDone = true;
-
- let {addonVersion} = require("info");
- let prevVersion = Prefs.currentVersion;
- if (prevVersion != addonVersion)
- {
- Prefs.currentVersion = addonVersion;
- this.addSubscription(window, prevVersion);
-
- // The "Hide placeholders" option has been removed from the UI in 2.6.6.3881
- // So we reset the option for users updating from older versions.
- if (prevVersion && Services.vc.compare(prevVersion, "2.6.6.3881") < 0)
- Prefs.fastcollapse = false;
- }
- },
-
- /**
- * Will be set to true after the check whether first-run actions should run
- * has been performed.
- * @type Boolean
- */
- firstRunDone: false,
-
- /**
- * Initializes Adblock Plus UI in a window.
- */
- applyToWindow: function(/**Window*/ window, /**Boolean*/ noDelay)
- {
- let {delayInitialization, isKnownWindow, getBrowser, addBrowserLocationListener} = require("appSupport");
- if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnownWindow(window))
- {
- // Add style processing instruction
- let style = window.document.createProcessingInstruction("xml-stylesheet", 'class="adblockplus-node" href="chrome://adblockplus/skin/overlay.css" type="text/css"');
- window.document.insertBefore(style, window.document.firstChild);
- }
-
- if (!isKnownWindow(window))
- return;
-
- // Thunderbird windows will not be initialized at this point, execute
- // delayed
- if (!noDelay && delayInitialization)
- {
- Utils.runAsync(this.applyToWindow.bind(this, window, true));
- return;
- }
-
- // Add general items to the document
- for (let i = 0; i < this.overlay.all.length; i++)
- window.document.documentElement.appendChild(this.overlay.all[i].cloneNode(true));
-
- // Add status bar icon
- this.updateStatusbarIcon(window);
-
- // Add tools menu item
- if ("abp-menuitem" in this.overlay)
- {
- let {toolsMenu} = require("appSupport");
- let [parent, before] = this.resolveInsertionPoint(window, toolsMenu);
- if (parent)
- parent.insertBefore(this.overlay["abp-menuitem"].cloneNode(true), before);
- }
-
- // Attach event handlers
- for (let i = 0; i < eventHandlers.length; i++)
- {
- let [id, event, handler] = eventHandlers[i];
- let element = window.document.getElementById(id);
- if (element)
- element.addEventListener(event, handler.bind(null, window), false);
- }
- window.addEventListener("popupshowing", this.onPopupShowing, false);
- window.addEventListener("keypress", this.onKeyPress, false);
-
- addBrowserLocationListener(window, function()
- {
- this.updateIconState(window, window.document.getElementById("abp-status"));
- this.updateIconState(window, window.document.getElementById("abp-toolbarbutton"));
-
- Notification.showNext(this.getCurrentLocation(window).spec);
- }.bind(this));
-
- let notificationPanel = window.document.getElementById("abp-notification");
- notificationPanel.addEventListener("command", function(event)
- {
- switch (event.target.id)
- {
- case "abp-notification-close":
- notificationPanel.classList.add("abp-closing");
- break;
- case "abp-notification-optout":
- Notification.toggleIgnoreCategory("*", true);
- /* FALL THROUGH */
- case "abp-notification-hide":
- notificationPanel.hidePopup();
- break;
- }
- }, false);
-
- // First-run actions?
- this.firstRunActions(window);
-
- // Some people actually switch off browser.frames.enabled and are surprised
- // that things stop working...
- window.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIWebNavigation)
- .QueryInterface(Ci.nsIDocShell)
- .allowSubframes = true;
- },
-
- /**
- * Removes Adblock Plus UI from a window.
- */
- removeFromWindow: function(/**Window*/ window)
- {
- let {isKnownWindow, removeBrowserLocationListeners} = require("appSupport");
- if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnownWindow(window))
- {
- // Remove style processing instruction
- for (let child = window.document.firstChild; child; child = child.nextSibling)
- if (child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.indexOf("adblockplus-node") >= 0)
- child.parentNode.removeChild(child);
- }
-
- if (!isKnownWindow(window))
- return;
-
- for (let id in this.overlay)
- {
- if (id == "all")
- {
- let list = this.overlay[id];
- for (let i = 0; i < list.length; i++)
- {
- let clone = window.document.getElementById(list[i].getAttribute("id"));
- if (clone)
- clone.parentNode.removeChild(clone);
- }
- }
- else
- {
- let clone = window.document.getElementById(id);
- if (clone)
- clone.parentNode.removeChild(clone);
- }
- }
-
- window.removeEventListener("popupshowing", this.onPopupShowing, false);
- window.removeEventListener("keypress", this.onKeyPress, false);
- removeBrowserLocationListeners(window);
- },
-
- /**
- * The overlay information to be used when adding elements to the UI.
- * @type Object
- */
- overlay: null,
-
- /**
- * Iterator for application windows that Adblock Plus should apply to.
- * @type Iterator
- */
- get applicationWindows()
- {
- let {isKnownWindow} = require("appSupport");
-
- let enumerator = Services.wm.getZOrderDOMWindowEnumerator(null, true);
- if (!enumerator.hasMoreElements())
- {
- // On Linux the list returned will be empty, see bug 156333. Fall back to random order.
- enumerator = Services.wm.getEnumerator(null);
- }
-
- let generate = function*()
- {
- while (enumerator.hasMoreElements())
- {
- let window = enumerator.getNext().QueryInterface(Ci.nsIDOMWindow);
- if (isKnownWindow(window))
- yield window;
- }
- };
-
- return generate();
- },
-
- /**
- * Returns the top-most application window or null if none exists.
- * @type Window
- */
- get currentWindow()
- {
- for (let window of this.applicationWindows)
- return window;
- return null;
- },
-
- /**
- * Opens a URL in the browser window. If browser window isn't passed as parameter,
- * this function attempts to find a browser window. If an event is passed in
- * it should be passed in to the browser if possible (will e.g. open a tab in
- * background depending on modifiers keys).
- */
- loadInBrowser: function(/**String*/ url, /**Window*/ currentWindow, /**Event*/ event)
- {
- if (!currentWindow)
- currentWindow = this.currentWindow;
-
- let {addTab} = require("appSupport");
- if (currentWindow && addTab)
- addTab(currentWindow, url, event);
- else
- {
- let protocolService = Cc["@mozilla.org/uriloader/external-protocol-service;1"].getService(Ci.nsIExternalProtocolService);
- protocolService.loadURI(Services.io.newURI(url, null, null), null);
- }
- },
-
- /**
- * Opens a pre-defined documentation link in the browser window. This will
- * send the UI language to adblockplus.org so that the correct language
- * version of the page can be selected.
- */
- loadDocLink: function(/**String*/ linkID, /**Window*/ window)
- {
- let link = Utils.getDocLink(linkID);
- this.loadInBrowser(link, window);
- },
-
-
- /**
- * Brings up the filter composer dialog to block an item. The optional nodesID
- * parameter must be a unique ID returned by
- * RequestNotifier.storeNodesForEntry() or similar.
- */
- blockItem: function(/**Window*/ window, /**string*/ nodesID, /**RequestEntry*/ item)
- {
- if (!item)
- return;
-
- window.openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank",
- "chrome,centerscreen,resizable,dialog=no,dependent", nodesID, item);
- },
-
- /**
- * Opens filter preferences dialog or focuses an already open dialog.
- * @param {Filter} [filter] filter to be selected
- */
- openFiltersDialog: function(filter)
- {
- let existing = Services.wm.getMostRecentWindow("abp:filters");
- if (existing)
- {
- try
- {
- existing.focus();
- } catch (e) {}
- if (filter)
- existing.SubscriptionActions.selectFilter(filter);
- }
- else
- {
- Services.ww.openWindow(null, "chrome://adblockplus/content/ui/filters.xul", "_blank", "chrome,centerscreen,resizable,dialog=no", {wrappedJSObject: filter});
- }
- },
-
- /**
- * Opens report wizard for the current page.
- */
- openReportDialog: function(/**Window*/ window)
- {
- let wnd = Services.wm.getMostRecentWindow("abp:sendReport");
- if (wnd)
- wnd.focus();
- else
- {
- let uri = this.getCurrentLocation(window);
- if (uri)
- {
- let {getBrowser} = require("appSupport");
- let browser = getBrowser(window);
- if ("selectedBrowser" in browser)
- browser = browser.selectedBrowser;
- window.openDialog("chrome://adblockplus/content/ui/sendReport.xul", "_blank", "chrome,centerscreen,resizable=no", browser.outerWindowID, uri, browser);
- }
- }
- },
-
- /**
- * Opens our contribution page.
- */
- openContributePage: function(/**Window*/ window)
- {
- this.loadDocLink("contribute", window);
- },
-
- /**
- * Executed on first run, adds a filter subscription and notifies that user
- * about that.
- */
- addSubscription: function(/**Window*/ window, /**String*/ prevVersion)
- {
- // Add "acceptable ads" subscription for new users and user updating from old ABP versions.
- // Don't add it for users of privacy subscriptions (use a hardcoded list for now).
- let addAcceptable = (Services.vc.compare(prevVersion, "2.0") < 0);
- let privacySubscriptions = {
- "https://easylist-downloads.adblockplus.org/easyprivacy+easylist.txt": true,
- "https://easylist-downloads.adblockplus.org/easyprivacy.txt": true,
- "https://secure.fanboy.co.nz/fanboy-tracking.txt": true,
- "https://fanboy-adblock-list.googlecode.com/hg/fanboy-adblocklist-stats.txt": true,
- "https://bitbucket.org/fanboy/fanboyadblock/raw/tip/fanboy-adblocklist-stats.txt": true,
- "https://hg01.codeplex.com/fanboyadblock/raw-file/tip/fanboy-adblocklist-stats.txt": true,
- "https://adversity.googlecode.com/hg/Adversity-Tracking.txt": true
- };
- if (FilterStorage.subscriptions.some((subscription) => subscription.url == Prefs.subscriptions_exceptionsurl || subscription.url in privacySubscriptions))
- addAcceptable = false;
-
- // Don't add subscription if the user has a subscription already
- let addSubscription = true;
- //if (FilterStorage.subscriptions.some((subscription) => subscription instanceof DownloadableSubscription && subscription.url != Prefs.subscriptions_exceptionsurl))
- addSubscription = false;
-
- // If this isn't the first run, only add subscription if the user has no custom filters
- if (addSubscription && Services.vc.compare(prevVersion, "0.0") > 0)
- {
- if (FilterStorage.subscriptions.some((subscription) => subscription.url != Prefs.subscriptions_exceptionsurl && subscription.filters.length))
- addSubscription = false;
- }
-
- // Add "acceptable ads" subscription
- if (false)
- {
- let subscription = Subscription.fromURL(Prefs.subscriptions_exceptionsurl);
- if (subscription)
- {
- subscription.title = "Allow non-intrusive advertising";
- FilterStorage.addSubscription(subscription);
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- }
- else
- addAcceptable = false;
- }
-
- /* Add "anti-adblock messages" subscription for new users and users updating from old ABP versions
- if (Services.vc.compare(prevVersion, "2.5") < 0)
- {
- let subscription = Subscription.fromURL(Prefs.subscriptions_antiadblockurl);
- if (subscription && !(subscription.url in FilterStorage.knownSubscriptions))
- {
- subscription.disabled = true;
- FilterStorage.addSubscription(subscription);
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- }
- }*/
-
- // Extra subsriptions
- let subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/blacklist.txt");
- subscription.disabled = false;
- FilterStorage.addSubscription(subscription);
- Synchronizer.execute(subscription);
-
- subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/third-party.txt");
- subscription.disabled = false;
- FilterStorage.addSubscription(subscription);
- Synchronizer.execute(subscription);
-
- if (!addSubscription && !addAcceptable)
- return;
-
- function notifyUser()
- {return;
-
- let {addTab} = require("appSupport");
- if (addTab)
- {
- addTab(window, "chrome://adblockplus/content/ui/firstRun.html");
- }
- else
- {
- let dialogSource = '\
- <?xml-stylesheet href="chrome://global/skin/" type="text/css"?>\
- <dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="document.title=content.document.title" buttons="accept" width="500" height="600">\
- <iframe type="content-primary" flex="1" src="chrome://adblockplus/content/ui/firstRun.html"/>\
- </dialog>';
- Services.ww.openWindow(window,
- "data:application/vnd.mozilla.xul+xml," + encodeURIComponent(dialogSource),
- "_blank", "chrome,centerscreen,resizable,dialog=no", null);
- }
- }
-
- if (addSubscription)
- {
- // Load subscriptions data
- let request = new XMLHttpRequest();
- request.mozBackgroundRequest = true;
- request.open("GET", "chrome://adblockplus/content/ui/subscriptions.xml");
- request.addEventListener("load", function()
- {
- if (onShutdown.done)
- return;
-
- let node = Utils.chooseFilterSubscription(request.responseXML.getElementsByTagName("subscription"));
- let subscription = (node ? Subscription.fromURL(node.getAttribute("url")) : null);
- if (subscription)
- {
- FilterStorage.addSubscription(subscription);
- subscription.disabled = false;
- subscription.title = node.getAttribute("title");
- subscription.homepage = node.getAttribute("homepage");
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
-
- notifyUser();
- }
- }, false);
- request.send();
- }
- else
- notifyUser();
- },
-
- /**
- * Called whenever child/subscribeLinks module intercepts clicks on abp: links
- * as well as links to subscribe.adblockplus.org.
- */
- subscribeLinkClicked: function({title, url,
- mainSubscriptionTitle, mainSubscriptionURL})
- {
- if (!url)
- return;
-
- // Default title to the URL
- if (!title)
- title = url;
-
- // Main subscription needs both title and URL
- if (mainSubscriptionTitle && !mainSubscriptionURL)
- mainSubscriptionTitle = null;
- if (mainSubscriptionURL && !mainSubscriptionTitle)
- mainSubscriptionURL = null;
-
- // Trim spaces in title and URL
- title = title.trim();
- url = url.trim();
- if (mainSubscriptionURL)
- {
- mainSubscriptionTitle = mainSubscriptionTitle.trim();
- mainSubscriptionURL = mainSubscriptionURL.trim();
- }
-
- // Verify that the URL is valid
- url = Utils.makeURI(url);
- if (!url || (url.scheme != "http" && url.scheme != "https" && url.scheme != "ftp"))
- return;
- url = url.spec;
-
- if (mainSubscriptionURL)
- {
- mainSubscriptionURL = Utils.makeURI(mainSubscriptionURL);
- if (!mainSubscriptionURL || (mainSubscriptionURL.scheme != "http" && mainSubscriptionURL.scheme != "https" && mainSubscriptionURL.scheme != "ftp"))
- mainSubscriptionURL = mainSubscriptionTitle = null;
- else
- mainSubscriptionURL = mainSubscriptionURL.spec;
- }
-
- this.openSubscriptionDialog(this.currentWindow, url, title, mainSubscriptionURL, mainSubscriptionTitle);
- },
-
- /**
- * Opens a dialog letting the user confirm/adjust a filter subscription to
- * be added.
- */
- openSubscriptionDialog: function(/**Window*/ window, /**String*/ url, /**String*/ title, /**String*/ mainURL, /**String*/ mainTitle)
- {
- let subscription = {url: url, title: title, disabled: false, external: false,
- mainSubscriptionTitle: mainTitle, mainSubscriptionURL: mainURL};
- window.openDialog("chrome://adblockplus/content/ui/subscriptionSelection.xul", "_blank",
- "chrome,centerscreen,resizable,dialog=no", subscription, null);
- },
-
- /**
- * Retrieves the current location of the browser.
- */
- getCurrentLocation: function(/**Window*/ window) /**nsIURI*/
- {
- let {getCurrentLocation} = require("appSupport");
- let result = getCurrentLocation(window);
- return (result ? Utils.unwrapURL(result) : null);
- },
-
- /**
- * Looks up an element with given ID in the window. If a list of IDs is given
- * will try all of them until an element exists.
- */
- findElement: function(/**Window*/ window, /**String|String[]*/ id) /**Element*/
- {
- if (id instanceof Array)
- {
- for (let candidate of id)
- {
- let result = window.document.getElementById(candidate);
- if (result)
- return result;
- }
- return null;
- }
- else
- return window.document.getElementById(id);
- },
-
- /**
- * Resolves an insertion point as specified in appSupport module. Returns
- * two elements: the parent element and the element to insert before.
- */
- resolveInsertionPoint: function(/**Window*/ window, /**Object*/ insertionPoint) /**Element[]*/
- {
- let parent = null;
- let before = null;
- if (insertionPoint)
- {
- if ("parent" in insertionPoint)
- parent = this.findElement(window, insertionPoint.parent);
-
- if (parent && "before" in insertionPoint)
- before = this.findElement(window, insertionPoint.before);
-
- if (parent && !before && "after" in insertionPoint)
- {
- let after = this.findElement(window, insertionPoint.after);
- if (after)
- before = after.nextElementSibling;
- }
-
- if (before && before.parentNode != parent)
- before = null;
- }
-
- return [parent, before];
- },
-
- /**
- * Toggles visibility state of the toolbar icon.
- */
- toggleToolbarIcon: function()
- {
- if (!CustomizableUI)
- return;
- if (this.isToolbarIconVisible())
- CustomizableUI.removeWidgetFromArea("abp-toolbarbutton");
- else
- {
- let {defaultToolbarPosition} = require("appSupport");
- CustomizableUI.addWidgetToArea("abp-toolbarbutton", defaultToolbarPosition.parent);
- }
- },
-
- /**
- * Updates Adblock Plus icon state for all windows.
- */
- updateState: function()
- {
- for (let window of this.applicationWindows)
- {
- this.updateIconState(window, window.document.getElementById("abp-status"));
- this.updateIconState(window, window.document.getElementById("abp-toolbarbutton"));
- }
- },
-
- /**
- * Updates Adblock Plus icon state for a single application window.
- */
- updateIconState: function(/**Window*/ window, /**Element*/ icon)
- {
- if (!icon)
- return;
-
- let state = (Prefs.enabled ? "active" : "disabled");
- if (state == "active")
- {
- let location = this.getCurrentLocation(window);
- if (location && Policy.isWhitelisted(location.spec))
- state = "whitelisted";
- }
-
- let popupId = "abp-status-popup";
- if (icon.localName == "statusbarpanel")
- {
- if (Prefs.defaultstatusbaraction == 0)
- {
- icon.setAttribute("popup", popupId);
- icon.removeAttribute("context");
- }
- else
- {
- icon.removeAttribute("popup");
- icon.setAttribute("context", popupId);
- }
- }
- else
- {
- if (Prefs.defaulttoolbaraction == 0)
- {
- icon.setAttribute("type", "menu");
- icon.removeAttribute("context");
- }
- else
- {
- icon.setAttribute("type", "menu-button");
- icon.setAttribute("context", popupId);
- }
- }
-
- icon.setAttribute("abpstate", state);
- },
-
- /**
- * Shows or hides status bar icons in all windows, according to pref.
- */
- updateStatusbarIcon: function(/**Window*/ window)
- {
- if (!("abp-status" in this.overlay))
- return;
-
- let {statusbarPosition} = require("appSupport");
- if (!statusbarPosition)
- return;
-
- let icon = window.document.getElementById("abp-status");
- if (Prefs.showinstatusbar && !icon)
- {
- let [parent, before] = this.resolveInsertionPoint(window, statusbarPosition);
- if (!parent)
- return;
-
- parent.insertBefore(this.overlay["abp-status"].cloneNode(true), before);
-
- icon = window.document.getElementById("abp-status");
- this.updateIconState(window, icon);
- icon.addEventListener("click", this.onIconClick, false);
- }
- else if (!Prefs.showinstatusbar && icon)
- icon.parentNode.removeChild(icon);
- },
-
- /**
- * Toggles the value of a boolean preference.
- */
- togglePref: function(/**String*/ pref)
- {
- Prefs[pref] = !Prefs[pref];
- },
-
- /**
- * If the given filter is already in user's list, removes it from the list. Otherwise adds it.
- */
- toggleFilter: function(/**Filter*/ filter)
- {
- if (filter.subscriptions.length)
- {
- if (filter.disabled || filter.subscriptions.some((subscription) => !(subscription instanceof SpecialSubscription)))
- filter.disabled = !filter.disabled;
- else
- FilterStorage.removeFilter(filter);
- }
- else
- {
- filter.disabled = false;
- FilterStorage.addFilter(filter);
- }
- },
-
-
- /**
- * Toggles "Count filter hits" option.
- */
- toggleSaveStats: function(window)
- {
- if (Prefs.savestats)
- {
- if (!Utils.confirm(window, Utils.getString("clearStats_warning")))
- return;
-
- FilterStorage.resetHitCounts();
- Prefs.savestats = false;
- }
- else
- Prefs.savestats = true;
- },
-
- /**
- * Sets the current filter subscription in a single-subscription scenario,
- * all other subscriptions will be removed.
- */
- setSubscription: function(url, title)
- {
- let subscription = Subscription.fromURL(url);
- let currentSubscriptions = FilterStorage.subscriptions.filter(
- ((subscription) => subscription instanceof DownloadableSubscription && subscription.url != Prefs.subscriptions_exceptionsurl)
- );
- if (!subscription || currentSubscriptions.indexOf(subscription) >= 0)
- return;
-
- for (let i = 0; i < currentSubscriptions.length; i++)
- FilterStorage.removeSubscription(currentSubscriptions[i]);
-
- subscription.title = title;
- FilterStorage.addSubscription(subscription);
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- },
-
- /**
- * Adds or removes "non-intrisive ads" filter list.
- * @return {Boolean} true if the filter list has been added
- **/
- toggleAcceptableAds: function()
- {
- let subscription = Subscription.fromURL(Prefs.subscriptions_exceptionsurl);
- if (!subscription)
- return false;
-
- subscription.disabled = false;
- subscription.title = "Allow non-intrusive advertising";
- if (subscription.url in FilterStorage.knownSubscriptions)
- FilterStorage.removeSubscription(subscription);
- else
- {
- FilterStorage.addSubscription(subscription);
- if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
- Synchronizer.execute(subscription);
- }
-
- return (subscription.url in FilterStorage.knownSubscriptions);
- },
-
- /**
- * Toggles the pref for the Adblock Plus sync engine.
- * @return {Boolean} new state of the sync engine
- */
- toggleSync: function()
- {
- let {Sync} = require("sync");
- let syncEngine = Sync.getEngine();
- if (syncEngine)
- {
- syncEngine.enabled = !syncEngine.enabled;
- return syncEngine.enabled;
- }
- else
- return false;
- },
-
- /**
- * Tests whether blockable items list is currently open.
- */
- isBottombarOpen: function(/**Window*/ window) /**Boolean*/
- {
- if (detachedBottombar && !detachedBottombar.closed)
- return true;
-
- return !!window.document.getElementById("abp-bottombar");
- },
-
- /**
- * Called when some pop-up in the application window shows up, initializes
- * pop-ups related to Adblock Plus.
- */
- onPopupShowing: function(/**Event*/ event)
- {
- if (event.defaultPrevented)
- return;
-
- let popup = event.originalTarget;
-
- let {contentContextMenu} = require("appSupport");
- if ((typeof contentContextMenu == "string" && popup.id == contentContextMenu) ||
- (contentContextMenu instanceof Array && contentContextMenu.indexOf(popup.id) >= 0))
- {
- this.fillContentContextMenu(popup);
- }
- else if (popup.id == "abp-tooltip")
- this.fillIconTooltip(event, popup.ownerDocument.defaultView);
- else
- {
- let match = /^(abp-(?:toolbar|status|menuitem)-)popup$/.exec(popup.id);
- if (match)
- this.fillIconMenu(event, popup.ownerDocument.defaultView, match[1]);
- }
- },
-
- /**
- * Handles click on toolbar and status bar icons.
- */
- onIconClick: function(/**Event*/ event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- let isToolbar = (event.target.localName != "statusbarpanel");
- let action = 0;
- if ((isToolbar && event.type == "command") || (!isToolbar && event.button == 0))
- action = (isToolbar ? Prefs.defaulttoolbaraction : Prefs.defaultstatusbaraction);
- else if (event.button == 1)
- action = 3;
-
- let window = event.target.ownerDocument.defaultView;
- if (action == 1)
- this.toggleBottombar(window);
- else if (action == 2)
- this.openFiltersDialog();
- else if (action == 3)
- {
- // If there is a whitelisting rule for current page - remove it (reenable).
- // Otherwise flip "enabled" pref.
- if (!this.removeWhitelist(window))
- this.togglePref("enabled");
- }
- },
-
- /**
- * Removes/disables the exception rule applying for the current page.
- */
- removeWhitelist: function(/**Window*/ window)
- {
- let location = this.getCurrentLocation(window);
- let filter = null;
- if (location)
- filter = Policy.isWhitelisted(location.spec);
- if (filter && filter.subscriptions.length && !filter.disabled)
- {
- UI.toggleFilter(filter);
- return true;
- }
- return false;
- },
-
- /**
- * Updates state of the icon tooltip.
- */
- fillIconTooltip: function(/**Event*/ event, /**Window*/ window)
- {
- let E = (id) => window.document.getElementById(id);
-
- let node = window.document.tooltipNode;
- if (!node || !node.hasAttribute("tooltip"))
- {
- event.preventDefault();
- return;
- }
-
- // Prevent tooltip from overlapping menu
- for (let id of ["abp-toolbar-popup", "abp-status-popup"])
- {
- let element = E(id);
- if (element && element.state == "open")
- {
- event.preventDefault();
- return;
- }
- }
-
- let type = (node.id == "abp-toolbarbutton" ? "toolbar" : "statusbar");
- let action = parseInt(Prefs["default" + type + "action"]);
- if (isNaN(action))
- action = -1;
-
- let actionDescr = E("abp-tooltip-action");
- actionDescr.hidden = (action < 0 || action > 3);
- if (!actionDescr.hidden)
- actionDescr.setAttribute("value", Utils.getString("action" + action + "_tooltip"));
-
- let statusDescr = E("abp-tooltip-status");
- let state = node.getAttribute("abpstate");
- let statusStr = Utils.getString(state + "_tooltip");
- if (state == "active")
- {
- let [activeSubscriptions, activeFilters] = FilterStorage.subscriptions.reduce(function([subscriptions, filters], current)
- {
- if (current instanceof SpecialSubscription)
- return [subscriptions, filters + current.filters.filter((filter) => !filter.disabled).length];
- else if (!current.disabled && !(Prefs.subscriptions_exceptionscheckbox && current.url == Prefs.subscriptions_exceptionsurl))
- return [subscriptions + 1, filters];
- else
- return [subscriptions, filters]
- }, [0, 0]);
-
- statusStr = statusStr.replace(/\?1\?/, activeSubscriptions).replace(/\?2\?/, activeFilters);
- }
- statusDescr.setAttribute("value", statusStr);
-
- E("abp-tooltip-blocked-label").hidden = true;
- E("abp-tooltip-blocked").hidden = true;
- E("abp-tooltip-filters-label").hidden = true;
- E("abp-tooltip-filters").hidden = true;
- E("abp-tooltip-more-filters").hidden = true;
-
- if (state == "active")
- {
- let {getBrowser} = require("appSupport");
- let browser = getBrowser(window);
- if ("selectedBrowser" in browser)
- browser = browser.selectedBrowser;
- let outerWindowID = browser.outerWindowID;
- RequestNotifier.getWindowStatistics(outerWindowID, (stats) =>
- {
- E("abp-tooltip-blocked-label").hidden = false;
- E("abp-tooltip-blocked").hidden = false;
-
- let blockedStr = Utils.getString("blocked_count_tooltip");
- blockedStr = blockedStr.replace(/\?1\?/, stats ? stats.blocked : 0).replace(/\?2\?/, stats ? stats.items : 0);
-
- if (stats && stats.whitelisted + stats.hidden)
- {
- blockedStr += " " + Utils.getString("blocked_count_addendum");
- blockedStr = blockedStr.replace(/\?1\?/, stats.whitelisted).replace(/\?2\?/, stats.hidden);
- }
-
- E("abp-tooltip-blocked").setAttribute("value", blockedStr);
-
- let activeFilters = [];
- if (stats)
- {
- let filterSort = function(a, b)
- {
- return stats.filters[b] - stats.filters[a];
- };
- for (let filter in stats.filters)
- activeFilters.push(filter);
- activeFilters = activeFilters.sort(filterSort);
- }
-
- if (activeFilters.length > 0)
- {
- let filtersContainer = E("abp-tooltip-filters");
- while (filtersContainer.firstChild)
- filtersContainer.removeChild(filtersContainer.firstChild);
-
- for (let i = 0; i < activeFilters.length && i < 3; i++)
- {
- let descr = filtersContainer.ownerDocument.createElement("description");
- descr.setAttribute("value", activeFilters[i] + " (" + stats.filters[activeFilters[i]] + ")");
- filtersContainer.appendChild(descr);
- }
- }
-
- E("abp-tooltip-filters-label").hidden = (activeFilters.length == 0);
- E("abp-tooltip-filters").hidden = (activeFilters.length == 0);
- E("abp-tooltip-more-filters").hidden = (activeFilters.length <= 3);
- });
- }
- },
-
- /**
- * Updates state of the icon context menu.
- */
- fillIconMenu: function(/**Event*/ event, /**Window*/ window, /**String*/ prefix)
- {
- function hideElement(id, hide)
- {
- let element = window.document.getElementById(id);
- if (element)
- element.hidden = hide;
- }
- function setChecked(id, checked)
- {
- let element = window.document.getElementById(id);
- if (element)
- element.setAttribute("checked", checked);
- }
- function setDisabled(id, disabled)
- {
- let element = window.document.getElementById(id);
- if (element)
- element.setAttribute("disabled", disabled);
- }
- function setDefault(id, isDefault)
- {
- let element = window.document.getElementById(id);
- if (element)
- element.setAttribute("default", isDefault);
- }
- function generateLabel(id, param)
- {
- let element = window.document.getElementById(id);
- if (element)
- element.setAttribute("label", element.getAttribute("labeltempl").replace(/\?1\?/, param));
- }
-
- let bottombarOpen = this.isBottombarOpen(window);
- hideElement(prefix + "openbottombar", bottombarOpen);
- hideElement(prefix + "closebottombar", !bottombarOpen);
-
- hideElement(prefix + "whitelistsite", true);
- hideElement(prefix + "whitelistpage", true);
-
- let location = this.getCurrentLocation(window);
- if (location && Policy.isBlockableScheme(location))
- {
- let host = null;
- try
- {
- host = location.host.replace(/^www\./, "");
- } catch (e) {}
-
- if (host)
- {
- let ending = "|";
- location = location.clone();
- if (location instanceof Ci.nsIURL)
- location.ref = "";
- if (location instanceof Ci.nsIURL && location.query)
- {
- location.query = "";
- ending = "?";
- }
-
- siteWhitelist = Filter.fromText("@@||" + host + "^$document");
- setChecked(prefix + "whitelistsite", siteWhitelist.subscriptions.length && !siteWhitelist.disabled);
- generateLabel(prefix + "whitelistsite", host);
- hideElement(prefix + "whitelistsite", false);
-
- pageWhitelist = Filter.fromText("@@|" + location.spec + ending + "$document");
- setChecked(prefix + "whitelistpage", pageWhitelist.subscriptions.length && !pageWhitelist.disabled);
- hideElement(prefix + "whitelistpage", false);
- }
- else
- {
- siteWhitelist = Filter.fromText("@@|" + location.spec + "|");
- setChecked(prefix + "whitelistsite", siteWhitelist.subscriptions.length && !siteWhitelist.disabled);
- generateLabel(prefix + "whitelistsite", location.spec.replace(/^mailto:/, ""));
- hideElement(prefix + "whitelistsite", false);
- }
- }
-
- setDisabled("abp-command-sendReport", !location || !Policy.isBlockableScheme(location) || location.scheme == "mailto");
-
- setChecked(prefix + "disabled", !Prefs.enabled);
- setChecked(prefix + "frameobjects", Prefs.frameobjects);
- setChecked(prefix + "savestats", Prefs.savestats);
-
- let {defaultToolbarPosition, statusbarPosition} = require("appSupport");
- let hasToolbar = defaultToolbarPosition;
- let hasStatusBar = statusbarPosition;
- hideElement(prefix + "showintoolbar", !hasToolbar || prefix == "abp-toolbar-");
- hideElement(prefix + "showinstatusbar", !hasStatusBar);
- hideElement(prefix + "shownotifications", !Prefs.notifications_showui);
- hideElement(prefix + "iconSettingsSeparator", (prefix == "abp-toolbar-" || !hasToolbar) && !hasStatusBar);
-
- setChecked(prefix + "showintoolbar", this.isToolbarIconVisible());
- setChecked(prefix + "showinstatusbar", Prefs.showinstatusbar);
- setChecked(prefix + "shownotifications", Prefs.notifications_ignoredcategories.indexOf("*") == -1);
-
- let {Sync} = require("sync");
- let syncEngine = Sync.getEngine();
- hideElement(prefix + "sync", !syncEngine);
- setChecked(prefix + "sync", syncEngine && syncEngine.enabled);
-
- let defAction = (!window.document.popupNode || window.document.popupNode.id == "abp-toolbarbutton" ?
- Prefs.defaulttoolbaraction :
- Prefs.defaultstatusbaraction);
- setDefault(prefix + "openbottombar", defAction == 1);
- setDefault(prefix + "closebottombar", defAction == 1);
- setDefault(prefix + "filters", defAction == 2);
- setDefault(prefix + "disabled", defAction == 3);
-
- let popup = window.document.getElementById(prefix + "popup");
- let items = (popup ? popup.querySelectorAll('menuitem[key]') : []);
- for (let i = 0; i < items.length; i++)
- {
- let item = items[i];
- let match = /^abp-key-/.exec(item.getAttribute("key"));
- if (!match)
- continue;
-
- let name = match.input.substr(match.index + match[0].length);
- if (!this.hotkeys)
- this.configureKeys(window);
- if (name in this.hotkeys)
- {
- let text = KeySelector.getTextForKey(this.hotkeys[name]);
- if (text)
- item.setAttribute("acceltext", text);
- else
- item.removeAttribute("acceltext");
- }
- }
-
- hideElement(prefix + "contributebutton", Prefs.hideContributeButton);
- },
-
- /**
- * Adds Adblock Plus menu items to the content area context menu when it shows
- * up.
- */
- fillContentContextMenu: function(/**Element*/ popup)
- {
- let window = popup.ownerDocument.defaultView;
- let data = window.gContextMenuContentData;
- if (!data)
- {
- // This is SeaMonkey Mail or Thunderbird, they won't get context menu data
- // for us. Send the notification ourselves.
- data = {
- event: {target: popup.triggerNode},
- addonInfo: {},
- get wrappedJSObject() {return this;}
- };
- Services.obs.notifyObservers(data, "AdblockPlus:content-contextmenu", null);
- }
-
- if (typeof data.addonInfo != "object" || typeof data.addonInfo.adblockplus != "object")
- return;
-
- let items = data.addonInfo.adblockplus;
- let clicked = null;
- let menuItems = [];
-
- function menuItemTriggered(id, nodeData)
- {
- clicked = id;
- this.blockItem(window, id, nodeData);
- }
-
- for (let [id, nodeData] of items)
- {
- let type = nodeData.type.toLowerCase();
- let label = this.overlay.attributes[type + "contextlabel"];
- if (!label)
- return;
-
- let item = popup.ownerDocument.createElement("menuitem");
- item.setAttribute("label", label);
- item.setAttribute("class", "abp-contextmenuitem");
- item.addEventListener("command", menuItemTriggered.bind(this, id, nodeData), false);
- popup.appendChild(item);
-
- menuItems.push(item);
- }
-
- // Add "Remove exception" menu item if necessary
- let location = this.getCurrentLocation(window);
- let filter = (location ? Policy.isWhitelisted(location.spec) : null);
- if (filter && filter.subscriptions.length && !filter.disabled)
- {
- let label = this.overlay.attributes.whitelistcontextlabel;
- if (!label)
- return;
-
- let item = popup.ownerDocument.createElement("menuitem");
- item.setAttribute("label", label);
- item.setAttribute("class", "abp-contextmenuitem");
- item.addEventListener("command", this.toggleFilter.bind(this, filter), false);
- popup.appendChild(item);
-
- menuItems.push(item);
- }
-
- // Make sure to clean up everything once the context menu is closed
- let cleanUp = function(event)
- {
- if (event.eventPhase != event.AT_TARGET)
- return;
-
- popup.removeEventListener("popuphidden", cleanUp, false);
- for (let menuItem of menuItems)
- if (menuItem.parentNode)
- menuItem.parentNode.removeChild(menuItem);
-
- for (let [id, nodeData] of items)
- if (id && id != clicked)
- Policy.deleteNodes(id);
- }.bind(this);
- popup.addEventListener("popuphidden", cleanUp, false);
- },
-
- /**
- * Called when the user presses a key in the application window, reacts to our
- * shortcut keys.
- */
- onKeyPress: function(/**Event*/ event)
- {
- if (!this.hotkeys)
- this.configureKeys(event.currentTarget);
-
- for (let key in this.hotkeys)
- {
- if (KeySelector.matchesKey(event, this.hotkeys[key]))
- {
- event.preventDefault();
- let command = event.currentTarget.document.getElementById("abp-command-" + key);
- if (command)
- command.doCommand();
- }
- }
- },
-
- /**
- * Checks whether the toolbar icon is currently displayed.
- */
- isToolbarIconVisible: function() /**Boolean*/
- {
- if (!CustomizableUI)
- return false;
- let placement = CustomizableUI.getPlacementOfWidget("abp-toolbarbutton");
- return !!placement;
- },
-
- /**
- * Stores the selected hotkeys, initialized when the user presses a key.
- */
- hotkeys: null,
-
- /**
- * Chooses shortcut keys that are available in the window according to
- * preferences.
- */
- configureKeys: function(/**Window*/ window)
- {
- let selector = new KeySelector(window);
-
- this.hotkeys = {};
- for (let name in Prefs)
- {
- let match = /_key$/.exec(name);
- if (match && typeof Prefs[name] == "string")
- {
- let keyName = match.input.substr(0, match.index);
- this.hotkeys[keyName] = selector.selectKey(Prefs[name]);
- }
- }
- },
-
- /**
- * Toggles open/closed state of the blockable items list.
- */
- toggleBottombar: function(/**Window*/ window)
- {
- if (detachedBottombar && !detachedBottombar.closed)
- {
- detachedBottombar.close();
- detachedBottombar = null;
- }
- else
- {
- let {addBottomBar, removeBottomBar, getBrowser} = require("appSupport");
- let mustDetach = !addBottomBar || !removeBottomBar || !("abp-bottombar-container" in this.overlay);
- let detach = mustDetach || Prefs.detachsidebar;
- if (!detach && window.document.getElementById("abp-bottombar"))
- {
- removeBottomBar(window);
-
- let browser = (getBrowser ? getBrowser(window) : null);
- if (browser && "selectedBrowser" in browser)
- browser = browser.selectedBrowser;
- if (browser)
- browser.focus();
- }
- else if (!detach)
- {
- addBottomBar(window, this.overlay["abp-bottombar-container"]);
- let element = window.document.getElementById("abp-bottombar");
- if (element)
- {
- element.setAttribute("width", Prefs.blockableItemsSize.width);
- element.setAttribute("height", Prefs.blockableItemsSize.height);
-
- let splitter = window.document.getElementById("abp-bottombar-splitter");
- if (splitter)
- {
- splitter.addEventListener("command", function()
- {
- Prefs.blockableItemsSize = {width: element.width, height: element.height};
- }, false);
- }
- }
- }
- else
- detachedBottombar = window.openDialog("chrome://adblockplus/content/ui/sidebarDetached.xul", "_blank", "chrome,resizable,dependent,dialog=no", mustDetach);
- }
- },
-
- /**
- * Hide contribute button and persist this choice.
- */
- hideContributeButton: function(/**Window*/ window)
- {
- Prefs.hideContributeButton = true;
-
- for (let id of ["abp-status-contributebutton", "abp-toolbar-contributebutton", "abp-menuitem-contributebutton"])
- {
- let button = window.document.getElementById(id);
- if (button)
- button.hidden = true;
- }
- },
-
- _showNotification: function(window, button, notification)
- {
- let panel = window.document.getElementById("abp-notification");
- if (panel.state !== "closed")
- return;
-
- function insertMessage(element, text, links)
- {
- let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(text);
- if (!match)
- {
- element.appendChild(window.document.createTextNode(text));
- return;
- }
-
- let [_, before, tagName, value, after] = match;
-
- insertMessage(element, before, links);
-
- let newElement = window.document.createElementNS("http://www.w3.org/1999/xhtml", tagName);
- if (tagName === "a" && links && links.length)
- newElement.setAttribute("href", links.shift());
- insertMessage(newElement, value, links);
- element.appendChild(newElement);
-
- insertMessage(element, after, links);
- }
-
- let texts = Notification.getLocalizedTexts(notification);
- let titleElement = window.document.getElementById("abp-notification-title");
- titleElement.textContent = texts.title;
- let messageElement = window.document.getElementById("abp-notification-message");
- messageElement.innerHTML = "";
- let docLinks = [];
- if (notification.links)
- for (let link of notification.links)
- docLinks.push(Utils.getDocLink(link));
-
- insertMessage(messageElement, texts.message, docLinks);
-
- messageElement.addEventListener("click", function(event)
- {
- let link = event.target;
- while (link && link !== messageElement && link.localName !== "a")
- link = link.parentNode;
- if (!link || link.localName !== "a")
- return;
- event.preventDefault();
- event.stopPropagation();
- this.loadInBrowser(link.href, window);
- }.bind(this));
-
- if (notification.type === "question")
- {
- function buttonHandler(approved, event)
- {
- event.preventDefault();
- event.stopPropagation();
- panel.hidePopup();
- Notification.triggerQuestionListeners(notification.id, approved)
- Notification.markAsShown(notification.id);
- }
- window.document.getElementById("abp-notification-yes").onclick = buttonHandler.bind(null, true);
- window.document.getElementById("abp-notification-no").onclick = buttonHandler.bind(null, false);
- }
- else
- Notification.markAsShown(notification.id);
-
- panel.setAttribute("class", "abp-" + notification.type);
- panel.setAttribute("noautohide", true);
- panel.openPopup(button, "bottomcenter topcenter", 0, 0, false, false, null);
- }
-};
-UI.onPopupShowing = UI.onPopupShowing.bind(UI);
-UI.onKeyPress = UI.onKeyPress.bind(UI);
-UI.onIconClick = UI.onIconClick.bind(UI);
-UI.init();
-
-/**
- * List of event handers to be registered for each window. For each event
- * handler the element ID, event and the actual event handler are listed.
- * @type Array
- */
-let eventHandlers = [
- ["abp-command-sendReport", "command", UI.openReportDialog.bind(UI)],
- ["abp-command-filters", "command", UI.openFiltersDialog.bind(UI)],
- ["abp-command-sidebar", "command", UI.toggleBottombar.bind(UI)],
- ["abp-command-togglesitewhitelist", "command", function() { UI.toggleFilter(siteWhitelist); }],
- ["abp-command-togglepagewhitelist", "command", function() { UI.toggleFilter(pageWhitelist); }],
- ["abp-command-toggleobjtabs", "command", UI.togglePref.bind(UI, "frameobjects")],
- ["abp-command-togglesavestats", "command", UI.toggleSaveStats.bind(UI)],
- ["abp-command-togglesync", "command", UI.toggleSync.bind(UI)],
- ["abp-command-toggleshowintoolbar", "command", UI.toggleToolbarIcon.bind(UI)],
- ["abp-command-toggleshowinstatusbar", "command", UI.togglePref.bind(UI, "showinstatusbar")],
- ["abp-command-enable", "command", UI.togglePref.bind(UI, "enabled")],
- ["abp-command-contribute", "command", UI.openContributePage.bind(UI)],
- ["abp-command-contribute-hide", "command", UI.hideContributeButton.bind(UI)],
- ["abp-command-toggleshownotifications", "command", Notification.toggleIgnoreCategory.bind(Notification, "*", null)]
-];
-
-onShutdown.add(function()
-{
- for (let window of UI.applicationWindows)
- if (UI.isBottombarOpen(window))
- UI.toggleBottombar(window);
-});