diff options
Diffstat (limited to 'data/extensions/spyblock@gnu.org/chrome/content')
48 files changed, 0 insertions, 9978 deletions
diff --git a/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js b/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js deleted file mode 100644 index ff824ae..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js +++ /dev/null @@ -1,167 +0,0 @@ -// We are currently limited to ECMAScript 5 in this file, because it is being -// used in the browser tests. See https://issues.adblockplus.org/ticket/4796 - -var propertySelectorRegExp = /\[\-abp\-properties=(["'])([^"']+)\1\]/; - -function splitSelector(selector) -{ - if (selector.indexOf(",") == -1) - return [selector]; - - var selectors = []; - var start = 0; - var level = 0; - var sep = ""; - - for (var i = 0; i < selector.length; i++) - { - var chr = selector[i]; - - if (chr == "\\") // ignore escaped characters - i++; - else if (chr == sep) // don't split within quoted text - sep = ""; // e.g. [attr=","] - else if (sep == "") - { - if (chr == '"' || chr == "'") - sep = chr; - else if (chr == "(") // don't split between parentheses - level++; // e.g. :matches(div,span) - else if (chr == ")") - level = Math.max(0, level - 1); - else if (chr == "," && level == 0) - { - selectors.push(selector.substring(start, i)); - start = i + 1; - } - } - } - - selectors.push(selector.substring(start)); - return selectors; -} - -function ElemHideEmulation(window, getFiltersFunc, addSelectorsFunc) -{ - this.window = window; - this.getFiltersFunc = getFiltersFunc; - this.addSelectorsFunc = addSelectorsFunc; -} - -ElemHideEmulation.prototype = { - stringifyStyle: function(style) - { - var styles = []; - for (var i = 0; i < style.length; i++) - { - var property = style.item(i); - var value = style.getPropertyValue(property); - var priority = style.getPropertyPriority(property); - styles.push(property + ": " + value + (priority ? " !" + priority : "") + ";"); - } - styles.sort(); - return styles.join(" "); - }, - - isSameOrigin: function(stylesheet) - { - try - { - return new URL(stylesheet.href).origin == this.window.location.origin; - } - catch (e) - { - // Invalid URL, assume that it is first-party. - return true; - } - }, - - findSelectors: function(stylesheet, selectors, filters) - { - // Explicitly ignore third-party stylesheets to ensure consistent behavior - // between Firefox and Chrome. - if (!this.isSameOrigin(stylesheet)) - return; - - var rules = stylesheet.cssRules; - if (!rules) - return; - - for (var i = 0; i < rules.length; i++) - { - var rule = rules[i]; - if (rule.type != rule.STYLE_RULE) - continue; - - var style = this.stringifyStyle(rule.style); - for (var j = 0; j < this.patterns.length; j++) - { - var pattern = this.patterns[j]; - if (pattern.regexp.test(style)) - { - var subSelectors = splitSelector(rule.selectorText); - for (var k = 0; k < subSelectors.length; k++) - { - var subSelector = subSelectors[k]; - selectors.push(pattern.prefix + subSelector + pattern.suffix); - filters.push(pattern.text); - } - } - } - } - }, - - addSelectors: function(stylesheets) - { - var selectors = []; - var filters = []; - for (var i = 0; i < stylesheets.length; i++) - this.findSelectors(stylesheets[i], selectors, filters); - this.addSelectorsFunc(selectors, filters); - }, - - onLoad: function(event) - { - var stylesheet = event.target.sheet; - if (stylesheet) - this.addSelectors([stylesheet]); - }, - - apply: function() - { - this.getFiltersFunc(function(patterns) - { - this.patterns = []; - for (var i = 0; i < patterns.length; i++) - { - var pattern = patterns[i]; - var match = propertySelectorRegExp.exec(pattern.selector); - if (!match) - continue; - - var propertyExpression = match[2]; - var regexpString; - if (propertyExpression.length >= 2 && propertyExpression[0] == "/" && - propertyExpression[propertyExpression.length - 1] == "/") - regexpString = propertyExpression.slice(1, -1) - .replace("\\x7B ", "{").replace("\\x7D ", "}"); - else - regexpString = filterToRegExp(propertyExpression); - - this.patterns.push({ - text: pattern.text, - regexp: new RegExp(regexpString, "i"), - prefix: pattern.selector.substr(0, match.index), - suffix: pattern.selector.substr(match.index + match[0].length) - }); - } - - if (this.patterns.length > 0) - { - var document = this.window.document; - this.addSelectors(document.styleSheets); - document.addEventListener("load", this.onLoad.bind(this), true); - } - }.bind(this)); - } -}; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css b/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css deleted file mode 100644 index 62ad04b..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css +++ /dev/null @@ -1,82 +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/>. - */ - -@namespace url("http://www.w3.org/1999/xhtml"); - -.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%%, .%%CLASSHIDDEN%% -{ - position: fixed !important; - display: block !important; - - width: auto !important; - height: auto !important; - right: auto !important; - bottom: auto !important; - z-index: 65535 !important; - float: left !important; - border-color: black !important; - border-style: solid !important; - background: white !important; - color: black !important; - cursor: pointer !important; - white-space: nowrap !important; - font-family: Arial,Helvetica,Sans-Serif !important; - font-size: 10px !important; - font-style: normal !important; - font-variant: normal !important; - font-weight: normal !important; - letter-spacing: normal !important; - line-height: normal !important; - text-align: center !important; - text-decoration: none !important; - text-indent: 0px !important; - text-transform: none !important; - direction: ltr !important; - padding: 0px 5px !important; - -moz-binding: none !important; - -moz-user-focus: none !important; - -moz-user-input: none !important; - -moz-user-select: none !important; -} - -.%%CLASSVISIBLETOP%%, .%%CLASSHIDDEN%% -{ - border-width: 1px 1px 0px 1px !important; - border-top-left-radius: 10px !important; - border-top-right-radius: 10px !important; - border-bottom-left-radius: 0px !important; - border-bottom-right-radius: 0px !important; -} - -.%%CLASSVISIBLEBOTTOM%% -{ - border-width: 0px 1px 1px 1px !important; - border-top-left-radius: 0px !important; - border-top-right-radius: 0px !important; - border-bottom-left-radius: 10px !important; - border-bottom-right-radius: 10px !important; -} - -.%%CLASSVISIBLETOP%%, .%%CLASSVISIBLEBOTTOM%% -{ - visibility: visible !important; -} - -.%%CLASSHIDDEN%% -{ - visibility: hidden !important; -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js deleted file mode 100644 index ec20ede..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js +++ /dev/null @@ -1,154 +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/>. - */ - -/* globals Components */ - -"use strict"; - -function E(id) -{ - return document.getElementById(id); -} - -function getDocLink(link, callback) -{ - ext.backgroundPage.sendMessage({ - type: "app.get", - what: "doclink", - link - }, callback); -} - -function checkShareResource(url, callback) -{ - ext.backgroundPage.sendMessage({ - type: "filters.blocked", - url, - requestType: "SCRIPT", - docDomain: "adblockplus.org", - thirdParty: true - }, callback); -} - -function openSharePopup(url) -{ - let glassPane = E("glass-pane"); - if (!glassPane) - { - glassPane = document.createElement("div"); - glassPane.setAttribute("id", "glass-pane"); - document.body.appendChild(glassPane); - } - - let iframe = E("share-popup"); - if (!iframe) - { - iframe = document.createElement("iframe"); - iframe.setAttribute("id", "share-popup"); - iframe.setAttribute("scrolling", "no"); - glassPane.appendChild(iframe); - } - - // Firefox 38+ no longer allows messaging using postMessage so we need - // to have a fake top level frame to avoid problems with scripts that try to - // communicate with the first-run page - let isGecko = ("Components" in window); - if (isGecko) - { - try - { - let Ci = Components.interfaces; - let docShell = iframe.contentWindow - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShell); - - if (typeof docShell.frameType != "undefined") - { - // Gecko 47+ - docShell.frameType = docShell.FRAME_TYPE_BROWSER; - } - else - { - // Legacy branch - docShell.setIsBrowserInsideApp( - Ci.nsIScriptSecurityManager.UNKNOWN_APP_ID - ); - } - } - catch (ex) - { - console.error(ex); - } - } - - let popupMessageReceived = false; - function resizePopup(width, height) - { - iframe.width = width; - iframe.height = height; - iframe.style.marginTop = -height / 2 + "px"; - iframe.style.marginLeft = -width / 2 + "px"; - popupMessageReceived = true; - window.removeEventListener("message", popupMessageListener); - } - - let popupMessageListener = function(event) - { - if (!/[./]adblockplus\.org$/.test(event.origin) || - !("width" in event.data) || !("height" in event.data)) - return; - - resizePopup(event.data.width, event.data.height); - }; - // Firefox requires last parameter to be true to be triggered by - // unprivileged pages - window.addEventListener("message", popupMessageListener, false, true); - - let popupLoadListener = function() - { - if (!popupMessageReceived && isGecko) - { - let rootElement = iframe.contentDocument.documentElement; - let {width, height} = rootElement.dataset; - if (width && height) - resizePopup(width, height); - } - - if (popupMessageReceived) - { - iframe.className = "visible"; - - let popupCloseListener = function() - { - iframe.className = glassPane.className = ""; - document.removeEventListener("click", popupCloseListener); - }; - document.addEventListener("click", popupCloseListener, false); - } - else - { - glassPane.className = ""; - window.removeEventListener("message", popupMessageListener); - } - - iframe.removeEventListener("load", popupLoadListener); - }; - iframe.addEventListener("load", popupLoadListener, false); - - iframe.src = url; - glassPane.className = "visible"; -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.js deleted file mode 100644 index 8170cee..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.js +++ /dev/null @@ -1,402 +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/>. - */ - -var nodesID = null; -var item = null; -var advancedMode = false; - -function init() -{ - [nodesID, item] = window.arguments; - window.addEventListener("unload", () => Policy.deleteNodes(nodesID)); - - E("filterType").value = (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter ? "filterlist" : "whitelist"); - E("customPattern").value = item.location; - - let insertionPoint = E("customPatternBox"); - let addSuggestion = function(address) - { - // Always drop protocol and www. from the suggestion - address = address.replace(/^[\w\-]+:\/+(?:www\.)?/, ""); - - let suggestion = document.createElement("radio"); - suggestion.setAttribute("value", address); - suggestion.setAttribute("label", address); - suggestion.setAttribute("crop", "center"); - suggestion.setAttribute("class", "suggestion"); - insertionPoint.parentNode.insertBefore(suggestion, insertionPoint); - - return address; - } - - let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - try - { - let suggestions = [""]; - - let url = ioService.newURI(item.location, null, null) - .QueryInterface(Ci.nsIURL); - let suffix = (url.query ? "?*" : ""); - url.query = ""; - url.ref = ""; - suggestions[1] = addSuggestion(url.spec + suffix); - - let parentURL = ioService.newURI(url.fileName == "" ? ".." : ".", null, url); - if (!parentURL.equals(url)) - suggestions[2] = addSuggestion(parentURL.spec + "*"); - else - suggestions[2] = suggestions[1]; - - let rootURL = ioService.newURI("/", null, url); - if (!rootURL.equals(parentURL) && !rootURL.equals(url)) - suggestions[3] = addSuggestion(rootURL.spec + "*"); - else - suggestions[3] = suggestions[2]; - - try - { - suggestions[4] = addSuggestion(url.host.replace(/^www\./, "") + "^"); - - // Prefer example.com^ to example.com/* - let undesired = suggestions[4].replace(/\^$/, "/*"); - for (let i = 0; i < suggestions.length - 1; i++) - if (suggestions[i] == undesired) - suggestions[i] = suggestions[4]; - - for (let child = insertionPoint.parentNode.firstChild; child; child = child.nextSibling) - { - if (child.localName == "radio" && child.getAttribute("value") == undesired) - { - child.parentNode.removeChild(child); - break; - } - } - } - catch (e) - { - suggestions[4] = suggestions[3]; - } - - try - { - let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService); - let host = url.host; - let baseDomain = effectiveTLD.getBaseDomainFromHost(host); - if (baseDomain != host.replace(/^www\./, "")) - suggestions[5] = addSuggestion(baseDomain + "^"); - else - suggestions[5] = suggestions[4]; - } - catch (e) - { - suggestions[5] = suggestions[4]; - } - - E("patternGroup").value = (Prefs.composer_default in suggestions ? suggestions[Prefs.composer_default] : suggestions[1]); - } - catch (e) - { - // IOService returned nsIURI - not much we can do with it - addSuggestion(item.location); - E("patternGroup").value = ""; - } - if (Prefs.composer_default == 0) - E("customPattern").focus(); - else - E("patternGroup").focus(); - - let types = Array.from(new Set(Policy.contentTypes.values())); - types.sort(); - - let docDomain = item.docDomain; - let thirdParty = item.thirdParty; - - if (docDomain) - docDomain = docDomain.replace(/^www\./i, "").replace(/\.+$/, ""); - if (docDomain) - E("domainRestriction").value = docDomain; - - E("thirdParty").hidden = !thirdParty; - E("firstParty").hidden = thirdParty; - - let typeGroup = E("typeGroup"); - let defaultTypes = RegExpFilter.prototype.contentType & ~RegExpFilter.typeMap.DOCUMENT; - let isDefaultType = (RegExpFilter.typeMap[item.type] & defaultTypes) != 0; - for (let type of types) - { - if (type == "ELEMHIDE" || type == "GENERICBLOCK" || type == "GENERICHIDE") - continue; - - let typeNode = document.createElement("checkbox"); - typeNode.setAttribute("value", type.toLowerCase().replace(/\_/g, "-")); - typeNode.setAttribute("label", Utils.getString("type_label_" + type.toLowerCase())); - - let typeMask = RegExpFilter.typeMap[type]; - typeNode._defaultType = (typeMask & defaultTypes) != 0; - if ((isDefaultType && typeNode._defaultType) || (!isDefaultType && item.type == type)) - typeNode.setAttribute("checked", "true"); - - if (item.type == type) - typeNode.setAttribute("disabled", "true"); - typeNode.addEventListener("command", () => checkboxUpdated(typeNode), false); - typeGroup.appendChild(typeNode); - } - - let collapseDefault = E("collapseDefault"); - collapseDefault.label = collapseDefault.getAttribute(Prefs.fastcollapse ? "label_no" : "label_yes"); - E("collapse").value = ""; - E("collapse").setAttribute("label", collapseDefault.label); - - let warning = E("disabledWarning"); - generateLinkText(warning); - warning.hidden = Prefs.enabled; - - updatePatternSelection(); -} - -function checkboxUpdated(checkbox) -{ - checkbox._lastChange = Date.now(); - updateFilter(); -} - -function updateFilter() -{ - let filter = ""; - - let type = E("filterType").value - if (type == "whitelist") - filter += "@@"; - - let pattern = E("patternGroup").value; - if (pattern == "") - pattern = E("customPattern").value; - - if (E("anchorStart").checked) - filter += E("anchorStart").flexibleAnchor ? "||" : "|"; - - filter += pattern; - - if (E("anchorEnd").checked) - filter += "|"; - - if (advancedMode) - { - let options = []; - - if (E("domainRestrictionEnabled").checked) - { - let domainRestriction = E("domainRestriction").value.replace(/[,\s]/g, "").replace(/\.+$/, ""); - if (domainRestriction) - options.push([E("domainRestrictionEnabled")._lastChange || 0, "domain=" + domainRestriction]); - } - - if (E("firstParty").checked) - options.push([E("firstParty")._lastChange || 0, "~third-party"]); - if (E("thirdParty").checked) - options.push([E("thirdParty")._lastChange || 0, "third-party"]); - - if (E("matchCase").checked) - options.push([E("matchCase")._lastChange || 0, "match-case"]); - - let collapse = E("collapse"); - disableElement(collapse, type == "whitelist", "value", ""); - if (collapse.value != "") - options.push([collapse._lastChange, collapse.value]); - - let enabledTypes = []; - let disabledTypes = []; - let forceEnabledTypes = []; - for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling) - { - let value = typeNode.getAttribute("value"); - if (value == "document") - disableElement(typeNode, type != "whitelist", "checked", false); - - if (!typeNode._defaultType) - { - if (typeNode.getAttribute("checked") == "true") - forceEnabledTypes.push([typeNode._lastChange || 0, value]); - } - else if (typeNode.getAttribute("checked") == "true") - enabledTypes.push([typeNode._lastChange || 0, value]); - else - disabledTypes.push([typeNode._lastChange || 0, "~" + value]); - } - if (!forceEnabledTypes.length && disabledTypes.length < enabledTypes.length) - options.push.apply(options, disabledTypes); - else - options.push.apply(options, enabledTypes); - options.push.apply(options, forceEnabledTypes); - - if (options.length) - { - options.sort((a, b) => a[0] - b[0]); - filter += "$" + options.map(o => o[1]).join(","); - } - } - else - { - let defaultTypes = RegExpFilter.prototype.contentType & ~RegExpFilter.typeMap.DOCUMENT; - let isDefaultType = (RegExpFilter.typeMap[item.type] & defaultTypes) != 0; - if (!isDefaultType) - filter += "$" + item.type.toLowerCase().replace(/\_/g, "-"); - } - - filter = Filter.normalize(filter); - E("regexpWarning").hidden = !Filter.regexpRegExp.test(filter); - - let isSlow = false; - let compiledFilter = Filter.fromText(filter); - if (E("regexpWarning").hidden) - { - if (compiledFilter instanceof RegExpFilter && defaultMatcher.isSlowFilter(compiledFilter)) - isSlow = true; - } - E("shortpatternWarning").hidden = !isSlow; - - E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); - - E("filter").value = filter; -} - -function generateLinkText(element, replacement) -{ - let template = element.getAttribute("textTemplate"); - if (typeof replacement != "undefined") - template = template.replace(/\?1\?/g, replacement) - - let [, beforeLink, linkText, afterLink] = /(.*)\[link\](.*)\[\/link\](.*)/.exec(template) || [null, "", template, ""]; - while (element.firstChild && element.firstChild.nodeType != Node.ELEMENT_NODE) - element.removeChild(element.firstChild); - while (element.lastChild && element.lastChild.nodeType != Node.ELEMENT_NODE) - element.removeChild(element.lastChild); - if (!element.firstChild) - return; - - element.firstChild.textContent = linkText; - element.insertBefore(document.createTextNode(beforeLink), element.firstChild); - element.appendChild(document.createTextNode(afterLink)); -} - -function updatePatternSelection() -{ - let pattern = E("patternGroup").value; - if (pattern == "") - { - pattern = E("customPattern").value; - } - else - { - E("anchorStart").checked = true; - E("anchorEnd").checked = false; - } - - function testFilter(/**String*/ filter) /**Boolean*/ - { - return RegExpFilter.fromText(filter + "$" + item.type).matches(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); - } - - let anchorStartCheckbox = E("anchorStart"); - if (!/^\*/.test(pattern) && testFilter("||" + pattern)) - { - disableElement(anchorStartCheckbox, false, "checked", false); - [anchorStartCheckbox.label, anchorStartCheckbox.accessKey] = Utils.splitLabel(anchorStartCheckbox.getAttribute("labelFlexible")); - anchorStartCheckbox.flexibleAnchor = true; - } - else - { - disableElement(anchorStartCheckbox, /^\*/.test(pattern) || !testFilter("|" + pattern), "checked", false); - [anchorStartCheckbox.label, anchorStartCheckbox.accessKey] = Utils.splitLabel(anchorStartCheckbox.getAttribute("labelRegular")); - anchorStartCheckbox.flexibleAnchor = false; - } - disableElement(E("anchorEnd"), /[\*\^]$/.test(pattern) || !testFilter(pattern + "|"), "checked", false); - - updateFilter(); - setAdvancedMode(document.documentElement.getAttribute("advancedMode") == "true"); -} - -function updateCustomPattern() -{ - E("patternGroup").value = ""; - updatePatternSelection(); -} - -function addFilter() { - let filter = Filter.fromText(document.getElementById("filter").value); - filter.disabled = false; - - FilterStorage.addFilter(filter); - - if (nodesID) - Policy.refilterNodes(nodesID, item); - - return true; -} - -function setAdvancedMode(mode) { - advancedMode = mode; - - var dialog = document.documentElement; - dialog.setAttribute("advancedMode", advancedMode); - - var button = dialog.getButton("disclosure"); - button.setAttribute("label", dialog.getAttribute(advancedMode ? "buttonlabeldisclosure_off" : "buttonlabeldisclosure_on")); - - updateFilter(); -} - -function disableElement(element, disable, valueProperty, disabledValue) { - if ((element.getAttribute("disabled") == "true") == disable) - return; - - if (disable) - { - element.setAttribute("disabled", "true"); - element._abpStoredValue = element[valueProperty]; - element[valueProperty] = disabledValue; - } - else - { - element.removeAttribute("disabled"); - if ("_abpStoredValue" in element) - element[valueProperty] = element._abpStoredValue; - delete element._abpStoredValue; - } -} - -function openPreferences() -{ - UI.openFiltersDialog(Filter.fromText(E("filter").value)); -} - -function doEnable() { - Prefs.enabled = true; - E("disabledWarning").hidden = true; -} - -/** - * Selects or unselects all type checkboxes except those - * that are disabled. - */ -function selectAllTypes(/**Boolean*/ select) -{ - for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling) - if (typeNode.getAttribute("disabled") != "true") - typeNode.checked = select; - updateFilter(); -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul deleted file mode 100644 index 2cf1502..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul +++ /dev/null @@ -1,118 +0,0 @@ -<?xml version="1.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/>. - --> - -<!DOCTYPE overlay SYSTEM "chrome://adblockplus/locale/composer.dtd"> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://adblockplus/skin/composer.css" type="text/css"?> - -<dialog id="abp-composer" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - title="&dialog.title;" - onload="init()" - ondialogaccept="return addFilter()" - ondialogdisclosure="setAdvancedMode(!advancedMode)" - buttons="accept,cancel,disclosure" - width="800px" - height="400px" - persist="screenX screenY width height sizemode advancedMode" - advancedMode="false" - buttonlabelaccept="&accept.label;" - buttonlabeldisclosure="&advanced.label;" - buttonlabeldisclosure_on="&advanced.label;" - buttonlabeldisclosure_off="&basic.label;" - windowtype="abp:composer"> - - <script type="application/x-javascript;version=1.7" src="utils.js"/> - <script type="application/x-javascript;version=1.7" src="composer.js"/> - - <popupset> - <tooltip id="domainRestrictionHelp" label="&domainRestriction.help;"/> - </popupset> - - <description id="disabledWarning" hidden="true" textTemplate="&disabled.warning;"> - <label class="text-link" onclick="doEnable()"/> - </description> - - <hbox id="filterBox" align="center"> - <label control="filter" value="&filter.label;"/> - <textbox id="filter" flex="1" tabindex="-1" readonly="true"/> - <button id="preferences" label="&preferences.label;" oncommand="openPreferences()"/> - </hbox> - - <radiogroup orient="horizontal" id="filterType" oncommand="updateFilter()"> - <radio label="&type.filter.label;" value="filterlist" flex="1"/> - <radio label="&type.whitelist.label;" value="whitelist" flex="1"/> - </radiogroup> - - <hbox flex="1"> - <groupbox id="pattern" flex="1"> - <caption label="&pattern.label;"/> - <radiogroup id="patternGroup" flex="1" oncommand="updatePatternSelection()" style="overflow: auto;"> - <description id="patternExplanation">&pattern.explanation;</description> - <description id="regexpWarning" hidden="true">®exp.warning;</description> - <description id="shortpatternWarning" hidden="true">&shortpattern.warning;</description> - <description id="matchWarning" hidden="true">&match.warning;</description> - <hbox id="customPatternBox"> - <radio id="customPatternRadio" label="&custom.pattern.label;" value="" control="customPattern"/> - <textbox id="customPattern" flex="1" oninput="updateCustomPattern()"/> - </hbox> - </radiogroup> - <hbox id="anchorGroup" pack="start" align="baseline"> - <label value="&anchors.label;"/> - <description flex="1" style="margin: 0; padding: 0;"> - <checkbox id="anchorStart" labelRegular="&anchor.start.label;" - labelFlexible="&anchor.start.flexible.label;" - oncommand="updateFilter()"/> - <checkbox id="anchorEnd" label="&anchor.end.label;" oncommand="updateFilter()"/> - </description> - </hbox> - </groupbox> - <groupbox id="options"> - <caption label="&options.label;"/> - <checkbox id="firstParty" label="&firstParty.label;" oncommand="checkboxUpdated(this);"/> - <checkbox id="thirdParty" label="&thirdParty.label;" oncommand="checkboxUpdated(this);"/> - <checkbox id="matchCase" label="&matchCase.label;" oncommand="checkboxUpdated(this);"/> - <hbox align="baseline"> - <checkbox id="domainRestrictionEnabled" label="&domainRestriction.label;" oncommand="checkboxUpdated(this);"/> - <description class="help" value="?" tooltip="domainRestrictionHelp"/> - </hbox> - <textbox id="domainRestriction" oninput="updateFilter()"/> - - <label id="typeGroupLabel" value="&types.label;"/> - <hbox> - <label id="selectAllTypes" class="text-link" value="&selectAllTypes.label;" onclick="selectAllTypes(true)"/> - <spacer flex="1"/> - <label id="unselectAllTypes" class="text-link" value="&unselectAllTypes.label;" onclick="selectAllTypes(false)"/> - </hbox> - <vbox flex="1" id="typeGroup"/> - - <vbox> - <label control="collapse" value="&collapse.label;"/> - <menulist id="collapse" oncommand="updateFilter()"> - <menupopup> - <menuitem id="collapseDefault" value="" label_yes="&collapse.default.yes.label;" label_no="&collapse.default.no.label;" selected="true"/> - <menuitem label="&collapse.yes.label;" value="collapse"/> - <menuitem label="&collapse.no.label;" value="~collapse"/> - </menupopup> - </menulist> - </vbox> - </groupbox> - </hbox> -</dialog> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/common.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/common.js deleted file mode 100644 index 296c00f..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/common.js +++ /dev/null @@ -1,124 +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(global) -{ - const Cu = Components.utils; - - let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); - - if (!global.ext) - global.ext = {}; - - var wrapperSymbol = Symbol("ext-wrapper"); - - function wrapFrames(frames) - { - if (!frames.length) - return null; - - // We have frames as an array, non-Firefox code expects url and parent - // properties however. - Object.defineProperty(frames, "url", { - enumerable: true, - get: () => new URL(frames[0].location) - }); - - Object.defineProperty(frames, "parent", { - enumerable: true, - get: () => wrapFrames(frames.slice(1)) - }); - - return frames; - } - - var EventTarget = global.ext._EventTarget = function(port, windowID) - { - this._port = port; - this._windowID = windowID; - this.addListener((payload, sender, resolve) => - { - if (payload.type) - { - let result = this._port._dispatch(payload.type, payload, sender); - if (typeof result != "undefined") - resolve(result); - } - }); - }; - EventTarget.prototype = { - addListener: function(listener) - { - var wrapper = (message, sender) => - { - if (this._windowID && this._windowID != message.targetID) - return undefined; - - return new Promise((resolve, reject) => - { - var sender = {}; - if (message.senderID) - { - // We will only get here on the background side so we can access - // the Page object. - const Page = require("ext_background").Page; - sender.page = new Page(message.senderID); - } - if (message.frames) - sender.frame = wrapFrames(message.frames); - if (!listener(message.payload, sender, resolve)) - resolve(undefined); - }); - }; - listener[wrapperSymbol] = wrapper; - this._port.on("ext_message", wrapper); - }, - - removeListener: function(listener) - { - if (listener[wrapperSymbol]) - this._port.off("ext_message", listener[wrapperSymbol]); - } - }; - - let pageName = "global"; - if (typeof location !== "undefined") - pageName = location.pathname.replace(/.*\//, "").replace(/\..*?$/, ""); - - let stringBundle = Services.strings.createBundle( - "chrome://adblockplus/locale/" + pageName + ".properties?" + Math.random()); - - global.ext.i18n = { - getMessage(key, args) - { - try { - return stringBundle.GetStringFromName(key); - } - catch(e) - { - // Don't report errors for special strings, these are expected to be - // missing. - if (key[0] != "@") - Cu.reportError(e); - return ""; - } - } - }; - - if (typeof exports == "object") - exports = global.ext; -})(this); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/content.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/content.js deleted file mode 100644 index 366325a..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/content.js +++ /dev/null @@ -1,82 +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(global) -{ - const Cc = Components.classes; - const Ci = Components.interfaces; - const Cu = Components.utils; - - var Services = Cu.import("resource://gre/modules/Services.jsm", {}).Services; - - function require(/**String*/ module) - { - var result = {}; - result.wrappedJSObject = result; - Services.obs.notifyObservers(result, "adblockplus-require", module); - return result.exports; - } - - function getOuterWindowID() - { - if (!getOuterWindowID.result) - { - getOuterWindowID.result = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindowUtils) - .outerWindowID; - } - return getOuterWindowID.result; - } - - const Port = require("messaging").Port; - - if (!global.ext) - global.ext = {}; - - /* Message passing */ - var port = new Port(Cc["@mozilla.org/childprocessmessagemanager;1"] - .getService(Ci.nsIMessageSender)); - window.addEventListener("unload", function() - { - try - { - port.emit("ext_disconnect", getOuterWindowID()); - } - catch (e) - { - // This is expected to fail if Adblock Plus was disabled/uninstalled with - // the page still open. - } - port.disconnect(); - }, false); - - global.ext.onMessage = new global.ext._EventTarget(port, getOuterWindowID()); - global.ext.backgroundPage = { - sendMessage: function(payload, responseCallback) - { - var message = { - senderID: getOuterWindowID(), - payload - }; - if (typeof responseCallback == "function") - port.emitWithResponse("ext_message", message).then(responseCallback); - else - port.emit("ext_message", message); - } - }; - -})(this); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/fennecSettings.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/fennecSettings.xul deleted file mode 100644 index 6e7675f..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/fennecSettings.xul +++ /dev/null @@ -1,36 +0,0 @@ -<?xml version="1.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/>. - --> - -<!DOCTYPE vbox [ -<!ENTITY % overlayDTD SYSTEM "chrome://adblockplus/locale/overlay.dtd"> -%overlayDTD; -<!ENTITY % filtersDTD SYSTEM "chrome://adblockplus/locale/filters.dtd"> -%filtersDTD; -]> - -<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <setting pref="extensions.adblockplus.enabled" type="bool" inverted="true" title="&disable.label;"/> - <setting type="control" title="&subscriptions.tab.label;"> - <menulist id="adblockplus-subscription-list"/> - </setting> - <setting id="adblockplus-acceptableAds" type="bool" title="&acceptableAds2.label;" - oncommand="/**See bug 762015*/ if (event.type == 'oncommand') {event = document.createEvent('Events'); event.initEvent('command', false, false); this.dispatchEvent(event);}"/> - <setting id="adblockplus-sync" type="bool" title="&sync.label;" - oncommand="/**See bug 762015*/ if (event.type == 'oncommand') {event = document.createEvent('Events'); event.initEvent('command', false, false); this.dispatchEvent(event);}"/> -</vbox> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-backup.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-backup.js deleted file mode 100644 index b3f8b94..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-backup.js +++ /dev/null @@ -1,367 +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/Services.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); - -/** - * Implementation of backup and restore functionality. - * @class - */ -var Backup = -{ - /** - * Template for menu items to be displayed in the Restore menu (for automated - * backups). - * @type Element - */ - restoreTemplate: null, - - /** - * Element after which restore items should be inserted. - * @type Element - */ - restoreInsertionPoint: null, - - /** - * Regular expression to recognize checksum comments. - */ - CHECKSUM_REGEXP: /^!\s*checksum[\s\-:]+([\w\+\/]+)/i, - - /** - * Regular expression to recognize group title comments. - */ - GROUPTITLE_REGEXP: /^!\s*\[(.*)\]((?:\/\w+)*)\s*$/, - - - /** - * Initializes backup UI. - */ - init: function() - { - this.restoreTemplate = E("restoreBackupTemplate"); - this.restoreInsertionPoint = this.restoreTemplate.previousSibling; - this.restoreTemplate.parentNode.removeChild(this.restoreTemplate); - this.restoreTemplate.removeAttribute("id"); - this.restoreTemplate.removeAttribute("hidden"); - }, - - /** - * Gets the default download dir, as used by the browser itself. - */ - getDefaultDir: function() /**nsIFile*/ - { - try - { - return Utils.prefService.getComplexValue("browser.download.lastDir", Ci.nsILocalFile); - } - catch (e) - { - // No default download location. Default to desktop. - return FileUtils.getDir("Desk", [], false); - } - }, - - /** - * Saves new default download dir after the user chose a different directory to - * save his files to. - */ - saveDefaultDir: function(/**nsIFile*/ dir) - { - try - { - Utils.prefService.setComplexValue("browser.download.lastDir", Ci.nsILocalFile, dir); - } catch(e) {}; - }, - - /** - * Called when the Restore menu is being opened, fills in "Automated backup" - * entries. - */ - fillRestorePopup: function() - { - while (this.restoreInsertionPoint.nextSibling && !this.restoreInsertionPoint.nextSibling.id) - this.restoreInsertionPoint.parentNode.removeChild(this.restoreInsertionPoint.nextSibling); - - FilterStorage.getBackupFiles().then(backups => - { - backups.reverse(); - for (let backup of backups) - { - let item = this.restoreTemplate.cloneNode(true); - let label = item.getAttribute("label"); - label = label.replace(/\?1\?/, Utils.formatTime(backup.lastModified)); - item.setAttribute("label", label); - item.addEventListener("command", function() - { - FilterStorage.restoreBackup(backup.index); - }, false); - this.restoreInsertionPoint.parentNode.insertBefore(item, this.restoreInsertionPoint.nextSibling); - } - }); - }, - - /** - * Lets the user choose a file to restore filters from. - */ - restoreFromFile: function() - { - let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - picker.init(window, E("backupButton").getAttribute("_restoreDialogTitle"), picker.modeOpen); - picker.defaultExtension = ".ini"; - picker.appendFilter(E("backupButton").getAttribute("_fileFilterComplete"), "*.ini"); - picker.appendFilter(E("backupButton").getAttribute("_fileFilterCustom"), "*.txt"); - - if (picker.show() != picker.returnCancel) - { - this.saveDefaultDir(picker.file.parent); - if (picker.filterIndex == 0) - this.restoreAllData(picker.file); - else - this.restoreCustomFilters(picker.file); - } - }, - - /** - * Restores patterns.ini from a file. - */ - restoreAllData: function(/**nsIFile*/ file) - { - let sink = FilterStorage.importData(); - let lines = []; - IO.readFromFile(file, { - process(line) - { - if (line === null) - { - let match; - if (lines.length < 2 || lines[0] != "# Adblock Plus preferences" || !(match = /version=(\d+)/.exec(lines[1]))) - { - Utils.alert(window, E("backupButton").getAttribute("_restoreError"), E("backupButton").getAttribute("_restoreDialogTitle")); - return; - } - - let warning = E("backupButton").getAttribute("_restoreCompleteWarning"); - let minVersion = parseInt(match[1], 10); - if (minVersion > FilterStorage.formatVersion) - warning += "\n\n" + E("backupButton").getAttribute("_restoreVersionWarning"); - - if (!Utils.confirm(window, warning, E("backupButton").getAttribute("_restoreDialogTitle"))) - return; - } - else if (lines.length < 2) - lines.push(line); - - sink(line); - } - }, error => - { - if (error) - alert(error); - else - FilterStorage.saveToDisk(); - }); - }, - - /** - * Restores custom filters from a file. - */ - restoreCustomFilters: function(/**nsIFile*/ file) - { - IO.readFromFile(file, { - seenHeader: false, - subscription: null, - process: function(line) - { - if (!this.seenHeader) - { - // This should be a header - this.seenHeader = true; - let match = /\[Adblock(?:\s*Plus\s*([\d\.]+)?)?\]/i.exec(line); - if (match) - { - let warning = E("backupButton").getAttribute("_restoreCustomWarning"); - let minVersion = match[1]; - if (minVersion && Utils.versionComparator.compare(minVersion, Utils.addonVersion) > 0) - warning += "\n\n" + E("backupButton").getAttribute("_restoreVersionWarning"); - - if (Utils.confirm(window, warning, E("backupButton").getAttribute("_restoreDialogTitle"))) - { - let subscriptions = FilterStorage.subscriptions.filter(s => s instanceof SpecialSubscription); - for (let i = 0; i < subscriptions.length; i++) - FilterStorage.removeSubscription(subscriptions[i]); - - return; - } - else - throw Cr.NS_BASE_STREAM_WOULD_BLOCK; - } - else - throw new Error("Invalid file"); - } - else if (line === null) - { - // End of file - if (this.subscription) - FilterStorage.addSubscription(this.subscription); - E("tabs").selectedIndex = 1; - } - else if (Backup.CHECKSUM_REGEXP.test(line)) - { - // Ignore checksums - } - else if (Backup.GROUPTITLE_REGEXP.test(line)) - { - // New group start - if (this.subscription) - FilterStorage.addSubscription(this.subscription); - - let [, title, options] = Backup.GROUPTITLE_REGEXP.exec(line); - this.subscription = SpecialSubscription.create(title); - - let defaults = []; - if (options) - options = options.split("/"); - for (let j = 0; j < options.length; j++) - if (options[j] in SpecialSubscription.defaultsMap) - defaults.push(options[j]); - if (defaults.length) - this.subscription.defaults = defaults; - } - else - { - // Regular filter - line = Filter.normalize(line); - if (line) - { - if (!this.subscription) - this.subscription = SpecialSubscription.create(Utils.getString("newGroup_title")); - this.subscription.filters.push(Filter.fromText(line)); - } - } - } - }, function(e) - { - if (e && e.result != Cr.NS_BASE_STREAM_WOULD_BLOCK) - { - Cu.reportError(e); - Utils.alert(window, E("backupButton").getAttribute("_restoreError"), E("backupButton").getAttribute("_restoreDialogTitle")); - } - }); - }, - - /** - * Lets the user choose a file to backup filters to. - */ - backupToFile: function() - { - let picker = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); - picker.init(window, E("backupButton").getAttribute("_backupDialogTitle"), picker.modeSave); - picker.defaultExtension = ".ini"; - picker.appendFilter(E("backupButton").getAttribute("_fileFilterComplete"), "*.ini"); - picker.appendFilter(E("backupButton").getAttribute("_fileFilterCustom"), "*.txt"); - - if (picker.show() != picker.returnCancel) - { - this.saveDefaultDir(picker.file.parent); - if (picker.filterIndex == 0) - this.backupAllData(picker.file); - else - this.backupCustomFilters(picker.file); - } - }, - - /** - * Writes all patterns.ini data to a file. - */ - backupAllData: function(/**nsIFile*/ file) - { - IO.writeToFile(file, FilterStorage.exportData(), error => - { - if (error) - alert(error); - }); - }, - - /** - * Writes user's custom filters to a file. - */ - backupCustomFilters: function(/**nsIFile*/ file) - { - let subscriptions = FilterStorage.subscriptions.filter(s => s instanceof SpecialSubscription); - let minVersion = "2.0" - let list = []; - for (let i = 0; i < subscriptions.length; i++) - { - let subscription = subscriptions[i]; - let typeAddition = ""; - if (subscription.defaults) - typeAddition = "/" + subscription.defaults.join("/"); - list.push("! [" + getSubscriptionTitle(subscription) + "]" + typeAddition); - for (let j = 0; j < subscription.filters.length; j++) - { - let filter = subscription.filters[j]; - // Skip checksums - if (filter instanceof CommentFilter && this.CHECKSUM_REGEXP.test(filter.text)) - continue; - // Skip group headers - if (filter instanceof CommentFilter && this.GROUPTITLE_REGEXP.test(filter.text)) - continue; - list.push(filter.text); - - if (filter instanceof ElemHideException && Services.vc.compare(minVersion, "2.1") < 0) - minVersion = "2.1"; - - if (filter instanceof RegExpFilter && filter.contentType & (RegExpFilter.typeMap.GENERICHIDE | RegExpFilter.typeMap.GENERICBLOCK) && Services.vc.compare(minVersion, "2.6.12") < 0) - minVersion = "2.6.12"; - - if (filter instanceof ElemHideEmulationFilter && Services.vc.compare(minVersion, "2.7.3") < 0) - minVersion = "2.7.3"; - - if (filter instanceof RegExpFilter && - (filter.contentType & RegExpFilter.typeMap.WEBSOCKET) && - Services.vc.compare(minVersion, "2.8")) - { - minVersion = "2.8"; - } - } - } - list.unshift("[Adblock Plus " + minVersion + "]"); - - // Insert checksum. Have to add an empty line to the end of the list to - // account for the trailing newline in the file. - list.push(""); - let checksum = Utils.generateChecksum(list); - list.pop(); - if (checksum) - list.splice(1, 0, "! Checksum: " + checksum); - - IO.writeToFile(file, list, function(e) - { - if (e) - { - Cu.reportError(e); - Utils.alert(window, E("backupButton").getAttribute("_backupError"), E("backupButton").getAttribute("_backupDialogTitle")); - } - }); - } -}; - -window.addEventListener("load", function() -{ - Backup.init(); -}, false); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filteractions.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filteractions.js deleted file mode 100644 index ad128b8..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filteractions.js +++ /dev/null @@ -1,564 +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/>. - */ - -/** - * Implementation of the various actions performed on the filters. - * @class - */ -var FilterActions = -{ - /** - * Initializes filter actions. - */ - init: function() - { - this.treeElement.parentNode.addEventListener("keydown", this.keyDown.bind(this), true); - this.treeElement.view = FilterView; - - // Work around https://bugzilla.mozilla.org/show_bug.cgi?id=777832, don't - // allow the tree to receive keypress/keydown events triggered by cursor - // keys pressed in the editor, it will call preventDefault() on them. - let propagationStopper = function(event) - { - if (event.keyCode >= event.DOM_VK_PAGE_UP && event.keyCode <= event.DOM_VK_DOWN) - event.stopPropagation(); - }; - - this.treeElement.inputField.addEventListener("keypress", propagationStopper, false); - this.treeElement.inputField.addEventListener("keydown", propagationStopper, false); - - // Create a copy of the view menu - function fixId(node, newId) - { - if (node.nodeType == node.ELEMENT_NODE) - { - if (node.hasAttribute("id")) - node.setAttribute("id", node.getAttribute("id").replace(/\d+$/, newId)); - - for (let i = 0, len = node.childNodes.length; i < len; i++) - fixId(node.childNodes[i], newId); - } - return node; - } - E("viewMenu").appendChild(fixId(E("filters-view-menu1").cloneNode(true), "2")); - }, - - /** - * <tree> element containing the filters. - * @type XULElement - */ - get treeElement() E("filtersTree"), - - /** - * Tests whether the tree is currently visible. - */ - get visible() - { - return !this.treeElement.parentNode.collapsed; - }, - - /** - * Tests whether the tree is currently focused. - * @type Boolean - */ - get focused() - { - let focused = document.commandDispatcher.focusedElement; - while (focused) - { - if ("treeBoxObject" in focused && focused.treeBoxObject == FilterView.boxObject) - return true; - focused = focused.parentNode; - } - return false; - }, - - /** - * Updates visible filter commands whenever the selected subscription changes. - */ - updateCommands: function() - { - E("filters-add-command").setAttribute("disabled", !FilterView.editable); - }, - - /** - * Called whenever filter actions menu is opened, initializes menu items. - */ - fillActionsPopup: function() - { - let editable = FilterView.editable; - let items = FilterView.selectedItems.filter(i => !i.filter.dummy); - items.sort((entry1, entry2) => entry1.index - entry2.index); - let activeItems = items.filter(i => i.filter instanceof ActiveFilter); - - E("filters-edit-command").setAttribute("disabled", !editable || !items.length); - E("filters-delete-command").setAttribute("disabled", !editable || !items.length); - E("filters-resetHitCounts-command").setAttribute("disabled", !activeItems.length); - E("filters-moveUp-command").setAttribute("disabled", !editable || FilterView.isSorted() || !items.length || items[0].index == 0); - E("filters-moveDown-command").setAttribute("disabled", !editable || FilterView.isSorted() || !items.length || items[items.length - 1].index == FilterView.rowCount - 1); - E("filters-copy-command").setAttribute("disabled", !items.length); - E("filters-cut-command").setAttribute("disabled", !editable || !items.length); - E("filters-paste-command").setAttribute("disabled", !editable || !Utils.clipboard.hasDataMatchingFlavors(["text/unicode"], 1, Utils.clipboard.kGlobalClipboard)); - }, - - /** - * Changes sort current order for the tree. Sorts by filter column if the list is unsorted. - * @param {String} order either "ascending" or "descending" - */ - setSortOrder: function(sortOrder) - { - let col = (FilterView.sortColumn ? FilterView.sortColumn.id : "col-filter"); - FilterView.sortBy(col, sortOrder); - }, - - /** - * Toggles the visibility of a tree column. - */ - toggleColumn: function(/**String*/ id) - { - let col = E(id); - col.setAttribute("hidden", col.hidden ? "false" : "true"); - }, - - /** - * Enables or disables all filters in the current selection. - */ - selectionToggleDisabled: function() - { - if (this.treeElement.editingColumn) - return; - - let items = FilterView.selectedItems.filter(i => i.filter instanceof ActiveFilter); - if (items.length) - { - FilterView.boxObject.beginUpdateBatch(); - let newValue = !items[0].filter.disabled; - for (let i = 0; i < items.length; i++) - items[i].filter.disabled = newValue; - FilterView.boxObject.endUpdateBatch(); - } - }, - - /** - * Selects all entries in the list. - */ - selectAll: function() - { - if (this.treeElement.editingColumn) - return; - - FilterView.selection.selectAll(); - this.treeElement.focus(); - }, - - /** - * Starts editing the current filter. - */ - startEditing: function() - { - if (this.treeElement.editingColumn) - return; - - this.treeElement.startEditing(FilterView.selection.currentIndex, FilterView.boxObject.columns.getNamedColumn("col-filter")); - }, - - /** - * Starts editing a new filter at the current position. - */ - insertFilter: function() - { - if (!FilterView.editable || this.treeElement.editingColumn) - return; - - FilterView.insertEditDummy(); - this.startEditing(); - - let tree = this.treeElement; - let listener = function(event) - { - if (event.attrName == "editing" && tree.editingRow < 0) - { - tree.removeEventListener("DOMAttrModified", listener, false); - FilterView.removeEditDummy(); - } - } - tree.addEventListener("DOMAttrModified", listener, false); - }, - - /** - * Deletes items from the list. - */ - deleteItems: function(/**Array*/ items) - { - let oldIndex = FilterView.selection.currentIndex; - items.sort((entry1, entry2) => entry2.index - entry1.index); - - for (let i = 0; i < items.length; i++) - FilterStorage.removeFilter(items[i].filter, FilterView._subscription, items[i].index); - - FilterView.selectRow(oldIndex); - }, - - /** - * Deletes selected filters. - */ - deleteSelected: function() - { - if (!FilterView.editable || this.treeElement.editingColumn) - return; - - let items = FilterView.selectedItems; - if (items.length == 0 || (items.length >= 2 && !Utils.confirm(window, this.treeElement.getAttribute("_removewarning")))) - return; - - this.deleteItems(items) - }, - - /** - * Resets hit counts of the selected filters. - */ - resetHitCounts: function() - { - if (this.treeElement.editingColumn) - return; - - let items = FilterView.selectedItems.filter(i => i.filter instanceof ActiveFilter); - if (items.length) - FilterStorage.resetHitCounts(items.map(i => i.filter)); - }, - - /** - * Moves items to a different position in the list. - * @param {Array} items - * @param {Integer} offset negative offsets move the items up, positive down - */ - _moveItems: function(/**Array*/ items, /**Integer*/ offset) - { - if (!items.length) - return; - - if (offset < 0) - { - items.sort((entry1, entry2) => entry1.index - entry2.index); - let position = items[0].index + offset; - if (position < 0) - return; - - for (let i = 0; i < items.length; i++) - FilterStorage.moveFilter(items[i].filter, FilterView._subscription, items[i].index, position++); - FilterView.selection.rangedSelect(position - items.length, position - 1, false); - } - else if (offset > 0) - { - items.sort((entry1, entry2) => entry2.index - entry1.index); - let position = items[0].index + offset; - if (position >= FilterView.rowCount) - return; - - for (let i = 0; i < items.length; i++) - FilterStorage.moveFilter(items[i].filter, FilterView._subscription, items[i].index, position--); - FilterView.selection.rangedSelect(position + 1, position + items.length, false); - } - }, - - /** - * Moves selected filters one line up. - */ - moveUp: function() - { - if (!FilterView.editable || FilterView.isEmpty || FilterView.isSorted() || this.treeElement.editingColumn) - return; - - this._moveItems(FilterView.selectedItems, -1); - }, - - /** - * Moves selected filters one line down. - */ - moveDown: function() - { - if (!FilterView.editable || FilterView.isEmpty || FilterView.isSorted() || this.treeElement.editingColumn) - return; - - this._moveItems(FilterView.selectedItems, 1); - }, - - /** - * Fills the context menu of the filters columns. - */ - fillColumnPopup: function(/**Element*/ element) - { - let suffix = element.id.match(/\d+$/)[0] || "1"; - - E("filters-view-filter" + suffix).setAttribute("checked", !E("col-filter").hidden); - E("filters-view-slow" + suffix).setAttribute("checked", !E("col-slow").hidden); - E("filters-view-enabled" + suffix).setAttribute("checked", !E("col-enabled").hidden); - E("filters-view-hitcount" + suffix).setAttribute("checked", !E("col-hitcount").hidden); - E("filters-view-lasthit" + suffix).setAttribute("checked", !E("col-lasthit").hidden); - - let sortColumn = FilterView.sortColumn; - let sortColumnID = (sortColumn ? sortColumn.id : null); - let sortDir = (sortColumn ? sortColumn.getAttribute("sortDirection") : "natural"); - E("filters-sort-none" + suffix).setAttribute("checked", sortColumn == null); - E("filters-sort-filter" + suffix).setAttribute("checked", sortColumnID == "col-filter"); - E("filters-sort-enabled" + suffix).setAttribute("checked", sortColumnID == "col-enabled"); - E("filters-sort-hitcount" + suffix).setAttribute("checked", sortColumnID == "col-hitcount"); - E("filters-sort-lasthit" + suffix).setAttribute("checked", sortColumnID == "col-lasthit"); - E("filters-sort-asc" + suffix).setAttribute("checked", sortDir == "ascending"); - E("filters-sort-desc" + suffix).setAttribute("checked", sortDir == "descending"); - }, - - /** - * Fills tooltip with the item data. - */ - fillTooltip: function(event) - { - let item = FilterView.getItemAt(event.clientX, event.clientY); - if (!item || item.filter.dummy) - { - event.preventDefault(); - return; - } - - function setMultilineContent(box, text) - { - while (box.firstChild) - box.removeChild(box.firstChild); - - let lines = text.match(/.{1,80}/g); - if (lines.length > 7) - { - // Text is too long to display in full so we cut out the middle part - lines = lines.slice(0,3).concat("\u2026", lines.slice(-3)); - } - - for (let line of lines) - { - let description = document.createElement("description"); - description.setAttribute("value", line); - box.appendChild(description); - } - } - - setMultilineContent(E("tooltip-filter"), item.filter.text); - - E("tooltip-hitcount-row").hidden = !(item.filter instanceof ActiveFilter); - E("tooltip-lasthit-row").hidden = !(item.filter instanceof ActiveFilter) || !item.filter.lastHit; - if (item.filter instanceof ActiveFilter) - { - E("tooltip-hitcount").setAttribute("value", item.filter.hitCount) - E("tooltip-lasthit").setAttribute("value", Utils.formatTime(item.filter.lastHit)) - } - - E("tooltip-additional").hidden = false; - if (item.filter instanceof InvalidFilter && item.filter.reason) - E("tooltip-additional").textContent = Utils.getString(item.filter.reason); - else if (item.filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(item.filter)) - E("tooltip-additional").textContent = Utils.getString("filter_regexp_tooltip"); - else - E("tooltip-additional").hidden = true; - }, - - /** - * Called whenever a key is pressed on the list. - */ - keyDown: function(/**Event*/ event) - { - if (event.target != E("filtersTree")) - return; - - let modifiers = 0; - if (event.altKey) - modifiers |= SubscriptionActions._altMask; - if (event.ctrlKey) - modifiers |= SubscriptionActions._ctrlMask; - if (event.metaKey) - modifiers |= SubscriptionActions._metaMask; - - if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_SPACE && modifiers == 0 && !E("col-enabled").hidden) - this.selectionToggleDisabled(); - else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_UP && modifiers == SubscriptionActions._accelMask) - { - E("filters-moveUp-command").doCommand(); - event.preventDefault(); - event.stopPropagation(); - } - else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_DOWN && modifiers == SubscriptionActions._accelMask) - { - E("filters-moveDown-command").doCommand(); - event.preventDefault(); - event.stopPropagation(); - } - }, - - /** - * Copies selected items to clipboard and optionally removes them from the - * list after that. - */ - copySelected: function(/**Boolean*/ keep) - { - let items = FilterView.selectedItems; - if (!items.length) - return; - - items.sort((entry1, entry2) => entry1.index - entry2.index); - let text = items.map(i => i.filter.text).join(IO.lineBreak); - Utils.clipboardHelper.copyString(text); - - if (!keep && FilterView.editable && !this.treeElement.editingColumn) - this.deleteItems(items); - }, - - /** - * Pastes text from clipboard as filters at the current position. - */ - paste: function() - { - if (!FilterView.editable || this.treeElement.editingColumn) - return; - - let transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); - transferable.addDataFlavor("text/unicode"); - - let data; - try - { - data = {}; - Utils.clipboard.getData(transferable, Utils.clipboard.kGlobalClipboard); - transferable.getTransferData("text/unicode", data, {}); - data = data.value.QueryInterface(Ci.nsISupportsString).data; - } - catch (e) { - return; - } - - let item = FilterView.currentItem; - let position = (item ? item.index : FilterView.data.length); - - let lines = data.replace(/\r/g, "").split("\n"); - for (let i = 0; i < lines.length; i++) - { - let line = Filter.normalize(lines[i]); - if (line) - { - let filter = Filter.fromText(line); - FilterStorage.addFilter(filter, FilterView._subscription, position++); - } - } - }, - - dragItems: null, - - /** - * Called whenever the user starts a drag operation. - */ - startDrag: function(/**Event*/ event) - { - let items = FilterView.selectedItems; - if (!items.length) - return; - - items.sort((entry1, entry2) => entry1.index - entry2.index); - event.dataTransfer.setData("text/plain", items.map(i => i.filter.text).join(IO.lineBreak)); - this.dragItems = items; - event.stopPropagation(); - }, - - /** - * Called to check whether moving the items to the given position is possible. - */ - canDrop: function(/**Integer*/ newPosition, /**nsIDOMDataTransfer*/ dataTransfer) - { - if (!FilterView.editable || this.treeElement.editingColumn) - return false; - - // If we aren't dragging items then maybe we got filters as plain text - if (!this.dragItems) - return dataTransfer && dataTransfer.getData("text/plain"); - - if (FilterView.isEmpty || FilterView.isSorted()) - return false; - - if (newPosition < this.dragItems[0].index) - return true; - else if (newPosition > this.dragItems[this.dragItems.length - 1].index + 1) - return true; - else - return false; - }, - - /** - * Called when the user decides to drop the items. - */ - drop: function(/**Integer*/ newPosition, /**nsIDOMDataTransfer*/ dataTransfer) - { - if (!FilterView.editable || this.treeElement.editingColumn) - return; - - if (!this.dragItems) - { - // We got filters as plain text, insert them into the list - let data = (dataTransfer ? dataTransfer.getData("text/plain") : null); - if (data) - { - let lines = data.replace(/\r/g, "").split("\n"); - for (let i = 0; i < lines.length; i++) - { - let line = Filter.normalize(lines[i]); - if (line) - { - let filter = Filter.fromText(line); - FilterStorage.addFilter(filter, FilterView._subscription, newPosition++); - } - } - } - return; - } - - if (FilterView.isEmpty || FilterView.isSorted()) - return; - - if (newPosition < this.dragItems[0].index) - this._moveItems(this.dragItems, newPosition - this.dragItems[0].index); - else if (newPosition > this.dragItems[this.dragItems.length - 1].index + 1) - this._moveItems(this.dragItems, newPosition - this.dragItems[this.dragItems.length - 1].index - 1); - }, - - /** - * Called whenever the a drag operation finishes. - */ - endDrag: function(/**Event*/ event) - { - this.dragItems = null; - }, - - /** - * Called if filters have been dragged into a subscription and need to be removed. - */ - removeDraggedFilters: function() - { - if (!this.dragItems) - return; - - this.deleteItems(this.dragItems); - } -}; - -window.addEventListener("load", function() -{ - FilterActions.init(); -}, false); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filterview.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filterview.js deleted file mode 100644 index b1d701d..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filterview.js +++ /dev/null @@ -1,851 +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"); - -/** - * nsITreeView implementation to display filters of a particular filter - * subscription. - * @class - */ -var FilterView = -{ - /** - * Initialization function. - */ - init: function() - { - // "Manually" remove access key for col-slow tooltip, Utils.splitAllLabels() - // won't do it. - let slowColumn = document.getElementById("col-slow"); - if (slowColumn) - { - for (let attr of ["display", "tooltiptext"]) - { - let value = slowColumn.getAttribute(attr); - if (!value) - continue; - let [label, accessKey] = Utils.splitLabel(value); - if (label != value) - slowColumn.setAttribute(attr, label); - } - } - - if (this.sortProcs) - return; - - function compareText(/**Filter*/ filter1, /**Filter*/ filter2) - { - if (filter1.text < filter2.text) - return -1; - else if (filter1.text > filter2.text) - return 1; - else - return 0; - } - function compareSlow(/**Filter*/ filter1, /**Filter*/ filter2) - { - let isSlow1 = filter1 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter1); - let isSlow2 = filter2 instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter2); - return isSlow1 - isSlow2; - } - function compareEnabled(/**Filter*/ filter1, /**Filter*/ filter2) - { - let hasEnabled1 = (filter1 instanceof ActiveFilter ? 1 : 0); - let hasEnabled2 = (filter2 instanceof ActiveFilter ? 1 : 0); - if (hasEnabled1 != hasEnabled2) - return hasEnabled1 - hasEnabled2; - else if (hasEnabled1) - return (filter2.disabled - filter1.disabled); - else - return 0; - } - function compareHitCount(/**Filter*/ filter1, /**Filter*/ filter2) - { - let hasHitCount1 = (filter1 instanceof ActiveFilter ? 1 : 0); - let hasHitCount2 = (filter2 instanceof ActiveFilter ? 1 : 0); - if (hasHitCount1 != hasHitCount2) - return hasHitCount1 - hasHitCount2; - else if (hasHitCount1) - return filter1.hitCount - filter2.hitCount; - else - return 0; - } - function compareLastHit(/**Filter*/ filter1, /**Filter*/ filter2) - { - let hasLastHit1 = (filter1 instanceof ActiveFilter ? 1 : 0); - let hasLastHit2 = (filter2 instanceof ActiveFilter ? 1 : 0); - if (hasLastHit1 != hasLastHit2) - return hasLastHit1 - hasLastHit2; - else if (hasLastHit1) - return filter1.lastHit - filter2.lastHit; - else - return 0; - } - - /** - * Creates a sort function from a primary and a secondary comparison function. - * @param {Function} cmpFunc comparison function to be called first - * @param {Function} fallbackFunc (optional) comparison function to be called if primary function returns 0 - * @param {Boolean} desc if true, the result of the primary function (not the secondary function) will be reversed - sorting in descending order - * @result {Function} comparison function to be used - */ - function createSortFunction(cmpFunc, fallbackFunc, desc) - { - let factor = (desc ? -1 : 1); - - return function(entry1, entry2) - { - // Comment replacements not bound to a filter always go last - let isLast1 = ("origFilter" in entry1 && entry1.filter == null); - let isLast2 = ("origFilter" in entry2 && entry2.filter == null); - if (isLast1) - return (isLast2 ? 0 : 1) - else if (isLast2) - return -1; - - let ret = cmpFunc(entry1.filter, entry2.filter); - if (ret == 0 && fallbackFunc) - return fallbackFunc(entry1.filter, entry2.filter); - else - return factor * ret; - } - } - - this.sortProcs = { - filter: createSortFunction(compareText, null, false), - filterDesc: createSortFunction(compareText, null, true), - slow: createSortFunction(compareSlow, compareText, true), - slowDesc: createSortFunction(compareSlow, compareText, false), - enabled: createSortFunction(compareEnabled, compareText, false), - enabledDesc: createSortFunction(compareEnabled, compareText, true), - hitcount: createSortFunction(compareHitCount, compareText, false), - hitcountDesc: createSortFunction(compareHitCount, compareText, true), - lasthit: createSortFunction(compareLastHit, compareText, false), - lasthitDesc: createSortFunction(compareLastHit, compareText, true) - }; - - let me = this; - let proxy = function() - { - return me._onChange.apply(me, arguments); - }; - FilterNotifier.addListener(proxy); - window.addEventListener("unload", function() - { - FilterNotifier.removeListener(proxy); - }, false); - }, - - /** - * Filter change processing. - * @see FilterNotifier.addListener() - */ - _onChange: function(action, item, param1, param2, param3) - { - switch (action) - { - case "subscription.updated": - { - if (item == this._subscription) - this.refresh(true); - break; - } - case "filter.disabled": - case "filter.hitCount": - case "filter.lastHit": - { - this.updateFilter(item); - break; - } - case "filter.added": - { - let subscription = param1; - let position = param2; - if (subscription == this._subscription) - this.addFilterAt(position, item); - break; - } - case "filter.removed": - { - let subscription = param1; - let position = param2; - if (subscription == this._subscription) - this.removeFilterAt(position); - break; - } - case "filter.moved": - { - let subscription = param1; - let oldPosition = param2; - let newPosition = param3; - if (subscription == this._subscription) - this.moveFilterAt(oldPosition, newPosition); - break; - } - } - }, - - /** - * Box object of the tree that this view is attached to. - * @type nsITreeBoxObject - */ - boxObject: null, - - /** - * Map of used cell properties to the corresponding nsIAtom representations. - */ - atoms: null, - - /** - * "Filter" to be displayed if no filter group is selected. - */ - noGroupDummy: null, - - /** - * "Filter" to be displayed if the selected group is empty. - */ - noFiltersDummy: null, - - /** - * "Filter" to be displayed for a new filter being edited. - */ - editDummy: null, - - /** - * Displayed list of filters, might be sorted. - * @type Filter[] - */ - data: [], - - /** - * <tree> element that the view is attached to. - * @type XULElement - */ - get treeElement() this.boxObject ? this.boxObject.treeBody.parentNode : null, - - /** - * Checks whether the list is currently empty (regardless of dummy entries). - * @type Boolean - */ - get isEmpty() - { - return !this._subscription || !this._subscription.filters.length; - }, - - /** - * Checks whether the filters in the view can be changed. - * @type Boolean - */ - get editable() - { - return (FilterView._subscription instanceof SpecialSubscription); - }, - - /** - * Returns current item of the list. - * @type Object - */ - get currentItem() - { - let index = this.selection.currentIndex; - if (index >= 0 && index < this.data.length) - return this.data[index]; - return null; - }, - - /** - * Returns items that are currently selected in the list. - * @type Object[] - */ - get selectedItems() - { - let items = [] - for (let i = 0; i < this.selection.getRangeCount(); i++) - { - let min = {}; - let max = {}; - this.selection.getRangeAt(i, min, max); - for (let j = min.value; j <= max.value; j++) - if (j >= 0 && j < this.data.length) - items.push(this.data[j]); - } - return items; - }, - - getItemAt: function(x, y) - { - let row = this.boxObject.getRowAt(x, y); - if (row >= 0 && row < this.data.length) - return this.data[row]; - else - return null; - }, - - _subscription: 0, - - /** - * Filter subscription being displayed. - * @type Subscription - */ - get subscription() this._subscription, - set subscription(value) - { - if (value == this._subscription) - return; - - // Make sure the editor is done before we update the list. - if (this.treeElement) - this.treeElement.stopEditing(true); - - this._subscription = value; - this.refresh(true); - }, - - /** - * Will be true if updates are outstanding because the list was hidden. - */ - _dirty: false, - - /** - * Updates internal view data after a change. - * @param {Boolean} force if false, a refresh will only happen if previous - * changes were suppressed because the list was hidden - */ - refresh: function(force) - { - if (FilterActions.visible) - { - if (!force && !this._dirty) - return; - this._dirty = false; - this.updateData(); - this.selectRow(0); - } - else - this._dirty = true; - }, - - /** - * Map of comparison functions by column ID or column ID + "Desc" for - * descending sort order. - * @const - */ - sortProcs: null, - - /** - * Column that the list is currently sorted on. - * @type Element - */ - sortColumn: null, - - /** - * Sorting function currently in use. - * @type Function - */ - sortProc: null, - - /** - * Resorts the list. - * @param {String} col ID of the column to sort on. If null, the natural order is restored. - * @param {String} direction "ascending" or "descending", if null the sort order is toggled. - */ - sortBy: function(col, direction) - { - let newSortColumn = null; - if (col) - { - newSortColumn = this.boxObject.columns.getNamedColumn(col).element; - if (!direction) - { - if (this.sortColumn == newSortColumn) - direction = (newSortColumn.getAttribute("sortDirection") == "ascending" ? "descending" : "ascending"); - else - direction = "ascending"; - } - } - - if (this.sortColumn && this.sortColumn != newSortColumn) - this.sortColumn.removeAttribute("sortDirection"); - - this.sortColumn = newSortColumn; - if (this.sortColumn) - { - this.sortColumn.setAttribute("sortDirection", direction); - this.sortProc = this.sortProcs[col.replace(/^col-/, "") + (direction == "descending" ? "Desc" : "")]; - } - else - this.sortProc = null; - - if (this.data.length > 1) - { - this.updateData(); - this.boxObject.invalidate(); - } - }, - - /** - * Inserts dummy entry into the list if necessary. - */ - addDummyRow: function() - { - if (this.boxObject && this.data.length == 0) - { - if (this._subscription) - this.data.splice(0, 0, this.noFiltersDummy); - else - this.data.splice(0, 0, this.noGroupDummy); - this.boxObject.rowCountChanged(0, 1); - } - }, - - /** - * Removes dummy entry from the list if present. - */ - removeDummyRow: function() - { - if (this.boxObject && this.isEmpty && this.data.length) - { - this.data.splice(0, 1); - this.boxObject.rowCountChanged(0, -1); - } - }, - - /** - * Inserts dummy row when a new filter is being edited. - */ - insertEditDummy: function() - { - FilterView.removeDummyRow(); - let position = this.selection.currentIndex; - if (position >= this.data.length) - position = this.data.length - 1; - if (position < 0) - position = 0; - - this.editDummy.index = (position < this.data.length ? this.data[position].index : this.data.length); - this.editDummy.position = position; - this.data.splice(position, 0, this.editDummy); - this.boxObject.rowCountChanged(position, 1); - this.selectRow(position); - }, - - /** - * Removes dummy row once the edit is finished. - */ - removeEditDummy: function() - { - let position = this.editDummy.position; - if (typeof position != "undefined" && position < this.data.length && this.data[position] == this.editDummy) - { - this.data.splice(position, 1); - this.boxObject.rowCountChanged(position, -1); - FilterView.addDummyRow(); - - this.selectRow(position); - } - }, - - /** - * Selects a row in the tree and makes sure it is visible. - * @param {number} row - * row index - * @param {boolean} [scrollToTop] - * if true, the selected row should become the top row of the list if - * possible, otherwise the list is only scrolled if the row isn't visible. - */ - selectRow: function(row, scrollToTop) - { - if (this.selection) - { - row = Math.min(Math.max(row, 0), this.data.length - 1); - this.selection.select(row); - if (scrollToTop) - this.boxObject.scrollToRow(row); - else - this.boxObject.ensureRowIsVisible(row); - } - }, - - /** - * Finds a particular filter in the list and selects it. - */ - selectFilter: function(/**Filter*/ filter) - { - let index = -1; - for (let i = 0; i < this.data.length; i++) - { - if (this.data[i].filter == filter) - { - index = i; - break; - } - } - if (index >= 0) - { - this.selectRow(index, true); - this.treeElement.focus(); - } - }, - - /** - * Updates value of data property on sorting or filter subscription changes. - */ - updateData: function() - { - let oldCount = this.rowCount; - if (this._subscription && this._subscription.filters.length) - { - this.data = this._subscription.filters.map((f, i) => ({index: i, filter: f})); - if (this.sortProc) - { - // Hide comments in the list, they should be sorted like the filter following them - let followingFilter = null; - for (let i = this.data.length - 1; i >= 0; i--) - { - if (this.data[i].filter instanceof CommentFilter) - { - this.data[i].origFilter = this.data[i].filter; - this.data[i].filter = followingFilter; - } - else - followingFilter = this.data[i].filter; - } - - this.data.sort(this.sortProc); - - // Restore comments - for (let i = 0; i < this.data.length; i++) - { - if ("origFilter" in this.data[i]) - { - this.data[i].filter = this.data[i].origFilter; - delete this.data[i].origFilter; - } - } - } - } - else - this.data = []; - - if (this.boxObject) - { - this.boxObject.rowCountChanged(0, -oldCount); - this.boxObject.rowCountChanged(0, this.rowCount); - } - - this.addDummyRow(); - }, - - /** - * Called to update the view when a filter property is changed. - */ - updateFilter: function(/**Filter*/ filter) - { - for (let i = 0; i < this.data.length; i++) - if (this.data[i].filter == filter) - this.boxObject.invalidateRow(i); - }, - - /** - * Called if a filter has been inserted at the specified position. - */ - addFilterAt: function(/**Integer*/ position, /**Filter*/ filter) - { - if (this.data.length == 1 && this.data[0].filter.dummy) - { - this.data.splice(0, 1); - this.boxObject.rowCountChanged(0, -1); - } - - if (this.sortProc) - { - this.updateData(); - for (let i = 0; i < this.data.length; i++) - { - if (this.data[i].index == position) - { - position = i; - break; - } - } - } - else - { - for (let i = 0; i < this.data.length; i++) - if (this.data[i].index >= position) - this.data[i].index++; - this.data.splice(position, 0, {index: position, filter: filter}); - } - this.boxObject.rowCountChanged(position, 1); - this.selectRow(position); - }, - - /** - * Called if a filter has been removed at the specified position. - */ - removeFilterAt: function(/**Integer*/ position) - { - for (let i = 0; i < this.data.length; i++) - { - if (this.data[i].index == position) - { - this.data.splice(i, 1); - this.boxObject.rowCountChanged(i, -1); - i--; - } - else if (this.data[i].index > position) - this.data[i].index--; - } - this.addDummyRow(); - }, - - /** - * Called if a filter has been moved within the list. - */ - moveFilterAt: function(/**Integer*/ oldPosition, /**Integer*/ newPosition) - { - let dir = (oldPosition < newPosition ? 1 : -1); - for (let i = 0; i < this.data.length; i++) - { - if (this.data[i].index == oldPosition) - this.data[i].index = newPosition; - else if (dir * this.data[i].index > dir * oldPosition && dir * this.data[i].index <= dir * newPosition) - this.data[i].index -= dir; - } - - if (!this.sortProc) - { - let item = this.data[oldPosition]; - this.data.splice(oldPosition, 1); - this.data.splice(newPosition, 0, item); - this.boxObject.invalidateRange(Math.min(oldPosition, newPosition), Math.max(oldPosition, newPosition)); - } - }, - - QueryInterface: XPCOMUtils.generateQI([Ci.nsITreeView]), - - setTree: function(boxObject) - { - if (!boxObject) - return; - - this.init(); - this.boxObject = boxObject; - - this.noGroupDummy = {index: 0, filter: {text: this.boxObject.treeBody.getAttribute("noGroupText"), dummy: true}}; - this.noFiltersDummy = {index: 0, filter: {text: this.boxObject.treeBody.getAttribute("noFiltersText"), dummy: true}}; - this.editDummy = {filter: {text: ""}}; - - let atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService); - let stringAtoms = ["col-filter", "col-enabled", "col-hitcount", "col-lasthit", "type-invalid", "type-comment", "type-blocking", "type-whitelist", "type-elemhide", "type-elemhideexception", "type-elemhideemulation"]; - let boolAtoms = ["selected", "dummy", "slow", "disabled"]; - - this.atoms = {}; - for (let atom of stringAtoms) - this.atoms[atom] = atomService.getAtom(atom); - for (let atom of boolAtoms) - { - this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true"); - this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false"); - } - - let columns = this.boxObject.columns; - for (let i = 0; i < columns.length; i++) - if (columns[i].element.hasAttribute("sortDirection")) - this.sortBy(columns[i].id, columns[i].element.getAttribute("sortDirection")); - - this.refresh(true); - - // Stop propagation of keypress events so that these aren't intercepted by - // the findbar. - this.treeElement.inputField.addEventListener("keypress", event => { - event.stopPropagation(); - }, false); - }, - - selection: null, - - get rowCount() this.data.length, - - getCellText: function(row, col) - { - if (row < 0 || row >= this.data.length) - return null; - - col = col.id; - if (col != "col-filter" && col != "col-slow" && col != "col-hitcount" && col != "col-lasthit") - return null; - - let filter = this.data[row].filter; - if (col == "col-filter") - return filter.text; - else if (col == "col-slow") - return (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter) ? "!" : null); - else if (filter instanceof ActiveFilter) - { - if (col == "col-hitcount") - return filter.hitCount; - else if (col == "col-lasthit") - return (filter.lastHit ? Utils.formatTime(filter.lastHit) : null); - } - - return null; - }, - - generateProperties: function(list, properties) - { - if (properties) - { - // Gecko 21 and below: we have an nsISupportsArray parameter, add atoms - // to that. - for (let i = 0; i < list.length; i++) - if (list[i] in this.atoms) - properties.AppendElement(this.atoms[list[i]]); - return null; - } - else - { - // Gecko 22+: no parameter, just return a string - return list.join(" "); - } - }, - - getColumnProperties: function(col, properties) - { - return this.generateProperties(["col-" + col.id], properties); - }, - - getRowProperties: function(row, properties) - { - if (row < 0 || row >= this.data.length) - return ""; - - let list = []; - let filter = this.data[row].filter; - list.push("selected-" + this.selection.isSelected(row)); - list.push("slow-" + (filter instanceof RegExpFilter && defaultMatcher.isSlowFilter(filter))); - if (filter instanceof ActiveFilter) - list.push("disabled-" + filter.disabled); - list.push("dummy-" + ("dummy" in filter)); - list.push("type-" + filter.type); - - return this.generateProperties(list, properties); - }, - - getCellProperties: function(row, col, properties) - { - return this.getRowProperties(row, properties) + " " + this.getColumnProperties(col, properties); - }, - - cycleHeader: function(col) - { - let oldDirection = col.element.getAttribute("sortDirection"); - if (oldDirection == "ascending") - this.sortBy(col.id, "descending"); - else if (oldDirection == "descending") - this.sortBy(null, null); - else - this.sortBy(col.id, "ascending"); - }, - - isSorted: function() - { - return (this.sortProc != null); - }, - - canDrop: function(row, orientation, dataTransfer) - { - if (orientation == Ci.nsITreeView.DROP_ON || row < 0 || row >= this.data.length || !this.editable) - return false; - - let item = this.data[row]; - let position = (orientation == Ci.nsITreeView.DROP_BEFORE ? item.index : item.index + 1); - return FilterActions.canDrop(position, dataTransfer); - }, - - drop: function(row, orientation, dataTransfer) - { - if (orientation == Ci.nsITreeView.DROP_ON || row < 0 || row >= this.data.length || !this.editable) - return; - - let item = this.data[row]; - let position = (orientation == Ci.nsITreeView.DROP_BEFORE ? item.index : item.index + 1); - FilterActions.drop(position, dataTransfer); - }, - - isEditable: function(row, col) - { - if (row < 0 || row >= this.data.length || !this.editable) - return false; - - let filter = this.data[row].filter; - if (col.id == "col-filter") - return !("dummy" in filter); - else - return false; - }, - - setCellText: function(row, col, value) - { - if (row < 0 || row >= this.data.length || col.id != "col-filter") - return; - - let oldFilter = this.data[row].filter; - let position = this.data[row].index; - value = Filter.normalize(value); - if (!value || value == oldFilter.text) - return; - - // Make sure we don't get called recursively (see https://adblockplus.org/forum/viewtopic.php?t=9003) - this.treeElement.stopEditing(); - - let newFilter = Filter.fromText(value); - if (this.data[row] == this.editDummy) - this.removeEditDummy(); - else - FilterStorage.removeFilter(oldFilter, this._subscription, position); - FilterStorage.addFilter(newFilter, this._subscription, position); - }, - - cycleCell: function(row, col) - { - if (row < 0 || row >= this.data.length || col.id != "col-enabled") - return; - - let filter = this.data[row].filter; - if (filter instanceof ActiveFilter) - filter.disabled = !filter.disabled; - }, - - isContainer: row => false, - isContainerOpen: row => false, - isContainerEmpty: row => true, - getLevel: row => 0, - getParentIndex: row => -1, - hasNextSibling: (row, afterRow) => false, - toggleOpenState: row => {}, - getProgressMode: () => null, - getImageSrc: () => null, - isSeparator: () => false, - performAction: () => {}, - performActionOnRow: () => {}, - performActionOnCell: () => {}, - getCellValue: () => null, - setCellValue: () => {}, - selectionChanged: () => {} -}; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-search.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-search.js deleted file mode 100644 index 23bb4b5..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-search.js +++ /dev/null @@ -1,191 +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/>. - */ - -/** - * Implementation of the filter search functionality. - * @class - */ -var FilterSearch = -{ - lastSearchString: null, - - /** - * Handles keypress events on the findbar widget. - */ - keyPress: function(/**Event*/ event) - { - if (event.keyCode == KeyEvent.DOM_VK_RETURN) - event.preventDefault(); - else if (event.keyCode == KeyEvent.DOM_VK_ESCAPE) - { - event.preventDefault(); - this.close(); - } - else if (event.keyCode == KeyEvent.DOM_VK_UP) - { - event.preventDefault(); - this.search(-1); - } - else if (event.keyCode == KeyEvent.DOM_VK_DOWN) - { - event.preventDefault(); - this.search(1); - } - else if (event.keyCode == KeyEvent.DOM_VK_PAGE_UP) - { - event.preventDefault(); - E("filtersTree").treeBoxObject.scrollByPages(-1); - } - else if (event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN) - { - event.preventDefault(); - E("filtersTree").treeBoxObject.scrollByPages(1); - } - }, - - /** - * Makes the find bar visible and focuses it. - */ - open: function() - { - E("findbar").hidden = false; - E("findbar-textbox").focus(); - }, - - /** - * Closes the find bar. - */ - close: function() - { - E("findbar").hidden = true; - }, - - /** - * Performs a filter search. - * @param {Integer} [direction] - * See @link{FilterSearch#search} - * @return {String} - * result status, one of "" (success), "notFound", "wrappedEnd", - * "wrappedStart" - */ - _search: function(direction) - { - let text = E("findbar-textbox").value.trim(); - if (!text) - return ""; - - let caseSensitive = E("findbar-case-sensitive").checked; - - if (typeof direction == "undefined") - direction = (text == this.lastSearchString ? 1 : 0); - this.lastSearchString = text; - - let normalizeString = (caseSensitive ? - string => string : - string => string.toLowerCase()); - - function findText(startIndex) - { - let list = E("filtersTree"); - let col = list.columns.getNamedColumn("col-filter"); - let count = list.view.rowCount; - for (let i = startIndex + direction; i >= 0 && i < count; i += (direction || 1)) - { - let filter = normalizeString(list.view.getCellText(i, col)); - if (filter.indexOf(text) >= 0) - { - FilterView.selectRow(i, true); - return true; - } - } - return false; - } - - text = normalizeString(text); - - // First try to find the entry in the current list - if (findText(E("filtersTree").currentIndex)) - return ""; - - // Now go through the other subscriptions - let result = ""; - let subscriptions = FilterStorage.subscriptions.slice(); - subscriptions.sort((s1, s2) => (s1 instanceof SpecialSubscription) - (s2 instanceof SpecialSubscription)); - let current = subscriptions.indexOf(FilterView.subscription); - direction = direction || 1; - for (let i = current + direction; ; i+= direction) - { - if (i < 0) - { - i = subscriptions.length - 1; - result = "wrappedStart"; - } - else if (i >= subscriptions.length) - { - i = 0; - result = "wrappedEnd"; - } - if (i == current) - break; - - let subscription = subscriptions[i]; - for (let j = 0; j < subscription.filters.length; j++) - { - let filter = normalizeString(subscription.filters[j].text); - if (filter.indexOf(text) >= 0) - { - let list = E(subscription instanceof SpecialSubscription ? "groups" : "subscriptions"); - let node = Templater.getNodeForData(list, "subscription", subscription); - if (!node) - break; - - // Select subscription in its list and restore focus after that - let oldFocus = document.commandDispatcher.focusedElement; - E("tabs").selectedIndex = (subscription instanceof SpecialSubscription ? 1 : 0); - list.ensureElementIsVisible(node); - list.selectItem(node); - if (oldFocus) - { - oldFocus.focus(); - Utils.runAsync(() => oldFocus.focus()); - } - - Utils.runAsync(() => findText(direction == 1 ? -1 : subscription.filters.length)); - return result; - } - } - } - - return "notFound"; - }, - - /** - * Performs a filter search and displays the resulting search status. - * @param {Integer} [direction] - * search direction: -1 (backwards), 0 (forwards starting with current), - * 1 (forwards starting with next) - */ - search: function(direction) - { - E("findbar").setAttribute("data-status", this._search(direction)); - } -}; - -window.addEventListener("load", event => -{ - E("findbar").setAttribute("data-os", Services.appinfo.OS.toLowerCase()); -}); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionactions.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionactions.js deleted file mode 100644 index ed875f9..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionactions.js +++ /dev/null @@ -1,606 +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/>. - */ - -/** - * Implemetation of the various actions that can be performed on subscriptions. - * @class - */ -var SubscriptionActions = -{ - /** - * Returns the subscription list currently having focus if any. - * @type Element - */ - get focusedList() - { - return E("tabs").selectedPanel.getElementsByTagName("richlistbox")[0]; - }, - - /** - * Returns the currently selected and focused subscription item if any. - * @type Element - */ - get selectedItem() - { - let list = this.focusedList; - return (list ? list.selectedItem : null); - }, - - /** - * Finds the subscription for a particular filter, selects it and selects the - * filter. - */ - selectFilter: function(/**Filter*/ filter) - { - let node = null; - let tabIndex = -1; - let subscriptions = filter.subscriptions.slice(); - subscriptions.sort((s1, s2) => s1.disabled - s2.disabled); - for (let i = 0; i < subscriptions.length; i++) - { - let subscription = subscriptions[i]; - let list = E(subscription instanceof SpecialSubscription ? "groups" : "subscriptions"); - tabIndex = (subscription instanceof SpecialSubscription ? 1 : 0); - node = Templater.getNodeForData(list, "subscription", subscription); - if (node) - break; - } - if (node) - { - E("tabs").selectedIndex = tabIndex; - Utils.runAsync(function() - { - node.parentNode.ensureElementIsVisible(node); - node.parentNode.selectItem(node); - if (!FilterActions.visible) - E("subscription-showHideFilters-command").doCommand(); - Utils.runAsync(() => FilterView.selectFilter(filter)); - }); - } - }, - - /** - * Updates subscription commands whenever the selected subscription changes. - * Note: this method might be called with a wrong "this" value. - */ - updateCommands: function() - { - let node = SubscriptionActions.selectedItem; - let data = Templater.getDataForNode(node); - let subscription = (data ? data.subscription : null) - E("subscription-editTitle-command").setAttribute("disabled", !subscription || - subscription.fixedTitle); - E("subscription-update-command").setAttribute("disabled", !subscription || - !(subscription instanceof DownloadableSubscription) || - Synchronizer.isExecuting(subscription.url)); - E("subscription-moveUp-command").setAttribute("disabled", !subscription || - !node || !node.previousSibling || !!node.previousSibling.id); - E("subscription-moveDown-command").setAttribute("disabled", !subscription || - !node || !node.nextSibling || !!node.nextSibling.id); - }, - - /** - * Starts title editing for the selected subscription. - */ - editTitle: function() - { - let node = this.selectedItem; - if (node) - TitleEditor.start(node); - }, - - /** - * Triggers re-download of a filter subscription. - */ - updateFilters: function(/**Node*/ node) - { - let data = Templater.getDataForNode(node || this.selectedItem); - if (data && data.subscription instanceof DownloadableSubscription) - Synchronizer.execute(data.subscription, true); - }, - - /** - * Triggers re-download of all filter subscriptions. - */ - updateAllFilters: function() - { - for (let i = 0; i < FilterStorage.subscriptions.length; i++) - { - let subscription = FilterStorage.subscriptions[i]; - if (subscription instanceof DownloadableSubscription) - Synchronizer.execute(subscription, true); - } - }, - - /** - * Sets Subscription.disabled field to a new value. - */ - setDisabled: function(/**Element*/ node, /**Boolean*/ value) - { - let data = Templater.getDataForNode(node || this.selectedItem); - if (data) - data.subscription.disabled = value; - }, - - /** - * Enables all disabled filters in a subscription. - */ - enableFilters: function(/**Element*/ node) - { - let data = Templater.getDataForNode(node); - if (!data) - return; - - let filters = data.subscription.filters; - for (let i = 0, l = filters.length; i < l; i++) - if (filters[i] instanceof ActiveFilter && filters[i].disabled) - filters[i].disabled = false; - }, - - /** - * Removes a filter subscription from the list (after a warning). - */ - remove: function(/**Node*/ node) - { - let data = Templater.getDataForNode(node || this.selectedItem); - if (data && Utils.confirm(window, Utils.getString(data.subscription instanceof SpecialSubscription ? "remove_group_warning" : "remove_subscription_warning"))) - FilterStorage.removeSubscription(data.subscription); - }, - - /** - * Adds a new filter group and allows the user to change its title. - */ - addGroup: function() - { - let subscription = SpecialSubscription.create(); - FilterStorage.addSubscription(subscription); - - let list = E("groups"); - let node = Templater.getNodeForData(list, "subscription", subscription); - if (node) - { - list.focus(); - list.ensureElementIsVisible(node); - list.selectedItem = node; - this.editTitle(); - } - }, - - /** - * Moves a filter subscription one line up. - */ - moveUp: function(/**Node*/ node) - { - node = Templater.getDataNode(node || this.selectedItem); - let data = Templater.getDataForNode(node); - if (!data) - return; - - let previousData = Templater.getDataForNode(node.previousSibling); - if (!previousData) - return; - - FilterStorage.moveSubscription(data.subscription, previousData.subscription); - }, - - /** - * Moves a filter subscription one line down. - */ - moveDown: function(/**Node*/ node) - { - node = Templater.getDataNode(node || this.selectedItem); - let data = Templater.getDataForNode(node); - if (!data) - return; - - let nextNode = node.nextSibling; - if (!Templater.getDataForNode(nextNode)) - return; - - let nextData = Templater.getDataForNode(nextNode.nextSibling); - FilterStorage.moveSubscription(data.subscription, nextData ? nextData.subscription : null); - }, - - /** - * Opens the context menu for a subscription node. - */ - openMenu: function(/**Event*/ event, /**Node*/ node) - { - node.getElementsByClassName("actionMenu")[0].openPopupAtScreen(event.screenX, event.screenY, true); - }, - - _altMask: 2, - _ctrlMask: 4, - _metaMask: 8, - get _accelMask() - { - let result = this._ctrlMask; - try { - let accelKey = Utils.prefService.getIntPref("ui.key.accelKey"); - if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_META) - result = this._metaMask; - else if (accelKey == Ci.nsIDOMKeyEvent.DOM_VK_ALT) - result = this._altMask; - } catch(e) {} - Object.defineProperty(this, "_accelMask", {value: result}); - return result; - }, - - /** - * Called when a key is pressed on the subscription list. - */ - keyPress: function(/**Event*/ event) - { - let modifiers = 0; - if (event.altKey) - modifiers |= this._altMask; - if (event.ctrlKey) - modifiers |= this._ctrlMask; - if (event.metaKey) - modifiers |= this._metaMask; - - if (event.charCode == " ".charCodeAt(0) && modifiers == 0) - { - // Ignore if Space is pressed on a button - for (let node = event.target; node; node = node.parentNode) - if (node.localName == "button") - return; - - let data = Templater.getDataForNode(this.selectedItem); - if (data) - data.subscription.disabled = !data.subscription.disabled; - } - else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_UP && modifiers == this._accelMask) - { - E("subscription-moveUp-command").doCommand(); - event.preventDefault(); - event.stopPropagation(); - } - else if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_DOWN && modifiers == this._accelMask) - { - E("subscription-moveDown-command").doCommand(); - event.preventDefault(); - event.stopPropagation(); - } - }, - - /** - * Subscription currently being dragged if any. - * @type Subscription - */ - dragSubscription: null, - - /** - * Called when a subscription entry is dragged. - */ - startDrag: function(/**Event*/ event, /**Node*/ node) - { - let data = Templater.getDataForNode(node); - if (!data) - return; - - event.dataTransfer.addElement(node); - event.dataTransfer.setData("text/x-moz-url", data.subscription.url); - event.dataTransfer.setData("text/plain", getSubscriptionTitle(data.subscription)); - this.dragSubscription = data.subscription; - event.stopPropagation(); - }, - - /** - * Called when something is dragged over a subscription entry or subscriptions list. - */ - dragOver: function(/**Event*/ event) - { - // Don't allow dragging onto a scroll bar - for (let node = event.originalTarget; node; node = node.parentNode) - if (node.localName == "scrollbar") - return; - - // Don't allow dragging onto element's borders - let target = event.originalTarget; - while (target && target.localName != "richlistitem") - target = target.parentNode; - if (!target) - target = event.originalTarget; - - let styles = window.getComputedStyle(target, null); - let rect = target.getBoundingClientRect(); - if (event.clientX < rect.left + parseInt(styles.borderLeftWidth, 10) || - event.clientY < rect.top + parseInt(styles.borderTopWidth, 10) || - event.clientX > rect.right - parseInt(styles.borderRightWidth, 10) - 1 || - event.clientY > rect.bottom - parseInt(styles.borderBottomWidth, 10) - 1) - { - return; - } - - // If not dragging a subscription check whether we can accept plain text - if (!this.dragSubscription) - { - let data = Templater.getDataForNode(event.target); - if (!data || !(data.subscription instanceof SpecialSubscription) || !event.dataTransfer.getData("text/plain")) - return; - } - - event.preventDefault(); - event.stopPropagation(); - }, - - /** - * Called when something is dropped on a subscription entry or subscriptions list. - */ - drop: function(/**Event*/ event, /**Node*/ node) - { - if (!this.dragSubscription) - { - // Not dragging a subscription, maybe this is plain text that we can add as filters? - let data = Templater.getDataForNode(node); - if (data && data.subscription instanceof SpecialSubscription) - { - let lines = event.dataTransfer.getData("text/plain").replace(/\r/g, "").split("\n"); - for (let i = 0; i < lines.length; i++) - { - let line = Filter.normalize(lines[i]); - if (line) - { - let filter = Filter.fromText(line); - FilterStorage.addFilter(filter, data.subscription); - } - } - FilterActions.removeDraggedFilters(); - event.stopPropagation(); - } - return; - } - - // When dragging down we need to insert after the drop node, otherwise before it. - node = Templater.getDataNode(node); - if (node) - { - let dragNode = Templater.getNodeForData(node.parentNode, "subscription", this.dragSubscription); - if (node.compareDocumentPosition(dragNode) & node.DOCUMENT_POSITION_PRECEDING) - node = node.nextSibling; - } - - let data = Templater.getDataForNode(node); - FilterStorage.moveSubscription(this.dragSubscription, data ? data.subscription : null); - event.stopPropagation(); - }, - - /** - * Called when the drag operation for a subscription is finished. - */ - endDrag: function() - { - this.dragSubscription = null; - } -}; - -/** - * Subscription title editing functionality. - * @class - */ -var TitleEditor = -{ - /** - * List item corresponding with the currently edited subscription if any. - * @type Node - */ - subscriptionEdited: null, - - /** - * Starts editing of a subscription title. - * @param {Node} node subscription list entry or a child node - * @param {Boolean} [checkSelection] if true the editor will not start if the - * item was selected in the preceding mousedown event - */ - start: function(node, checkSelection) - { - if (this.subscriptionEdited) - this.end(true); - - let subscriptionNode = Templater.getDataNode(node); - if (!subscriptionNode || (checkSelection && !subscriptionNode._wasSelected)) - return; - - let subscription = Templater.getDataForNode(subscriptionNode).subscription; - if (!subscription || subscription.fixedTitle) - return; - - subscriptionNode.getElementsByClassName("titleBox")[0].selectedIndex = 1; - let editor = subscriptionNode.getElementsByClassName("titleEditor")[0]; - editor.value = getSubscriptionTitle(subscription); - editor.setSelectionRange(0, editor.value.length); - this.subscriptionEdited = subscriptionNode; - editor.focus(); - }, - - /** - * Stops editing of a subscription title. - * @param {Boolean} save if true the entered value will be saved, otherwise dismissed - */ - end: function(save) - { - if (!this.subscriptionEdited) - return; - - let subscriptionNode = this.subscriptionEdited; - this.subscriptionEdited = null; - - let newTitle = null; - if (save) - { - newTitle = subscriptionNode.getElementsByClassName("titleEditor")[0].value; - newTitle = newTitle.trim(); - } - - let subscription = Templater.getDataForNode(subscriptionNode).subscription - if (newTitle && newTitle != subscription.title) - subscription.title = newTitle; - else - { - subscriptionNode.getElementsByClassName("titleBox")[0].selectedIndex = 0; - subscriptionNode.parentNode.focus(); - } - }, - - /** - * Processes keypress events on the subscription title editor field. - */ - keyPress: function(/**Event*/ event) - { - // Prevent any key presses from triggering outside actions - event.stopPropagation(); - - if (event.keyCode == event.DOM_VK_RETURN || event.keyCode == event.DOM_VK_ENTER) - { - event.preventDefault(); - this.end(true); - } - else if (event.keyCode == event.DOM_VK_CANCEL || event.keyCode == event.DOM_VK_ESCAPE) - { - event.preventDefault(); - this.end(false); - } - } -}; - -/** - * Methods called when choosing and adding a new filter subscription. - * @class - */ -var SelectSubscription = -{ - /** - * Starts selection of a filter subscription to add. - */ - start: function(/**Event*/ event) - { - let panel = E("selectSubscriptionPanel"); - let list = E("selectSubscription"); - let template = E("selectSubscriptionTemplate"); - let parent = list.menupopup; - - if (panel.state == "open") - { - list.focus(); - return; - } - - // Remove existing entries if any - while (parent.lastChild) - parent.removeChild(parent.lastChild); - - // Load data - let request = new XMLHttpRequest(); - request.open("GET", "subscriptions.xml"); - request.onload = function() - { - // Avoid race condition if two downloads are started in parallel - if (panel.state == "open") - return; - - // Add subscription entries to the list - let subscriptions = request.responseXML.getElementsByTagName("subscription"); - let listedSubscriptions = []; - for (let i = 0; i < subscriptions.length; i++) - { - let subscription = subscriptions[i]; - let url = subscription.getAttribute("url"); - if (!url || url in FilterStorage.knownSubscriptions) - continue; - - let localePrefix = Utils.checkLocalePrefixMatch(subscription.getAttribute("prefixes")); - let node = Templater.process(template, { - __proto__: null, - node: subscription, - localePrefix: localePrefix - }); - parent.appendChild(node); - listedSubscriptions.push(subscription); - } - let selectedNode = Utils.chooseFilterSubscription(listedSubscriptions); - list.selectedItem = Templater.getNodeForData(parent, "node", selectedNode) || parent.firstChild; - - // Show panel and focus list - let position = (Utils.versionComparator.compare(Utils.platformVersion, "2.0") < 0 ? "after_end" : "bottomcenter topleft"); - panel.openPopup(E("selectSubscriptionButton"), position, 0, 0, false, false, event); - Utils.runAsync(() => list.focus()); - }; - request.send(); - }, - - /** - * Adds filter subscription that is selected. - */ - add: function() - { - E("selectSubscriptionPanel").hidePopup(); - - let data = Templater.getDataForNode(E("selectSubscription").selectedItem); - if (!data) - return; - - let subscription = Subscription.fromURL(data.node.getAttribute("url")); - if (!subscription) - return; - - FilterStorage.addSubscription(subscription); - subscription.disabled = false; - subscription.title = data.node.getAttribute("title"); - subscription.homepage = data.node.getAttribute("homepage"); - - // Make sure the subscription is visible and selected - let list = E("subscriptions"); - let node = Templater.getNodeForData(list, "subscription", subscription); - if (node) - { - list.ensureElementIsVisible(node); - list.selectedItem = node; - list.focus(); - } - - // Trigger download if necessary - if (subscription instanceof DownloadableSubscription && !subscription.lastDownload) - Synchronizer.execute(subscription); - }, - - /** - * Called if the user chooses to view the complete subscriptions list. - */ - chooseOther: function() - { - E("selectSubscriptionPanel").hidePopup(); - window.openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", null, null); - }, - - /** - * Called for keys pressed on the subscription selection panel. - */ - keyPress: function(/**Event*/ event) - { - // Buttons and text links handle Enter key themselves - if (event.target.localName == "button" || event.target.localName == "label") - return; - - if (event.keyCode == event.DOM_VK_RETURN || event.keyCode == event.DOM_VK_ENTER) - { - // This shouldn't accept our dialog, only the panel - event.preventDefault(); - E("selectSubscriptionAccept").doCommand(); - } - } -}; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionview.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionview.js deleted file mode 100644 index 7b2bc1b..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionview.js +++ /dev/null @@ -1,346 +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/>. - */ - -/** - * Fills a list of filter groups and keeps it updated. - * @param {Element} list richlistbox element to be filled - * @param {Node} template template to use for the groups - * @param {Function} filter filter to decide which lists should be included - * @param {Function} listener function to be called on changes - * @constructor - */ -function ListManager(list, template, filter, listener) -{ - this._list = list; - this._template = template; - this._filter = filter; - this._listener = listener || function(){}; - - this._deck = this._list.parentNode; - - this._list.listManager = this; - this.reload(); - - let me = this; - let proxy = function() - { - return me._onChange.apply(me, arguments); - }; - FilterNotifier.addListener(proxy); - window.addEventListener("unload", function() - { - FilterNotifier.removeListener(proxy); - }, false); -} -ListManager.prototype = -{ - /** - * List element being managed. - * @type Element - */ - _list: null, - /** - * Template used for the groups. - * @type Node - */ - _template: null, - /** - * Filter function to decide which subscriptions should be included. - * @type Function - */ - _filter: null, - /** - * Function to be called whenever list contents change. - * @type Function - */ - _listener: null, - /** - * Deck switching between list display and "no entries" message. - * @type Element - */ - _deck: null, - - /** - * Completely rebuilds the list. - */ - reload: function() - { - // Remove existing entries if any - while (this._list.firstChild) - this._list.removeChild(this._list.firstChild); - - // Now add all subscriptions - let subscriptions = FilterStorage.subscriptions.filter(this._filter, this); - if (subscriptions.length) - { - for (let subscription of subscriptions) - this.addSubscription(subscription, null); - - // Make sure first list item is selected after list initialization - Utils.runAsync(() => this._list.selectItem(this._list.getItemAtIndex(this._list.getIndexOfFirstVisibleRow()))); - } - - this._deck.selectedIndex = (subscriptions.length ? 1 : 0); - this._listener(); - }, - - /** - * Adds a filter subscription to the list. - */ - addSubscription: function(/**Subscription*/ subscription, /**Node*/ insertBefore) /**Node*/ - { - let disabledFilters = 0; - for (let i = 0, l = subscription.filters.length; i < l; i++) - if (subscription.filters[i] instanceof ActiveFilter && subscription.filters[i].disabled) - disabledFilters++; - - let node = Templater.process(this._template, { - __proto__: null, - subscription: subscription, - isExternal: subscription instanceof ExternalSubscription, - downloading: Synchronizer.isExecuting(subscription.url), - disabledFilters: disabledFilters, - upgradeRequired: ListManager.isUpgradeRequired(subscription) - }); - if (insertBefore) - this._list.insertBefore(node, insertBefore); - else - this._list.appendChild(node); - return node; - }, - - /** - * Map indicating subscriptions that need their "disabledFilters" property to - * be updated by next updateDisabled() call. - * @type Object - */ - _scheduledUpdateDisabled: null, - - /** - * Updates subscriptions that had some of their filters enabled/disabled. - */ - updateDisabled: function() - { - let list = this._scheduledUpdateDisabled; - this._scheduledUpdateDisabled = null; - for (let url in list) - { - let subscription = Subscription.fromURL(url); - let subscriptionNode = Templater.getNodeForData(this._list, "subscription", subscription); - if (subscriptionNode) - { - let data = Templater.getDataForNode(subscriptionNode); - let disabledFilters = 0; - for (let i = 0, l = subscription.filters.length; i < l; i++) - if (subscription.filters[i] instanceof ActiveFilter && subscription.filters[i].disabled) - disabledFilters++; - - if (disabledFilters != data.disabledFilters) - { - data.disabledFilters = disabledFilters; - Templater.update(this._template, subscriptionNode); - - if (!document.commandDispatcher.focusedElement) - this._list.focus(); - } - } - } - }, - - /** - * Subscriptions change processing. - * @see FilterNotifier.addListener() - */ - _onChange: function(action, item, param1, param2) - { - if ((action == "subscription.added" || action == "subscription.removed") && item.url == Prefs.subscriptions_exceptionsurl) - E("acceptableAds").checked = FilterStorage.subscriptions.some(s => s.url == Prefs.subscriptions_exceptionsurl); - - if (action == "filter.disabled") - { - if (this._scheduledUpdateDisabled == null) - { - this._scheduledUpdateDisabled = Object.create(null); - Utils.runAsync(() => this.updateDisabled()); - } - for (let i = 0; i < item.subscriptions.length; i++) - this._scheduledUpdateDisabled[item.subscriptions[i].url] = true; - return; - } - - if (action != "load" && !this._filter(item)) - return; - - switch (action) - { - case "load": - { - this.reload(); - break; - } - case "subscription.added": - { - let index = FilterStorage.subscriptions.indexOf(item); - if (index >= 0) - { - let insertBefore = null; - for (index++; index < FilterStorage.subscriptions.length && !insertBefore; index++) - insertBefore = Templater.getNodeForData(this._list, "subscription", FilterStorage.subscriptions[index]); - this.addSubscription(item, insertBefore); - this._deck.selectedIndex = 1; - this._listener(); - } - break; - } - case "subscription.removed": - { - let node = Templater.getNodeForData(this._list, "subscription", item); - if (node) - { - let newSelection = node.nextSibling || node.previousSibling; - node.parentNode.removeChild(node); - if (!this._list.firstChild) - { - this._deck.selectedIndex = 0; - this._list.selectedIndex = -1; - } - else if (newSelection) - { - this._list.ensureElementIsVisible(newSelection); - this._list.selectedItem = newSelection; - } - this._listener(); - } - break - } - case "subscription.moved": - { - let node = Templater.getNodeForData(this._list, "subscription", item); - if (node) - { - node.parentNode.removeChild(node); - let insertBefore = null; - let index = FilterStorage.subscriptions.indexOf(item); - if (index >= 0) - for (index++; index < FilterStorage.subscriptions.length && !insertBefore; index++) - insertBefore = Templater.getNodeForData(this._list, "subscription", FilterStorage.subscriptions[index]); - this._list.insertBefore(node, insertBefore); - this._list.ensureElementIsVisible(node); - this._listener(); - } - break; - } - case "subscription.title": - case "subscription.disabled": - case "subscription.homepage": - case "subscription.lastDownload": - case "subscription.downloadStatus": - case "subscription.downloading": - { - let subscriptionNode = Templater.getNodeForData(this._list, "subscription", item); - if (subscriptionNode) - { - let data = Templater.getDataForNode(subscriptionNode); - data.downloading = Synchronizer.isExecuting(item.url); - data.upgradeRequired = ListManager.isUpgradeRequired(item); - Templater.update(this._template, subscriptionNode); - - if (!document.commandDispatcher.focusedElement) - this._list.focus(); - this._listener(); - } - break; - } - case "subscription.fixedTitle": - { - SubscriptionActions.updateCommands(); - break; - } - case "subscription.updated": - { - if (this._scheduledUpdateDisabled == null) - { - this._scheduledUpdateDisabled = Object.create(null); - Utils.runAsync(() => this.updateDisabled()); - } - this._scheduledUpdateDisabled[item.url] = true; - break; - } - } - } -}; - -/** - * Attaches list managers to the lists. - */ -ListManager.init = function() -{ - new ListManager(E("subscriptions"), - E("subscriptionTemplate"), - s => s instanceof RegularSubscription && !(ListManager.acceptableAdsCheckbox && s.url == Prefs.subscriptions_exceptionsurl), - SubscriptionActions.updateCommands); - new ListManager(E("groups"), - E("groupTemplate"), - s => s instanceof SpecialSubscription, - SubscriptionActions.updateCommands); - E("acceptableAds").checked = FilterStorage.subscriptions.some(s => s.url == Prefs.subscriptions_exceptionsurl); - E("acceptableAds").parentNode.hidden = !ListManager.acceptableAdsCheckbox; -}; - -/** - * Defines whether the "acceptable ads" subscription needs special treatment. - * @type Boolean - */ -ListManager.acceptableAdsCheckbox = Prefs.subscriptions_exceptionscheckbox; - -/** - * Adds or removes filter subscription allowing acceptable ads. - */ -ListManager.allowAcceptableAds = function(/**Boolean*/ allow) -{ - let subscription = Subscription.fromURL(Prefs.subscriptions_exceptionsurl); - if (!subscription) - return; - - subscription.disabled = false; - subscription.title = "Allow non-intrusive advertising"; - if (allow) - { - FilterStorage.addSubscription(subscription); - if (subscription instanceof DownloadableSubscription && !subscription.lastDownload) - Synchronizer.execute(subscription); - } - else - FilterStorage.removeSubscription(subscription); -}; - -/** - * Checks whether Adblock Plus needs to be upgraded in order to support filters - * in a particular subscription. - */ -ListManager.isUpgradeRequired = function(/**Subscription*/ subscription) -{ - if (subscription instanceof DownloadableSubscription && subscription.requiredVersion) - { - let {addonVersion} = require("info"); - if (Services.vc.compare(subscription.requiredVersion, addonVersion) > 0) - return true; - } - return false; -}; - -window.addEventListener("load", ListManager.init, false); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.js deleted file mode 100644 index 3c75c6b..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.js +++ /dev/null @@ -1,227 +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/>. - */ - -/** - * Initialization function, called when the window is loaded. - */ -function init() -{ - if (window.arguments && window.arguments.length) - { - let filter = window.arguments[0].wrappedJSObject; - if (filter instanceof Filter) - Utils.runAsync(() => SubscriptionActions.selectFilter(filter)); - } -} - -/** - * Called whenever the currently selected tab changes. - */ -function onTabChange(/**Element*/ tabbox) -{ - updateSelectedSubscription(); - - Utils.runAsync(function() - { - let panel = tabbox.selectedPanel; - if (panel) - panel.getElementsByClassName("initialFocus")[0].focus(); - SubscriptionActions.updateCommands(); - }); -} - -/** - * Called whenever the selected subscription changes. - */ -function onSelectionChange(/**Element*/ list) -{ - SubscriptionActions.updateCommands(); - updateSelectedSubscription(); - list.focus(); - - // Take elements of the previously selected item out of the tab order - if ("previousSelection" in list && list.previousSelection) - { - let elements = list.previousSelection.getElementsByClassName("tabable"); - for (let i = 0; i < elements.length; i++) - elements[i].setAttribute("tabindex", "-1"); - } - // Put elements of the selected item into tab order - if (list.selectedItem) - { - let elements = list.selectedItem.getElementsByClassName("tabable"); - for (let i = 0; i < elements.length; i++) - elements[i].removeAttribute("tabindex"); - } - list.previousSelection = list.selectedItem; -} - -/** - * Called when splitter state changes to make sure it is persisted properly. - */ -function onSplitterStateChange(/**Element*/ splitter) -{ - let state = splitter.getAttribute("state"); - if (!state) - { - splitter.setAttribute("state", "open"); - document.persist(splitter.id, "state"); - } -} - -/** - * Updates filter list when selected subscription changes. - */ -function updateSelectedSubscription() -{ - let panel = E("tabs").selectedPanel; - if (!panel) - return; - - let list = panel.getElementsByTagName("richlistbox")[0]; - if (!list) - return; - - let data = Templater.getDataForNode(list.selectedItem); - FilterView.subscription = (data ? data.subscription : null); - FilterActions.updateCommands(); -} - -/** - * Template processing functions. - * @class - */ -var Templater = -{ - /** - * Processes a template node using given data object. - */ - process: function(/**Node*/ template, /**Object*/ data) /**Node*/ - { - // Use a sandbox to resolve attributes (for convenience, not security) - let sandbox = Cu.Sandbox(window); - for (let key in data) - sandbox[key] = data[key]; - sandbox.formatTime = Utils.formatTime; - sandbox.getSubscriptionTitle = getSubscriptionTitle; - - // Clone template but remove id/hidden attributes from it - let result = template.cloneNode(true); - result.removeAttribute("id"); - result.removeAttribute("hidden"); - result._data = data; - - // Resolve any attributes of the for attr="{obj.foo}" - let conditionals = []; - let nodeIterator = document.createNodeIterator(result, NodeFilter.SHOW_ELEMENT, null, false); - for (let node = nodeIterator.nextNode(); node; node = nodeIterator.nextNode()) - { - if (node.localName == "if") - conditionals.push(node); - for (let i = 0; i < node.attributes.length; i++) - { - let attribute = node.attributes[i]; - let len = attribute.value.length; - if (len >= 2 && attribute.value[0] == "{" && attribute.value[len - 1] == "}") - { - let value = Cu.evalInSandbox(attribute.value.substr(1, len - 2), sandbox); - if (attribute.name == "condition") - value = value ? "true" : "false"; - attribute.value = value; - } - } - } - - // Process <if> tags - remove if condition is false, replace by their children - // if it is true - for (let node of conditionals) - { - let fragment = document.createDocumentFragment(); - let condition = node.getAttribute("condition"); - if (condition == "false") - condition = false; - for (let i = 0; i < node.childNodes.length; i++) - { - let child = node.childNodes[i]; - if (child.localName == "elif" || child.localName == "else") - { - if (condition) - break; - condition = (child.localName == "elif" ? child.getAttribute("condition") : true); - if (condition == "false") - condition = false; - } - else if (condition) - fragment.appendChild(node.childNodes[i--]); - } - node.parentNode.replaceChild(fragment, node); - } - - return result; - }, - - /** - * Updates first child of a processed template if the underlying data changed. - */ - update: function(/**Node*/ template, /**Node*/ node) - { - if (!("_data" in node)) - return; - let newChild = Templater.process(template.firstChild, node._data); - delete newChild._data; - node.replaceChild(newChild, node.firstChild); - }, - - /** - * Walks up the parent chain for a node until the node corresponding with a - * template is found. - */ - getDataNode: function(/**Node*/ node) /**Node*/ - { - while (node) - { - if ("_data" in node) - return node; - node = node.parentNode; - } - return null; - }, - - /** - * Returns the data used to generate the node from a template. - */ - getDataForNode: function(/**Node*/ node) /**Object*/ - { - node = Templater.getDataNode(node); - if (node) - return node._data; - else - return null; - }, - - /** - * Returns a node that has been generated from a template using a particular - * data object. - */ - getNodeForData: function(/**Node*/ parent, /**String*/ property, /**Object*/ data) /**Node*/ - { - for (let child = parent.firstChild; child; child = child.nextSibling) - if ("_data" in child && property in child._data && child._data[property] == data) - return child; - return null; - } -}; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul deleted file mode 100644 index dac1b65..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul +++ /dev/null @@ -1,406 +0,0 @@ -<?xml version="1.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/>. - --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://adblockplus/skin/filters.css" type="text/css"?> - -<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/filters.dtd"> - -<dialog - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - title="&dialog.title;" - id="abpFiltersWindow" - onload="init()" - buttons="accept" - width="950" - height="450" - persist="screenX screenY width height sizemode" - windowtype="abp:filters"> - -<script type="application/x-javascript;version=1.7" src="utils.js"/> -<script type="application/x-javascript;version=1.7" src="filters.js"/> -<script type="application/x-javascript;version=1.7" src="filters-subscriptionview.js"/> -<script type="application/x-javascript;version=1.7" src="filters-subscriptionactions.js"/> -<script type="application/x-javascript;version=1.7" src="filters-filterview.js"/> -<script type="application/x-javascript;version=1.7" src="filters-filteractions.js"/> -<script type="application/x-javascript;version=1.7" src="filters-backup.js"/> -<script type="application/x-javascript;version=1.7" src="filters-search.js"/> - -<keyset id="filtersKeyset"> - <key id="subscription-update-key" key="T" modifiers="accel" command="subscription-update-command"/> - <key id="subscription-update-all-key" key="T" modifiers="accel,shift" command="subscription-update-all-command"/> - <key id="edit-key" keycode="VK_F2" oncommand="E(FilterActions.focused ? 'filters-edit-command' : 'subscription-editTitle-command').doCommand();"/> - <key id="delete-key" keycode="VK_DELETE" oncommand="E(FilterActions.focused ? 'filters-delete-command' : 'subscription-delete-command').doCommand();"/> - <key id="subscription-showHideFilters-key" key="R" modifiers="accel" command="subscription-showHideFilters-command"/> - <key id="moveUp-key" keycode="VK_UP" modifiers="accel"/> - <key id="moveDown-key" keycode="VK_DOWN" modifiers="accel"/> - <key id="filters-add-key" keycode="VK_INSERT" oncommand="E('filters-add-command').doCommand();"/> - <key id="filters-selectAll-key" key="A" modifiers="accel" oncommand="if (FilterActions.focused) E('filters-selectAll-command').doCommand();"/> - <key id="filters-copy-key" key="C" modifiers="accel" oncommand="if (FilterActions.focused) E('filters-copy-command').doCommand();"/> - <key id="filters-cut-key" key="X" modifiers="accel" oncommand="if (FilterActions.focused) E('filters-cut-command').doCommand();"/> - <key id="filters-paste-key" key="V" modifiers="accel" oncommand="if (FilterActions.focused) E('filters-paste-command').doCommand();"/> - <key id="backup-key" key="E" modifiers="accel" oncommand="E('backup').doCommand();"/> - <key id="restore-key" key="I" modifiers="accel" oncommand="E('restoreOwnBackup').doCommand();"/> - <key id="find-key" key="F" modifiers="accel" oncommand="if (FilterActions.visible) E('find-command').doCommand();"/> - <key id="find-again-key" key="G" modifiers="accel" oncommand="if (FilterActions.visible) E('find-again-command').doCommand();"/> - <key id="find-previous-key" key="G" modifiers="accel,shift" oncommand="if (FilterActions.visible) E('find-previous-command').doCommand();"/> - <key id="find-again-key2" keycode="VK_F3" oncommand="if (FilterActions.visible) E('find-again-command').doCommand();"/> - <key id="find-previous-key2" keycode="VK_F3" modifiers="shift" oncommand="if (FilterActions.visible) E('find-previous-command').doCommand();"/> -</keyset> - -<commandset id="filtersCommandset"> - <command id="subscription-update-command" oncommand="SubscriptionActions.updateFilters();"/> - <command id="subscription-update-all-command" oncommand="SubscriptionActions.updateAllFilters();"/> - <command id="subscription-editTitle-command" oncommand="SubscriptionActions.editTitle();"/> - <command id="subscription-delete-command" oncommand="SubscriptionActions.remove();"/> - <command id="subscription-showHideFilters-command" oncommand="E('filtersGrippy').doCommand();"/> - <command id="subscription-moveUp-command" oncommand="SubscriptionActions.moveUp();"/> - <command id="subscription-moveDown-command" oncommand="SubscriptionActions.moveDown();"/> - <command id="subscription-add-command" oncommand="SelectSubscription.start(event);"/> - <command id="subscription-addSelected-command" oncommand="SelectSubscription.add();"/> - <command id="subscription-addOther-command" oncommand="SelectSubscription.chooseOther();"/> - <command id="group-add-command" oncommand="SubscriptionActions.addGroup();"/> - <command id="filters-selectAll-command" oncommand="FilterActions.selectAll();"/> - <command id="filters-edit-command" oncommand="FilterActions.startEditing();"/> - <command id="filters-add-command" oncommand="FilterActions.insertFilter();"/> - <command id="filters-delete-command" oncommand="FilterActions.deleteSelected();"/> - <command id="filters-resetHitCounts-command" oncommand="FilterActions.resetHitCounts();"/> - <command id="filters-moveUp-command" oncommand="FilterActions.moveUp();"/> - <command id="filters-moveDown-command" oncommand="FilterActions.moveDown();"/> - <command id="filters-copy-command" oncommand="FilterActions.copySelected(true);"/> - <command id="filters-cut-command" oncommand="FilterActions.copySelected(false);"/> - <command id="filters-paste-command" oncommand="FilterActions.paste();"/> - <command id="find-command" oncommand="FilterSearch.open();"/> - <command id="find-again-command" oncommand="FilterSearch.search(1);"/> - <command id="find-previous-command" oncommand="FilterSearch.search(-1);"/> -</commandset> - -<popupset id="filtersPopupset"> - <menupopup id="filters-view-menu1" onpopupshowing="FilterActions.fillColumnPopup(this);"> - <menuitem id="filters-view-filter1" label="&filter.column;" type="checkbox" disabled="true"/> - <menuitem id="filters-view-slow1" label="&slow.column;" type="checkbox" oncommand="FilterActions.toggleColumn('col-slow')"/> - <menuitem id="filters-view-enabled1" label="&enabled.column;" type="checkbox" oncommand="FilterActions.toggleColumn('col-enabled')"/> - <menuitem id="filters-view-hitcount1" label="&hitcount.column;" type="checkbox" oncommand="FilterActions.toggleColumn('col-hitcount')"/> - <menuitem id="filters-view-lasthit1" label="&lasthit.column;" type="checkbox" oncommand="FilterActions.toggleColumn('col-lasthit')"/> - <menuseparator/> - <menu id="filters-sort-menu1" label="&sort.label;"> - <menupopup id="filters-sort-popup1"> - <menuitem id="filters-sort-none1" label="&sort.none.label;" type="radio" name="sortColumn" oncommand="FilterView.sortBy(null)"/> - <menuitem id="filters-sort-filter1" label="&filter.column;" type="radio" name="sortColumn" oncommand="FilterView.sortBy('col-filter')"/> - <menuitem id="filters-sort-slow1" label="&slow.column;" type="radio" name="sortColumn" oncommand="FilterView.sortBy('col-slow')"/> - <menuitem id="filters-sort-enabled1" label="&enabled.column;" type="radio" name="sortColumn" oncommand="FilterView.sortBy('col-enabled')"/> - <menuitem id="filters-sort-hitcount1" label="&hitcount.column;" type="radio" name="sortColumn" oncommand="FilterView.sortBy('col-hitcount')"/> - <menuitem id="filters-sort-lasthit1" label="&lasthit.column;" type="radio" name="sortColumn" oncommand="FilterView.sortBy('col-lasthit')"/> - <menuseparator/> - <menuitem id="filters-sort-asc1" label="&sort.ascending.label;" type="radio" name="sortOrder" oncommand="FilterActions.setSortOrder('ascending')"/> - <menuitem id="filters-sort-desc1" label="&sort.descending.label;" type="radio" name="sortOrder" oncommand="FilterActions.setSortOrder('descending')"/> - </menupopup> - </menu> - </menupopup> - <tooltip id="filtersTooltip" onpopupshowing="FilterActions.fillTooltip(event);"> - <grid> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows> - <row id="tooltip-filter-row" align="top"> - <label class="tooltipLabel" value="&filter.column;"/> - <vbox id="tooltip-filter"/> - </row> - <row id="tooltip-hitcount-row"> - <label class="tooltipLabel" value="&hitcount.column;"/> - <description id="tooltip-hitcount"/> - </row> - <row id="tooltip-lasthit-row"> - <label class="tooltipLabel" value="&lasthit.column;"/> - <description id="tooltip-lasthit"/> - </row> - </rows> - </grid> - - <description id="tooltip-additional"/> - </tooltip> -</popupset> - -<hbox id="content" flex="1"> - <tabbox id="tabs" flex="1" persist="selectedIndex"> - <tabs onselect="onTabChange(this.parentNode);"> - <tab label="&subscriptions.tab.label;"/> - <tab label="&filters.tab.label;"/> - </tabs> - <tabpanels flex="1"> - <tabpanel id="subscriptionsTab" orient="vertical" flex="1"> - <hbox pack="end"> - <button id="selectSubscriptionButton" label="&addSubscription.label;…" command="subscription-add-command"/> - </hbox> - - <panel id="selectSubscriptionPanel" type="arrow" position="bottomcenter topleft" - orient="vertical" onkeypress="SelectSubscription.keyPress(event);"> - <menuitem id="selectSubscriptionTemplate" hidden="true" - class="{localePrefix ? 'localeMatch' : ''}" - label="{node.getAttribute('title')}" - value="{node.getAttribute('url')}"> - <label class="selectSubscriptionItem" value="{node.getAttribute('title') + ' (' + node.getAttribute('specialization') + ')'}"/> - </menuitem> - <menulist id="selectSubscription"> - <menupopup/> - </menulist> - <hbox align="baseline"> - <label class="text-link" value="&addSubscriptionOther.label;" onclick="E('subscription-addOther-command').doCommand();"/> - <spacer flex="1"/> - <button id="selectSubscriptionAccept" default="true" label="&addSubscriptionAdd.label;" command="subscription-addSelected-command"/> - <spacer flex="1"/> - <button label="&addSubscriptionCancel.label;" oncommand="E('selectSubscriptionPanel').hidePopup();"/> - </hbox> - </panel> - - <richlistitem id="subscriptionTemplate" class="subscription" hidden="true" orient="vertical" - onmousedown="this._wasSelected = (this.parentNode.selectedItem == this);" - ondragstart="SubscriptionActions.startDrag(event, this);" - ondragend="SubscriptionActions.endDrag();" - ondragover="SubscriptionActions.dragOver(event);" - ondrop="SubscriptionActions.drop(event, this);" - oncontextmenu="SubscriptionActions.openMenu(event, this);"> - <vbox class="{subscription.disabled ? 'disabled' : ''}"> - <hbox align="center"> - <checkbox label="&subscription.enabled.label;" class="enabledCheckbox tabable" tabindex="-1" - checked="{subscription.disabled ? 'false' : 'true'}" oncommand="SubscriptionActions.setDisabled(this, !this.checked);"/> - - <vbox flex="1"> - <hbox align="center"> - <deck class="titleBox" flex="1" selectedIndex="0" onselect="event.stopPropagation();"> - <description ondblclick="if (event.button == 0) TitleEditor.start(this, true);"> - <description class="title" value="{getSubscriptionTitle(subscription)}" flex="1" crop="end"/> - (<if condition="{isExternal}"> - <description value="&subscription.external.label;"/> - <else/> - <if condition="{subscription.homepage}"> - <description class="link" value="&subscription.homepage.label;" - _url="{subscription.homepage}" tooltiptext="{subscription.homepage}" - onclick="if (event.button == 0) { event.stopPropagation();UI.loadInBrowser(this.getAttribute('_url')); }"/>,  - </if> - <description class="link" value="&subscription.source.label;" - _url="{subscription.url}" tooltiptext="{subscription.url}" - onclick="if (event.button == 0) { event.stopPropagation();UI.loadInBrowser(this.getAttribute('_url')); }"/> - </if>) - </description> - <textbox oncontextmenu="event.stopPropagation();" class="titleEditor" onkeypress="TitleEditor.keyPress(event);" onblur="TitleEditor.end(true);"/> - </deck> - </hbox> - <hbox align="center"> - <description flex="1" class="status"> - <description value="&subscription.lastDownload.label;"/>  - <if condition="{downloading}"> - <description value="&subscription.lastDownload.inProgress;"/> - <elif condition="{!subscription.lastDownload}"/> - <description value="&subscription.lastDownload.unknown;"/> - <else/> - <description value="{formatTime(subscription.lastDownload * 1000)}"/> - <if condition="{subscription.downloadStatus}"> - <description> -  (<if condition="{subscription.downloadStatus == 'synchronize_invalid_url'}"> - <description value="&subscription.lastDownload.invalidURL;"/> - <elif condition="{subscription.downloadStatus == 'synchronize_connection_error'}"/> - <description value="&subscription.lastDownload.connectionError;"/> - <elif condition="{subscription.downloadStatus == 'synchronize_invalid_data'}"/> - <description value="&subscription.lastDownload.invalidData;"/> - <elif condition="{subscription.downloadStatus == 'synchronize_checksum_mismatch'}"/> - <description value="&subscription.lastDownload.checksumMismatch;"/> - <else/> <!-- synchronize_ok --> - <description value="&subscription.lastDownload.success;"/> - </if>) - </description> - </if> - </if> - </description> - </hbox> - </vbox> - - <button class="actionButton tabable" type="menu" label="&subscription.actions.label;" tabindex="-1"> - <menupopup class="actionMenu"> - <menuitem label="&subscription.editTitle.label;" key="edit-key" command="subscription-editTitle-command"/> - <menuitem label="&subscription.update.label;" key="subscription-update-key" command="subscription-update-command"/> - <menuitem label="&subscription.showHideFilters.label;" key="subscription-showHideFilters-key" command="subscription-showHideFilters-command"/> - <menuitem label="&subscription.delete.label;…" key="delete-key" command="subscription-delete-command"/> - <menuseparator/> - <menuitem label="&subscription.moveUp.label;" key="moveUp-key" command="subscription-moveUp-command"/> - <menuitem label="&subscription.moveDown.label;" key="moveDown-key" command="subscription-moveDown-command"/> - </menupopup> - </button> - </hbox> - - <description class="warning" hidden="{!upgradeRequired}">&subscription.minVersion.warning;</description> - <description class="warning" hidden="{!disabledFilters}"> - &subscription.disabledFilters.warning; - <description class="link" value="&subscription.disabledFilters.enable;" onclick="SubscriptionActions.enableFilters(this);"/> - </description> - </vbox> - </richlistitem> - - <deck id="noSubscriptionsDeck" flex="1"> - <description flex="1">&noSubscriptions.text;</description> - <richlistbox id="subscriptions" class="initialFocus" flex="1" - onselect="onSelectionChange(this);" - ondragover="SubscriptionActions.dragOver(event);" - ondrop="SubscriptionActions.drop(event, null);" - onkeypress="SubscriptionActions.keyPress(event);"> - </richlistbox> - </deck> - - </tabpanel> - <tabpanel id="filtersTab" orient="vertical" flex="1"> - <hbox pack="end"> - <button id="addGroupButton" label="&addGroup.label;" command="group-add-command"/> - </hbox> - - <richlistitem id="groupTemplate" class="subscription" hidden="true" orient="vertical" - onmousedown="this._wasSelected = (this.parentNode.selectedItem == this);" - ondragstart="SubscriptionActions.startDrag(event, this);" - ondragend="SubscriptionActions.endDrag();" - ondragover="SubscriptionActions.dragOver(event);" - ondrop="SubscriptionActions.drop(event, this);" - oncontextmenu="SubscriptionActions.openMenu(event, this);"> - <hbox class="{subscription.disabled ? 'disabled' : ''}" align="center"> - <checkbox label="&subscription.enabled.label;" class="enabledCheckbox tabable" tabindex="-1" - checked="{subscription.disabled ? 'false' : 'true'}" oncommand="SubscriptionActions.setDisabled(this, !this.checked);"/> - <hbox align="center" flex="1"> - <deck class="titleBox" flex="1" selectedIndex="0" onselect="event.stopPropagation();"> - <description class="title" value="{getSubscriptionTitle(subscription)}" crop="end" ondblclick="if (event.button == 0) TitleEditor.start(this, true);"/> - <textbox oncontextmenu="event.stopPropagation();" class="titleEditor" onkeypress="TitleEditor.keyPress(event);" onblur="TitleEditor.end(true);"/> - </deck> - </hbox> - <button class="actionButton tabable" type="menu" label="&subscription.actions.label;" tabindex="-1"> - <menupopup class="actionMenu"> - <menuitem label="&subscription.editTitle.label;" key="edit-key" command="subscription-editTitle-command"/> - <menuitem label="&subscription.showHideFilters.label;" key="subscription-showHideFilters-key" command="subscription-showHideFilters-command"/> - <menuitem label="&subscription.delete.label;…" key="delete-key" command="subscription-delete-command"/> - <menuseparator/> - <menuitem label="&subscription.moveUp.label;" key="moveUp-key" command="subscription-moveUp-command"/> - <menuitem label="&subscription.moveDown.label;" key="moveDown-key" command="subscription-moveDown-command"/> - </menupopup> - </button> - </hbox> - </richlistitem> - - <deck id="noFiltersDeck" flex="1"> - <description flex="1">&noFilters.text;</description> - <richlistbox id="groups" class="initialFocus" flex="1" - onselect="onSelectionChange(this);" - ondragover="SubscriptionActions.dragOver(event);" - ondrop="SubscriptionActions.drop(event, null);" - onkeypress="SubscriptionActions.keyPress(event);"> - </richlistbox> - </deck> - </tabpanel> - </tabpanels> - </tabbox> - - <splitter id="filtersSplitter" persist="state" orient="horizontal" collapse="after" state="collapsed" oncommand="FilterView.refresh();onSplitterStateChange(this);"> - <grippy id="filtersGrippy"/> - </splitter> - - <vbox id="filtersContainer" persist="width height" width="500"> - <hbox pack="end"> - <button id="findButton" label="&find.label;" command="find-command"/> - <button id="filterActionButton" type="menu" label="&filter.actions.label;"> - <menupopup id="filterActionMenu" onpopupshowing="FilterActions.fillActionsPopup();"> - <menuitem label="&filter.edit.label;" key="edit-key" command="filters-edit-command"/> - <menuitem label="&filter.cut.label;" key="filters-cut-key" command="filters-cut-command"/> - <menuitem label="&filter.copy.label;" key="filters-copy-key" command="filters-copy-command"/> - <menuitem label="&filter.paste.label;" key="filters-paste-key" command="filters-paste-command"/> - <menuitem label="&filter.delete.label;" key="delete-key" command="filters-delete-command"/> - <menuseparator/> - <menuitem label="&filter.selectAll.label;" key="filters-selectAll-key" command="filters-selectAll-command"/> - <menuitem label="&filter.resetHitCounts.label;" command="filters-resetHitCounts-command"/> - <menuseparator/> - <menuitem label="&filter.moveUp.label;" key="moveUp-key" command="filters-moveUp-command"/> - <menuitem label="&filter.moveDown.label;" key="moveDown-key" command="filters-moveDown-command"/> - <menuseparator/> - <menu id="viewMenu" label="&viewMenu.label;"/> - </menupopup> - </button> - <button id="addFilterButton" label="&addFilter.label;" command="filters-add-command"/> - </hbox> - - <hbox id="findbar" hidden="true" align="center" onkeypress="FilterSearch.keyPress(event);"> - <toolbarbutton id="findbar-closebutton" tooltiptext="&findbar.close;" oncommand="FilterSearch.close();"/> - <textbox id="findbar-textbox" type="search" placeholder="&findbar.placeholder;" flex="1" oncommand="FilterSearch.search();"/> - <spinbuttons id="findbar-findAgain" onup="FilterSearch.search(-1);" ondown="FilterSearch.search(1);"/> - <button id="findbar-case-sensitive" type="checkbox" label="&findbar.caseSensitive;" oncommand="FilterSearch.search(0);"/> - <stack> - <label id="findbar-status-wrappedStart" class="findbar-status" value="&findbar.statusWrappedStart;"/> - <label id="findbar-status-wrappedEnd" class="findbar-status" value="&findbar.statusWrappedEnd;"/> - <label id="findbar-status-notFound" class="findbar-status" value="&findbar.statusNotFound;"/> - </stack> - </hbox> - - <tree id="filtersTree" - flex="1" - editable="true" - seltype="multiple" - enableColumnDrag="true" - hidecolumnpicker="true" - _removewarning="&filters.remove.warning;"> - <treecols context="filters-view-menu1"> - <treecol id="col-enabled" label="&enabled.column;" cycler="true" flex="0" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="col-filter" label="&filter.column;" flex="10" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="col-slow" label="!" display="&slow.column;" tooltiptext="&slow.column;" flex="0" width="16" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="col-hitcount" label="&hitcount.column;" flex="0" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="col-lasthit" label="&lasthit.column;" hidden="true" flex="4" persist="width ordinal sortDirection hidden"/> - </treecols> - - <treechildren id="filtersTreeChildren" - oncontextmenu="E('filterActionMenu').openPopupAtScreen(event.screenX, event.screenY, true);" - tooltip="filtersTooltip" - noGroupText="&noGroupSelected.text;" - noFiltersText="&noFiltersInGroup.text;" - ondragstart="FilterActions.startDrag(event);" - ondragend="FilterActions.endDrag(event);"/> - </tree> - </vbox> -</hbox> - -<hbox id="buttons"> - <button id="backupButton" type="menu" - label="&backupButton.label;" - _backupDialogTitle="&backup.label;" _restoreDialogTitle="&restore.own.label;" - _fileFilterComplete="&backup.complete.title;" _fileFilterCustom="&backup.custom.title;" - _backupError="&backup.error;" _restoreError="&restore.error;" - _restoreCompleteWarning="&restore.complete.warning;" _restoreCustomWarning="&restore.custom.warning;" - _restoreVersionWarning="&restore.minVersion.warning;" - oncommand="if (event.target == this) Utils.runAsync(() => this.open = true);"> - <menupopup onpopupshowing="Backup.fillRestorePopup();"> - <menuitem id="backup" key="backup-key" label="&backup.label;…" oncommand="Backup.backupToFile();"/> - <menuseparator/> - <menuitem id="restoreBackupTemplate" label="&restore.default.label;" hidden="true"/> - <menuitem id="restoreOwnBackup" key="restore-key" label="&restore.own.label;…" oncommand="Backup.restoreFromFile();"/> - </menupopup> - </button> - - <spacer flex="1"/> - - <button id="close" dlgtype="accept" label="&close.label;"/> -</hbox> - -</dialog> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html b/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html deleted file mode 100644 index 958c4f6..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html +++ /dev/null @@ -1,98 +0,0 @@ -<!DOCTYPE html> -<!-- - - 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/>. - --> - -<html> - <head> - <title class="i18n_firstRun_title"></title> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link type="text/css" href="skin/common.css" rel="stylesheet" /> - <link type="text/css" href="skin/firstRun.css" rel="stylesheet"/> - <script type="text/javascript" src="ext/common.js"></script> - <script type="text/javascript" src="ext/content.js"></script> - <script type="text/javascript" src="common.js"></script> - <script type="text/javascript" src="i18n.js"></script> - <script type="text/javascript" src="firstRun.js"></script> - </head> - <body> - - - <header> - <img id="logo"> - <h1 id="title-main" class="i18n_firstRun_title"></h1> - </header> - - <section id="filterlistsReinitializedWarning" class="i18n_firstRun_filterlistsReinitializedWarning warning" hidden="true"></section> - - <div id="content"> - <section id="general"> - <div id="acceptable-ads-block" class="block"> - <h2 class="i18n_firstRun_acceptableAdsHeadline"></h2> - <p id="acceptable-ads-explanation" class="i18n_firstRun_acceptableAdsExplanation"></p> - </div> - <div id="abb-promotion-block" class="block"> - <h2 class="i18n_firstRun_abbPromotionHeadline"></h2> - <a href="https://adblockbrowser.org/?ref=frp"> - <div> - <img src="skin/abb-logo.png" alt="Adblock Browser logo" /> - </div> - <div> - <div class="i18n_firstRun_abbButtonTitle title"></div> - <div class="i18n_firstRun_abbButtonSubtitle subtitle"></div> - </div> - </a> - </div> - </section> - - - <section id="share"> - <h2 id="share-headline" class="i18n_firstRun_share_headline"></h2> - - <div class="block"> - <a id="donate" class="i18n_firstRun_donate" target="_blank"></a> - <span id="donate-label" class="i18n_firstRun_donate_label"></span> - </div> - - <div class="block"> - <div id="share-general" class="share-buttons"> - <a id="share-facebook" href="https://www.facebook.com/adblockplus" target="_blank" data-script="https://facebook.com/plugins/like.php?"> - </a> - <a id="share-twitter" href="https://twitter.com/adblockplus" target="_blank" data-script="https://platform.twitter.com/widgets/"> - </a> - <a id="share-gplus" href="https://www.google.com/+AdblockPlus" target="_blank" data-script="https://apis.google.com/se/0/_/+1/fastbutton?"> - </a> - </div> - - <!-- Chinese social networks --> - <div id="share-chinese" class="share-buttons"> - <a id="share-renren" href="http://www.renren.com/601651969" target="_blank"> - </a> - <a id="share-weibo" href="http://e.weibo.com/adblockplus/" target="_blank"> - </a> - </div> - <span class="i18n_firstRun_share"></span> - </div> - </section> - - </div> - - <footer> - <a id="contributors" class="i18n_firstRun_contributor_credits"></a> - </footer> - </body> -</html> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.js deleted file mode 100644 index 14d3db2..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.js +++ /dev/null @@ -1,146 +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/>. - */ - -/* globals checkShareResource, getDocLink, openSharePopup, E */ - -"use strict"; - -(function() -{ - function onDOMLoaded() - { - // Set up logo image - let logo = E("logo"); - logo.src = "skin/abp-128.png"; - let errorCallback = function() - { - logo.removeEventListener("error", errorCallback, false); - // We are probably in Chrome/Opera/Safari, the image has a different path. - logo.src = "icons/detailed/abp-128.png"; - }; - logo.addEventListener("error", errorCallback, false); - - // Set up URLs - getDocLink("donate", (link) => - { - E("donate").href = link; - }); - - getDocLink("contributors", (link) => - { - E("contributors").href = link; - }); - - getDocLink("acceptable_ads_criteria", (link) => - { - setLinks("acceptable-ads-explanation", link, openFilters); - }); - - getDocLink("contribute", (link) => - { - setLinks("share-headline", link); - }); - - ext.backgroundPage.sendMessage({ - type: "app.get", - what: "issues" - }, (issues) => - { - // Show warning if filterlists settings were reinitialized - if (issues.filterlistsReinitialized) - { - E("filterlistsReinitializedWarning").removeAttribute("hidden"); - setLinks("filterlistsReinitializedWarning", openFilters); - } - }); - - updateSocialLinks(); - - ext.onMessage.addListener((message) => - { - if (message.type == "subscriptions.respond") - { - updateSocialLinks(); - } - }); - ext.backgroundPage.sendMessage({ - type: "subscriptions.listen", - filter: ["added", "removed", "updated", "disabled"] - }); - } - - function updateSocialLinks() - { - for (let network of ["twitter", "facebook", "gplus"]) - { - let link = E("share-" + network); - checkShareResource(link.getAttribute("data-script"), (isBlocked) => - { - // Don't open the share page if the sharing script would be blocked - if (isBlocked) - link.removeEventListener("click", onSocialLinkClick, false); - else - link.addEventListener("click", onSocialLinkClick, false); - }); - } - } - - function onSocialLinkClick(event) - { - if (window.matchMedia("(max-width: 970px)").matches) - return; - - event.preventDefault(); - - getDocLink(event.target.id, (link) => - { - openSharePopup(link); - }); - } - - function setLinks(id, ...args) - { - let element = E(id); - if (!element) - { - return; - } - - let links = element.getElementsByTagName("a"); - - for (let i = 0; i < links.length; i++) - { - if (typeof args[i] == "string") - { - links[i].href = args[i]; - links[i].setAttribute("target", "_blank"); - } - else if (typeof args[i] == "function") - { - links[i].href = "javascript:void(0);"; - links[i].addEventListener("click", args[i], false); - } - } - } - - function openFilters() - { - ext.backgroundPage.sendMessage({type: "app.open", what: "options"}); - } - - document.addEventListener("DOMContentLoaded", onDOMLoaded, false); -}()); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js deleted file mode 100644 index a21fa24..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js +++ /dev/null @@ -1,122 +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"; - -// This variable should no longer be necessary once options.js in Chrome -// accesses ext.i18n directly. -let {i18n} = ext; - -// Getting UI locale cannot be done synchronously on Firefox, -// requires messaging the background page. For Chrome and Safari, -// we could get the UI locale here, but would need to duplicate -// the logic implemented in Utils.appLocale. -ext.backgroundPage.sendMessage( - { - type: "app.get", - what: "localeInfo" - }, - (localeInfo) => - { - document.documentElement.lang = localeInfo.locale; - document.documentElement.dir = localeInfo.bidiDir; - } -); - -// Inserts i18n strings into matching elements. Any inner HTML already -// in the element is parsed as JSON and used as parameters to -// substitute into placeholders in the i18n message. -ext.i18n.setElementText = function(element, stringName, args) -{ - function processString(str, currentElement) - { - let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(str); - if (match) - { - processString(match[1], currentElement); - - let e = document.createElement(match[2]); - processString(match[3], e); - currentElement.appendChild(e); - - processString(match[4], currentElement); - } - else - currentElement.appendChild(document.createTextNode(str)); - } - - while (element.lastChild) - element.removeChild(element.lastChild); - processString(ext.i18n.getMessage(stringName, args), element); -}; - -// Loads i18n strings -function loadI18nStrings() -{ - function addI18nStringsToElements(containerElement) - { - let elements = containerElement.querySelectorAll("[class^='i18n_']"); - for (let node of elements) - { - let args = JSON.parse("[" + node.textContent + "]"); - if (args.length == 0) - args = null; - - let {className} = node; - if (className instanceof SVGAnimatedString) - className = className.animVal; - let stringName = className.split(/\s/)[0].substring(5); - - ext.i18n.setElementText(node, stringName, args); - } - } - addI18nStringsToElements(document); - // Content of Template is not rendered on runtime so we need to add - // translation strings for each Template documentFragment content - // individually. - for (let template of document.querySelectorAll("template")) - addI18nStringsToElements(template.content); -} - -// Provides a more readable string of the current date and time -function i18nTimeDateStrings(when) -{ - let d = new Date(when); - let timeString = d.toLocaleTimeString(); - - let now = new Date(); - if (d.toDateString() == now.toDateString()) - return [timeString]; - return [timeString, d.toLocaleDateString()]; -} - -// Formats date string to ["YYYY-MM-DD", "mm:ss"] format -function i18nFormatDateTime(when) -{ - let date = new Date(when); - let dateParts = [date.getFullYear(), date.getMonth() + 1, date.getDate(), - date.getHours(), date.getMinutes()]; - - dateParts = dateParts.map( - (datePart) => datePart < 10 ? "0" + datePart : datePart - ); - - return [dateParts.splice(0, 3).join("-"), dateParts.join(":")]; -} - -// Fill in the strings as soon as possible -window.addEventListener("DOMContentLoaded", loadI18nStrings, true); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul deleted file mode 100644 index d1de4c0..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul +++ /dev/null @@ -1,134 +0,0 @@ -<?xml version="1.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/>. - --> - -<!DOCTYPE overlay [ - <!ENTITY % overlayDTD SYSTEM "chrome://adblockplus/locale/overlay.dtd"> - %overlayDTD; - <!ENTITY % subscriptionsDTD SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd"> - %subscriptionsDTD; -]> - -<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - imagecontextlabel="&context.image.label;…" objectcontextlabel="&context.object.label;…" - mediacontextlabel="&context.media.label;…" subdocumentcontextlabel="&context.frame.label;…" - whitelistcontextlabel="&context.removeWhitelist.label;" - objtabtext="&objecttab.title;…" objtabtooltip="&objecttab.tooltip;" - subscriptionDialogTitle="&dialog.title;" - subscriptionDialogMessage="&title.label; ?1? &location.label; ?2?"> - <popupset id="abp-popupset"> - <!-- Icon's tooltip --> - <tooltip id="abp-tooltip" orient="vertical"> - <description id="abp-tooltip-action" hidden="true"/> - <label id="abp-tooltip-status-label" value="&status.tooltip;"/> - <description id="abp-tooltip-status"/> - <label id="abp-tooltip-blocked-label" value="&blocked.tooltip;" hidden="true"/> - <description id="abp-tooltip-blocked" hidden="true"/> - <label id="abp-tooltip-filters-label" value="&filters.tooltip;" hidden="true"/> - <vbox id="abp-tooltip-filters" hidden="true"/> - <description id="abp-tooltip-more-filters" value="…" hidden="true"/> - </tooltip> - </popupset> - - <!-- Icon's context menu --> - <menupopup id="abp-status-popup" context=""> - <menuitem id="abp-status-openbottombar" label="&opensidebar.label;" key="abp-key-sidebar" command="abp-command-sidebar"/> - <menuitem id="abp-status-closebottombar" label="&closesidebar.label;" key="abp-key-sidebar" command="abp-command-sidebar"/> - <menuitem id="abp-status-filters" label="&filters.label;…" key="abp-key-filters" command="abp-command-filters"/> - <menuseparator id="abp-status-whitelist-sep"/> - <menuitem id="abp-status-whitelistsite" labeltempl="&whitelist.site.label;" type="checkbox" command="abp-command-togglesitewhitelist"/> - <menuitem id="abp-status-whitelistpage" label="&whitelist.page.label;" type="checkbox" command="abp-command-togglepagewhitelist"/> - <menuitem id="abp-status-disabled" label="&disable.label;" type="checkbox" key="abp-key-enable" command="abp-command-enable"/> - <menuseparator/> - <menu id="abp-status-options" label="&options.label;"> - <menupopup id="abp-status-options-popup"> - <menuitem id="abp-status-frameobjects" label="&objecttabs.label;" type="checkbox" command="abp-command-toggleobjtabs"/> - <menuitem id="abp-status-savestats" label="&counthits.label;" type="checkbox" command="abp-command-togglesavestats"/> - <menuitem id="abp-status-sync" label="&sync.label;" type="checkbox" command="abp-command-togglesync"/> - <menuitem id="abp-status-shownotifications" label="&shownotifications.label;" type="checkbox" command="abp-command-toggleshownotifications"/> - <menuseparator id="abp-status-iconSettingsSeparator"/> - <menuitem id="abp-status-showintoolbar" label="&showintoolbar.label;" type="checkbox" command="abp-command-toggleshowintoolbar"/> - <menuitem id="abp-status-showinstatusbar" label="&showinstatusbar.label;" type="checkbox" command="abp-command-toggleshowinstatusbar"/> - </menupopup> - </menu> - - </menupopup> - - <keyset id="abp-keyset"/> - - <!-- Dummy oncommand attributes are work-arounds for bug 371900 --> - <commandset id="abp-commandset"> - <command id="abp-command-filters" oncommand="//"/> - <command id="abp-command-settings" oncommand="//"/> - <command id="abp-command-sidebar" oncommand="//"/> - <command id="abp-command-togglesitewhitelist"/> - <command id="abp-command-togglepagewhitelist"/> - <command id="abp-command-toggleobjtabs"/> - <command id="abp-command-togglesavestats"/> - <command id="abp-command-togglesync"/> - <command id="abp-command-toggleshowintoolbar"/> - <command id="abp-command-toggleshowinstatusbar"/> - <command id="abp-command-enable" oncommand="//"/> - <command id="abp-command-contribute"/> - <command id="abp-command-contribute-hide"/> - <command id="abp-command-toggleshownotifications"/> - </commandset> - - <statusbarpanel id="abp-status" class="statusbarpanel-iconic" - tooltip="abp-tooltip"/> - - <toolbarbutton id="abp-toolbarbutton" class="toolbarbutton-1" label="&toolbarbutton.label;" - tooltip="abp-tooltip"/> - - <!-- Tools menu --> - <menu id="abp-menuitem" label="&toolbarbutton.label;"/> - - <!-- Bottom bar --> - <hbox id="abp-bottombar-container"> - <splitter id="abp-bottombar-splitter"/> - <vbox id="abp-bottombar"> - <toolbox id="abp-bottombar-header"> - <toolbar id="abp-bottombar-toolbar" align="center" grippyhidden="true" fullscreentoolbar="true"> - <label id="abp-bottombar-title" control="abp-bottombar-browser" value="&sidebar.title;" flex="1" crop="end"/> - <toolbarbutton id="abp-bottombar-close" command="abp-command-sidebar" tooltiptext="&closesidebar.label;"/> - </toolbar> - </toolbox> - <iframe id="abp-bottombar-browser" src="chrome://adblockplus/content/ui/sidebar.xul" flex="1"/> - </vbox> - </hbox> - - <!-- Notification panel --> - <panel id="abp-notification" type="arrow" orient="vertical" - xmlns:html="http://www.w3.org/1999/xhtml"> - <vbox id="abp-notification-content"> - <toolbar align="start"> - <label id="abp-notification-title" class="header" flex="1" crop="end"/> - <toolbarbutton id="abp-notification-close" tooltiptext="¬ification.button.close;"/> - </toolbar> - <html:p id="abp-notification-message"/> - <hbox id="abp-notification-question"> - <button id="abp-notification-yes" label="¬ification.button.yes;"/> - <button id="abp-notification-no" label="¬ification.button.no;"/> - </hbox> - </vbox> - <vbox id="abp-notification-close-content"> - <toolbarbutton id="abp-notification-hide" label="¬ification.closing.button.hide;"/> - <toolbarbutton id="abp-notification-optout" label="¬ification.closing.button.optout;"/> - </vbox> - </panel> -</overlay> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.js deleted file mode 100644 index fadad52..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.js +++ /dev/null @@ -1,164 +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() -{ - let progressBar, canvas, headers, isRTL; - - function onLoad() - { - window.removeEventListener("load", onLoad, false); - - // Init global variables - progressBar = document.getElementById("progressBar"); - canvas = document.getElementById("progressBarCanvas"); - - headers = Array.prototype.slice.call(progressBar.getElementsByTagName("label")); - for (let i = 0; i < headers.length; i++) - canvas.parentNode.appendChild(headers[i]); - - // Expose properties - Object.defineProperty(progressBar, "activeItem", - { - get: getActiveItem, - set: setActiveItem - }); - Object.defineProperty(progressBar, "activeItemComplete", - { - get: getActiveItemComplete, - set: setActiveItemComplete - }); - - isRTL = (window.getComputedStyle(document.documentElement).direction == "rtl"); - - // Run actual drawing delayed, once the sizes are fixed - window.setTimeout(init, 0); - }; - window.addEventListener("load", onLoad, false); - - function init() - { - const gapWidth = 5; - const arrowheadWidth = 5; - - let width = canvas.width = canvas.offsetWidth; - let height = canvas.height = canvas.offsetHeight; - - let context = canvas.getContext("2d"); - context.fillStyle = window.getComputedStyle(progressBar, "").color; - context.strokeStyle = window.getComputedStyle(progressBar, "").color; - context.lineWidth = 1; - if (isRTL) - { - context.translate(width, 0); - context.scale(-1, 1); - } - - let panelCount = headers.length; - let panelWidth = (width - gapWidth * (panelCount - 1) - 1) / panelCount; - for (let i = 0; i < panelCount; i++) - { - context.save(); - context.translate(Math.round(i * (panelWidth + gapWidth)) + 0.5, 0.5); - context.beginPath(); - if (i) - context.moveTo(-arrowheadWidth, 0); - else - context.moveTo(0, 0); - context.lineTo(panelWidth - arrowheadWidth, 0); - context.lineTo(panelWidth, (height - 1) / 2); - context.lineTo(panelWidth - arrowheadWidth, height - 1); - if (i) - { - context.lineTo(-arrowheadWidth, height - 1); - context.lineTo(0, (height - 1) / 2); - context.lineTo(-arrowheadWidth, 0); - } - else - { - context.lineTo(0, height - 1); - context.lineTo(0, 0); - } - - context.stroke(); - context.restore(); - - let childLeft = Math.round(i * (panelWidth + gapWidth) + 1); - let childWidth = panelWidth - arrowheadWidth - 2; - let child = headers[i]; - child.style.MozMarginStart = childLeft + "px"; - child.style.MozMarginEnd = (width - childLeft - childWidth) + "px"; - child.style.width = childWidth + "px"; - } - - // Resize after initialization should be ignored - canvas.parentNode.removeAttribute("flex"); - } - - function getActiveItem() - { - for (let i = 0; i < headers.length; i++) - { - let header = headers[i]; - if (header.classList.contains("active")) - return header; - } - return null; - } - - function setActiveItem(val) - { - let complete = true; - for (let i = 0; i < headers.length; i++) - { - let header = headers[i]; - if (header == val) - complete = false; - - if (!complete && header.value[0] == "✔") - header.value = header.value.replace(/^✔\s*/, ""); - else if (complete && header.value[0] != "✔") - header.value = "✔ " + header.value; - - if (header == val) - header.classList.add("active"); - else - header.classList.remove("active"); - } - } - - function getActiveItemComplete() - { - let activeItem = this.activeItem; - if (!activeItem) - return false; - else - return activeItem.value[0] == "✔"; - } - - function setActiveItemComplete(val) - { - let activeItem = this.activeItem; - if (!activeItem) - return; - - if (!val && activeItem.value[0] == "✔") - activeItem.value = activeItem.value.replace(/^✔\s*/, ""); - else if (val && activeItem.value[0] != "✔") - activeItem.value = "✔ " + activeItem.value; - } -})(); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul deleted file mode 100644 index 0e85303..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul +++ /dev/null @@ -1,29 +0,0 @@ -<?xml version="1.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/>. - --> - -<overlay id="progressBarOverlay" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - <script type="application/x-javascript;version=1.7" src="progressBar.js"/> - - <hbox id="progressBar" pack="center"> - <stack flex="1"> - <canvas xmlns="http://www.w3.org/1999/xhtml" id="progressBarCanvas" width="1" height="1"/> - </stack> - </hbox> -</overlay> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js deleted file mode 100644 index ee9e7f5..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js +++ /dev/null @@ -1,1565 +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/>. - */ - -// -// Report data template, more data will be added during data collection -// - -let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); -let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); - -const MILLISECONDS_IN_SECOND = 1000; -const SECONDS_IN_MINUTE = 60; -const SECONDS_IN_HOUR = 60 * SECONDS_IN_MINUTE; -const SECONDS_IN_DAY = 24 * SECONDS_IN_HOUR; - -let outerWindowID = window.arguments[0]; -let windowURI = window.arguments[1]; -if (typeof windowURI == "string") - windowURI = Services.newURI(windowURI, null, null); -let browser = window.arguments[2]; -let isPrivate = false; - -let reportData = new DOMParser().parseFromString("<report></report>", "text/xml"); - -// Some helper functions to work with the report data -function reportElement(tag) -{ - for (let child = reportData.documentElement.firstChild; child; child = child.nextSibling) - if (child.nodeType == Node.ELEMENT_NODE && child.tagName == tag) - return child; - let element = reportData.createElement(tag); - reportData.documentElement.appendChild(element); - return element; -} -function removeReportElement(tag) -{ - for (let child = reportData.documentElement.firstChild; child; child = child.nextSibling) - if (child.nodeType == Node.ELEMENT_NODE && child.tagName == tag) - child.parentNode.removeChild(child); -} -function appendElement(parent, tag, attributes, body) -{ - let element = parent.ownerDocument.createElement(tag); - if (typeof attributes == "object" && attributes !== null) - for (let attribute in attributes) - if (attributes.hasOwnProperty(attribute)) - element.setAttribute(attribute, attributes[attribute]); - if (typeof body != "undefined" && body !== null) - element.textContent = body; - parent.appendChild(element); - return element; -} -function serializeReportData() -{ - let result = new XMLSerializer().serializeToString(reportData); - - // Insert line breaks before each new tag - result = result.replace(/(<[^\/]([^"<>]*|"[^"]*")*>)/g, "\n$1"); - result = result.replace(/^\n+/, ""); - return result; -} - -{ - let element = reportElement("adblock-plus"); - let {addonVersion} = require("info"); - element.setAttribute("version", addonVersion); - element.setAttribute("locale", Utils.appLocale); -} -{ - let element = reportElement("application"); - element.setAttribute("name", Services.appinfo.name); - element.setAttribute("vendor", Services.appinfo.vendor); - element.setAttribute("version", Services.appinfo.version); - element.setAttribute("userAgent", window.navigator.userAgent); -} -{ - let element = reportElement("platform"); - element.setAttribute("name", "Gecko"); - element.setAttribute("version", Services.appinfo.platformVersion); - element.setAttribute("build", Services.appinfo.platformBuildID); -}; -{ - let element = reportElement("options"); - appendElement(element, "option", {id: "enabled"}, Prefs.enabled); - appendElement(element, "option", {id: "objecttabs"}, Prefs.frameobjects); - appendElement(element, "option", {id: "collapse"}, !Prefs.fastcollapse); - appendElement(element, "option", {id: "subscriptionsAutoUpdate"}, Prefs.subscriptions_autoupdate); - appendElement(element, "option", {id: "javascript"}, Services.prefs.getBoolPref("javascript.enabled")); - appendElement(element, "option", {id: "cookieBehavior"}, Services.prefs.getIntPref("network.cookie.cookieBehavior")); -}; - -// -// Data collectors -// - -var reportsListDataSource = -{ - list: [], - - collectData: function(outerWindowID, windowURI, browser, callback) - { - let data = Prefs.recentReports; - if (data && "length" in data) - { - for (let i = 0; i < data.length; i++) - { - let entry = data[i]; - if (typeof entry.reportURL == "string" && entry.reportURL && - typeof entry.time == "number" && Date.now() - entry.time < 30*24*60*60*1000) - { - let newEntry = {site: null, reportURL: entry.reportURL, time: entry.time}; - if (typeof entry.site == "string" && entry.site) - newEntry.site = entry.site; - this.list.push(newEntry); - } - } - } - - if (this.list.length > 10) - this.list.splice(10); - - E("recentReports").hidden = !this.list.length; - if (this.list.length) - { - let rows = E("recentReportsRows") - for (let i = 0; i < this.list.length; i++) - { - let entry = this.list[i]; - let row = document.createElement("row"); - - let link = document.createElement("description"); - link.setAttribute("class", "text-link"); - link.setAttribute("url", entry.reportURL); - link.textContent = entry.reportURL.replace(/^.*\/(?=[^\/])/, ""); - row.appendChild(link); - - let site = document.createElement("description"); - if (entry.site) - site.textContent = entry.site; - row.appendChild(site); - - let time = document.createElement("description"); - time.textContent = Utils.formatTime(entry.time); - row.appendChild(time); - - rows.appendChild(row); - } - } - - callback(); - }, - - addReport: function(site, reportURL) - { - this.list.unshift({site: site, reportURL: reportURL, time: Date.now()}); - Prefs.recentReports = this.list; - }, - - clear: function() - { - this.list = []; - Prefs.recentReports = this.list; - E("recentReports").hidden = true; - }, - - handleClick: function(event) - { - if (event.button != 0 || !event.target || !event.target.hasAttribute("url")) - return; - - UI.loadInBrowser(event.target.getAttribute("url")); - } -}; - -var requestsDataSource = -{ - requests: reportElement("requests"), - origRequests: [], - requestNotifier: null, - callback: null, - nodeByKey: Object.create(null), - - collectData: function(outerWindowID, windowURI, browser, callback) - { - this.callback = callback; - this.requestNotifier = new RequestNotifier(outerWindowID, this.onRequestFound, this); - }, - - onRequestFound: function(entry, scanComplete) - { - if (entry) - { - let key = entry.location + " " + entry.type + " " + entry.docDomain; - let requestXML; - if (key in this.nodeByKey) - { - requestXML = this.nodeByKey[key]; - requestXML.setAttribute("count", parseInt(requestXML.getAttribute("count"), 10) + 1); - } - else - { - requestXML = this.nodeByKey[key] = appendElement(this.requests, "request", { - location: censorURL(entry.location), - type: entry.type, - docDomain: entry.docDomain, - thirdParty: entry.thirdParty, - count: 1 - }); - - // Location is meaningless for element hiding hits - if (requestXML.getAttribute("location")[0] == "#") - requestXML.removeAttribute("location"); - } - - if (entry.filter) - requestXML.setAttribute("filter", entry.filter); - - this.origRequests.push(entry); - } - - if (scanComplete) - { - this.requestNotifier.shutdown(); - this.requestNotifier = null; - this.callback(); - } - } -}; - -var filtersDataSource = -{ - origFilters: [], - - collectData: function(outerWindowID, windowURI, browser, callback) - { - RequestNotifier.getWindowStatistics(outerWindowID, (wndStats) => - { - if (wndStats) - { - let filters = reportElement("filters"); - for (let f in wndStats.filters) - { - let filter = Filter.fromText(f) - let hitCount = wndStats.filters[f]; - appendElement(filters, "filter", { - text: filter.text, - subscriptions: filter.subscriptions.filter(subscriptionsDataSource.subscriptionFilter).map(s => s.url).join(" "), - hitCount: hitCount - }); - this.origFilters.push(filter); - } - } - callback(); - }); - } -}; - -var subscriptionsDataSource = -{ - subscriptionFilter: function(s) - { - if (s.disabled || !(s instanceof RegularSubscription)) - return false; - if (s instanceof DownloadableSubscription && !/^(http|https|ftp):/i.test(s.url)) - return false; - return true; - }, - - collectData: function(outerWindowID, windowURI, browser, callback) - { - let subscriptions = reportElement("subscriptions"); - let now = Math.round(Date.now() / 1000); - for (let i = 0; i < FilterStorage.subscriptions.length; i++) - { - let subscription = FilterStorage.subscriptions[i]; - if (!this.subscriptionFilter(subscription)) - continue; - - let subscriptionXML = appendElement(subscriptions, "subscription", { - id: subscription.url, - disabledFilters: subscription.filters.filter(filter => filter instanceof ActiveFilter && filter.disabled).length - }); - if (subscription.version) - subscriptionXML.setAttribute("version", subscription.version); - if (subscription.lastDownload) - subscriptionXML.setAttribute("lastDownloadAttempt", subscription.lastDownload - now); - if (subscription instanceof DownloadableSubscription) - { - if (subscription.lastSuccess) - subscriptionXML.setAttribute("lastDownloadSuccess", subscription.lastSuccess - now); - if (subscription.softExpiration) - subscriptionXML.setAttribute("softExpiration", subscription.softExpiration - now); - if (subscription.expires) - subscriptionXML.setAttribute("hardExpiration", subscription.expires - now); - subscriptionXML.setAttribute("downloadStatus", subscription.downloadStatus); - } - } - callback(); - } -}; - -var remoteDataSource = -{ - collectData: function(outerWindowID, windowURI, browser, callback) - { - let {port} = require("messaging"); - let screenshotWidth = screenshotDataSource.getWidth(); - port.emitWithResponse("collectData", {outerWindowID, screenshotWidth}) - .then(data => - { - screenshotDataSource.setData(data && data.screenshot); - framesDataSource.setData(windowURI, data && data.opener, data && data.referrer, data && data.frames); - - if (data && data.isPrivate) - isPrivate = true; - let element = reportElement("options"); - appendElement(element, "option", {id: "privateBrowsing"}, isPrivate); - - callback(); - }); - } -} - -var screenshotDataSource = -{ - imageOffset: 10, - - // Fields used for user interaction - _enabled: true, - _canvas: null, - _context: null, - _selectionType: "mark", - _currentData: null, - _undoQueue: [], - - getWidth: function() - { - let canvas = E("screenshotCanvas"); - return canvas.offsetWidth - this.imageOffset * 2; - }, - - setData: function(screenshot) - { - let canvas = E("screenshotCanvas"); - - // Do not resize canvas any more (no idea why Gecko requires both to be set) - canvas.parentNode.style.MozBoxAlign = "center"; - canvas.parentNode.align = "center"; - - let context = canvas.getContext("2d"); - this._canvas = canvas; - this._context = context; - - if (screenshot) - { - canvas.width = screenshot.width + this.imageOffset * 2; - canvas.height = screenshot.height + this.imageOffset * 2; - context.putImageData(screenshot, this.imageOffset, this.imageOffset); - } - - // Init canvas settings - context.fillStyle = "rgb(0, 0, 0)"; - context.strokeStyle = "rgba(255, 0, 0, 0.7)"; - context.lineWidth = 3; - context.lineJoin = "round"; - }, - - get enabled() - { - return this._enabled; - }, - set enabled(enabled) - { - if (this._enabled == enabled) - return; - - this._enabled = enabled; - this._canvas.style.opacity = this._enabled ? "" : "0.3" - E("screenshotMarkButton").disabled = !this._enabled; - E("screenshotRemoveButton").disabled = !this._enabled; - E("screenshotUndoButton").disabled = !this._enabled || !this._undoQueue.length; - }, - - get selectionType() - { - return this._selectionType; - }, - set selectionType(type) - { - if (this._selectionType == type) - return; - - // Abort selection already in progress - this.abortSelection(); - - this._selectionType = type; - }, - - exportData: function() - { - removeReportElement("screenshot"); - if (this.enabled) - { - appendElement(reportData.documentElement, "screenshot", { - edited: (this._undoQueue.length ? 'true' : 'false') - }, this._canvas.toDataURL()); - } - }, - - abortSelection: function() - { - if (this._currentData && this._currentData.data) - { - this._context.putImageData(this._currentData.data, - Math.min(this._currentData.anchorX, this._currentData.currentX), - Math.min(this._currentData.anchorY, this._currentData.currentY)); - } - document.removeEventListener("keypress", this.handleKeyPress, true); - this._currentData = null; - }, - - handleKeyPress: function(event) - { - if (event.keyCode == Ci.nsIDOMKeyEvent.DOM_VK_ESCAPE) - { - event.stopPropagation(); - event.preventDefault(); - screenshotDataSource.abortSelection(); - } - }, - - startSelection: function(event) - { - if (event.button == 2) - this.abortSelection(); // Right mouse button aborts selection - - if (event.button != 0 || !this.enabled) - return; - - // Abort selection already in progress - this.abortSelection(); - - let boxObject = document.getBoxObjectFor(this._canvas); - let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY]; - this._currentData = { - data: null, - anchorX: x, - anchorY: y, - currentX: -1, - currentY: -1 - }; - this.updateSelection(event); - - document.addEventListener("keypress", this.handleKeyPress, true); - }, - - updateSelection: function(event) - { - if (event.button != 0 || !this._currentData) - return; - - let boxObject = document.getBoxObjectFor(this._canvas); - let [x, y] = [event.screenX - boxObject.screenX, event.screenY - boxObject.screenY]; - if (this._currentData.currentX == x && this._currentData.currentY == y) - return; - - if (this._currentData.data) - { - this._context.putImageData(this._currentData.data, - Math.min(this._currentData.anchorX, this._currentData.currentX), - Math.min(this._currentData.anchorY, this._currentData.currentY)); - } - - this._currentData.currentX = x; - this._currentData.currentY = y; - - let left = Math.min(this._currentData.anchorX, this._currentData.currentX); - let right = Math.max(this._currentData.anchorX, this._currentData.currentX); - let top = Math.min(this._currentData.anchorY, this._currentData.currentY); - let bottom = Math.max(this._currentData.anchorY, this._currentData.currentY); - - let minDiff = (this._selectionType == "mark" ? 3 : 1); - if (right - left >= minDiff && bottom - top >= minDiff) - this._currentData.data = this._context.getImageData(left, top, right - left, bottom - top); - else - this._currentData.data = null; - - if (this._selectionType == "mark") - { - // all coordinates need to be moved 1.5px inwards to get the desired result - left += 1.5; - right -= 1.5; - top += 1.5; - bottom -= 1.5; - if (left < right && top < bottom) - this._context.strokeRect(left, top, right - left, bottom - top); - } - else if (this._selectionType == "remove") - this._context.fillRect(left, top, right - left, bottom - top); - }, - - stopSelection: function(event) - { - if (event.button != 0 || !this._currentData) - return; - - if (this._currentData.data) - { - this._undoQueue.push(this._currentData); - E("screenshotUndoButton").disabled = false; - } - - this._currentData = null; - document.removeEventListener("keypress", this.handleKeyPress, true); - }, - - undo: function() - { - let op = this._undoQueue.pop(); - if (!op) - return; - - this._context.putImageData(op.data, - Math.min(op.anchorX, op.currentX), - Math.min(op.anchorY, op.currentY)); - - if (!this._undoQueue.length) - E("screenshotUndoButton").disabled = true; - } -}; - -var framesDataSource = -{ - site: null, - - setData: function(windowURI, opener, referrer, frames) - { - try - { - this.site = windowURI.host; - if (this.site) - document.title += " (" + this.site + ")"; - } - catch (e) - { - // Expected exception - not all URL schemes have a host name - } - - let window = reportElement("window"); - window.setAttribute("url", censorURL(windowURI.spec)); - if (opener) - window.setAttribute("opener", censorURL(opener)); - if (referrer) - window.setAttribute("referrer", censorURL(referrer)); - this.addFrames(frames || [], window); - }, - - addFrames: function(frames, xmlList) - { - for (let frame of frames) - { - let frameXML = appendElement(xmlList, "frame", { - url: censorURL(frame.url) - }); - this.addFrames(frame.frames, frameXML); - } - } -}; - -var errorsDataSource = -{ - collectData: function(outerWindowID, windowURI, browser, callback) - { - let {addonID} = require("info"); - addonID = addonID.replace(/[\{\}]/g, ""); - - // See https://bugzilla.mozilla.org/show_bug.cgi?id=664695 - starting with - // Gecko 19 this function returns the result, before that it wrote to a - // parameter. - let outparam = {}; - let messages = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService).getMessageArray(outparam, {}); - messages = messages || outparam.value || []; - messages = messages.filter(function(message) - { - return (message instanceof Ci.nsIScriptError && - !/^https?:/i.test(message.sourceName) && - (/adblock/i.test(message.errorMessage) || /adblock/i.test(message.sourceName) || - message.errorMessage.indexOf(addonID) >= 0 || message.sourceName && message.sourceName.indexOf(addonID) >= 0)); - }); - if (messages.length > 10) // Only the last 10 messages - messages = messages.slice(messages.length - 10, messages.length); - - // Censor app and profile paths in error messages - let censored = Object.create(null); - let pathList = [["ProfD", "%PROFILE%"], ["GreD", "%GRE%"], ["CurProcD", "%APP%"]]; - for (let i = 0; i < pathList.length; i++) - { - let [pathID, placeholder] = pathList[i]; - try - { - let file = FileUtils.getDir(pathID, [], false); - censored[file.path.replace(/[\\\/]+$/, '')] = placeholder; - let uri = Utils.ioService.newFileURI(file); - censored[uri.spec.replace(/[\\\/]+$/, '')] = placeholder; - } catch(e) {} - } - - function str2regexp(str, flags) - { - return new RegExp(str.replace(/\W/g, "\\$&"), flags); - } - - let errors = reportElement("errors"); - for (let i = 0; i < messages.length; i++) - { - let message = messages[i]; - - let text = message.errorMessage; - for (let path in censored) - text = text.replace(str2regexp(path, "gi"), censored[path]); - if (text.length > 256) - text = text.substr(0, 256) + "..."; - - let file = message.sourceName; - for (let path in censored) - file = file.replace(str2regexp(path, "gi"), censored[path]); - if (file.length > 256) - file = file.substr(0, 256) + "..."; - - let sourceLine = message.sourceLine; - if (sourceLine.length > 256) - sourceLine = sourceLine.substr(0, 256) + "..."; - - appendElement(errors, "error", { - type: message.flags & Ci.nsIScriptError.warningFlag ? "warning" : "error", - text: text, - file: file, - line: message.lineNumber, - column: message.columnNumber, - sourceLine: sourceLine - }); - } - - callback(); - } -}; - -var extensionsDataSource = -{ - data: reportData.createElement("extensions"), - - collectData: function(outerWindowID, windowURI, browser, callback) - { - try - { - let AddonManager = Cu.import("resource://gre/modules/AddonManager.jsm", null).AddonManager; - AddonManager.getAddonsByTypes(["extension", "plugin"], function(items) - { - for (let i = 0; i < items.length; i++) - { - let item = items[i]; - if (!item.isActive) - continue; - appendElement(this.data, "extension", { - id: item.id, - name: item.name, - type: item.type, - version: item.version - }); - } - callback(); - }.bind(this)); - } - catch (e) - { - // No add-on manager, what's going on? Skip this step. - callback(); - } - }, - - exportData: function(doExport) - { - if (doExport) - reportData.documentElement.appendChild(this.data); - else if (this.data.parentNode) - this.data.parentNode.removeChild(this.data); - } -}; - -var subscriptionUpdateDataSource = -{ - browser: null, - type: null, - outdated: null, - needUpdate: null, - - subscriptionFilter: function(s) - { - if (s instanceof DownloadableSubscription) - return subscriptionsDataSource.subscriptionFilter(s); - else - return false; - }, - - collectData: function(outerWindowID, windowURI, browser, callback) - { - this.browser = browser; - let now = Date.now() / MILLISECONDS_IN_SECOND; - let outdatedThreshold = now - 14 * SECONDS_IN_DAY; - let needUpdateThreshold = now - 1 * SECONDS_IN_HOUR; - - this.outdated = []; - this.needUpdate = []; - - let subscriptions = FilterStorage.subscriptions.filter(this.subscriptionFilter); - for (let i = 0; i < subscriptions.length; i++) - { - let lastSuccess = subscriptions[i].lastSuccess; - if (lastSuccess < outdatedThreshold) - this.outdated.push(subscriptions[i]); - if (lastSuccess < needUpdateThreshold) - this.needUpdate.push(subscriptions[i]); - } - - callback(); - }, - - updatePage: function(type) - { - this.type = type; - E("updateInProgress").hidden = (type != "false positive" || this.needUpdate.length == 0); - E("outdatedSubscriptions").hidden = !E("updateInProgress").hidden || this.outdated.length == 0; - if (!E("outdatedSubscriptions").hidden) - { - let template = E("outdatedSubscriptionTemplate"); - let list = E("outdatedSubscriptionsList"); - while (list.lastChild) - list.removeChild(list.lastChild); - - for (let i = 0; i < this.outdated.length; i++) - { - let subscription = this.outdated[i]; - let entry = template.cloneNode(true); - entry.removeAttribute("id"); - entry.removeAttribute("hidden"); - entry.setAttribute("_url", subscription.url); - entry.setAttribute("tooltiptext", subscription.url); - entry.textContent = getSubscriptionTitle(subscription); - list.appendChild(entry); - } - } - return !E("updateInProgress").hidden || !E("outdatedSubscriptions").hidden; - }, - - showPage: function() - { - document.documentElement.canAdvance = false; - - if (!E("updateInProgress").hidden) - { - document.documentElement.canRewind = false; - - for (let i = 0; i < this.needUpdate.length; i++) - Synchronizer.execute(this.needUpdate[i], true); - - let listener = function(action) - { - if (!/^subscription\./.test(action)) - return; - - for (let i = 0; i < this.needUpdate.length; i++) - if (Synchronizer.isExecuting(this.needUpdate[i].url)) - return; - - FilterNotifier.removeListener(listener); - E("updateInProgress").hidden = "true"; - - let filtersRemoved = false; - let requests = requestsDataSource.origRequests; - for (let i = 0; i < requests.length; i++) - { - if (!requests[i].filter) - continue; - - let filter = Filter.fromText(requests[i].filter); - if (!filter.subscriptions.some(s => !s.disabled)) - filtersRemoved = true; - } - - if (filtersRemoved) - { - // Force the user to reload the page - E("updateFixedIssue").hidden = false; - document.documentElement.canAdvance = true; - - let nextButton = document.documentElement.getButton("next"); - [nextButton.label, nextButton.accessKey] = Utils.splitLabel(E("updatePage").getAttribute("reloadButtonLabel")); - document.documentElement.addEventListener("wizardnext", event => - { - event.preventDefault(); - event.stopPropagation(); - window.close(); - this.browser.reload(); - }, true); - } - else - { - this.collectData(null, null, null, function() {}); - this.needUpdate = []; - if (this.outdated.length) - { - document.documentElement.canRewind = true; - - this.updatePage(this.type); - this.showPage(); - } - else - { - // No more issues, make sure to remove this page from history and - // advance to the next page. - document.documentElement.canRewind = true; - document.documentElement.canAdvance = true; - - let next = document.documentElement.currentPage.next; - document.documentElement.rewind(); - document.documentElement.currentPage.next = next; - - document.documentElement.advance(); - } - } - }.bind(this); - - FilterNotifier.addListener(listener); - window.addEventListener("unload", function() - { - FilterNotifier.removeListener(listener); - }); - } - }, - - updateOutdated: function() - { - for (let i = 0; i < this.outdated.length; i++) - Synchronizer.execute(this.outdated[i], true); - } -} - -var issuesDataSource = -{ - browser: null, - isEnabled: Prefs.enabled, - whitelistFilter: null, - disabledFilters: [], - disabledSubscriptions: [], - ownFilters: [], - numSubscriptions: 0, - numAppliedFilters: Infinity, - - subscriptionFilter: function(s) - { - if (s instanceof DownloadableSubscription && - s.url != Prefs.subscriptions_exceptionsurl && - s.url != Prefs.subscriptions_antiadblockurl) - { - return subscriptionsDataSource.subscriptionFilter(s); - } - else - return false; - }, - - collectData: function(outerWindowID, windowURI, browser, callback) - { - this.browser = browser; - this.whitelistFilter = Policy.isWhitelisted(windowURI.spec); - - if (!this.whitelistFilter && this.isEnabled) - { - // Find disabled filters in active subscriptions matching any of the requests - let disabledMatcher = new CombinedMatcher(); - for (let subscription of FilterStorage.subscriptions) - { - if (subscription.disabled) - continue; - - for (let filter of subscription.filters) - if (filter instanceof BlockingFilter && filter.disabled) - disabledMatcher.add(filter); - } - - let seenFilters = Object.create(null); - for (let request of requestsDataSource.origRequests) - { - if (request.filter) - continue; - - let filter = disabledMatcher.matchesAny(request.location, RegExpFilter.typeMap[request.type], request.docDomain, request.thirdParty); - if (filter && !(filter.text in seenFilters)) - { - this.disabledFilters.push(filter); - seenFilters[filter.text] = true; - } - } - - // Find disabled subscriptions with filters matching any of the requests - let seenSubscriptions = Object.create(null); - for (let subscription of FilterStorage.subscriptions) - { - if (!subscription.disabled) - continue; - - disabledMatcher.clear(); - for (let filter of subscription.filters) - if (filter instanceof BlockingFilter) - disabledMatcher.add(filter); - - for (let request of requestsDataSource.origRequests) - { - if (request.filter) - continue; - - let filter = disabledMatcher.matchesAny(request.location, RegExpFilter.typeMap[request.type], request.docDomain, request.thirdParty); - if (filter && !(subscription.url in seenSubscriptions)) - { - this.disabledSubscriptions.push(subscription); - seenSubscriptions[subscription.text] = true; - break; - } - } - } - - this.numSubscriptions = FilterStorage.subscriptions.filter(this.subscriptionFilter).length; - this.numAppliedFilters = 0; - for (let filter of filtersDataSource.origFilters) - { - if (filter instanceof WhitelistFilter) - continue; - - this.numAppliedFilters++; - if (filter.subscriptions.some(subscription => subscription instanceof SpecialSubscription)) - this.ownFilters.push(filter); - } - } - - callback(); - }, - - updateIssues: function(type) - { - if (type == "other") - { - E("typeSelectorPage").next = "typeWarning"; - return; - } - - E("issuesWhitelistBox").hidden = !this.whitelistFilter; - E("issuesDisabledBox").hidden = this.isEnabled; - E("issuesNoFiltersBox").hidden = (type != "false positive" || this.numAppliedFilters > 0); - E("issuesNoSubscriptionsBox").hidden = (type != "false negative" || this.numAppliedFilters > 0 || this.numSubscriptions > 0); - E("issuesSubscriptionCountBox").hidden = (this.numSubscriptions < 5); - - let ownFiltersBox = E("issuesOwnFilters"); - if (this.ownFilters.length && !ownFiltersBox.firstChild) - { - let template = E("issuesOwnFiltersTemplate"); - for (let filter of this.ownFilters) - { - let element = template.cloneNode(true); - element.removeAttribute("id"); - element.removeAttribute("hidden"); - element.firstChild.setAttribute("value", filter.text); - element.firstChild.setAttribute("tooltiptext", filter.text); - element.abpFilter = filter; - ownFiltersBox.appendChild(element); - } - } - E("issuesOwnFiltersBox").hidden = (type != "false positive" || this.ownFilters.length == 0); - - let disabledSubscriptionsBox = E("issuesDisabledSubscriptions"); - if (this.disabledSubscriptions.length && !disabledSubscriptionsBox.firstChild) - { - let template = E("issuesDisabledSubscriptionsTemplate"); - for (let subscription of this.disabledSubscriptions) - { - let element = template.cloneNode(true); - element.removeAttribute("id"); - element.removeAttribute("hidden"); - element.firstChild.setAttribute("value", getSubscriptionTitle(subscription)); - element.setAttribute("tooltiptext", subscription instanceof DownloadableSubscription ? subscription.url : getSubscriptionTitle(subscription)); - element.abpSubscription = subscription; - disabledSubscriptionsBox.appendChild(element); - } - } - E("issuesDisabledSubscriptionsBox").hidden = (type != "false negative" || this.disabledSubscriptions.length == 0); - - let disabledFiltersBox = E("issuesDisabledFilters"); - if (this.disabledFilters.length && !disabledFiltersBox.firstChild) - { - let template = E("issuesDisabledFiltersTemplate"); - for (let filter of this.disabledFilters) - { - let element = template.cloneNode(true); - element.removeAttribute("id"); - element.removeAttribute("hidden"); - element.firstChild.setAttribute("value", filter.text); - element.setAttribute("tooltiptext", filter.text); - element.abpFilter = filter; - disabledFiltersBox.appendChild(element); - } - } - E("issuesDisabledFiltersBox").hidden = (type != "false negative" || this.disabledFilters.length == 0); - - // Don't allow sending report if the page is whitelisted - we need the data. - // Also disallow reports without matching filters or without subscriptions, - // subscription authors cannot do anything about those. - E("issuesOverride").hidden = !E("issuesWhitelistBox").hidden || - !E("issuesDisabledBox").hidden || - !E("issuesNoFiltersBox").hidden || - !E("issuesNoSubscriptionsBox").hidden || - !E("issuesSubscriptionCountBox").hidden; - - let page = E("typeSelectorPage"); - if (subscriptionUpdateDataSource.updatePage(type)) - { - page.next = "update"; - page = E("updatePage"); - } - - if (E("issuesWhitelistBox").hidden && E("issuesDisabledBox").hidden && - E("issuesNoFiltersBox").hidden && E("issuesNoSubscriptionsBox").hidden && - E("issuesOwnFiltersBox").hidden && E("issuesDisabledFiltersBox").hidden && - E("issuesDisabledSubscriptionsBox").hidden && E("issuesSubscriptionCountBox").hidden) - { - page.next = "screenshot"; - } - else - { - page.next = "issues"; - } - }, - - forceReload: function() - { - // User changed configuration, don't allow sending report now - page needs - // to be reloaded - E("issuesOverride").hidden = true; - E("issuesChangeMessage").hidden = false; - document.documentElement.canRewind = false; - document.documentElement.canAdvance = true; - - let nextButton = document.documentElement.getButton("next"); - [nextButton.label, nextButton.accessKey] = Utils.splitLabel(E("updatePage").getAttribute("reloadButtonLabel")); - document.documentElement.addEventListener("wizardnext", event => - { - event.preventDefault(); - event.stopPropagation(); - window.close(); - this.browser.reload(); - }, true); - }, - - removeWhitelist: function() - { - if (this.whitelistFilter && this.whitelistFilter.subscriptions.length) - this.whitelistFilter.disabled = true; - E("issuesWhitelistBox").hidden = true; - this.forceReload(); - }, - - enable: function() - { - Prefs.enabled = true; - E("issuesDisabledBox").hidden = true; - this.forceReload(); - }, - - addSubscription: function() - { - let result = {}; - openDialog("subscriptionSelection.xul", "_blank", "chrome,centerscreen,modal,resizable,dialog=no", null, result); - if (!("url" in result)) - return; - - let subscriptionResults = [[result.url, result.title]]; - if ("mainSubscriptionURL" in result) - subscriptionResults.push([result.mainSubscriptionURL, result.mainSubscriptionTitle]); - - for (let [url, title] of subscriptionResults) - { - let subscription = Subscription.fromURL(url); - if (!subscription) - continue; - - FilterStorage.addSubscription(subscription); - - subscription.disabled = false; - subscription.title = title; - - if (subscription instanceof DownloadableSubscription && !subscription.lastDownload) - Synchronizer.execute(subscription); - } - - E("issuesNoSubscriptionsBox").hidden = true; - this.forceReload(); - }, - - disableFilter: function(node) - { - let filter = node.abpFilter; - if (filter && filter.subscriptions.length) - filter.disabled = true; - - node.parentNode.removeChild(node); - if (!E("issuesOwnFilters").firstChild) - E("issuesOwnFiltersBox").hidden = true; - this.forceReload(); - }, - - enableFilter: function(node) - { - let filter = node.abpFilter; - if (filter && filter.subscriptions.length) - filter.disabled = false; - - node.parentNode.removeChild(node); - if (!E("issuesDisabledFilters").firstChild) - E("issuesDisabledFiltersBox").hidden = true; - this.forceReload(); - }, - - - enableSubscription: function(node) - { - let subscription = node.abpSubscription; - if (subscription) - subscription.disabled = false; - - node.parentNode.removeChild(node); - if (!E("issuesDisabledSubscriptions").firstChild) - E("issuesDisabledSubscriptionsBox").hidden = true; - this.forceReload(); - } -}; - -let dataCollectors = [reportsListDataSource, requestsDataSource, filtersDataSource, subscriptionsDataSource, - remoteDataSource, errorsDataSource, extensionsDataSource, - subscriptionUpdateDataSource, issuesDataSource]; - -// -// Wizard logic -// - -function initWizard() -{ - // Make sure no issue type is selected by default - E("typeGroup").selectedItem = null; - document.documentElement.addEventListener("pageshow", updateNextButton, false); - - // Move wizard header - let header = document.getAnonymousElementByAttribute(document.documentElement, "class", "wizard-header"); - if (header) - { - document.getElementById("wizardHeaderLabel").setAttribute("value", document.documentElement.wizardPages[0].getAttribute("label")); - document.documentElement.insertBefore(document.getElementById("wizardHeader"), document.documentElement.firstChild); - document.documentElement.addEventListener("pageshow", function() - { - document.getElementById("wizardHeaderDeck").selectedIndex = (document.documentElement.pageIndex == 0 ? 0 : 1); - }, false); - } - - // Move privacy link - let extraButton = document.documentElement.getButton("extra1"); - extraButton.parentNode.insertBefore(E("privacyLink"), extraButton); -} - -function updateNextButton() -{ - let nextButton = document.documentElement.getButton("next"); - if (!nextButton) - return; - - if (document.documentElement.currentPage.id == "commentPage") - { - if (!("_origLabel" in nextButton)) - { - nextButton._origLabel = nextButton.label; - nextButton._origAccessKey = nextButton.accessKey; - [nextButton.label, nextButton.accessKey] = Utils.splitLabel(document.documentElement.getAttribute("sendbuttonlabel")); - } - } - else - { - if ("_origLabel" in nextButton) - { - nextButton.label = nextButton._origLabel; - nextButton.accessKey = nextButton._origAccessKey; - delete nextButton._origLabel; - delete nextButton._origAccessKey; - } - } -} - -function initDataCollectorPage() -{ - document.documentElement.canAdvance = false; - - let totalSteps = dataCollectors.length; - let initNextDataSource = function() - { - if (!dataCollectors.length) - { - // We are done, continue to next page - document.documentElement.canAdvance = true; - document.documentElement.advance(); - return; - } - - let progress = (totalSteps - dataCollectors.length) / totalSteps * 100; - if (progress > 0) - { - let progressMeter = E("dataCollectorProgress"); - progressMeter.mode = "determined"; - progressMeter.value = progress; - } - - // Continue with the next data source, asynchronously to allow progress meter to update - let dataSource = dataCollectors.shift(); - Utils.runAsync(function() - { - dataSource.collectData(outerWindowID, windowURI, browser, initNextDataSource); - }); - }; - - initNextDataSource(); -} - -function initTypeSelectorPage() -{ - E("progressBar").activeItem = E("typeSelectorHeader"); - let header = document.getAnonymousElementByAttribute(document.documentElement, "class", "wizard-header"); - if (header) - header.setAttribute("viewIndex", "1"); - - document.documentElement.canRewind = false; - typeSelectionUpdated(); -} - -function typeSelectionUpdated() -{ - let selection = E("typeGroup").selectedItem; - document.documentElement.canAdvance = (selection != null); - if (selection) - { - if (reportData.documentElement.getAttribute("type") != selection.value) - { - E("screenshotCheckbox").checked = (selection.value != "other"); - E("screenshotCheckbox").doCommand(); - E("extensionsCheckbox").checked = (selection.value == "other"); - E("extensionsCheckbox").doCommand(); - } - reportData.documentElement.setAttribute("type", selection.value); - - issuesDataSource.updateIssues(selection.value); - } -} - -function initIssuesPage() -{ - updateIssuesOverride(); -} - -function updateIssuesOverride() -{ - document.documentElement.canAdvance = E("issuesOverride").checked; -} - -function initTypeWarningPage() -{ - updateTypeWarningOverride(); - - let textElement = E("typeWarningText"); - if ("abpInitialized" in textElement) - return; - - let template = textElement.textContent.replace(/[\r\n\s]+/g, " "); - - let [, beforeLink, linkText, afterLink] = /(.*)\[link\](.*)\[\/link\](.*)/.exec(template) || [null, "", template, ""]; - while (textElement.firstChild && textElement.firstChild.nodeType != Node.ELEMENT_NODE) - textElement.removeChild(textElement.firstChild); - while (textElement.lastChild && textElement.lastChild.nodeType != Node.ELEMENT_NODE) - textElement.removeChild(textElement.lastChild); - - if (textElement.firstChild) - textElement.firstChild.textContent = linkText; - textElement.insertBefore(document.createTextNode(beforeLink), textElement.firstChild); - textElement.appendChild(document.createTextNode(afterLink)); - textElement.abpInitialized = true; -} - -function updateTypeWarningOverride() -{ - document.documentElement.canAdvance = E("typeWarningOverride").checked; -} - -function initScreenshotPage() -{ - document.documentElement.canAdvance = true; - - E("progressBar").activeItem = E("screenshotHeader"); -} - -function initCommentPage() -{ - E("progressBar").activeItem = E("commentPageHeader"); - - updateEmail(); - - screenshotDataSource.exportData(); - updateDataField(); -} - -function showDataField() -{ - E('dataDeck').selectedIndex = 1; - updateDataField(); - E('data').focus(); -} - -let _dataFieldUpdateTimeout = null; - -function _updateDataField() -{ - let dataField = E("data"); - let [selectionStart, selectionEnd] = [dataField.selectionStart, dataField.selectionEnd]; - dataField.value = serializeReportData(); - dataField.setSelectionRange(selectionStart, selectionEnd); -} - -function updateDataField() -{ - // Don't do anything if data field is hidden - if (E('dataDeck').selectedIndex != 1) - return; - - if (_dataFieldUpdateTimeout) - { - window.clearTimeout(_dataFieldUpdateTimeout); - _dataFieldUpdateTimeout = null; - } - - _dataFieldUpdateTimeout = window.setTimeout(_updateDataField, 200); -} - -function updateComment() -{ - removeReportElement("comment"); - - let value = E("comment").value; - appendElement(reportData.documentElement, "comment", null, value.substr(0, 1000)); - E("commentLengthWarning").setAttribute("visible", value.length > 1000); - updateDataField(); -} - -function updateEmail() -{ - removeReportElement("email"); - - let anonymous = E("anonymousCheckbox").checked; - - let value = E("email").value; - - // required for persist to work on textbox, see: https://bugzilla.mozilla.org/show_bug.cgi?id=111486 - E("email").setAttribute("value", value); - - E("email").disabled = anonymous; - E("emailLabel").disabled = anonymous; - E("anonymityWarning").setAttribute("visible", anonymous); - - if (!anonymous) - appendElement(reportData.documentElement, "email", null, value); - - updateDataField(); - - document.documentElement.canAdvance = anonymous || /\S/.test(value); -} - -function updateExtensions(attach) -{ - extensionsDataSource.exportData(attach); - updateDataField(); -} - -function initSendPage() -{ - E("progressBar").activeItem = E("sendPageHeader"); - - E("result").hidden = true; - E("sendReportErrorBox").hidden = true; - E("sendReportMessage").hidden = false; - E("sendReportProgress").hidden = false; - E("sendReportProgress").mode = "undetermined"; - - document.documentElement.canRewind = false; - document.documentElement.getButton("finish").disabled = true; - - let guid = Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString().replace(/[\{\}]/g, ""); - let url = Prefs.report_submiturl.replace(/%GUID%/g, guid).replace(/%LANG%/g, Utils.appLocale); - let request = new XMLHttpRequest(); - request.open("POST", url); - request.setRequestHeader("Content-Type", "text/xml"); - request.setRequestHeader("X-Adblock-Plus", "1"); - request.addEventListener("load", reportSent, false); - request.addEventListener("error", reportSent, false); - if ("upload" in request && request.upload) - request.upload.addEventListener("progress", updateReportProgress, false); - request.send(serializeReportData()); -} - -function updateReportProgress(event) -{ - if (!event.lengthComputable) - return; - - let progress = Math.round(event.loaded / event.total * 100); - if (progress > 0) - { - let progressMeter = E("sendReportProgress"); - progressMeter.mode = "determined"; - progressMeter.value = progress; - } -} - -function reportSent(event) -{ - let request = event.target; - let success = false; - let errorMessage = E("sendReportError").getAttribute("defaultError"); - try - { - let status = request.channel.status; - if (Components.isSuccessCode(status)) - { - success = (request.status == 200 || request.status == 0); - errorMessage = request.status + " " + request.statusText; - } - else - { - errorMessage = "0x" + status.toString(16); - - // Try to find the name for the status code - let exception = Cc["@mozilla.org/js/xpc/Exception;1"].createInstance(Ci.nsIXPCException); - exception.initialize(null, status, null, null, null, null); - if (exception.name) - errorMessage = exception.name; - } - } catch (e) {} - - let result = ""; - try - { - result = request.responseText; - } catch (e) {} - - result = result.replace(/%CONFIRMATION%/g, encodeHTML(E("result").getAttribute("confirmationMessage"))); - result = result.replace(/%KNOWNISSUE%/g, encodeHTML(E("result").getAttribute("knownIssueMessage"))); - result = result.replace(/(<html)\b/, '$1 dir="' + window.getComputedStyle(document.documentElement, "").direction + '"'); - - if (!success) - { - let errorElement = E("sendReportError"); - let template = errorElement.getAttribute("textTemplate").replace(/[\r\n\s]+/g, " "); - - let [, beforeLink, linkText, afterLink] = /(.*)\[link\](.*)\[\/link\](.*)/.exec(template) || [null, "", template, ""]; - beforeLink = beforeLink.replace(/\?1\?/g, errorMessage); - afterLink = afterLink.replace(/\?1\?/g, errorMessage); - - while (errorElement.firstChild && errorElement.firstChild.nodeType != Node.ELEMENT_NODE) - errorElement.removeChild(errorElement.firstChild); - while (errorElement.lastChild && errorElement.lastChild.nodeType != Node.ELEMENT_NODE) - errorElement.removeChild(errorElement.lastChild); - - if (errorElement.firstChild) - errorElement.firstChild.textContent = linkText; - errorElement.insertBefore(document.createTextNode(beforeLink), errorElement.firstChild); - errorElement.appendChild(document.createTextNode(afterLink)); - - E("sendReportErrorBox").hidden = false; - } - - E("sendReportProgress").hidden = true; - - let frame = E("result"); - frame.hidden = false; - frame.docShell.allowAuth = false; - frame.docShell.allowJavascript = false; - frame.docShell.allowMetaRedirects = false; - frame.docShell.allowPlugins = false; - frame.docShell.allowSubframes = false; - - frame.setAttribute("src", "data:text/html;charset=utf-8," + encodeURIComponent(result)); - - E("sendReportMessage").hidden = true; - - if (success) - { - try - { - let link = request.responseXML.getElementById("link").getAttribute("href"); - let button = E("copyLink"); - button.setAttribute("url", link); - button.removeAttribute("disabled"); - - if (!isPrivate) - reportsListDataSource.addReport(framesDataSource.site, link); - } catch (e) {} - E("copyLinkBox").hidden = false; - - document.documentElement.getButton("finish").disabled = false; - document.documentElement.getButton("cancel").disabled = true; - E("progressBar").activeItemComplete = true; - } -} - -function processLinkClick(event) -{ - if (event.button != 0) - return; - - event.preventDefault(); - - let link = event.target; - while (link && !(link instanceof HTMLAnchorElement)) - link = link.parentNode; - - if (link && (link.protocol == "http:" || link.protocol == "https:")) - UI.loadInBrowser(link.href); -} - -function copyLink(url) -{ - Utils.clipboardHelper.copyString(url); -} - -function censorURL(url) -{ - return url.replace(/([?;&\/#][^?;&\/#]+?=)[^?;&\/#]+/g, "$1*"); -} - -function encodeHTML(str) -{ - return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """); -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul deleted file mode 100644 index 403513d..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul +++ /dev/null @@ -1,262 +0,0 @@ -<?xml version="1.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/>. - --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://global/skin/wizard.css" type="text/css"?> -<?xml-stylesheet href="chrome://adblockplus/skin/sendReport.css" type="text/css"?> - -<?xul-overlay href="progressBar.xul"?> - -<!DOCTYPE dialog [ -<!ENTITY % reporterDTD SYSTEM "chrome://adblockplus/locale/sendReport.dtd"> -%reporterDTD; -<!ENTITY % filtersDTD SYSTEM "chrome://adblockplus/locale/filters.dtd"> -%filtersDTD; -]> - -<wizard - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - title="&wizard.title;" - id="abpSendReportWizard" - onload="initWizard();" - width="800" - height="550" - sendbuttonlabel="&sendButton.label;" - windowtype="abp:sendReport"> - -<script type="application/x-javascript;version=1.7" src="utils.js"/> -<script type="application/x-javascript;version=1.7" src="sendReport.js"/> - -<keyset id="wizardKeys"> - <key id="undoKey" modifiers="accel" key="Z" oncommand="if (document.documentElement.currentPage.id == 'screenshotPage') screenshotDataSource.undo();"/> -</keyset> - -<box hidden="true"> - <vbox id="wizardHeader" class="wizard-header"> - <deck id="wizardHeaderDeck"> - <description id="wizardHeaderLabel" class="wizard-header-label"/> - <hbox id="progressBar"> - <label id="typeSelectorHeader" class="progressLabel" value="&typeSelector.heading;" crop="end"/> - <label id="screenshotHeader" class="progressLabel" value="&screenshot.heading;" crop="end"/> - <label id="commentPageHeader" class="progressLabel" value="&commentPage.heading;" crop="end"/> - <label id="sendPageHeader" class="progressLabel" value="&sendPage.heading;" crop="end"/> - </hbox> - </deck> - </vbox> - - <label id="privacyLink" class="text-link" value="&privacyPolicy.label;" onclick="UI.loadDocLink('reporter_privacy');"/> -</box> - -<wizardpage id="dataCollectorPage" pageid="dataCollector" next="typeSelector" label="&dataCollector.heading;" onpageshow="initDataCollectorPage();"> - <description>&dataCollector.description;</description> - - <progressmeter id="dataCollectorProgress" mode="undetermined"/> -</wizardpage> - -<wizardpage id="typeSelectorPage" pageid="typeSelector" next="screenshot" label="&typeSelector.heading;" onpageshow="initTypeSelectorPage();"> - <description>&typeSelector.description;</description> - - <radiogroup id="typeGroup" oncommand="typeSelectionUpdated();"> - <radio id="typeFalsePositive" value="false positive" label="&typeSelector.falsePositive.label;"/> - <description class="radioDescription">&typeSelector.falsePositive.description;</description> - <radio id="typeFalseNegative" value="false negative" label="&typeSelector.falseNegative.label;"/> - <description class="radioDescription">&typeSelector.falseNegative.description;</description> - <radio id="typeOther" value="other" label="&typeSelector.other.label;"/> - <description class="radioDescription">&typeSelector.other.description;</description> - </radiogroup> - - <deck id="recentReports" currentIndex="0" flex="1"> - <vbox pack="end"> - <label class="text-link" value="&showRecentReports.label;" onclick="E('recentReports').selectedIndex = 1;"/> - </vbox> - <groupbox flex="1"> - <caption label="&recentReports.label;"/> - <grid flex="1" id="recentReportsList"> - <columns> - <column flex="2"/> - <column flex="1"/> - <column/> - </columns> - <rows id="recentReportsRows" onclick="reportsListDataSource.handleClick(event);"/> - </grid> - - <hbox pack="start"> - <button label="&recentReports.clear.label;" oncommand="reportsListDataSource.clear();"/> - </hbox> - </groupbox> - </deck> -</wizardpage> - -<wizardpage id="updatePage" pageid="update" next="screenshot" onpageshow="subscriptionUpdateDataSource.showPage();" reloadButtonLabel="&reloadButton.label;"> - <vbox id="updateInProgress"> - <description>&update.inProgress.description;</description> - <progressmeter mode="undetermined"/> - </vbox> - - <description id="updateFixedIssue" hidden="true">&update.fixed.description;</description> - - <vbox id="outdatedSubscriptions"> - <description>&outdatedSubscriptions.description;</description> - - <description id="outdatedSubscriptionTemplate" class="text-link" onclick="UI.loadInBrowser(this.getAttribute('_url'));"/> - - <vbox id="outdatedSubscriptionsList"/> - - <hbox> - <button label="&update.start.label;" oncommand="subscriptionUpdateDataSource.updateOutdated();window.close();"/> - <button label="&issues.openPreferences.label;" oncommand="UI.openFiltersDialog();window.close();"/> - </hbox> - </vbox> -</wizardpage> - -<wizardpage id="issuesPage" pageid="issues" next="screenshot" onpageshow="initIssuesPage();" reloadButtonLabel="&reloadButton.label;"> - <description>&issues.description;</description> - - <vbox id="issuesBox" flex="1"> - <groupbox id="issuesWhitelistBox" hidden="true"> - <description>&issues.whitelist.description;</description> - <hbox pack="end"> - <button label="&issues.whitelist.remove.label;" oncommand="issuesDataSource.removeWhitelist();"/> - </hbox> - </groupbox> - <groupbox id="issuesDisabledBox" hidden="true"> - <description>&issues.disabled.description;</description> - <hbox pack="end"> - <button label="&issues.disabled.enable.label;" oncommand="issuesDataSource.enable();"/> - </hbox> - </groupbox> - <groupbox id="issuesNoFiltersBox" hidden="true"> - <description>&issues.nofilters.description;</description> - </groupbox> - <groupbox id="issuesNoSubscriptionsBox" hidden="true"> - <description>&issues.nosubscriptions.description;</description> - <hbox pack="end"> - <button label="&issues.nosubscriptions.add.label;" oncommand="issuesDataSource.addSubscription();"/> - </hbox> - </groupbox> - <groupbox id="issuesSubscriptionCountBox" hidden="true"> - <description>&issues.subscriptionCount.description;</description> - <hbox pack="end"> - <button label="&issues.openPreferences.label;" oncommand="UI.openFiltersDialog();window.close();"/> - </hbox> - </groupbox> - <groupbox id="issuesOwnFiltersBox" hidden="true"> - <description>&issues.ownfilters.description;</description> - <hbox id="issuesOwnFiltersTemplate" align="center" hidden="true"> - <description flex="1" crop="end"/> - <button label="&issues.ownfilters.disable.label;" oncommand="issuesDataSource.disableFilter(this.parentNode);"/> - </hbox> - <vbox id="issuesOwnFilters"/> - </groupbox> - <groupbox id="issuesDisabledSubscriptionsBox" hidden="true"> - <description>&issues.disabledgroups.description;</description> - <hbox id="issuesDisabledSubscriptionsTemplate" align="center" hidden="true"> - <description flex="1" crop="end"/> - <button label="&issues.disabledgroups.enable.label;" oncommand="issuesDataSource.enableSubscription(this.parentNode);"/> - </hbox> - <vbox id="issuesDisabledSubscriptions"/> - </groupbox> - <groupbox id="issuesDisabledFiltersBox" hidden="true"> - <description>&issues.disabledfilters.description;</description> - <hbox id="issuesDisabledFiltersTemplate" align="center" hidden="true"> - <description flex="1" crop="end"/> - <button label="&issues.disabledfilters.enable.label;" oncommand="issuesDataSource.enableFilter(this.parentNode);"/> - </hbox> - <vbox id="issuesDisabledFilters"/> - </groupbox> - </vbox> - - <checkbox id="issuesOverride" label="&issues.override.label;" oncommand="updateIssuesOverride();"/> - <description id="issuesChangeMessage" hidden="true">&issues.change.description;</description> -</wizardpage> - -<wizardpage id="typeWarningPage" pageid="typeWarning" next="screenshot" onpageshow="initTypeWarningPage();"> - <description id="typeWarningText"> - &typeWarning.description; - <label id="typeWarningTextLink" class="text-link" onclick="UI.loadDocLink('reporter_other_link');"/> - </description> - - <checkbox id="typeWarningOverride" label="&typeWarning.override.label;" oncommand="updateTypeWarningOverride();"/> -</wizardpage> - -<wizardpage id="screenshotPage" pageid="screenshot" next="comment" label="&screenshot.heading;" onpageshow="initScreenshotPage();"> - <description>&screenshot.description;</description> - - <checkbox id="screenshotCheckbox" checked="true" label="&screenshot.attach.label;" oncommand="screenshotDataSource.enabled = this.checked;"/> - <hbox id="screenshotButtons" pack="end"> - <button id="screenshotMarkButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'mark';" checked="true" label="&screenshot.mark.label;"/> - <button id="screenshotRemoveButton" type="radio" group="selectionType" oncommand="screenshotDataSource.selectionType = 'remove';" label="&screenshot.remove.label;"/> - <button id="screenshotUndoButton" oncommand="screenshotDataSource.undo();" disabled="true" label="&screenshot.undo.label;"/> - </hbox> - <vbox id="screenshotBox" flex="1"> - <canvas xmlns="http://www.w3.org/1999/xhtml" id="screenshotCanvas" onmousedown="screenshotDataSource.startSelection(event);" onmouseup="screenshotDataSource.stopSelection(event);" onmouseout="screenshotDataSource.stopSelection(event);" onmousemove="screenshotDataSource.updateSelection(event);"/> - </vbox> -</wizardpage> - -<wizardpage id="commentPage" pageid="comment" next="send" label="&commentPage.heading;" onpageshow="initCommentPage();"> - <description>&emailComment.label;</description> - <hbox class="topLabel" align="baseline"> - <label id="emailLabel" control="email" value="&email.label;"/> - <textbox id="email" type="email" persist="value" flex="1" maxlength="200" oninput="updateEmail();"/> - </hbox> - <hbox align="center"> - <checkbox id="anonymousCheckbox" label="&anonymous.label;" oncommand="updateEmail();"/> - <spacer flex="1"/> - <description id="anonymityWarning" visible="false">&anonymity.warning;</description> - </hbox> - - <description class="topLabel">&commentPage.description;</description> - <label class="topLabel" control="comment" value="&comment.label;"/> - <textbox id="comment" multiline="true" flex="1" oninput="updateComment();"/> - <description id="commentLengthWarning" visible="false">&comment.lengthWarning;</description> - - <checkbox id="extensionsCheckbox" label="&attachExtensions.label;" oncommand="updateExtensions(this.checked);"/> - - <deck id="dataDeck" selectedIndex="0" flex="2"> - <vbox pack="start"> - <label class="text-link" value="&showData.label;" onclick="showDataField();"/> - </vbox> - <vbox> - <label control="data" value="&data.label;"/> - <textbox id="data" readonly="true" multiline="true" wrap="off" flex="1"/> - </vbox> - </deck> -</wizardpage> - -<wizardpage id="sendPage" pageid="send" label="&sendPage.heading;" onpageshow="initSendPage();"> - <description id="sendReportMessage">&sendPage.waitMessage;</description> - - <vbox id="sendReportErrorBox" align="end" hidden="true"> - <description id="sendReportError" textTemplate="&sendPage.errorMessage;" defaultError="&subscription.lastDownload.connectionError;"> - <label id="sendReportErrorLinks" class="text-link" onclick="UI.loadDocLink('reporter_connect_issue');"/> - </description> - <button id="sendRetryButton" label="&sendPage.retry.label;" oncommand="initSendPage();"/> - </vbox> - - <progressmeter id="sendReportProgress" mode="undetermined"/> - - <iframe id="result" type="content" flex="1" hidden="true" onclick="processLinkClick(event);" - confirmationMessage="&sendPage.confirmation;" knownIssueMessage="&sendPage.knownIssue;"/> - - <hbox id="copyLinkBox" pack="end" hidden="true"> - <button id="copyLink" disabled="true" label="©Link.label;" oncommand="copyLink(this.getAttribute('url'));"/> - </hbox> -</wizardpage> - -</wizard> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul deleted file mode 100644 index 379cbc3..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul +++ /dev/null @@ -1,37 +0,0 @@ -<?xml version="1.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/>. - --> - -<!DOCTYPE vbox SYSTEM "chrome://adblockplus/locale/overlay.dtd"> - -<window - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - width="1" - height="1" - onload="window.close();"> <!-- Close window if it gets opened directly for some reason --> - <setting type="control"> - <button id="adblockplus-filters" label="&filters.label;…"/> - </setting> - <setting pref="extensions.adblockplus.enabled" type="bool" inverted="true" title="&disable.label;"/> - <setting pref="extensions.adblockplus.frameobjects" type="bool" title="&objecttabs.label;"/> - <setting id="adblockplus-savestats" type="bool" title="&counthits.label;"/> - <setting id="adblockplus-sync" type="bool" title="&sync.label;"/> - <setting id="adblockplus-shownotifications" type="bool" title="&shownotifications.label;"/> - <setting id="adblockplus-showintoolbar" type="bool" title="&showintoolbar.label;"/> - <setting id="adblockplus-showinstatusbar" pref="extensions.adblockplus.showinstatusbar" type="bool" title="&showinstatusbar.label;"/> -</window> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.js deleted file mode 100644 index 688c248..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.js +++ /dev/null @@ -1,1337 +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"); - -// Main browser window -var mainWin = parent; - -// Location of the content window that the list refers to -var contentLocation = null; - -// The window handler currently in use -var requestNotifier = null; - -var cacheStorage = null; - -// Matcher for disabled filters -var disabledMatcher = new CombinedMatcher(); - -// Cached string values -var docDomainThirdParty = null; -var docDomainFirstParty = null; - -// Localized type names -var localizedTypes = new Map(); - -function init() { - docDomainThirdParty = document.documentElement.getAttribute("docDomainThirdParty"); - docDomainFirstParty = document.documentElement.getAttribute("docDomainFirstParty"); - - var list = E("list"); - list.view = treeView; - - // Restore previous state - var params = Utils.getParams(); - if (params && params.filter) - { - E("searchField").value = params.filter; - treeView.setFilter(params.filter); - } - if (params && params.focus && E(params.focus)) - E(params.focus).focus(); - else - E("searchField").focus(); - - var selected = null; - if (/sidebarDetached\.xul$/.test(parent.location.href)) - { - mainWin = parent.opener; - mainWin.addEventListener("unload", mainUnload, false); - E("detachButton").hidden = true; - E("reattachButton").hidden = false; - - let mustDetach = parent.arguments[0]; - if (mustDetach) - E("reattachButton").setAttribute("disabled", "true"); - if ("sidebar" in UI.hotkeys) - { - let {KeySelector} = require("keySelector"); - parent.addEventListener("keypress", function(event) - { - if (KeySelector.matchesKey(event, UI.hotkeys.sidebar)) - doClose(); - }, false); - } - - // Set default size/position unless already persisted - let defaults = {screenX: 0, screenY: 0, width: 600, height: 300}; - if (params && params.position) - defaults = params.position; - - let wnd = parent.document.documentElement; - for (let attr in defaults) - if (!wnd.hasAttribute(attr)) - wnd.setAttribute(attr, defaults[attr]); - } - - let {addBrowserLocationListener} = require("appSupport"); - updateContentLocation(); - - // Initialize matcher for disabled filters - reloadDisabledFilters(); - FilterNotifier.on("subscription.added", reloadDisabledFilters); - FilterNotifier.on("subscription.removed", reloadDisabledFilters); - FilterNotifier.on("subscription.disabled", reloadDisabledFilters); - FilterNotifier.on("subscription.updated", reloadDisabledFilters); - FilterNotifier.on("filter.added", reloadDisabledFilters); - FilterNotifier.on("filter.removed", reloadDisabledFilters); - FilterNotifier.on("filter.disabled", reloadDisabledFilters); - Prefs.addListener(onPrefChange); - - // Activate flasher - list.addEventListener("select", onSelectionChange, false); - - // Initialize data - handleLocationChange(); - - // Install a progress listener to catch location changes - if (addBrowserLocationListener) - addBrowserLocationListener(mainWin, handleLocationChange, true); - - for (let type of Policy.contentTypes.values()) - localizedTypes.set(type, Utils.getString("type_label_" + type.toLowerCase())); -} - -// To be called for a detached window when the main window has been closed -function mainUnload() { - parent.close(); -} - -function updateContentLocation() -{ - let {getCurrentLocation} = require("appSupport"); - let location = getCurrentLocation(mainWin); - if (location instanceof Ci.nsIURI) - location = location.spec; - contentLocation = location; -} - -function getOuterWindowID() -{ - let {getBrowser} = require("appSupport"); - let browser = getBrowser(mainWin); - if ("selectedBrowser" in browser) - browser = browser.selectedBrowser; - return browser.outerWindowID; -} - -function getFilter(item) -{ - if ("filter" in item && item.filter) - return Filter.fromText(item.filter); - else - return null; -} - -// To be called on unload -function cleanUp() { - requestNotifier.shutdown(); - FilterNotifier.off("subscription.added", reloadDisabledFilters); - FilterNotifier.off("subscription.removed", reloadDisabledFilters); - FilterNotifier.off("subscription.disabled", reloadDisabledFilters); - FilterNotifier.off("subscription.updated", reloadDisabledFilters); - FilterNotifier.off("filter.added", reloadDisabledFilters); - FilterNotifier.off("filter.removed", reloadDisabledFilters); - FilterNotifier.off("filter.disabled", reloadDisabledFilters); - Prefs.removeListener(onPrefChange); - E("list").view = null; - - let {removeBrowserLocationListener} = require("appSupport"); - if (removeBrowserLocationListener) - removeBrowserLocationListener(mainWin, handleLocationChange); - mainWin.removeEventListener("unload", mainUnload, false); -} - -/** - * Tracks preference changes, calls reloadDisabledFilters whenever Adblock Plus - * is enabled/disabled. - */ -function onPrefChange(name) -{ - if (name == "enabled") - reloadDisabledFilters(); -} - -let reloadDisabledScheduled = false; - -/** - * Updates matcher for disabled filters (global disabledMatcher variable), - * called on each filter change. Execute delayed to prevent multiple subsequent - * invocations. - */ -function reloadDisabledFilters() -{ - if (reloadDisabledScheduled) - return; - - Utils.runAsync(reloadDisabledFiltersInternal); - reloadDisabledScheduled = true; -} - -function reloadDisabledFiltersInternal() -{ - reloadDisabledScheduled = false; - disabledMatcher.clear(); - - if (Prefs.enabled) - { - for (let subscription of FilterStorage.subscriptions) - { - if (subscription.disabled) - continue; - - for (let filter of subscription.filters) - if (filter instanceof RegExpFilter && filter.disabled) - disabledMatcher.add(filter); - } - } - - treeView.updateFilters(); -} - -// Called whenever list selection changes - triggers flasher -function onSelectionChange() { - var item = treeView.getSelectedItem(); - if (item) - E("copy-command").removeAttribute("disabled"); - else - E("copy-command").setAttribute("disabled", "true"); - - if (item) - { - let key = item.location + " " + item.type + " " + item.docDomain; - RequestNotifier.storeWindowData(getOuterWindowID(), key); - treeView.itemToSelect = null; - } - - if (requestNotifier) - requestNotifier.flashNodes(item ? item.ids : null, Prefs.flash_scrolltoitem); -} - -function handleLocationChange() -{ - if (requestNotifier) - requestNotifier.shutdown(); - - updateContentLocation(); - treeView.clearData(); - - let outerWindowID = getOuterWindowID(); - RequestNotifier.retrieveWindowData(outerWindowID, key => - { - treeView.itemToSelect = key; - }); - requestNotifier = new RequestNotifier(outerWindowID, (item, scanComplete) => - { - if (item) - treeView.addItem(item, scanComplete); - }); - cacheStorage = null; -} - -// Fills a box with text splitting it up into multiple lines if necessary -function setMultilineContent(box, text, noRemove) -{ - if (!noRemove) - while (box.firstChild) - box.removeChild(box.firstChild); - - let lines = text.match(/.{1,80}/g); - if (lines.length > 7) - { - // Text is too long to display in full so we cut out the middle part - lines = lines.slice(0,3).concat("\u2026", lines.slice(-3)); - } - - for (let line of lines) - { - let description = document.createElement("description"); - description.setAttribute("value", line); - box.appendChild(description); - } -} - -// Fill in tooltip data before showing it -function fillInTooltip(e) { - // Prevent tooltip from overlapping menu - if (E("context").state == "open") - { - e.preventDefault(); - return; - } - - var item; - if (treeView.data && !treeView.data.length) - item = treeView.getDummyTooltip(); - else - item = treeView.getItemAt(e.clientX, e.clientY); - - if (!item) - { - e.preventDefault(); - return; - } - - let filter = getFilter(item); - let subscriptions = (filter ? filter.subscriptions.filter(function(subscription) { return !subscription.disabled; }) : []); - - E("tooltipDummy").hidden = !("tooltip" in item); - E("tooltipAddressRow").hidden = ("tooltip" in item); - E("tooltipTypeRow").hidden = ("tooltip" in item); - E("tooltipDocDomainRow").hidden = ("tooltip" in item || !item.docDomain); - E("tooltipFilterRow").hidden = !filter; - E("tooltipFilterSourceRow").hidden = !subscriptions.length; - - if ("tooltip" in item) - E("tooltipDummy").setAttribute("value", item.tooltip); - else - { - E("tooltipAddress").parentNode.hidden = (item.type == "ELEMHIDE"); - setMultilineContent(E("tooltipAddress"), item.location); - - var type = localizedTypes.get(item.type); - if (filter && filter instanceof WhitelistFilter) - type += " " + E("tooltipType").getAttribute("whitelisted"); - else if (filter && item.type != "ELEMHIDE") - type += " " + E("tooltipType").getAttribute("filtered"); - E("tooltipType").setAttribute("value", type); - - E("tooltipDocDomain").setAttribute("value", item.docDomain + " " + (item.thirdParty ? docDomainThirdParty : docDomainFirstParty)); - } - - if (filter) - { - let filterField = E("tooltipFilter"); - setMultilineContent(filterField, filter.text); - if (filter.disabled) - { - let disabledText = document.createElement("description"); - disabledText.className = "disabledTextLabel"; - disabledText.textContent = filterField.getAttribute("disabledText"); - filterField.appendChild(disabledText); - } - - if (subscriptions.length) - { - let sourceElement = E("tooltipFilterSource"); - while (sourceElement.firstChild) - sourceElement.removeChild(sourceElement.firstChild); - for (let i = 0; i < subscriptions.length; i++) - setMultilineContent(sourceElement, getSubscriptionTitle(subscriptions[i]), true); - } - } - - E("tooltipSizeRow").hidden = true; - if (!("tooltip" in item)) - { - getItemSize(item, (size) => - { - if (size) - { - E("tooltipSizeRow").hidden = false; - E("tooltipSize").setAttribute("value", size.join(" x ")); - } - }); - } - - var showPreview = Prefs.previewimages && !("tooltip" in item); - showPreview = showPreview && item.type == "IMAGE"; - showPreview = showPreview && (!filter || filter.disabled || filter instanceof WhitelistFilter); - E("tooltipPreviewBox").hidden = true; - if (showPreview) - { - if (!cacheStorage) - { - let {Services} = Cu.import("resource://gre/modules/Services.jsm", null); - let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null); - cacheStorage = Services.cache2.diskCacheStorage(LoadContextInfo.default, false); - } - - let showTooltipPreview = function () - { - E("tooltipPreview").setAttribute("src", item.location); - E("tooltipPreviewBox").hidden = false; - }; - try - { - cacheStorage.asyncOpenURI(Utils.makeURI(item.location), "", Ci.nsICacheStorage.OPEN_READONLY, { - onCacheEntryCheck: function (entry, appCache) - { - return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED; - }, - onCacheEntryAvailable: function (entry, isNew, appCache, status) - { - if (Components.isSuccessCode(status) && !isNew) - showTooltipPreview(); - } - }); - } - catch (e) - { - Cu.reportError(e); - } - } -} - -const visual = { - OTHER: true, - IMAGE: true, - SUBDOCUMENT: true -} - -/** - * Updates context menu before it is shown. - */ -function fillInContext(/**Event*/ e) -{ - let item, allItems; - if (treeView.data && !treeView.data.length) - { - item = treeView.getDummyTooltip(); - allItems = [item]; - } - else - { - item = treeView.getItemAt(e.clientX, e.clientY); - allItems = treeView.getAllSelectedItems(); - } - - if (!item || ("tooltip" in item && !("filter" in item))) - return false; - - E("contextDisableFilter").hidden = true; - E("contextEnableFilter").hidden = true; - E("contextDisableOnSite").hidden = true; - let filter = getFilter(item); - if (filter) - { - let menuItem = E(filter.disabled ? "contextEnableFilter" : "contextDisableFilter"); - menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, filter.text)); - menuItem.hidden = false; - - if (filter instanceof ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(subscription => !(subscription instanceof SpecialSubscription))) - { - let domain = null; - try { - domain = Utils.effectiveTLD.getBaseDomainFromHost(item.docDomain); - } catch (e) {} - - if (domain && !filter.isActiveOnlyOnDomain(domain)) - { - menuItem = E("contextDisableOnSite"); - menuItem.setAttribute("label", menuItem.getAttribute("labeltempl").replace(/\?1\?/, domain)); - menuItem.hidden = false; - } - } - } - - E("contextWhitelist").hidden = ("tooltip" in item || !filter || filter.disabled || filter instanceof WhitelistFilter || item.type == "ELEMHIDE"); - E("contextBlock").hidden = !E("contextWhitelist").hidden; - E("contextBlock").setAttribute("disabled", filter && !filter.disabled); - E("contextEditFilter").setAttribute("disabled", !filter); - E("contextOpen").setAttribute("disabled", "tooltip" in item || item.type == "ELEMHIDE"); - E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.type in visual) || (filter && !filter.disabled && !(filter instanceof WhitelistFilter))); - E("contextCopyFilter").setAttribute("disabled", !allItems.some(getFilter)); - - return true; -} - -/** - * Processed mouse clicks on the item list. - * @param {Event} event - */ -function handleClick(event) -{ - let item = treeView.getItemAt(event.clientX, event.clientY); - if (event.button == 0 && treeView.getColumnAt(event.clientX, event.clientY) == "state") - { - let filter = getFilter(item); - if (filter) - enableFilter(filter, filter.disabled); - event.preventDefault(); - } - else if (event.button == 1) - { - openInTab(item, event); - event.preventDefault(); - } -} - -/** - * Processes double-clicks on the item list. - * @param {Event} event - */ -function handleDblClick(event) -{ - if (event.button != 0 || treeView.getColumnAt(event.clientX, event.clientY) == "state") - return; - - doBlock(); -} - -/** - * Opens the item in a new tab. - */ -function openInTab(item, /**Event*/ event) -{ - let items = (item ? [item] : treeView.getAllSelectedItems()); - for (let item of items) - { - if (item && item.type != "ELEMHIDE") - UI.loadInBrowser(item.location, mainWin, event); - } -} - -function doBlock() { - var item = treeView.getSelectedItem(); - if (!item || item.type == "ELEMHIDE") - return; - - var filter = getFilter(item); - if (filter && !filter.disabled && filter instanceof WhitelistFilter) - return; - - if (requestNotifier) - { - requestNotifier.storeNodesForEntries(item.ids, (nodesID) => - { - UI.blockItem(window, nodesID, item.orig); - }); - } -} - -function editFilter() -{ - var item = treeView.getSelectedItem(); - if (treeView.data && !treeView.data.length) - item = treeView.getDummyTooltip(); - - let filter = getFilter(item); - if (!filter) - return; - - UI.openFiltersDialog(filter); -} - -function enableFilter(filter, enable) { - filter.disabled = !enable; - - treeView.boxObject.invalidate(); -} - -/** - * Edits the filter to disable it on a particular domain. - */ -function disableOnSite() -{ - let item = treeView.getSelectedItem(); - let filter = getFilter(item); - if (!(filter instanceof ActiveFilter) || filter.disabled || !filter.subscriptions.length || filter.subscriptions.some(subscription => !(subscription instanceof SpecialSubscription))) - return; - - let domain; - try { - domain = Utils.effectiveTLD.getBaseDomainFromHost(item.docDomain).toUpperCase(); - } - catch (e) - { - return; - } - - // Generate text for new filter that excludes current domain - let text = filter.text; - if (filter instanceof RegExpFilter) - { - let match = Filter.optionsRegExp.exec(text); - if (match) - { - let found = false; - let options = match[1].toUpperCase().split(","); - for (let i = 0; i < options.length; i++) - { - let match = /^DOMAIN=(.*)/.exec(options[i]); - if (match) - { - let domains = match[1].split("|").filter(d => d != domain && d != "~" + domain && (d.length <= domain.length || d.lastIndexOf("." + domain) != d.length - domain.length - 1)); - domains.push("~" + domain); - options[i] = "DOMAIN=" + domains.join("|"); - found = true; - break; - } - } - if (!found) - options.push("DOMAIN=~" + domain); - - text = text.replace(Filter.optionsRegExp, "$" + options.join(",").toLowerCase()); - } - else - text += "$domain=~" + domain.toLowerCase(); - } - else if (filter instanceof ElemHideBase) - { - let match = /^([^#]+)(#.*)/.exec(text); - if (match) - { - let selector = match[2]; - let domains = match[1].toUpperCase().split(",").filter(d => d != domain && (d.length <= domain.length || d != "~" + domain && d.lastIndexOf("." + domain) != d.length - domain.length - 1)); - domains.push("~" + domain); - text = domains.join(",").toLowerCase() + selector; - } - else - text = "~" + domain.toLowerCase() + text; - } - - if (text == filter.text) - return; // Just in case, shouldn't happen - - // Insert new filter before the old one and remove the old one then - let newFilter = Filter.fromText(text); - if (newFilter.disabled && newFilter.subscriptions.length) - newFilter.disabled = false; - else if (!newFilter.subscriptions.length) - { - newFilter.disabled = false; - let subscription = filter.subscriptions.filter(s => s instanceof SpecialSubscription)[0]; - if (subscription) - FilterStorage.addFilter(newFilter, subscription, subscription.filters.indexOf(filter)); - } - FilterStorage.removeFilter(filter); - - // Update display - for (let i = 0; i < treeView.allData.length; i++) - if (getFilter(treeView.allData[i]) == filter) - treeView.allData[i].filter = null; - treeView.boxObject.invalidate(); -} - -function copyToClipboard() { - var items = treeView.getAllSelectedItems(); - if (!items.length) - return; - - Utils.clipboardHelper.copyString(items.map(function(item) {return item.location}).join(IO.lineBreak)); -} - -function copyFilter() { - var items = treeView.getAllSelectedItems().filter(getFilter); - if (treeView.data && !treeView.data.length) - items = [treeView.getDummyTooltip()]; - - if (!items.length) - return; - - Utils.clipboardHelper.copyString(items.map(function(item) {return item.filter}).join(IO.lineBreak)); -} - -function selectAll() { - treeView.selectAll(); -} - -// Saves sidebar's state before detaching/reattaching -function saveState() { - var focused = document.commandDispatcher.focusedElement; - while (focused && (!focused.id || !("focus" in focused))) - focused = focused.parentNode; - - // Calculate default position for the detached window - var boxObject = document.documentElement.boxObject; - var position = {screenX: boxObject.screenX, screenY: boxObject.screenY, width: boxObject.width, height: boxObject.height}; - - var params = { - filter: treeView.filter, - focus: (focused ? focused.id : null), - position: position - }; - Utils.setParams(params); -} - -// closes the sidebar -function doClose() -{ - mainWin.document.getElementById("abp-command-sidebar").doCommand(); -} - -// detaches/reattaches the sidebar -function detach(doDetach) -{ - saveState(); - - // Store variables locally, global variables will go away when we are closed - let myPrefs = Prefs; - let myMainWin = mainWin; - - // Close sidebar and open detached window - myMainWin.document.getElementById("abp-command-sidebar").doCommand(); - myPrefs.detachsidebar = doDetach; - myMainWin.document.getElementById("abp-command-sidebar").doCommand(); -} - -// Returns item's size if already known, otherwise undefined -function getCachedItemSize(item) -{ - if ("size" in item) - return item.size; - - let filter = getFilter(item); - if (filter && !filter.disabled && filter instanceof BlockingFilter) - return null; - - return undefined; -} - -// Retrieves item's size in the document if available -function getItemSize(item, callback) -{ - let size = getCachedItemSize(item); - if (typeof size != "undefined" || !requestNotifier) - { - callback(size); - return; - } - - requestNotifier.retrieveNodeSize(item.ids, function(size) - { - if (size) - item.size = size; - callback(size); - }); -} - -// Sort functions for the item list -function sortByAddress(item1, item2) { - if (item1.location < item2.location) - return -1; - else if (item1.location > item2.location) - return 1; - else - return 0; -} - -function sortByAddressDesc(item1, item2) { - return -sortByAddress(item1, item2); -} - -function compareType(item1, item2) { - let type1 = localizedTypes.get(item1.type); - let type2 = localizedTypes.get(item2.type); - if (type1 < type2) - return -1; - else if (type1 > type2) - return 1; - else - return 0; -} - -function compareFilter(item1, item2) { - var hasFilter1 = (item1.filter ? 1 : 0); - var hasFilter2 = (item2.filter ? 1 : 0); - if (hasFilter1 != hasFilter2) - return hasFilter1 - hasFilter2; - else if (hasFilter1 && item1.filter < item2.filter) - return -1; - else if (hasFilter1 && item1.filter > item2.filter) - return 1; - else - return 0; -} - -function compareState(item1, item2) -{ - let filter1 = getFilter(item1); - let filter2 = getFilter(item2); - let state1 = (!filter1 ? 0 : (filter1.disabled ? 1 : (filter1 instanceof WhitelistFilter ? 2 : 3))); - let state2 = (!filter2 ? 0 : (filter2.disabled ? 1 : (filter2 instanceof WhitelistFilter ? 2 : 3))); - return state1 - state2; -} - -function compareSize(item1, item2) -{ - let size1 = getCachedItemSize(item1); - let size2 = getCachedItemSize(item2); - - size1 = size1 ? size1[0] * size1[1] : 0; - size2 = size2 ? size2[0] * size2[1] : 0; - return size1 - size2; -} - -function compareDocDomain(item1, item2) -{ - if (item1.docDomain < item2.docDomain) - return -1; - else if (item1.docDomain > item2.docDomain) - return 1; - else if (item1.thirdParty && !item2.thirdParty) - return -1; - else if (!item1.thirdParty && item2.thirdParty) - return 1; - else - return 0; -} - -function compareFilterSource(item1, item2) -{ - let filter1 = getFilter(item1); - let filter2 = getFilter(item2); - let subs1 = filter1 ? filter1.subscriptions.map(s => getSubscriptionTitle(s)).join(", ") : ""; - let subs2 = filter2 ? filter2.subscriptions.map(s => getSubscriptionTitle(s)).join(", ") : ""; - if (subs1 < subs2) - return -1; - else if (subs1 > subs2) - return 1; - else - return 0; -} - -function createSortWithFallback(cmpFunc, fallbackFunc, desc) { - var factor = (desc ? -1 : 1); - return function(item1, item2) { - var ret = cmpFunc(item1, item2); - if (ret == 0) - return fallbackFunc(item1, item2); - else - return factor * ret; - } -} - -// Item list's tree view object -var treeView = { - // - // nsISupports implementation - // - - QueryInterface: function(uuid) { - if (!uuid.equals(Ci.nsISupports) && - !uuid.equals(Ci.nsITreeView)) - { - throw Cr.NS_ERROR_NO_INTERFACE; - } - - return this; - }, - - // - // nsITreeView implementation - // - - selection: null, - - setTree: function(boxObject) { - if (!boxObject) - return; - this.boxObject = boxObject; - this.itemsDummy = boxObject.treeBody.getAttribute("noitemslabel"); - this.whitelistDummy = boxObject.treeBody.getAttribute("whitelistedlabel"); - var stringAtoms = ["col-address", "col-type", "col-filter", "col-state", "col-size", "col-docDomain", "col-filterSource", "state-regular", "state-filtered", "state-whitelisted", "state-hidden", "state-hiddenexception"]; - var boolAtoms = ["selected", "dummy", "filter-disabled"]; - var atomService = Cc["@mozilla.org/atom-service;1"].getService(Ci.nsIAtomService); - this.atoms = {}; - for (let atom of stringAtoms) - this.atoms[atom] = atomService.getAtom(atom); - for (let atom of boolAtoms) - { - this.atoms[atom + "-true"] = atomService.getAtom(atom + "-true"); - this.atoms[atom + "-false"] = atomService.getAtom(atom + "-false"); - } - - this.itemsDummyTooltip = Utils.getString("no_blocking_suggestions"); - this.whitelistDummyTooltip = Utils.getString("whitelisted_page"); - - // Check current sort direction - var cols = document.getElementsByTagName("treecol"); - var sortDir = null; - for (let i = 0; i < cols.length; i++) { - var col = cols[i]; - var dir = col.getAttribute("sortDirection"); - if (dir && dir != "natural") { - this.sortColumn = col; - sortDir = dir; - } - } - if (!this.sortColumn) - { - let defaultSort = E("list").getAttribute("defaultSort"); - let match = /^(\w+)\s+(ascending|descending)$/.exec(defaultSort); - if (match) - { - this.sortColumn = E(match[1]); - if (this.sortColumn) - { - sortDir = match[2]; - this.sortColumn.setAttribute("sortDirection", sortDir); - } - } - } - - if (sortDir) - { - this.sortProc = this.sortProcs[this.sortColumn.id + (sortDir == "descending" ? "Desc" : "")]; - E("list").setAttribute("defaultSort", " "); - } - - // Make sure to update the dummy row every two seconds - setInterval(function(view) { - if (!view.data || !view.data.length) - view.boxObject.invalidateRow(0); - }, 2000, this); - - // Prevent a reference through closures - boxObject = null; - }, - get rowCount() { - return (this.data && this.data.length ? this.data.length : 1); - }, - getCellText: function(row, col) { - col = col.id; - if (col != "type" && col != "address" && col != "filter" && col != "size" && col != "docDomain" && col != "filterSource") - return ""; - if (this.data && this.data.length) { - if (row >= this.data.length) - return ""; - if (col == "type") - return localizedTypes.get(this.data[row].type); - else if (col == "filter") - return (this.data[row].filter || ""); - else if (col == "size") - { - let size = getCachedItemSize(this.data[row]); - if (typeof size == "undefined") - { - getItemSize(this.data[row], (size) => - { - if (size) - this.boxObject.invalidateRow(row) - }); - } - return (size ? size.join(" x ") : ""); - } - else if (col == "docDomain") - return this.data[row].docDomain + " " + (this.data[row].thirdParty ? docDomainThirdParty : docDomainFirstParty); - else if (col == "filterSource") - { - let filter = getFilter(this.data[row]) - if (!filter) - return ""; - - return filter.subscriptions.filter(s => !s.disabled).map(s => getSubscriptionTitle(s)).join(", "); - } - else - return this.data[row].location; - } - else { - // Empty list, show dummy - if (row > 0 || (col != "address" && col != "filter")) - return ""; - if (col == "filter") { - var filter = Policy.isWhitelisted(contentLocation); - return filter ? filter.text : ""; - } - - return (Policy.isWhitelisted(contentLocation) ? this.whitelistDummy : this.itemsDummy); - } - }, - - generateProperties: function(list, properties) - { - if (properties) - { - // Gecko 21 and below: we have an nsISupportsArray parameter, add atoms - // to that. - for (let i = 0; i < list.length; i++) - if (list[i] in this.atoms) - properties.AppendElement(this.atoms[list[i]]); - return null; - } - else - { - // Gecko 22+: no parameter, just return a string - return list.join(" "); - } - }, - - getColumnProperties: function(col, properties) - { - return this.generateProperties(["col-" + col.id], properties); - }, - - getRowProperties: function(row, properties) - { - if (row >= this.rowCount) - return ""; - - let list = []; - list.push("selected-" + this.selection.isSelected(row)); - - let state; - if (this.data && this.data.length) { - list.push("dummy-false"); - - let filter = getFilter(this.data[row]); - if (filter) - list.push("filter-disabled-" + filter.disabled); - - state = "state-regular"; - if (filter && !filter.disabled) - { - if (filter instanceof WhitelistFilter) - state = "state-whitelisted"; - else if (filter instanceof BlockingFilter) - state = "state-filtered"; - else if (filter instanceof ElemHideFilter || filter instanceof ElemHideEmulationFilter) - state = "state-hidden"; - else if (filter instanceof ElemHideException) - state = "state-hiddenexception"; - } - } - else { - list.push("dummy-true"); - - state = "state-filtered"; - if (this.data && Policy.isWhitelisted(contentLocation)) - state = "state-whitelisted"; - } - list.push(state); - return this.generateProperties(list, properties); - }, - - getCellProperties: function(row, col, properties) - { - return this.getRowProperties(row, properties) + " " + this.getColumnProperties(col, properties); - }, - - cycleHeader: function(col) { - col = col.id; - - col = E(col); - if (!col) - return; - - var cycle = { - natural: 'ascending', - ascending: 'descending', - descending: 'natural' - }; - - var curDirection = "natural"; - if (this.sortColumn == col) - curDirection = col.getAttribute("sortDirection"); - else if (this.sortColumn) - this.sortColumn.removeAttribute("sortDirection"); - - curDirection = cycle[curDirection]; - - if (curDirection == "natural") - this.sortProc = null; - else - this.sortProc = this.sortProcs[col.id + (curDirection == "descending" ? "Desc" : "")]; - - if (this.data) - this.refilter(); - - col.setAttribute("sortDirection", curDirection); - this.sortColumn = col; - - this.boxObject.invalidate(); - }, - - isSorted: function() { - return this.sortProc; - }, - - isContainer: function() {return false}, - isContainerOpen: function() {return false}, - isContainerEmpty: function() {return false}, - getLevel: function() {return 0}, - getParentIndex: function() {return -1}, - hasNextSibling: function() {return false}, - toggleOpenState: function() {}, - canDrop: function() {return false}, - drop: function() {}, - getCellValue: function() {return null}, - getProgressMode: function() {return null}, - getImageSrc: function() {return null}, - isSeparator: function() {return false}, - isEditable: function() {return false}, - cycleCell: function() {}, - performAction: function() {}, - performActionOnRow: function() {}, - performActionOnCell: function() {}, - selectionChanged: function() {}, - - // - // Custom properties and methods - // - - boxObject: null, - atoms: null, - filter: "", - data: null, - allData: [], - dataMap: Object.create(null), - sortColumn: null, - sortProc: null, - resortTimeout: null, - itemsDummy: null, - whitelistDummy: null, - itemsDummyTooltip: null, - whitelistDummyTooltip: null, - itemToSelect: null, - - sortProcs: { - address: sortByAddress, - addressDesc: sortByAddressDesc, - type: createSortWithFallback(compareType, sortByAddress, false), - typeDesc: createSortWithFallback(compareType, sortByAddress, true), - filter: createSortWithFallback(compareFilter, sortByAddress, false), - filterDesc: createSortWithFallback(compareFilter, sortByAddress, true), - state: createSortWithFallback(compareState, sortByAddress, false), - stateDesc: createSortWithFallback(compareState, sortByAddress, true), - size: createSortWithFallback(compareSize, sortByAddress, false), - sizeDesc: createSortWithFallback(compareSize, sortByAddress, true), - docDomain: createSortWithFallback(compareDocDomain, sortByAddress, false), - docDomainDesc: createSortWithFallback(compareDocDomain, sortByAddress, true), - filterSource: createSortWithFallback(compareFilterSource, sortByAddress, false), - filterSourceDesc: createSortWithFallback(compareFilterSource, sortByAddress, true) - }, - clearData: function(data) { - var oldRows = this.rowCount; - this.allData = []; - this.dataMap = Object.create(null); - this.refilter(); - - this.boxObject.rowCountChanged(0, -oldRows); - this.boxObject.rowCountChanged(0, this.rowCount); - }, - - addItem: function(/**RequestEntry*/ item, /**Boolean*/ scanComplete) - { - // Merge duplicate entries - let key = item.location + " " + item.type + " " + item.docDomain; - if (key in this.dataMap) - { - // We know this item already - take over the filter if any and be done with it - let existing = this.dataMap[key]; - if (item.filter) - existing.filter = item.filter; - existing.ids.push(item.id); - - this.invalidateItem(existing); - return; - } - - // Add new item to the list - // Store original item in orig property - reading out prototype is messed up in Gecko 1.9.2 - item = {__proto__: item, orig: item, ids: [item.id]}; - this.allData.push(item); - this.dataMap[key] = item; - - // Show disabled filters if no other filter applies - if (!item.filter) - { - let disabledMatch = disabledMatcher.matchesAny(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); - if (disabledMatch) - item.filter = disabledMatch.text; - } - - if (!this.matchesFilter(item)) - return; - - let index = -1; - if (this.sortProc && this.sortColumn && this.sortColumn.id == "size") - { - // Sorting by size requires accessing content document, and that's - // dangerous from a content policy (and we are likely called directly - // from a content policy call). Size data will be inaccurate anyway, - // delay sorting until later. - if (this.resortTimeout) - clearTimeout(this.resortTimeout); - this.resortTimeout = setTimeout(function(me) - { - if (me.sortProc) - me.data.sort(me.sortProc); - me.boxObject.invalidate(); - }, 500, this); - } - else if (this.sortProc) - for (var i = 0; index < 0 && i < this.data.length; i++) - if (this.sortProc(item, this.data[i]) < 0) - index = i; - - if (index >= 0) - this.data.splice(index, 0, item); - else { - this.data.push(item); - index = this.data.length - 1; - } - - if (this.data.length == 1) - this.boxObject.invalidateRow(0); - else - this.boxObject.rowCountChanged(index, 1); - - if (this.itemToSelect == key) - { - this.selection.select(index); - this.boxObject.ensureRowIsVisible(index); - this.itemToSelect = null; - } - else if (!scanComplete && this.selection.currentIndex >= 0) // Keep selected row visible while scanning - this.boxObject.ensureRowIsVisible(this.selection.currentIndex); - }, - - updateFilters: function() - { - for (let item of this.allData) - { - let filter = getFilter(item); - if (filter instanceof RegExpFilter && filter.disabled) - delete item.filter; - if (!filter) - { - let disabledMatch = disabledMatcher.matchesAny(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); - if (disabledMatch) - item.filter = disabledMatch.text; - } - } - this.refilter(); - }, - - /** - * Updates the list after a filter or sorting change. - */ - refilter: function() - { - if (this.resortTimeout) - clearTimeout(this.resortTimeout); - - this.data = this.allData.filter(this.matchesFilter, this); - - if (this.sortProc) - this.data.sort(this.sortProc); - }, - - /** - * Tests whether an item matches current list filter. - * @return {Boolean} true if the item should be shown - */ - matchesFilter: function(item) - { - if (!this.filter) - return true; - - return (item.location.toLowerCase().indexOf(this.filter) >= 0 || - (item.filter && item.filter.toLowerCase().indexOf(this.filter) >= 0) || - item.type.toLowerCase().indexOf(this.filter.replace(/-/g, "_")) >= 0 || - localizedTypes.get(item.type).toLowerCase().indexOf(this.filter) >= 0 || - (item.docDomain && item.docDomain.toLowerCase().indexOf(this.filter) >= 0) || - (item.docDomain && item.thirdParty && docDomainThirdParty.toLowerCase().indexOf(this.filter) >= 0) || - (item.docDomain && !item.thirdParty && docDomainFirstParty.toLowerCase().indexOf(this.filter) >= 0)); - }, - - setFilter: function(filter) { - var oldRows = this.rowCount; - - this.filter = filter.toLowerCase(); - this.refilter(); - - var newRows = this.rowCount; - if (oldRows != newRows) - this.boxObject.rowCountChanged(oldRows < newRows ? oldRows : newRows, this.rowCount - oldRows); - this.boxObject.invalidate(); - }, - - selectAll: function() { - this.selection.selectAll(); - }, - - getSelectedItem: function() { - if (!this.data || this.selection.currentIndex < 0 || this.selection.currentIndex >= this.data.length) - return null; - - return this.data[this.selection.currentIndex]; - }, - - getAllSelectedItems: function() { - let result = []; - if (!this.data) - return result; - - let numRanges = this.selection.getRangeCount(); - for (let i = 0; i < numRanges; i++) - { - let min = {}; - let max = {}; - let range = this.selection.getRangeAt(i, min, max); - for (let j = min.value; j <= max.value; j++) - { - if (j >= 0 && j < this.data.length) - result.push(this.data[j]); - } - } - return result; - }, - - getItemAt: function(x, y) - { - if (!this.data) - return null; - - var row = this.boxObject.getRowAt(x, y); - if (row < 0 || row >= this.data.length) - return null; - - return this.data[row]; - }, - - getColumnAt: function(x, y) - { - if (!this.data) - return null; - - let col = {}; - this.boxObject.getCellAt(x, y, {}, col, {}); - return (col.value ? col.value.id : null); - }, - - getDummyTooltip: function() { - if (!this.data || this.data.length) - return null; - - var filter = Policy.isWhitelisted(contentLocation); - if (filter) - return {tooltip: this.whitelistDummyTooltip, filter: filter.text}; - else - return {tooltip: this.itemsDummyTooltip}; - }, - - invalidateItem: function(item) - { - let row = this.data.indexOf(item); - if (row >= 0) - this.boxObject.invalidateRow(row); - } -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul deleted file mode 100644 index d77cefb..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.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/>. - --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://adblockplus/skin/sidebar.css" type="text/css"?> - -<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd"> - -<page - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - id="abp-sidebar" - onload="init()" - onunload="cleanUp()" - docDomainThirdParty="&docDomain.thirdParty;" - docDomainFirstParty="&docDomain.firstParty;"> - - <script type="application/x-javascript;version=1.7" src="utils.js"/> - <script type="application/x-javascript;version=1.7" src="sidebar.js"/> - - <keyset id="sidebarKeys"> - <key id="block-key" keycode="VK_ENTER"/> - <key id="copy-key" modifiers="accel" key="C" command="copy-command"/> - <key id="selectAll-key" modifiers="accel" key="A" command="selectAll-command"/> - </keyset> - - <commandset id="sidebarCommands"> - <command id="copy-command" oncommand="copyToClipboard()" disabled="true"/> - <command id="selectAll-command" oncommand="selectAll()"/> - </commandset> - - <popupset id="sidebarPopups"> - <tooltip id="tooltip" orient="vertical" onpopupshowing="fillInTooltip(event);"> - <description id="tooltipDummy"/> - <hbox id="tooltipPreviewBox" pack="start"> - <image id="tooltipPreview" validate="never"/> - </hbox> - <grid> - <columns> - <column/> - <column flex="1"/> - </columns> - <rows> - <row id="tooltipAddressRow" align="top"> - <label value="&tooltip.address.label;"/> - <vbox id="tooltipAddress"/> - </row> - <row id="tooltipTypeRow"> - <label value="&tooltip.type.label;"/> - <description id="tooltipType" filtered="&tooltip.type.blocked;" whitelisted="&tooltip.type.whitelisted;"/> - </row> - <row id="tooltipSizeRow"> - <label value="&tooltip.size.label;"/> - <description id="tooltipSize"/> - </row> - <row id="tooltipDocDomainRow"> - <label value="&tooltip.docDomain.label;"/> - <description id="tooltipDocDomain"/> - </row> - <row id="tooltipFilterRow" align="top"> - <label value="&tooltip.filter.label;"/> - <vbox id="tooltipFilter" disabledText="&tooltip.filter.disabled;"/> - </row> - <row id="tooltipFilterSourceRow" align="top"> - <label value="&tooltip.filterSource.label;"/> - <vbox id="tooltipFilterSource"/> - </row> - </rows> - </grid> - </tooltip> - - <menupopup id="context" onpopupshowing="return fillInContext(event)"> - <menuitem id="contextBlock" label="&context.block.label;…" oncommand="doBlock()" key="block-key"/> - <menuitem id="contextWhitelist" label="&context.whitelist.label;…" oncommand="doBlock()" key="block-key"/> - <menuitem id="contextEditFilter" label="&context.editfilter.label;…" oncommand="editFilter()"/> - <menuitem id="contextDisableFilter" labeltempl="&context.disablefilter.label;" oncommand="enableFilter(getFilter(treeView.getSelectedItem()), false)"/> - <menuitem id="contextEnableFilter" labeltempl="&context.enablefilter.label;" oncommand="enableFilter(getFilter(treeView.getSelectedItem()), true)"/> - <menuitem id="contextDisableOnSite" labeltempl="&context.disablefilteronsite.label;" oncommand="disableOnSite()"/> - <menuseparator id="contextOpenSep"/> - <menuitem id="contextOpen" label="&context.open.label;" oncommand="openInTab(null, event)"/> - <menuitem id="contextFlash" label="&context.flash.label;" oncommand="onSelectionChange()"/> - <menuitem id="contextCopy" label="&context.copy.label;" command="copy-command" key="copy-key"/> - <menuitem id="contextCopyFilter" label="&context.copyFilter.label;" oncommand="copyFilter()"/> - <menuseparator id="contextSelectSep"/> - <menuitem id="contextSelectAll" label="&context.selectAll.label;" command="selectAll-command" key="selectAll-key"/> - </menupopup> - </popupset> - - <hbox> - <hbox align="center" flex="1"> - <label value="&search.label;" control="searchField"/> - <textbox id="searchField" flex="1" type="search" oncommand="treeView.setFilter(this.value)"/> - </hbox> - <description id="detachButton" value="&detach.label;" onclick="detach(true)"/> - <description id="reattachButton" value="&reattach.label;" onclick="if (this.getAttribute('disabled') != 'true') detach(false)" hidden="true"/> - </hbox> - - <tree id="list" context="context" flex="1" seltype="multiple" enableColumnDrag="true" - defaultSort="state descending" persist="defaultSort" - onkeypress="if (event.keyCode == event.DOM_VK_RETURN || event.keyCode == event.DOM_VK_ENTER) doBlock()"> - <treecols> - <treecol id="address" label="&address.label;" flex="2" crop="center" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="filter" label="&filter.label;" flex="1" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="type" label="&type.label;" width="80" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="state" label="&state.label;" width="16" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="size" label="&size.label;" width="60" hidden="true" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="docDomain" label="&docDomain.label;" width="100" hidden="true" persist="width ordinal sortDirection hidden"/> - <splitter class="tree-splitter"/> - <treecol id="filterSource" label="&filterSource.label;" width="100" hidden="true" persist="width ordinal sortDirection hidden"/> - </treecols> - <treechildren id="treechildren" - tooltip="tooltip" - onclick="handleClick(event)" - ondblclick="handleDblClick(event)" - noitemslabel="&noitems.label;" - whitelistedlabel="&whitelisted.label;"/> - </tree> -</page> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul deleted file mode 100644 index 19fdd64..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul +++ /dev/null @@ -1,50 +0,0 @@ -<?xml version="1.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/>. - --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> - -<!DOCTYPE page SYSTEM "chrome://adblockplus/locale/sidebar.dtd"> - -<window - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - id="abpDetachedSidebar" - title="&detached.title;" - persist="screenX screenY width height sizemode" - onclose="document.getElementById('abp-command-sidebar').doCommand(); return false;"> - - <script type="application/x-javascript"> - // Some people actually switch off browser.frames.enabled and are surprised - // that things stop working... - window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) - .getInterface(Components.interfaces.nsIWebNavigation) - .QueryInterface(Components.interfaces.nsIDocShell) - .allowSubframes = true; - </script> - - <keyset> - <key keycode="VK_ESCAPE" command="command-close"/> - <key modifiers="accel" key="w" command="command-close"/> - </keyset> - - <commandset> - <command id="command-close" oncommand="document.getElementById('sidebarFrame').contentWindow.doClose()"/> - </commandset> - - <iframe src="sidebar.xul" id="sidebarFrame" flex="1"/> -</window> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abb-logo.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abb-logo.png Binary files differdeleted file mode 100644 index ce4701f..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abb-logo.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abp-128.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abp-128.png Binary files differdeleted file mode 100644 index 1caffd0..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abp-128.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/ajax-loader.gif b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/ajax-loader.gif Binary files differdeleted file mode 100644 index a642494..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/ajax-loader.gif +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-main.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-main.png Binary files differdeleted file mode 100644 index 464a997..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-main.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-share.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-share.png Binary files differdeleted file mode 100644 index b572b56..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background-share.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background.png Binary files differdeleted file mode 100644 index bb19387..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/background.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/common.css b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/common.css deleted file mode 100644 index 4871e66..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/common.css +++ /dev/null @@ -1,59 +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/>. - */ - -#glass-pane, #share-popup -{ - visibility: hidden; - opacity: 0; - -webkit-transition-property: opacity; - transition-property: opacity; -} - -#glass-pane -{ - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - background: rgba(0, 0, 0, 0.5) url(ajax-loader.gif) no-repeat 50% 50%; - z-index: 101; - -webkit-transition-duration: 0.2s; - transition-duration: 0.2s; -} - -#share-popup -{ - position: absolute; - top: 50%; - left: 50%; - border: none; - -webkit-transition-delay: 0.1s; - transition-delay: 0.1s; -} - -#glass-pane.visible, #share-popup.visible -{ - visibility: visible; - opacity: 1; -} - -#share-popup.visible -{ - -webkit-transition-duration: 0.15s; - transition-duration: 0.15s; -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/donate.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/donate.png Binary files differdeleted file mode 100644 index 3e77b37..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/donate.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/firstRun.css b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/firstRun.css deleted file mode 100644 index fffc91c..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/firstRun.css +++ /dev/null @@ -1,519 +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/>. - */ - -@font-face { - font-family: "CreteRound"; - font-style: normal; - src: url(fonts/CreteRound-Regular.otf); - src: local ("Ø"), - /*local ("Ø") forces using no local font called CreteRound*/ - url(fonts/CreteRound-Regular.otf) format("otf"); -} - -@font-face { - font-family: "CreteRound"; - font-style: italic; - src: url(fonts/CreteRound-Italic.otf); - src: local ("Ø"), - /*local ("Ø") forces using no local font called CreteRound*/ - url(fonts/CreteRound-Italic.otf) format("otf"); -} - -body -{ - font-family: Helvetica, Arial, sans-serif; - font-size: 15px; - line-height: 140%; - color: #7f776b; - background-color: #f8f6f2; - background-image: url(background-main.png); - margin: 0; - padding: 0; -} - -a, a:link, a:visited -{ - color: #5a84b3; - text-decoration: underline; -} - -a:hover -{ - text-decoration: none; -} - -button -{ - cursor: pointer; -} - -ul -{ - margin: 0; - padding: 0; -} - -li -{ - margin: 0; - padding: 0; - list-style-type: none; -} - -header -{ - background-image: url(background.png); - background-repeat: repeat-x; - width: 100%; - padding-top: 25px; -} - -header h1 -{ - font-size: 24px; - font-weight: normal; - color: #57ab5b; - text-align: center; - margin: 21px auto; - padding: 16px 0px; - border: 1px #57ab5b; - border-style: dashed none; - /* border parallel fix - 957px is the value - * closest to 960px(page width) which makes - * the dashed border parallel - */ - max-width: 957px; -} - -h1, -h2, -h3 -{ - font-family: CreteRound, Helvetica, Arial, sans-serif; -} - -h2 -{ - font-size: 26px; - font-weight: lighter; - color: #968d81; - line-height: 28px; - text-align: center; - margin: 0; - padding: 0; -} - -h3 -{ - font-size: 22px; - color: #7F776B; - font-weight: normal; - margin-top: 0px; - margin-bottom: 10px; - padding: 0; - line-height: 24px; -} - -h4 -{ - font-size: 15px; - color: #7f776b; - font-weight: normal; - text-align: center; - margin: 0; - padding: 0; -} - -section -{ - margin: 0 auto; - margin-bottom: 30px; - max-width: 960px; - background-image: url(background.png); - padding: 40px 100px; - box-sizing: border-box; -} - -#general -{ - display: table; - padding-left: 0px; - padding-right: 0px; -} - -#general > .block -{ - display: table-cell; - width: 50%; - vertical-align: top; - padding: 0px 50px; - border: dashed 0 #969085; - -webkit-border-start-width: 1px; - -moz-border-start-width: 1px; - border-inline-start-width: 1px; -} - -#general > .block:first-child -{ - border: none; -} - -#acceptable-ads-block h2 -{ - margin-bottom: 34px; -} - -#abb-promotion-block:lang(fr) -{ - display: none; -} - -#abb-promotion-block -{ - text-align: center; -} - -#abb-promotion-block h2 -{ - color: #7795b6; - margin-bottom: 40px; -} - -#abb-promotion-block a -{ - border: solid 1px #446a96; - border-radius: 5px; - display: inline-block; - padding: 6px 16px; - background: -webkit-linear-gradient(bottom, #294e76, #6b92be); - background: linear-gradient(to top, #294e76, #6b92be); - text-decoration: none; - text-align: start; -} - -#abb-promotion-block a > div -{ - display: table-cell; - vertical-align: middle; - padding: 6px; -} - -#abb-promotion-block .title -{ - font-size: 21px; - color: #ffffff; - font-weight: bold; -} - -#abb-promotion-block .subtitle -{ - font-size: 12px; - color: #9ab7d6; -} - -#abb-promotion-block a:hover -{ - box-shadow: 0px 0px 5px #5D5D5D; -} - -#abb-promotion-block a:active -{ - box-shadow: 0px 0px 5px 1px #5D5D5D; -} - -section > p -{ - margin-top: 15px; -} - -#logo -{ - margin: 0 auto; - height: 128px; - width: 128px; - display: block; -} - -#share -{ - background-image: url(background-share.png); - text-align: center; - font-family: CreteRound, Helvetica, Arial, sans-serif; -} - -#share h2 -{ - margin-bottom: 30px; -} - -#share h2, -#share h2 > a -{ - color: #fff; -} - -#share h2 > a:hover -{ - color: #2e5075; -} - -#share span -{ - color: #bed1e6; - text-align: center; - line-height: 34px; - font-size: 22px; - display: block; -} - -#donate:hover, .share-buttons a:hover -{ - box-shadow: 0px 0px 0px 2px #8ca7c4; - border-radius: 30px; -} - -#share > .block -{ - display: inline-block; - vertical-align: top; - width: 49%; - padding: 5px 0px; - border: 1px dashed #37506d; - border-style: none dashed; -} - -#share > .block:last-child -{ - -webkit-border-start-style: none; - -moz-border-start-style: none; -} - -#share > .block > span -{ - margin: 10px 20px; -} - -.share-buttons -{ - margin-top: 6px; - vertical-align: top; - /* because inline block creates - * space if not captured with - * font-size and line-height 0px - */ - font-size: 0px; - line-height: 0px; -} - -.share-buttons > a -{ - width: 50px; - height: 50px; - margin: 0 8px; - text-decoration: none; - display: inline-block; -} - -#share-general, -#share-chinese:lang(zh) -{ - display: block; -} - -#share-general:lang(zh), -#share-chinese -{ - display: none; -} - -#share-chinese > a -{ - border-bottom: 2px solid transparent; -} - -#share-chinese > a:hover -{ - box-shadow: none; - border-radius: 0; - border-bottom: 2px solid #8CA7C4; -} - -#share-facebook -{ - background-image: url(social/facebook.png); - background-repeat: no-repeat; -} - -#share-twitter -{ - background-image: url(social/twitter.png); - background-repeat: no-repeat; -} - -#share-gplus -{ - background-image: url(social/googleplus.png); - background-repeat: no-repeat; -} - -#share-renren -{ - background-image: url(social/renren.png); - background-repeat: no-repeat; -} - -#share-weibo -{ - background-image: url(social/weibo.png); - background-repeat: no-repeat; -} - -.warning -{ - font-size: 160%; - border: 3px dashed red; - text-align: center; - line-height: 1.3em; -} - -#social ul -{ - list-style: none; - display: inline-block; - padding: 0; - margin: 0; -} - -#social:hover h1 -{ - opacity: 0; -} - -#social ul:hover li { - opacity: 0.3; -} - -#social ul li -{ - display: inline-block; - margin: 0px 5px; - -webkit-transition: opacity .5s ease, bottom .3s ease; - transition: opacity .5s ease, bottom .3s ease; - position: relative; - bottom: -30px; -} - -#social ul li:hover -{ - opacity: 1.0; - bottom: 0px; -} - -.share-button -{ - display: inline-block; - width: 82px; - height: 82px; -} - -/* Change order of the blocks for French */ -#content:lang(fr) -{ - display: table; - margin: auto; - caption-side: bottom; -} - -#share:lang(fr) -{ - display: table-caption; -} - -#donate -{ - height: 21px; - display: inline-block; - margin-top: 15px; - margin-bottom: 2px; - font-size: 16px; - color: #003366; - cursor: pointer; - font-weight: bold; - padding: 5px 18px; - text-decoration: none; - border-radius: 20px; - border: 1px solid #FF9933; - overflow: hidden; - font-family: arial, sans-serif; - background-image: url(donate.png); - background-repeat: repeat-x; -} - -footer -{ - margin: 0 auto 30px; - max-width: 960px; - text-align: center; -} - -@media (max-width: 970px) -{ - header - { - background-size: 100px 57px; - } - - #logo - { - width: 64px; - height: 64px; - } - - section - { - padding: 40px 20px; - } - - #general, - #general > .block, - #share > .block - { - display: block; - } - - #general > .block - { - width: auto; - margin-left: 20px; - margin-right: 20px; - padding: 10px 0px; - border-width: 1px 0px 0px; - } - - #share > .block - { - width: auto; - padding: 20px 0px; - border-style: dashed none none; - } - - #donate, - .share-buttons - { - margin-top: 10px; - } -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Italic.otf b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Italic.otf Binary files differdeleted file mode 100644 index 169bced..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Italic.otf +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Regular.otf b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Regular.otf Binary files differdeleted file mode 100644 index d951855..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/fonts/CreteRound-Regular.otf +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/facebook.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/facebook.png Binary files differdeleted file mode 100644 index f45c417..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/facebook.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/googleplus.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/googleplus.png Binary files differdeleted file mode 100644 index 53e6819..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/googleplus.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/renren.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/renren.png Binary files differdeleted file mode 100644 index e9af994..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/renren.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/twitter.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/twitter.png Binary files differdeleted file mode 100644 index fec913a..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/twitter.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/weibo.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/weibo.png Binary files differdeleted file mode 100644 index 176a628..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/social/weibo.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js deleted file mode 100644 index 261b710..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js +++ /dev/null @@ -1,308 +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/FileUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); - -let subscriptionListLoading = false; - -function init() -{ - if (window.arguments && window.arguments.length && window.arguments[0]) - { - let source = window.arguments[0]; - setCustomSubscription(source.title, source.url, - source.mainSubscriptionTitle, source.mainSubscriptionURL); - - E("all-subscriptions-container").hidden = true; - E("fromWebText").hidden = false; - } - else - loadSubscriptionList(); -} - -function updateSubscriptionInfo() -{ - let selectedSubscription = E("all-subscriptions").selectedItem; - - E("subscriptionInfo").setAttribute("invisible", !selectedSubscription); - if (selectedSubscription) - { - let url = selectedSubscription.getAttribute("_url"); - let homePage = selectedSubscription.getAttribute("_homepage") - - let viewLink = E("view-list"); - viewLink.setAttribute("_url", url); - viewLink.setAttribute("tooltiptext", url); - - let homePageLink = E("visit-homepage"); - homePageLink.hidden = !homePage; - if (homePage) - { - homePageLink.setAttribute("_url", homePage); - homePageLink.setAttribute("tooltiptext", homePage); - } - } -} - -function reloadSubscriptionList() -{ - subscriptionListLoading = false; - loadSubscriptionList(); -} - -function loadSubscriptionList() -{ - if (subscriptionListLoading) - return; - - E("all-subscriptions-container").selectedIndex = 0; - E("all-subscriptions-loading").hidden = false; - - let request = new XMLHttpRequest(); - let errorHandler = function() - { - E("all-subscriptions-container").selectedIndex = 2; - E("all-subscriptions-loading").hidden = true; - }; - let successHandler = function() - { - if (!request.responseXML || request.responseXML.documentElement.localName != "subscriptions") - { - errorHandler(); - return; - } - - try - { - processSubscriptionList(request.responseXML); - E("all-subscriptions").selectedIndex = 0; - E("all-subscriptions").focus(); - } - catch (e) - { - Cu.reportError(e); - errorHandler(); - } - }; - - request.open("GET", Prefs.subscriptions_listurl); - request.addEventListener("error", errorHandler, false); - request.addEventListener("load", successHandler, false); - request.send(null); - - subscriptionListLoading = true; -} - -function processSubscriptionList(doc) -{ - let list = E("all-subscriptions"); - while (list.firstChild) - list.removeChild(list.firstChild); - - addSubscriptions(list, doc.documentElement, 0, null, null); - E("all-subscriptions-container").selectedIndex = 1; - E("all-subscriptions-loading").hidden = true; -} - -function addSubscriptions(list, parent, level, parentTitle, parentURL) -{ - for (let i = 0; i < parent.childNodes.length; i++) - { - let node = parent.childNodes[i]; - if (node.nodeType != Node.ELEMENT_NODE || node.localName != "subscription") - continue; - - if (node.getAttribute("type") != "ads" || node.getAttribute("deprecated") == "true") - continue; - - let variants = node.getElementsByTagName("variants"); - if (!variants.length || !variants[0].childNodes.length) - continue; - variants = variants[0].childNodes; - - let isFirst = true; - let mainTitle = null; - let mainURL = null; - for (let j = 0; j < variants.length; j++) - { - let variant = variants[j]; - if (variant.nodeType != Node.ELEMENT_NODE || variant.localName != "variant") - continue; - - let item = document.createElement("richlistitem"); - item.setAttribute("_title", variant.getAttribute("title")); - item.setAttribute("_url", variant.getAttribute("url")); - if (parentTitle && parentURL && variant.getAttribute("complete") != "true") - { - item.setAttribute("_supplementForTitle", parentTitle); - item.setAttribute("_supplementForURL", parentURL); - } - item.setAttribute("tooltiptext", variant.getAttribute("url")); - item.setAttribute("_homepage", node.getAttribute("homepage")); - - let title = document.createElement("description"); - if (isFirst) - { - if (Utils.checkLocalePrefixMatch(node.getAttribute("prefixes"))) - title.setAttribute("class", "subscriptionTitle localeMatch"); - else - title.setAttribute("class", "subscriptionTitle"); - title.textContent = node.getAttribute("title") + " (" + node.getAttribute("specialization") + ")"; - mainTitle = variant.getAttribute("title"); - mainURL = variant.getAttribute("url"); - isFirst = false; - } - title.setAttribute("flex", "1"); - title.style.marginLeft = (20 * level) + "px"; - item.appendChild(title); - - let variantTitle = document.createElement("description"); - variantTitle.setAttribute("class", "variant"); - variantTitle.textContent = variant.getAttribute("title"); - variantTitle.setAttribute("crop", "end"); - item.appendChild(variantTitle); - - list.appendChild(item); - } - - let supplements = node.getElementsByTagName("supplements"); - if (supplements.length) - addSubscriptions(list, supplements[0], level + 1, mainTitle, mainURL); - } -} - -function onSelectionChange() -{ - let selectedItem = E("all-subscriptions").selectedItem; - if (!selectedItem) - return; - - setCustomSubscription(selectedItem.getAttribute("_title"), selectedItem.getAttribute("_url"), - selectedItem.getAttribute("_supplementForTitle"), selectedItem.getAttribute("_supplementForURL")); - - updateSubscriptionInfo(); -} - -function setCustomSubscription(title, url, mainSubscriptionTitle, mainSubscriptionURL) -{ - E("title").value = title; - E("location").value = url; - - let messageElement = E("supplementMessage"); - let addMainCheckbox = E("addMainSubscription"); - if (mainSubscriptionURL && !hasSubscription(mainSubscriptionURL)) - { - messageElement.removeAttribute("invisible"); - addMainCheckbox.removeAttribute("invisible"); - - let [, beforeLink, afterLink] = /(.*)\?1\?(.*)/.exec(messageElement.getAttribute("_textTemplate")) || [null, messageElement.getAttribute("_textTemplate"), ""]; - while (messageElement.firstChild) - messageElement.removeChild(messageElement.firstChild); - messageElement.appendChild(document.createTextNode(beforeLink)); - let link = document.createElement("label"); - link.className = "text-link"; - link.setAttribute("tooltiptext", mainSubscriptionURL); - link.addEventListener("click", () => UI.loadInBrowser(mainSubscriptionURL), false); - link.textContent = mainSubscriptionTitle; - messageElement.appendChild(link); - messageElement.appendChild(document.createTextNode(afterLink)); - - addMainCheckbox.value = mainSubscriptionURL; - addMainCheckbox.setAttribute("_mainSubscriptionTitle", mainSubscriptionTitle) - let [label, accesskey] = Utils.splitLabel(addMainCheckbox.getAttribute("_labelTemplate")); - addMainCheckbox.label = label.replace(/\?1\?/g, mainSubscriptionTitle); - addMainCheckbox.accessKey = accesskey; - } - else - { - messageElement.setAttribute("invisible", "true"); - addMainCheckbox.setAttribute("invisible", "true"); - } -} - -function validateURL(url) -{ - if (!url) - return null; - url = url.trim(); - - // Is this a file path? - try { - let file = new FileUtils.File(url); - return Services.io.newFileURI(file).spec; - } catch (e) {} - - // Is this a valid URL? - let uri = Utils.makeURI(url); - if (uri) - return uri.spec; - - return null; -} - -function addSubscription() -{ - let url = E("location").value; - url = validateURL(url); - if (!url) - { - Utils.alert(window, Utils.getString("subscription_invalid_location")); - E("location").focus(); - return false; - } - - let title = E("title").value.trim(); - if (!title) - title = url; - - doAddSubscription(url, title); - - let addMainCheckbox = E("addMainSubscription") - if (addMainCheckbox.getAttribute("invisible") != "true" && addMainCheckbox.checked) - { - let mainSubscriptionTitle = addMainCheckbox.getAttribute("_mainSubscriptionTitle"); - let mainSubscriptionURL = validateURL(addMainCheckbox.value); - if (mainSubscriptionURL) - doAddSubscription(mainSubscriptionURL, mainSubscriptionTitle); - } - - return true; -} - -/** - * Adds a new subscription to the list. - */ -function doAddSubscription(/**String*/ url, /**String*/ title) -{ - let subscription = Subscription.fromURL(url); - if (!subscription) - return; - - FilterStorage.addSubscription(subscription); - - subscription.disabled = false; - subscription.title = title; - - if (subscription instanceof DownloadableSubscription && !subscription.lastDownload) - Synchronizer.execute(subscription); -} - -function hasSubscription(url) -{ - return FilterStorage.subscriptions.some(subscription => subscription instanceof DownloadableSubscription && subscription.url == url); -} diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.xul deleted file mode 100644 index c2383c6..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.xul +++ /dev/null @@ -1,75 +0,0 @@ -<?xml version="1.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/>. - --> - -<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> -<?xml-stylesheet href="chrome://adblockplus/skin/subscriptionSelection.css" type="text/css"?> - -<!DOCTYPE dialog SYSTEM "chrome://adblockplus/locale/subscriptionSelection.dtd"> - -<dialog - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" - buttons="accept,cancel" - buttonlabelaccept="&addSubscription.label;" - title="&dialog.title;" - id="abpSubscriptionSelection" - windowtype="abp:subscriptionSelection" - onload="init();" - ondialogaccept="return addSubscription();"> - - <script type="application/x-javascript;version=1.7" src="utils.js"/> - <script type="application/x-javascript;version=1.7" src="subscriptionSelection.js"/> - - <deck id="all-subscriptions-container" selectedIndex="0" flex="1"> - <vbox pack="center"> - <progressmeter id="all-subscriptions-loading" mode="undetermined"/> - </vbox> - <vbox> - <richlistbox id="all-subscriptions" onselect="onSelectionChange()" flex="1"/> - <hbox id="subscriptionInfo" invisible="true"> - <label id="view-list" class="text-link" value="&viewList.label;" onclick="UI.loadInBrowser(this.getAttribute('_url'))"/> - <spacer flex="1"/> - <label id="visit-homepage" class="text-link" value="&visitHomepage.label;" onclick="UI.loadInBrowser(this.getAttribute('_url'))"/> - </hbox> - </vbox> - <vbox pack="center" align="center"> - <description value="&list.download.failed;"/> - <hbox> - <button label="&list.download.retry;" oncommand="reloadSubscriptionList()"/> - <button label="&list.download.website;" oncommand="UI.loadDocLink('subscriptions')"/> - </hbox> - </vbox> - </deck> - - <description id="fromWebText" hidden="true">&fromWeb.description;</description> - - <groupbox id="differentSubscription"> - <label value="&title.label;" control="title"/> - <textbox id="title"/> - - <label value="&location.label;" control="location"/> - <textbox id="location"/> - </groupbox> - - <description id="supplementMessage" invisible="true" _textTemplate="&supplementMessage;"> - &supplementMessage; - <label class="text-link" oncommand="">dummy dummy dummy dummy dummy dummy dummy dummy dummy dummy</label> - </description> - <checkbox id="addMainSubscription" invisible="true" checked="true" _labelTemplate="&addMain.label;" label="&addMain.label;"/> - -</dialog> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml deleted file mode 100644 index 953f16d..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml +++ /dev/null @@ -1,126 +0,0 @@ -<?xml version="1.0"?> - -<!-- - - This file is part of the Adblock Plus web scripts, - - 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/>. - --> - -<subscriptions> - <subscription title="EasyList" - specialization="English" - url="https://easylist-downloads.adblockplus.org/easylist.txt" - homepage="https://easylist.adblockplus.org/" - prefixes="en" - author="fanboy, MonztA, Famlam, Khrin" - type="ads"/> - <subscription title="ABPindo+EasyList" - specialization="Bahasa Indonesia" - url="https://easylist-downloads.adblockplus.org/abpindo+easylist.txt" - homepage="http://abpindo.blogspot.com/" - prefixes="id" - author="heradhis" - type="ads"/> - <subscription title="Bulgarian list+EasyList" - specialization="български" - url="https://easylist-downloads.adblockplus.org/bulgarian_list+easylist.txt" - homepage="http://stanev.org/abp/" - prefixes="bg" - author="Александър Станев" - type="ads"/> - <subscription title="EasyList China+EasyList" - specialization="中文" - url="https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt" - homepage="http://abpchina.org/forum/" - prefixes="zh" - author="John, Li" - type="ads"/> - <subscription title="EasyList Czech and Slovak+EasyList" - specialization="čeština, slovenčina" - url="https://easylist-downloads.adblockplus.org/easylistczechslovak+easylist.txt" - homepage="http://adblock.sk/" - prefixes="cs,sk" - author="tomasko126" - type="ads"/> - <subscription title="EasyList Dutch+EasyList" - specialization="Nederlands" - url="https://easylist-downloads.adblockplus.org/easylistdutch+easylist.txt" - homepage="https://easylist.adblockplus.org/" - prefixes="nl" - author="Famlam" - type="ads"/> - <subscription title="EasyList Germany+EasyList" - specialization="Deutsch" - url="https://easylist-downloads.adblockplus.org/easylistgermany+easylist.txt" - homepage="https://easylist.adblockplus.org/" - prefixes="de" - author="MonztA, Famlam" - type="ads"/> - <subscription title="EasyList Hebrew+EasyList" - specialization="עברית" - url="https://easylist-downloads.adblockplus.org/israellist+easylist.txt" - homepage="https://github.com/ABPIsrael/EasyListHebrew" - prefixes="he" - author="BsT" - type="ads"/> - <subscription title="EasyList Italy+EasyList" - specialization="italiano" - url="https://easylist-downloads.adblockplus.org/easylistitaly+easylist.txt" - homepage="https://easylist.adblockplus.org/" - prefixes="it" - author="Khrin" - type="ads"/> - <subscription title="EasyList Lithuania+EasyList" - specialization="lietuvių kalba" - url="https://easylist-downloads.adblockplus.org/easylistlithuania+easylist.txt" - homepage="http://margevicius.lt/" - prefixes="lt" - author="Algimantas Margevičius" - type="ads"/> - <subscription title="Latvian List+EasyList" - specialization="latviešu valoda" - url="https://easylist-downloads.adblockplus.org/latvianlist+easylist.txt" - homepage="https://notabug.org/latvian-list/adblock-latvian" - prefixes="lv" - author="anonymous74100" - type="ads"/> - <subscription title="Liste AR+Liste FR+EasyList" - specialization="العربية" - url="https://easylist-downloads.adblockplus.org/liste_ar+liste_fr+easylist.txt" - homepage="https://code.google.com/p/liste-ar-adblock/" - prefixes="ar" - author="smed79" - type="ads"/> - <subscription title="Liste FR+EasyList" - specialization="français" - url="https://easylist-downloads.adblockplus.org/liste_fr+easylist.txt" - homepage="http://adblock-listefr.com/" - prefixes="fr" - author="Lian, Crits, smed79" - type="ads"/> - <subscription title="ROList+EasyList" - specialization="românesc" - url="https://easylist-downloads.adblockplus.org/rolist+easylist.txt" - homepage="http://www.zoso.ro/rolist" - prefixes="ro" - author="MenetZ, Zoso" - type="ads"/> - <subscription title="RuAdList+EasyList" - specialization="русский, українська" - url="https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt" - homepage="https://forums.lanik.us/viewforum.php?f=102" - prefixes="ru,uk" - author="Lain_13" - type="ads"/> - </subscriptions>
\ No newline at end of file diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/utils.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/utils.js deleted file mode 100644 index 5f8d515..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/utils.js +++ /dev/null @@ -1,86 +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/>. - */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); - -/** - * Imports a module from Adblock Plus core. - */ -function require(/**String*/ module) -{ - var result = {}; - result.wrappedJSObject = result; - Services.obs.notifyObservers(result, "adblockplus-require", module); - return result.exports; -} - -var {Policy} = require("contentPolicy"); -var {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter, - BlockingFilter, WhitelistFilter, ElemHideBase, ElemHideFilter, - ElemHideException, ElemHideEmulationFilter} = require("filterClasses"); -var {FilterNotifier} = require("filterNotifier"); -var {FilterStorage} = require("filterStorage"); -var {IO} = require("legacyIO"); -var {defaultMatcher, Matcher, CombinedMatcher} = require("matcher"); -var {Prefs} = require("prefs"); -var {RequestNotifier} = require("requestNotifier"); -var {Subscription, SpecialSubscription, RegularSubscription, - ExternalSubscription, DownloadableSubscription} = require("subscriptionClasses"); -var {Synchronizer} = require("synchronizer"); -var {UI} = require("ui"); -var {Utils} = require("utils"); - -/** - * Shortcut for document.getElementById(id) - */ -function E(id) -{ - return document.getElementById(id); -} - -/** - * Determines subscription's title as it should be displayed in the UI. - * @return {String} - * subscription's title or an appropriate default title if none present - */ -function getSubscriptionTitle(/**Subscription*/ subscription) -{ - if (subscription.title) - return subscription.title; - - if (subscription instanceof DownloadableSubscription) - return subscription.url; - - if (subscription instanceof SpecialSubscription && subscription.defaults) - return Utils.getString(subscription.defaults + "Group_title"); - - return Utils.getString("newGroup_title"); -} - -/** - * Split up all labels into the label and access key portions. - */ -document.addEventListener("DOMContentLoaded", function splitAllLabelsHandler() -{ - document.removeEventListener("DOMContentLoaded", splitAllLabelsHandler, false); - Utils.splitAllLabels(document); -}, false); |