diff options
author | Ruben Rodriguez <ruben@gnu.org> | 2017-09-01 16:35:50 -0400 |
---|---|---|
committer | Ruben Rodriguez <ruben@gnu.org> | 2017-09-01 16:35:50 -0400 |
commit | e8730f68798f173bd4d1c2f9b7ce02985e3fd771 (patch) | |
tree | 711132ed84ef8ae9e0621de5436a6818a5fa1e12 /data/extensions/spyblock@gnu.org/chrome/content | |
parent | edde38bbb0e0afb9b8a78c002996c758fb6023b6 (diff) |
SpyBlock updated to 2.9.1
Diffstat (limited to 'data/extensions/spyblock@gnu.org/chrome/content')
41 files changed, 1556 insertions, 1609 deletions
diff --git a/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js b/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js new file mode 100644 index 0000000..ff824ae --- /dev/null +++ b/data/extensions/spyblock@gnu.org/chrome/content/elemHideEmulation.js @@ -0,0 +1,167 @@ +// 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/errors.html b/data/extensions/spyblock@gnu.org/chrome/content/errors.html deleted file mode 100644 index 24e05a5..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/errors.html +++ /dev/null @@ -1,111 +0,0 @@ -<!DOCTYPE html> - -<html> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <title>Adblock Plus Errors</title> - <style type="text/css"> - .warning, .error - { - border: 1px dashed black; - margin: 5px; - padding: 2px; - white-space: pre-wrap; - } - - .error - { - background-color: #fff0f0; - } - - .warning - { - background-color: #ffffe0; - } - - button - { - float: right; - } - </style> -</head> -<body> - <button onclick="window.location.reload();">Refresh</button> - <button onclick="clearErrors();">Clear errors</button> - - <script type="application/x-javascript;version=1.7"> - let id = null; - try { - let {addonVersion, addonID} = require("info"); - - let text = "You are running Adblock Plus " + addonVersion; - text += "."; - document.write("<p>" + text + "</p>"); - - id = addonID.replace(/[\{\}]/g, ""); - } catch (e) {} - - // 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 = Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .getMessageArray(outparam, {}); - messages = messages || outparam.value || []; - messages = messages.filter(function(message) - { - return (message instanceof Components.interfaces.nsIScriptError && - !/^https?:/i.test(message.sourceName) && - (/adblock/i.test(message.errorMessage) || /adblock/i.test(message.sourceName) || - id && (message.errorMessage.indexOf(id) >= 0 || message.sourceName && message.sourceName.indexOf(id) >= 0))); - }); - - if (messages.length) - { - document.write("<p>Errors related to Adblock Plus:</p>"); - - for (let message of messages) - { - let type = (message.flags & Components.interfaces.nsIScriptError.warningFlag ? "warning" : "error"); - let html = "<b>" + (type == "warning" ? "Warning:" : "Error:") + "</b><br>"; - html += encodeHTML(message.errorMessage) + "<br><br>"; - if (message.sourceLine) - html += "Source line: " + encodeHTML(message.sourceLine) + "<br>"; - if (message.sourceName) - html += "Location: " + encodeHTML(message.sourceName) + " line " + message.lineNumber + "<br>"; - html = html.replace(/(<br>)+$/, ""); - document.write("<div class='" + type + "'>" + - html + - "</div>"); - } - } - else - { - document.write("<p>No errors found.</p>"); - } - - function require(module) - { - let {Services} = Components.utils.import("resource://gre/modules/Services.jsm"); - let result = {}; - result.wrappedJSObject = result; - Services.obs.notifyObservers(result, "adblockplus-require", module); - return result.exports; - } - - function encodeHTML(string) - { - return string.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); - } - - function clearErrors() - { - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .reset(); - window.location.reload(); - } - </script> -</body> -</html> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css b/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css index d61f702..62ad04b 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css +++ b/data/extensions/spyblock@gnu.org/chrome/content/objtabs.css @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js new file mode 100644 index 0000000..ec20ede --- /dev/null +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/common.js @@ -0,0 +1,154 @@ +/* + * 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 index 98a38aa..8170cee 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -15,13 +15,14 @@ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. */ -let nodes = null; -let item = null; -let advancedMode = false; +var nodesID = null; +var item = null; +var advancedMode = false; function init() { - [nodes, item] = window.arguments; + [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; @@ -118,19 +119,8 @@ function init() else E("patternGroup").focus(); - let types = []; - for (let type in Policy.localizedDescr) - { - types.push(parseInt(type)); - } - types.sort(function(a, b) { - if (a < b) - return -1; - else if (a > b) - return 1; - else - return 0; - }); + let types = Array.from(new Set(Policy.contentTypes.values())); + types.sort(); let docDomain = item.docDomain; let thirdParty = item.thirdParty; @@ -145,24 +135,24 @@ function init() let typeGroup = E("typeGroup"); let defaultTypes = RegExpFilter.prototype.contentType & ~RegExpFilter.typeMap.DOCUMENT; - let isDefaultType = (RegExpFilter.typeMap[item.typeDescr] & defaultTypes) != 0; + let isDefaultType = (RegExpFilter.typeMap[item.type] & defaultTypes) != 0; for (let type of types) { - if (type == Policy.type.ELEMHIDE) + if (type == "ELEMHIDE" || type == "GENERICBLOCK" || type == "GENERICHIDE") continue; let typeNode = document.createElement("checkbox"); - typeNode.setAttribute("value", Policy.typeDescr[type].toLowerCase().replace(/\_/g, "-")); - typeNode.setAttribute("label", Policy.localizedDescr[type].toLowerCase()); + typeNode.setAttribute("value", type.toLowerCase().replace(/\_/g, "-")); + typeNode.setAttribute("label", Utils.getString("type_label_" + type.toLowerCase())); - let typeMask = RegExpFilter.typeMap[Policy.typeDescr[type]]; + 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", function() checkboxUpdated(this), false); + typeNode.addEventListener("command", () => checkboxUpdated(typeNode), false); typeGroup.appendChild(typeNode); } @@ -255,16 +245,16 @@ function updateFilter() if (options.length) { - options.sort(function(a, b) a[0] - b[0]); - filter += "$" + options.map(function(o) o[1]).join(","); + 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.typeDescr] & defaultTypes) != 0; + let isDefaultType = (RegExpFilter.typeMap[item.type] & defaultTypes) != 0; if (!isDefaultType) - filter += "$" + item.typeDescr.toLowerCase().replace(/\_/g, "-"); + filter += "$" + item.type.toLowerCase().replace(/\_/g, "-"); } filter = Filter.normalize(filter); @@ -279,7 +269,7 @@ function updateFilter() } E("shortpatternWarning").hidden = !isSlow; - E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, item.typeDescr, item.docDomain, item.thirdParty); + E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); E("filter").value = filter; } @@ -318,7 +308,7 @@ function updatePatternSelection() function testFilter(/**String*/ filter) /**Boolean*/ { - return RegExpFilter.fromText(filter + "$" + item.typeDescr).matches(item.location, item.typeDescr, item.docDomain, item.thirdParty); + return RegExpFilter.fromText(filter + "$" + item.type).matches(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); } let anchorStartCheckbox = E("anchorStart"); @@ -352,8 +342,8 @@ function addFilter() { FilterStorage.addFilter(filter); - if (nodes) - Policy.refilterNodes(nodes, item); + if (nodesID) + Policy.refilterNodes(nodesID, item); return true; } diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul index 66e64ef..2cf1502 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/composer.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 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 index 129f232..296c00f 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/common.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/common.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -17,140 +17,105 @@ (function(global) { - const Ci = Components.interfaces; + const Cu = Components.utils; + + let {Services} = Cu.import("resource://gre/modules/Services.jsm", {}); if (!global.ext) global.ext = {}; - var holder = { - get Page() - { - delete this.Page; - this.Page = (typeof require == "function" ? - require("ext_background").Page : - function() {}); - return this.Page; - } - }; + var wrapperSymbol = Symbol("ext-wrapper"); - var getSender = global.ext._getSender = function(origin) + function wrapFrames(frames) { - if (origin instanceof Ci.nsIDOMXULElement) - return origin.messageManager; - else if (origin instanceof Ci.nsIMessageSender) - return origin; - else + if (!frames.length) return null; - }; - var MessageProxy = global.ext._MessageProxy = function(messageManager, messageTarget) - { - this._messageManager = messageManager; - this._messageTarget = messageTarget; - this._callbacks = new Map(); - this._responseCallbackCounter = 0; + // 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) + }); - this._handleRequest = this._handleRequest.bind(this); - this._handleResponse = this._handleResponse.bind(this); - this._messageManager.addMessageListener("AdblockPlus:Message", this._handleRequest); - this._messageManager.addMessageListener("AdblockPlus:Response", this._handleResponse); - }; - MessageProxy.prototype = { - _disconnect: function() - { - this._messageManager.removeMessageListener("AdblockPlus:Message", this._handleRequest); - this._messageManager.removeMessageListener("AdblockPlus:Response", this._handleResponse); - }, + Object.defineProperty(frames, "parent", { + enumerable: true, + get: () => wrapFrames(frames.slice(1)) + }); - _sendResponse: function(sender, callbackId, message) - { - var response = { - callbackId: callbackId - }; - if (typeof response != "undefined") - response.payload = message; - sender.sendAsyncMessage("AdblockPlus:Response", response); - }, + return frames; + } - _handleRequest: function(message) + var EventTarget = global.ext._EventTarget = function(port, windowID) + { + this._port = port; + this._windowID = windowID; + this.addListener((payload, sender, resolve) => { - var sender = getSender(message.target); - var request = message.data; - - var sent = false; - var sendResponse; - if (sender && "callbackId" in request) + if (payload.type) { - sendResponse = function(message) - { - this._sendResponse(sender, request.callbackId, message); - sent = true; - }.bind(this); + let result = this._port._dispatch(payload.type, payload, sender); + if (typeof result != "undefined") + resolve(result); } - else - sendResponse = function() {}; - - var results = this._messageTarget._dispatch(request.payload, { - page: new holder.Page(sender) - }, sendResponse); - if (!sent && results.indexOf(true) == -1) - sendResponse(undefined); - }, - - _handleResponse: function(message) + }); + }; + EventTarget.prototype = { + addListener: function(listener) { - var response = message.data; - var callback = this._callbacks.get(response.callbackId); - if (callback) + var wrapper = (message, sender) => { - this._callbacks.delete(response.callbackId); - if ("payload" in response) - callback(response.payload); - } - }, + if (this._windowID && this._windowID != message.targetID) + return undefined; - sendMessage: function(message, responseCallback) - { - if (!(this._messageManager instanceof Ci.nsIMessageSender)) - throw new Error("Not implemented"); - - var request = { - payload: message + 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); + }); }; - if (responseCallback) - { - request.callbackId = ++this._responseCallbackCounter; - this._callbacks.set(request.callbackId, responseCallback); - } + listener[wrapperSymbol] = wrapper; + this._port.on("ext_message", wrapper); + }, - this._messageManager.sendAsyncMessage("AdblockPlus:Message", request); + removeListener: function(listener) + { + if (listener[wrapperSymbol]) + this._port.off("ext_message", listener[wrapperSymbol]); } }; - var EventTarget = global.ext._EventTarget = function() - { - this._listeners = []; - }; - EventTarget.prototype = { - addListener: function(listener) - { - if (this._listeners.indexOf(listener) == -1) - this._listeners.push(listener); - }, - removeListener: function(listener) - { - var idx = this._listeners.indexOf(listener); - if (idx != -1) - this._listeners.splice(idx, 1); - }, - _dispatch: function() - { - var results = []; + let pageName = "global"; + if (typeof location !== "undefined") + pageName = location.pathname.replace(/.*\//, "").replace(/\..*?$/, ""); - for (var i = 0; i < this._listeners.length; i++) - results.push(this._listeners[i].apply(null, arguments)); + let stringBundle = Services.strings.createBundle( + "chrome://adblockplus/locale/" + pageName + ".properties?" + Math.random()); - return results; + 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 ""; + } } }; 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 index db2d7e1..366325a 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/content.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/ext/content.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -17,86 +17,66 @@ (function(global) { + const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; - if (!global.ext) - global.ext = {}; - - /* Message passing */ - global.ext.onMessage = new global.ext._EventTarget(); + var Services = Cu.import("resource://gre/modules/Services.jsm", {}).Services; - global.ext.backgroundPage = new global.ext._MessageProxy( - window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShell) - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIContentFrameMessageManager), - global.ext.onMessage); - window.addEventListener("unload", function() + function require(/**String*/ module) { - global.ext.backgroundPage._disconnect(); - }, false); + var result = {}; + result.wrappedJSObject = result; + Services.obs.notifyObservers(result, "adblockplus-require", module); + return result.exports; + } - /* i18n */ - global.ext.i18n = (function() + function getOuterWindowID() { - var Services = Cu.import("resource://gre/modules/Services.jsm", null).Services; - var pageName = location.pathname.replace(/.*\//, "").replace(/\..*?$/, ""); - - // Randomize URI to work around bug 719376 - var stringBundle = Services.strings.createBundle("chrome://adblockplus/locale/" + pageName + - ".properties?" + Math.random()); - - function getI18nMessage(key) + if (!getOuterWindowID.result) { - return { - "message": stringBundle.GetStringFromName(key) - }; + getOuterWindowID.result = window.QueryInterface(Ci.nsIInterfaceRequestor) + .getInterface(Ci.nsIDOMWindowUtils) + .outerWindowID; } + return getOuterWindowID.result; + } - function getText(message, args) - { - var text = message.message; - var placeholders = message.placeholders; - - if (!args || !placeholders) - return text; - - for (var key in placeholders) - { - var content = placeholders[key].content; - if (!content) - continue; + const Port = require("messaging").Port; - var index = parseInt(content.slice(1), 10); - if (isNaN(index)) - continue; + if (!global.ext) + global.ext = {}; - var replacement = args[index - 1]; - if (typeof replacement === "undefined") - continue; + /* 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); - text = text.split("$" + key + "$").join(replacement); - } - return text; + 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); } + }; - return { - getMessage: function(key, args) - { - try{ - var message = getI18nMessage(key); - return getText(message, args); - } - catch(e) - { - // Don't report errors for special strings, these are expected to be - // missing. - if (key[0] != "@") - Cu.reportError(e); - return ""; - } - } - }; - })(); })(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 index c0f38f6..6e7675f 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/fennecSettings.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/fennecSettings.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -29,6 +29,8 @@ <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 index 9232b5f..b3f8b94 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-backup.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-backup.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -97,20 +97,22 @@ var Backup = while (this.restoreInsertionPoint.nextSibling && !this.restoreInsertionPoint.nextSibling.id) this.restoreInsertionPoint.parentNode.removeChild(this.restoreInsertionPoint.nextSibling); - let files = FilterStorage.getBackupFiles().reverse(); - for (let i = 0; i < files.length; i++) + FilterStorage.getBackupFiles().then(backups => { - let file = files[i]; - let item = this.restoreTemplate.cloneNode(true); - let label = item.getAttribute("label"); - label = label.replace(/\?1\?/, Utils.formatTime(file.lastModifiedTime)); - item.setAttribute("label", label); - item.addEventListener("command", function() + backups.reverse(); + for (let backup of backups) { - Backup.restoreAllData(file); - }, false); - this.restoreInsertionPoint.parentNode.insertBefore(item, this.restoreInsertionPoint.nextSibling); - } + 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); + } + }); }, /** @@ -139,34 +141,40 @@ var Backup = */ restoreAllData: function(/**nsIFile*/ file) { - let stream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); - stream.init(file, FileUtils.MODE_RDONLY, FileUtils.PERMS_FILE, 0); - stream.QueryInterface(Ci.nsILineInputStream); - + let sink = FilterStorage.importData(); let lines = []; - let line = {value: null}; - if (stream.readLine(line)) - lines.push(line.value); - if (stream.readLine(line)) - lines.push(line.value); - stream.close(); - - 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; - } + 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"); + 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; + if (!Utils.confirm(window, warning, E("backupButton").getAttribute("_restoreDialogTitle"))) + return; + } + else if (lines.length < 2) + lines.push(line); - FilterStorage.loadFromDisk(file); + sink(line); + } + }, error => + { + if (error) + alert(error); + else + FilterStorage.saveToDisk(); + }); }, /** @@ -193,7 +201,7 @@ var Backup = if (Utils.confirm(window, warning, E("backupButton").getAttribute("_restoreDialogTitle"))) { - let subscriptions = FilterStorage.subscriptions.filter(function(s) s instanceof SpecialSubscription); + let subscriptions = FilterStorage.subscriptions.filter(s => s instanceof SpecialSubscription); for (let i = 0; i < subscriptions.length; i++) FilterStorage.removeSubscription(subscriptions[i]); @@ -282,7 +290,11 @@ var Backup = */ backupAllData: function(/**nsIFile*/ file) { - FilterStorage.saveToDisk(file); + IO.writeToFile(file, FilterStorage.exportData(), error => + { + if (error) + alert(error); + }); }, /** @@ -290,7 +302,7 @@ var Backup = */ backupCustomFilters: function(/**nsIFile*/ file) { - let subscriptions = FilterStorage.subscriptions.filter(function(s) s instanceof SpecialSubscription); + let subscriptions = FilterStorage.subscriptions.filter(s => s instanceof SpecialSubscription); let minVersion = "2.0" let list = []; for (let i = 0; i < subscriptions.length; i++) @@ -299,7 +311,7 @@ var Backup = let typeAddition = ""; if (subscription.defaults) typeAddition = "/" + subscription.defaults.join("/"); - list.push("! [" + subscription.title + "]" + typeAddition); + list.push("! [" + getSubscriptionTitle(subscription) + "]" + typeAddition); for (let j = 0; j < subscription.filters.length; j++) { let filter = subscription.filters[j]; @@ -313,6 +325,19 @@ var Backup = 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 + "]"); @@ -325,13 +350,7 @@ var Backup = if (checksum) list.splice(1, 0, "! Checksum: " + checksum); - function generator() - { - for (let i = 0; i < list.length; i++) - yield list[i]; - } - - IO.writeToFile(file, generator(), function(e) + IO.writeToFile(file, list, function(e) { if (e) { 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 index 2a78e56..ad128b8 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filteractions.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filteractions.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -101,9 +101,9 @@ var FilterActions = fillActionsPopup: function() { let editable = FilterView.editable; - let items = FilterView.selectedItems.filter(function(i) !i.filter.dummy); - items.sort(function(entry1, entry2) entry1.index - entry2.index); - let activeItems = items.filter(function(i) i.filter instanceof ActiveFilter); + 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); @@ -142,7 +142,7 @@ var FilterActions = if (this.treeElement.editingColumn) return; - let items = FilterView.selectedItems.filter(function(i) i.filter instanceof ActiveFilter); + let items = FilterView.selectedItems.filter(i => i.filter instanceof ActiveFilter); if (items.length) { FilterView.boxObject.beginUpdateBatch(); @@ -205,7 +205,7 @@ var FilterActions = deleteItems: function(/**Array*/ items) { let oldIndex = FilterView.selection.currentIndex; - items.sort(function(entry1, entry2) entry2.index - entry1.index); + 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); @@ -236,9 +236,9 @@ var FilterActions = if (this.treeElement.editingColumn) return; - let items = FilterView.selectedItems.filter(function(i) i.filter instanceof ActiveFilter); + let items = FilterView.selectedItems.filter(i => i.filter instanceof ActiveFilter); if (items.length) - FilterStorage.resetHitCounts(items.map(function(i) i.filter)); + FilterStorage.resetHitCounts(items.map(i => i.filter)); }, /** @@ -253,7 +253,7 @@ var FilterActions = if (offset < 0) { - items.sort(function(entry1, entry2) entry1.index - entry2.index); + items.sort((entry1, entry2) => entry1.index - entry2.index); let position = items[0].index + offset; if (position < 0) return; @@ -264,7 +264,7 @@ var FilterActions = } else if (offset > 0) { - items.sort(function(entry1, entry2) entry2.index - entry1.index); + items.sort((entry1, entry2) => entry2.index - entry1.index); let position = items[0].index + offset; if (position >= FilterView.rowCount) return; @@ -339,10 +339,17 @@ var FilterActions = while (box.firstChild) box.removeChild(box.firstChild); - for (var i = 0; i < text.length; i += 80) + let lines = text.match(/.{1,80}/g); + if (lines.length > 7) { - var description = document.createElement("description"); - description.setAttribute("value", text.substr(i, 80)); + // 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); } } @@ -359,7 +366,7 @@ var FilterActions = E("tooltip-additional").hidden = false; if (item.filter instanceof InvalidFilter && item.filter.reason) - E("tooltip-additional").textContent = 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 @@ -408,8 +415,8 @@ var FilterActions = if (!items.length) return; - items.sort(function(entry1, entry2) entry1.index - entry2.index); - let text = items.map(function(i) i.filter.text).join(IO.lineBreak); + 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) @@ -465,8 +472,8 @@ var FilterActions = if (!items.length) return; - items.sort(function(entry1, entry2) entry1.index - entry2.index); - event.dataTransfer.setData("text/plain", items.map(function(i) i.filter.text).join(IO.lineBreak)); + 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(); }, 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 index 524356f..b1d701d 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filterview.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-filterview.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -462,14 +462,22 @@ var FilterView = /** * 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) + selectRow: function(row, scrollToTop) { if (this.selection) { row = Math.min(Math.max(row, 0), this.data.length - 1); this.selection.select(row); - this.boxObject.ensureRowIsVisible(row); + if (scrollToTop) + this.boxObject.scrollToRow(row); + else + this.boxObject.ensureRowIsVisible(row); } }, @@ -489,7 +497,7 @@ var FilterView = } if (index >= 0) { - this.selectRow(index); + this.selectRow(index, true); this.treeElement.focus(); } }, @@ -502,7 +510,7 @@ var FilterView = let oldCount = this.rowCount; if (this._subscription && this._subscription.filters.length) { - this.data = this._subscription.filters.map(function(f, i) ({index: i, filter: f})); + 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 @@ -633,35 +641,41 @@ var FilterView = setTree: function(boxObject) { + if (!boxObject) + return; + this.init(); this.boxObject = boxObject; - if (this.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: ""}}; + 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-comment", "type-filterlist", "type-whitelist", "type-elemhide", "type-elemhideexception", "type-invalid"]; - let boolAtoms = ["selected", "dummy", "slow", "disabled"]; + 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"); - } + 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")); + 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); - } + 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, @@ -728,19 +742,7 @@ var FilterView = if (filter instanceof ActiveFilter) list.push("disabled-" + filter.disabled); list.push("dummy-" + ("dummy" in filter)); - - if (filter instanceof CommentFilter) - list.push("type-comment"); - else if (filter instanceof BlockingFilter) - list.push("type-filterlist"); - else if (filter instanceof WhitelistFilter) - list.push("type-whitelist"); - else if (filter instanceof ElemHideFilter) - list.push("type-elemhide"); - else if (filter instanceof ElemHideException) - list.push("type-elemhideexception"); - else if (filter instanceof InvalidFilter) - list.push("type-invalid"); + list.push("type-" + filter.type); return this.generateProperties(list, properties); }, @@ -830,20 +832,20 @@ var FilterView = filter.disabled = !filter.disabled; }, - isContainer: function(row) false, - isContainerOpen: function(row) false, - isContainerEmpty: function(row) true, - getLevel: function(row) 0, - getParentIndex: function(row) -1, - hasNextSibling: function(row, afterRow) false, - toggleOpenState: function(row) {}, - getProgressMode: function() null, - getImageSrc: function() null, - isSeparator: function() false, - performAction: function() {}, - performActionOnRow: function() {}, - performActionOnCell: function() {}, - getCellValue: function() null, - setCellValue: function() {}, - selectionChanged: function() {}, + 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 index 2d0c0cf..23bb4b5 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-search.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-search.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -21,50 +21,84 @@ */ var FilterSearch = { + lastSearchString: null, + /** - * Initializes findbar widget. + * Handles keypress events on the findbar widget. */ - init: function() + keyPress: function(/**Event*/ event) { - let filters = E("filtersTree"); - for (let prop in FilterSearch.fakeBrowser) - filters[prop] = FilterSearch.fakeBrowser[prop]; - Object.defineProperty(filters, "_lastSearchString", { - get: function() - { - return this.finder.searchString; - }, - enumerable: true, - configurable: true - }); - - let findbar = E("findbar"); - findbar.browser = filters; - - findbar.addEventListener("keypress", function(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) { - // Work-around for bug 490047 - if (event.keyCode == KeyEvent.DOM_VK_RETURN) - event.preventDefault(); - }, false); + event.preventDefault(); + E("filtersTree").treeBoxObject.scrollByPages(-1); + } + else if (event.keyCode == KeyEvent.DOM_VK_PAGE_DOWN) + { + event.preventDefault(); + E("filtersTree").treeBoxObject.scrollByPages(1); + } + }, - // Hack to prevent "highlight all" from getting enabled - findbar.toggleHighlight = function() {}; + /** + * 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 text search. - * @param {String} text text to be searched - * @param {Integer} direction search direction: -1 (backwards), 0 (forwards - * starting with current), 1 (forwards starting with next) - * @param {Boolean} caseSensitive if true, a case-sensitive search is performed - * @result {Integer} one of the nsITypeAheadFind constants + * Performs a filter search. + * @param {Integer} [direction] + * See @link{FilterSearch#search} + * @return {String} + * result status, one of "" (success), "notFound", "wrappedEnd", + * "wrappedStart" */ - search: function(text, direction, caseSensitive) + _search: function(direction) { - function normalizeString(string) caseSensitive ? string : string.toLowerCase(); + 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(text, direction, startIndex) + function findText(startIndex) { let list = E("filtersTree"); let col = list.columns.getNamedColumn("col-filter"); @@ -74,7 +108,7 @@ var FilterSearch = let filter = normalizeString(list.view.getCellText(i, col)); if (filter.indexOf(text) >= 0) { - FilterView.selectRow(i); + FilterView.selectRow(i, true); return true; } } @@ -84,13 +118,13 @@ var FilterSearch = text = normalizeString(text); // First try to find the entry in the current list - if (findText(text, direction, E("filtersTree").currentIndex)) - return Ci.nsITypeAheadFind.FIND_FOUND; + if (findText(E("filtersTree").currentIndex)) + return ""; // Now go through the other subscriptions - let result = Ci.nsITypeAheadFind.FIND_FOUND; + let result = ""; let subscriptions = FilterStorage.subscriptions.slice(); - subscriptions.sort(function(s1, s2) (s1 instanceof SpecialSubscription) - (s2 instanceof SpecialSubscription)); + 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) @@ -98,12 +132,12 @@ var FilterSearch = if (i < 0) { i = subscriptions.length - 1; - result = Ci.nsITypeAheadFind.FIND_WRAPPED; + result = "wrappedStart"; } else if (i >= subscriptions.length) { i = 0; - result = Ci.nsITypeAheadFind.FIND_WRAPPED; + result = "wrappedEnd"; } if (i == current) break; @@ -127,113 +161,31 @@ var FilterSearch = if (oldFocus) { oldFocus.focus(); - Utils.runAsync(oldFocus.focus, oldFocus); + Utils.runAsync(() => oldFocus.focus()); } - Utils.runAsync(findText, null, text, direction, direction == 1 ? -1 : subscription.filters.length); + Utils.runAsync(() => findText(direction == 1 ? -1 : subscription.filters.length)); return result; } } } - return Ci.nsITypeAheadFind.FIND_NOTFOUND; - } -}; - -/** - * Fake browser implementation to make findbar widget happy - searches in - * the filter list. - */ -FilterSearch.fakeBrowser = -{ - finder: - { - _resultListeners: [], - searchString: null, - caseSensitive: false, - lastResult: null, - - _notifyResultListeners: function(result, findBackwards) - { - this.lastResult = result; - for (let listener of this._resultListeners) - { - // See https://bugzilla.mozilla.org/show_bug.cgi?id=958101, starting - // with Gecko 29 only one parameter is expected. - try - { - if (listener.onFindResult.length == 1) - { - listener.onFindResult({searchString: this.searchString, - result: result, findBackwards: findBackwards}); - } - else - listener.onFindResult(result, findBackwards); - } - catch (e) - { - Cu.reportError(e); - } - } - }, - - fastFind: function(searchString, linksOnly, drawOutline) - { - this.searchString = searchString; - let result = FilterSearch.search(this.searchString, 0, - this.caseSensitive); - this._notifyResultListeners(result, false); - }, - - findAgain: function(findBackwards, linksOnly, drawOutline) - { - let result = FilterSearch.search(this.searchString, - findBackwards ? -1 : 1, - this.caseSensitive); - this._notifyResultListeners(result, findBackwards); - }, - - addResultListener: function(listener) - { - if (this._resultListeners.indexOf(listener) === -1) - this._resultListeners.push(listener); - }, - - removeResultListener: function(listener) - { - let index = this._resultListeners.indexOf(listener); - if (index !== -1) - this._resultListeners.splice(index, 1); - }, - - // Irrelevant for us - requestMatchesCount: function(searchString, matchLimit, linksOnly) {}, - highlight: function(highlight, word) {}, - enableSelection: function() {}, - removeSelection: function() {}, - focusContent: function() {}, - keyPress: function() {} + return "notFound"; }, - currentURI: Utils.makeURI("http://example.com/"), - contentWindow: + /** + * 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) { - focus: function() - { - E("filtersTree").focus(); - }, - scrollByLines: function(num) - { - E("filtersTree").boxObject.scrollByLines(num); - }, - scrollByPages: function(num) - { - E("filtersTree").boxObject.scrollByPages(num); - }, + E("findbar").setAttribute("data-status", this._search(direction)); } }; -window.addEventListener("load", function() +window.addEventListener("load", event => { - FilterSearch.init(); -}, false); + 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 index 091a9f3..ed875f9 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionactions.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionactions.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -49,7 +49,7 @@ var SubscriptionActions = let node = null; let tabIndex = -1; let subscriptions = filter.subscriptions.slice(); - subscriptions.sort(function(s1, s2) s1.disabled - s2.disabled); + subscriptions.sort((s1, s2) => s1.disabled - s2.disabled); for (let i = 0; i < subscriptions.length; i++) { let subscription = subscriptions[i]; @@ -68,7 +68,7 @@ var SubscriptionActions = node.parentNode.selectItem(node); if (!FilterActions.visible) E("subscription-showHideFilters-command").doCommand(); - Utils.runAsync(FilterView.selectFilter, FilterView, filter); + Utils.runAsync(() => FilterView.selectFilter(filter)); }); } }, @@ -295,7 +295,7 @@ var SubscriptionActions = event.dataTransfer.addElement(node); event.dataTransfer.setData("text/x-moz-url", data.subscription.url); - event.dataTransfer.setData("text/plain", data.subscription.title); + event.dataTransfer.setData("text/plain", getSubscriptionTitle(data.subscription)); this.dragSubscription = data.subscription; event.stopPropagation(); }, @@ -422,7 +422,7 @@ var TitleEditor = subscriptionNode.getElementsByClassName("titleBox")[0].selectedIndex = 1; let editor = subscriptionNode.getElementsByClassName("titleEditor")[0]; - editor.value = subscription.title; + editor.value = getSubscriptionTitle(subscription); editor.setSelectionRange(0, editor.value.length); this.subscriptionEdited = subscriptionNode; editor.focus(); @@ -538,7 +538,7 @@ var SelectSubscription = // 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, list); + Utils.runAsync(() => list.focus()); }; request.send(); }, 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 index 8fc26e5..7b2bc1b 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionview.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters-subscriptionview.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -91,10 +91,7 @@ ListManager.prototype = this.addSubscription(subscription, null); // Make sure first list item is selected after list initialization - Utils.runAsync(function() - { - this._list.selectItem(this._list.getItemAtIndex(this._list.getIndexOfFirstVisibleRow())); - }, this); + Utils.runAsync(() => this._list.selectItem(this._list.getItemAtIndex(this._list.getIndexOfFirstVisibleRow()))); } this._deck.selectedIndex = (subscriptions.length ? 1 : 0); @@ -116,7 +113,8 @@ ListManager.prototype = subscription: subscription, isExternal: subscription instanceof ExternalSubscription, downloading: Synchronizer.isExecuting(subscription.url), - disabledFilters: disabledFilters + disabledFilters: disabledFilters, + upgradeRequired: ListManager.isUpgradeRequired(subscription) }); if (insertBefore) this._list.insertBefore(node, insertBefore); @@ -170,14 +168,14 @@ ListManager.prototype = _onChange: function(action, item, param1, param2) { if ((action == "subscription.added" || action == "subscription.removed") && item.url == Prefs.subscriptions_exceptionsurl) - E("acceptableAds").checked = FilterStorage.subscriptions.some(function(s) s.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, this); + Utils.runAsync(() => this.updateDisabled()); } for (let i = 0; i < item.subscriptions.length; i++) this._scheduledUpdateDisabled[item.subscriptions[i].url] = true; @@ -251,11 +249,14 @@ ListManager.prototype = case "subscription.homepage": case "subscription.lastDownload": case "subscription.downloadStatus": + case "subscription.downloading": { let subscriptionNode = Templater.getNodeForData(this._list, "subscription", item); if (subscriptionNode) { - Templater.getDataForNode(subscriptionNode).downloading = Synchronizer.isExecuting(item.url); + 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) @@ -274,7 +275,7 @@ ListManager.prototype = if (this._scheduledUpdateDisabled == null) { this._scheduledUpdateDisabled = Object.create(null); - Utils.runAsync(this.updateDisabled, this); + Utils.runAsync(() => this.updateDisabled()); } this._scheduledUpdateDisabled[item.url] = true; break; @@ -290,13 +291,13 @@ ListManager.init = function() { new ListManager(E("subscriptions"), E("subscriptionTemplate"), - function(s) s instanceof RegularSubscription && !(ListManager.acceptableAdsCheckbox && s.url == Prefs.subscriptions_exceptionsurl), + s => s instanceof RegularSubscription && !(ListManager.acceptableAdsCheckbox && s.url == Prefs.subscriptions_exceptionsurl), SubscriptionActions.updateCommands); new ListManager(E("groups"), E("groupTemplate"), - function(s) s instanceof SpecialSubscription, + s => s instanceof SpecialSubscription, SubscriptionActions.updateCommands); - E("acceptableAds").checked = FilterStorage.subscriptions.some(function(s) s.url == Prefs.subscriptions_exceptionsurl); + E("acceptableAds").checked = FilterStorage.subscriptions.some(s => s.url == Prefs.subscriptions_exceptionsurl); E("acceptableAds").parentNode.hidden = !ListManager.acceptableAdsCheckbox; }; @@ -327,4 +328,19 @@ ListManager.allowAcceptableAds = function(/**Boolean*/ allow) 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 index 29a2e31..3c75c6b 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -24,7 +24,7 @@ function init() { let filter = window.arguments[0].wrappedJSObject; if (filter instanceof Filter) - Utils.runAsync(SubscriptionActions.selectFilter, SubscriptionActions, filter); + Utils.runAsync(() => SubscriptionActions.selectFilter(filter)); } } @@ -117,6 +117,7 @@ var Templater = 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); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul index 2341cdc..dac1b65 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/filters.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -86,9 +86,9 @@ <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="E('findbar').startFind(E('findbar').FIND_NORMAL)"/> - <command id="find-again-command" oncommand="E('findbar').onFindAgainCommand(false)"/> - <command id="find-previous-command" oncommand="E('findbar').onFindAgainCommand(true)"/> + <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"> @@ -187,7 +187,7 @@ <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="{subscription.title}" flex="1" crop="end"/> + <description class="title" value="{getSubscriptionTitle(subscription)}" flex="1" crop="end"/> (<if condition="{isExternal}"> <description value="&subscription.external.label;"/> <else/> @@ -246,7 +246,7 @@ </button> </hbox> - <description class="warning" hidden="{!subscription.upgradeRequired}">&subscription.minVersion.warning;</description> + <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);"/> @@ -282,7 +282,7 @@ 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="{subscription.title}" crop="end" ondblclick="if (event.button == 0) TitleEditor.start(this, true);"/> + <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> @@ -338,6 +338,19 @@ </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" @@ -368,8 +381,6 @@ </vbox> </hbox> -<findbar id="findbar"/> - <hbox id="buttons"> <button id="backupButton" type="menu" label="&backupButton.label;" @@ -378,7 +389,7 @@ _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(function() this.open = true, this);"> + 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/> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html b/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html index cb2ec25..958c4f6 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.html @@ -1,7 +1,7 @@ <!DOCTYPE html> <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -19,10 +19,13 @@ <html> <head> <title class="i18n_firstRun_title"></title> - <meta charset="utf-8"> + <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> @@ -34,26 +37,38 @@ <h1 id="title-main" class="i18n_firstRun_title"></h1> </header> - <section id="legacySafariWarning" class="i18n_firstRun_legacySafariWarning warning" hidden="true"></section> <section id="filterlistsReinitializedWarning" class="i18n_firstRun_filterlistsReinitializedWarning warning" hidden="true"></section> - <section id="dataCorruptionWarning" class="i18n_firstRun_dataCorruptionWarning warning" hidden="true"></section> <div id="content"> - <section id="acceptable-ads"> - <h2 class="i18n_firstRun_acceptableAdsHeadline"></h2> - <p id="acceptableAdsExplanation" class="i18n_firstRun_acceptableAdsExplanation"></p> + <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 id="donate-block"> + <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 id="share-block"> + <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> @@ -74,70 +89,10 @@ </div> </section> - - <section id="can-do-more"> - <h2 class="i18n_firstRun_features"></h2> - - <div id="can-do-more-content"> - <ul id="features"> - <li id="feature-malware" class="feature"> - <div class="feature-image feature-malware-image"></div> - <div class="feature-description"> - <div class="feature-description-textblock"> - <h3 class="i18n_firstRun_feature_malware feature-title"></h3> - <span class="i18n_firstRun_feature_malware_description"></span> - </div> - <div id="toggle-malware" class="toggle"> - <div class="i18n_firstRun_toggle_on toggle-on"></div> - <div class="toggle-blob"></div> - <div class="i18n_firstRun_toggle_off toggle-off"></div> - </div> - </div> - - </li> - <li id="feature-social" class="feature"> - <div class="feature-image feature-social-image"></div> - <div class="feature-description"> - <div class="feature-description-textblock"> - <h3 class="i18n_firstRun_feature_social feature-title"></h3> - <span class="i18n_firstRun_feature_social_description"></span> - </div> - <div id="toggle-social" class="toggle"> - <div class="i18n_firstRun_toggle_on toggle-on"></div> - <div class="toggle-blob"></div> - <div class="i18n_firstRun_toggle_off toggle-off"></div> - </div> - </div> - </li> - - <li id="feature-tracking" class="feature"> - <div class="feature-image feature-tracking-image"></div> - <div class="feature-description"> - <div class="feature-description-textblock"> - <h3 class="i18n_firstRun_feature_tracking feature-title"></h3> - <span class="i18n_firstRun_feature_tracking_description"></span> - </div> - <div id="toggle-tracking" class="toggle"> - <div class="i18n_firstRun_toggle_on toggle-on"></div> - <div class="toggle-blob"></div> - <div class="i18n_firstRun_toggle_off toggle-off"></div> - </div> - </div> - </li> - - </ul> - - </div> - </section> </div> <footer> <a id="contributors" class="i18n_firstRun_contributor_credits"></a> </footer> - - - <div id="glass-pane"> - <iframe id="share-popup" scrolling="no"></iframe> - </div> </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 index 3a11a2e..14d3db2 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/firstRun.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -15,52 +15,18 @@ * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. */ +/* globals checkShareResource, getDocLink, openSharePopup, E */ + "use strict"; (function() { - function E(id) - { - return document.getElementById(id); - } - - // Load subscriptions for features - var featureSubscriptions = [ - { - feature: "malware", - homepage: "http://malwaredomains.com/", - title: "Malware Domains", - url: "https://easylist-downloads.adblockplus.org/malwaredomains_full.txt" - }, - { - feature: "social", - homepage: "https://www.fanboy.co.nz/", - title: "Fanboy's Social Blocking List", - url: "https://easylist-downloads.adblockplus.org/fanboy-social.txt" - }, - { - feature: "tracking", - homepage: "https://easylist.adblockplus.org/", - title: "EasyPrivacy", - url: "https://easylist-downloads.adblockplus.org/easyprivacy.txt" - } - ]; - - function getDocLink(link, callback) - { - ext.backgroundPage.sendMessage({ - type: "app.get", - what: "doclink", - link: link - }, callback); - } - function onDOMLoaded() { // Set up logo image - var logo = E("logo"); + let logo = E("logo"); logo.src = "skin/abp-128.png"; - var errorCallback = function() + let errorCallback = function() { logo.removeEventListener("error", errorCallback, false); // We are probably in Chrome/Opera/Safari, the image has a different path. @@ -69,22 +35,22 @@ logo.addEventListener("error", errorCallback, false); // Set up URLs - getDocLink("donate", function(link) + getDocLink("donate", (link) => { E("donate").href = link; }); - getDocLink("contributors", function(link) + getDocLink("contributors", (link) => { E("contributors").href = link; }); - getDocLink("acceptable_ads_criteria", function(link) + getDocLink("acceptable_ads_criteria", (link) => { - setLinks("acceptableAdsExplanation", link, openFilters); + setLinks("acceptable-ads-explanation", link, openFilters); }); - getDocLink("contribute", function(link) + getDocLink("contribute", (link) => { setLinks("share-headline", link); }); @@ -92,39 +58,22 @@ ext.backgroundPage.sendMessage({ type: "app.get", what: "issues" - }, function(issues) + }, (issues) => { - // Show warning if data corruption was detected - if (issues.seenDataCorruption) - { - E("dataCorruptionWarning").removeAttribute("hidden"); - getDocLink("knownIssuesChrome_filterstorage", function(link) - { - setLinks("dataCorruptionWarning", link); - }); - } - // Show warning if filterlists settings were reinitialized if (issues.filterlistsReinitialized) { E("filterlistsReinitializedWarning").removeAttribute("hidden"); setLinks("filterlistsReinitializedWarning", openFilters); } - - if (issues.legacySafariVersion) - E("legacySafariWarning").removeAttribute("hidden"); }); - // Set up feature buttons linked to subscriptions - featureSubscriptions.forEach(initToggleSubscriptionButton); - updateToggleButtons(); updateSocialLinks(); - ext.onMessage.addListener(function(message) + ext.onMessage.addListener((message) => { - if (message.type == "subscriptions.listen") + if (message.type == "subscriptions.respond") { - updateToggleButtons(); updateSocialLinks(); } }); @@ -134,127 +83,56 @@ }); } - function initToggleSubscriptionButton(featureSubscription) - { - var feature = featureSubscription.feature; - - var element = E("toggle-" + feature); - element.addEventListener("click", function(event) - { - ext.backgroundPage.sendMessage({ - type: "subscriptions.toggle", - url: featureSubscription.url, - title: featureSubscription.title, - homepage: featureSubscription.homepage - }); - }, false); - } - - function openSharePopup(url) - { - var iframe = E("share-popup"); - var glassPane = E("glass-pane"); - var popupMessageReceived = false; - - var popupMessageListener = function(event) - { - if (!/[.\/]adblockplus\.org$/.test(event.origin)) - return; - - var width = event.data.width; - var height = event.data.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); - }; - // Firefox requires last parameter to be true to be triggered by unprivileged pages - window.addEventListener("message", popupMessageListener, false, true); - - var popupLoadListener = function() - { - if (popupMessageReceived) - { - iframe.className = "visible"; - - var 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"; - } - function updateSocialLinks() { - var networks = ["twitter", "facebook", "gplus"]; - networks.forEach(function(network) + for (let network of ["twitter", "facebook", "gplus"]) { - var link = E("share-" + network); - var message = { - type: "filters.blocked", - url: link.getAttribute("data-script"), - requestType: "SCRIPT", - docDomain: "adblockplus.org", - thirdParty: true - }; - ext.backgroundPage.sendMessage(message, function(blocked) + 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 (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, function(link) + getDocLink(event.target.id, (link) => { openSharePopup(link); }); } - function setLinks(id) + function setLinks(id, ...args) { - var element = E(id); + let element = E(id); if (!element) { return; } - var links = element.getElementsByTagName("a"); + let links = element.getElementsByTagName("a"); - for (var i = 0; i < links.length; i++) + for (let i = 0; i < links.length; i++) { - if (typeof arguments[i + 1] == "string") + if (typeof args[i] == "string") { - links[i].href = arguments[i + 1]; + links[i].href = args[i]; links[i].setAttribute("target", "_blank"); } - else if (typeof arguments[i + 1] == "function") + else if (typeof args[i] == "function") { links[i].href = "javascript:void(0);"; - links[i].addEventListener("click", arguments[i + 1], false); + links[i].addEventListener("click", args[i], false); } } } @@ -264,33 +142,5 @@ ext.backgroundPage.sendMessage({type: "app.open", what: "options"}); } - function updateToggleButtons() - { - ext.backgroundPage.sendMessage({ - type: "subscriptions.get", - downloadable: true, - ignoreDisabled: true - }, function(subscriptions) - { - var known = Object.create(null); - for (var i = 0; i < subscriptions.length; i++) - known[subscriptions[i].url] = true; - for (var i = 0; i < featureSubscriptions.length; i++) - { - var featureSubscription = featureSubscriptions[i]; - updateToggleButton(featureSubscription.feature, featureSubscription.url in known); - } - }); - } - - function updateToggleButton(feature, isEnabled) - { - var button = E("toggle-" + feature); - if (isEnabled) - button.classList.remove("off"); - else - button.classList.add("off"); - } - document.addEventListener("DOMContentLoaded", onDOMLoaded, false); -})(); +}()); diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/flasher.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/flasher.js deleted file mode 100644 index 69f4c9e..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/flasher.js +++ /dev/null @@ -1,108 +0,0 @@ -/* - * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 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/>. - */ - -/** - * Draws a blinking border for a list of matching nodes. - */ - -var flasher = { - nodes: null, - count: 0, - timer: null, - - flash: function(nodes) - { - this.stop(); - if (nodes) - nodes = nodes.filter(function(node) node.nodeType == Node.ELEMENT_NODE); - if (!nodes || !nodes.length) - return; - - if (Prefs.flash_scrolltoitem && nodes[0].ownerDocument) - { - // Ensure that at least one node is visible when flashing - let wnd = nodes[0].ownerDocument.defaultView; - try - { - let topWnd = Utils.getChromeWindow(wnd); - let {getBrowser} = require("appSupport"); - let browser = (getBrowser ? getBrowser(topWnd) : null); - if (browser) - browser.markupDocumentViewer.scrollToNode(nodes[0]); - } - catch(e) - { - Cu.reportError(e); - } - } - - this.nodes = nodes; - this.count = 0; - - this.doFlash(); - }, - - doFlash: function() { - if (this.count >= 12) { - this.stop(); - return; - } - - if (this.count % 2) - this.switchOff(); - else - this.switchOn(); - - this.count++; - - this.timer = window.setTimeout(function() {flasher.doFlash()}, 300); - }, - - stop: function() { - if (this.timer) { - window.clearTimeout(this.timer); - this.timer = null; - } - - if (this.nodes) { - this.switchOff(); - this.nodes = null; - } - }, - - setOutline: function(outline, offset) - { - for (var i = 0; i < this.nodes.length; i++) - { - if ("style" in this.nodes[i]) - { - this.nodes[i].style.outline = outline; - this.nodes[i].style.outlineOffset = offset; - } - } - }, - - switchOn: function() - { - this.setOutline("#CC0000 dotted 2px", "-2px"); - }, - - switchOff: function() - { - this.setOutline("", ""); - } -}; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js index 9d380b7..a21fa24 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/i18n.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -15,9 +15,11 @@ * 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. -var i18n = ext.i18n; +let {i18n} = ext; // Getting UI locale cannot be done synchronously on Firefox, // requires messaging the background page. For Chrome and Safari, @@ -28,71 +30,92 @@ ext.backgroundPage.sendMessage( type: "app.get", what: "localeInfo" }, - function(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, arguments) +// 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, element) + function processString(str, currentElement) { - var match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(str); + let match = /^(.*?)<(a|strong)>(.*?)<\/\2>(.*)$/.exec(str); if (match) { - processString(match[1], element); + processString(match[1], currentElement); - var e = document.createElement(match[2]); + let e = document.createElement(match[2]); processString(match[3], e); - element.appendChild(e); + currentElement.appendChild(e); - processString(match[4], element); + processString(match[4], currentElement); } else - element.appendChild(document.createTextNode(str)); + currentElement.appendChild(document.createTextNode(str)); } while (element.lastChild) element.removeChild(element.lastChild); - processString(ext.i18n.getMessage(stringName, arguments), element); -} + processString(ext.i18n.getMessage(stringName, args), element); +}; // Loads i18n strings function loadI18nStrings() { - var nodes = document.querySelectorAll("[class^='i18n_']"); - for(var i = 0; i < nodes.length; i++) + function addI18nStringsToElements(containerElement) { - var node = nodes[i]; - var arguments = JSON.parse("[" + node.textContent + "]"); - if (arguments.length == 0) - arguments = null; + let elements = containerElement.querySelectorAll("[class^='i18n_']"); + for (let node of elements) + { + let args = JSON.parse("[" + node.textContent + "]"); + if (args.length == 0) + args = null; - var className = node.className; - if (className instanceof SVGAnimatedString) - className = className.animVal; - var stringName = className.split(/\s/)[0].substring(5); + let {className} = node; + if (className instanceof SVGAnimatedString) + className = className.animVal; + let stringName = className.split(/\s/)[0].substring(5); - ext.i18n.setElementText(node, stringName, arguments); + 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 i18n_timeDateStrings(when) +function i18nTimeDateStrings(when) { - var d = new Date(when); - var timeString = d.toLocaleTimeString(); + let d = new Date(when); + let timeString = d.toLocaleTimeString(); - var now = new Date(); + let now = new Date(); if (d.toDateString() == now.toDateString()) return [timeString]; - else - return [timeString, d.toLocaleDateString()]; + 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 diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul index 62c57e6..d1de4c0 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/overlay.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -60,6 +60,7 @@ <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"/> @@ -85,6 +86,7 @@ <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" @@ -113,12 +115,20 @@ <!-- Notification panel --> <panel id="abp-notification" type="arrow" orient="vertical" xmlns:html="http://www.w3.org/1999/xhtml"> - <label id="abp-notification-title" class="header"/> - <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;"/> - <toolbarbutton id="abp-notification-close" label="¬ification.button.close;"></toolbarbutton> - </hbox> + <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 index a449c2c..fadad52 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul index 3098d12..0e85303 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/progressBar.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js index c61dbbb..ee9e7f5 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -19,16 +19,20 @@ // Report data template, more data will be added during data collection // -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/FileUtils.jsm"); +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 contentWindow = window.arguments[0]; -let windowURI = (window.arguments[1] instanceof Ci.nsIURI ? window.arguments[1] : null); +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"); @@ -70,31 +74,30 @@ function serializeReportData() return result; } -let (element = reportElement("adblock-plus")) { + let element = reportElement("adblock-plus"); let {addonVersion} = require("info"); element.setAttribute("version", addonVersion); element.setAttribute("locale", Utils.appLocale); -}; -let (element = reportElement("application")) +} { + 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")) +} { + let element = reportElement("platform"); element.setAttribute("name", "Gecko"); element.setAttribute("version", Services.appinfo.platformVersion); element.setAttribute("build", Services.appinfo.platformBuildID); }; -let (element = reportElement("options")) { + 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: "privateBrowsing"}, PrivateBrowsing.enabledForWindow(contentWindow) || PrivateBrowsing.enabled); 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")); @@ -104,11 +107,11 @@ let (element = reportElement("options")) // Data collectors // -let reportsListDataSource = +var reportsListDataSource = { list: [], - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { let data = Prefs.recentReports; if (data && "length" in data) @@ -183,7 +186,7 @@ let reportsListDataSource = } }; -let requestsDataSource = +var requestsDataSource = { requests: reportElement("requests"), origRequests: [], @@ -191,17 +194,17 @@ let requestsDataSource = callback: null, nodeByKey: Object.create(null), - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { this.callback = callback; - this.requestNotifier = new RequestNotifier(wnd, this.onRequestFound, this); + this.requestNotifier = new RequestNotifier(outerWindowID, this.onRequestFound, this); }, - onRequestFound: function(frame, node, entry, scanComplete) + onRequestFound: function(entry, scanComplete) { if (entry) { - let key = entry.location + " " + entry.typeDescr + " " + entry.docDomain; + let key = entry.location + " " + entry.type + " " + entry.docDomain; let requestXML; if (key in this.nodeByKey) { @@ -212,29 +215,20 @@ let requestsDataSource = { requestXML = this.nodeByKey[key] = appendElement(this.requests, "request", { location: censorURL(entry.location), - type: entry.typeDescr, + type: entry.type, docDomain: entry.docDomain, thirdParty: entry.thirdParty, count: 1 }); - } - // Location is meaningless for element hiding hits - if (entry.filter && entry.filter instanceof ElemHideBase) - requestXML.removeAttribute("location"); + // Location is meaningless for element hiding hits + if (requestXML.getAttribute("location")[0] == "#") + requestXML.removeAttribute("location"); + } if (entry.filter) - requestXML.setAttribute("filter", entry.filter.text); - - if (node instanceof Element) - { - requestXML.setAttribute("node", (node.namespaceURI ? node.namespaceURI + "#" : "") + node.localName); + requestXML.setAttribute("filter", entry.filter); - try - { - requestXML.setAttribute("size", node.offsetWidth + "x" + node.offsetHeight); - } catch(e) {} - } this.origRequests.push(entry); } @@ -247,33 +241,35 @@ let requestsDataSource = } }; -let filtersDataSource = +var filtersDataSource = { origFilters: [], - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { - let wndStats = RequestNotifier.getWindowStatistics(wnd); - if (wndStats) + RequestNotifier.getWindowStatistics(outerWindowID, (wndStats) => { - let filters = reportElement("filters"); - for (let f in wndStats.filters) + if (wndStats) { - let filter = Filter.fromText(f) - let hitCount = wndStats.filters[f]; - appendElement(filters, "filter", { - text: filter.text, - subscriptions: filter.subscriptions.filter(subscriptionsDataSource.subscriptionFilter).map(function(s) s.url).join(" "), - hitCount: hitCount - }); - this.origFilters.push(filter); + 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(); + callback(); + }); } }; -let subscriptionsDataSource = +var subscriptionsDataSource = { subscriptionFilter: function(s) { @@ -284,7 +280,7 @@ let subscriptionsDataSource = return true; }, - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { let subscriptions = reportElement("subscriptions"); let now = Math.round(Date.now() / 1000); @@ -296,7 +292,7 @@ let subscriptionsDataSource = let subscriptionXML = appendElement(subscriptions, "subscription", { id: subscription.url, - disabledFilters: subscription.filters.filter(function(filter) filter instanceof ActiveFilter && filter.disabled).length + disabledFilters: subscription.filters.filter(filter => filter instanceof ActiveFilter && filter.disabled).length }); if (subscription.version) subscriptionXML.setAttribute("version", subscription.version); @@ -317,16 +313,31 @@ let subscriptionsDataSource = } }; -let screenshotDataSource = +var remoteDataSource = { - imageOffset: 10, + 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(); + }); + } +} - // Fields used for color reduction - _mapping: [0x00, 0x55, 0xAA, 0xFF], - _i: null, - _max: null, - _pixelData: null, - _callback: null, +var screenshotDataSource = +{ + imageOffset: 10, // Fields used for user interaction _enabled: true, @@ -336,76 +347,42 @@ let screenshotDataSource = _currentData: null, _undoQueue: [], - collectData: function(wnd, windowURI, callback) + getWidth: function() { - this._callback = callback; - this._canvas = E("screenshotCanvas"); - this._canvas.width = this._canvas.offsetWidth; - - // Do not resize canvas any more (no idea why Gecko requires both to be set) - this._canvas.parentNode.style.MozBoxAlign = "center"; - this._canvas.parentNode.align = "center"; - - this._context = this._canvas.getContext("2d"); - let wndWidth = wnd.document.documentElement.scrollWidth; - let wndHeight = wnd.document.documentElement.scrollHeight; + let canvas = E("screenshotCanvas"); + return canvas.offsetWidth - this.imageOffset * 2; + }, - // Copy scaled screenshot of the webpage. We scale the webpage by width - // but leave 10px on each side for easier selecting. + setData: function(screenshot) + { + let canvas = E("screenshotCanvas"); - // Gecko doesn't like sizes more than 64k, restrict to 30k to be on the safe side. - // Also, make sure height is at most five times the width to keep image size down. - let copyWidth = Math.min(wndWidth, 30000); - let copyHeight = Math.min(wndHeight, 30000, copyWidth * 5); - let copyX = Math.max(Math.min(wnd.scrollX - copyWidth / 2, wndWidth - copyWidth), 0); - let copyY = Math.max(Math.min(wnd.scrollY - copyHeight / 2, wndHeight - copyHeight), 0); + // 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 scalingFactor = (this._canvas.width - this.imageOffset * 2) / copyWidth; - this._canvas.height = copyHeight * scalingFactor + this.imageOffset * 2; + let context = canvas.getContext("2d"); + this._canvas = canvas; + this._context = context; - this._context.save(); - this._context.translate(this.imageOffset, this.imageOffset); - this._context.scale(scalingFactor, scalingFactor); - this._context.drawWindow(wnd, copyX, copyY, copyWidth, copyHeight, "rgb(255,255,255)"); - this._context.restore(); + 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 - this._context.fillStyle = "rgb(0, 0, 0)"; - this._context.strokeStyle = "rgba(255, 0, 0, 0.7)"; - this._context.lineWidth = 3; - this._context.lineJoin = "round"; - - // Reduce colors asynchronously - this._pixelData = this._context.getImageData(this.imageOffset, this.imageOffset, - this._canvas.width - this.imageOffset * 2, - this._canvas.height - this.imageOffset * 2); - this._max = this._pixelData.width * this._pixelData.height * 4; - this._i = 0; - Utils.runAsync(this.run.bind(this)); + context.fillStyle = "rgb(0, 0, 0)"; + context.strokeStyle = "rgba(255, 0, 0, 0.7)"; + context.lineWidth = 3; + context.lineJoin = "round"; }, - run: function() + get enabled() { - // Process only 5000 bytes at a time to prevent browser hangs - let endIndex = Math.min(this._i + 5000, this._max); - let i = this._i; - for (; i < endIndex; i++) - this._pixelData.data[i] = this._mapping[this._pixelData.data[i] >> 6]; - - if (i >= this._max) - { - // Save data back and we are done - this._context.putImageData(this._pixelData, this.imageOffset, this.imageOffset); - this._callback(); - } - else - { - this._i = i; - Utils.runAsync(this.run.bind(this)); - } + return this._enabled; }, - - get enabled() this._enabled, set enabled(enabled) { if (this._enabled == enabled) @@ -418,7 +395,10 @@ let screenshotDataSource = E("screenshotUndoButton").disabled = !this._enabled || !this._undoQueue.length; }, - get selectionType() this._selectionType, + get selectionType() + { + return this._selectionType; + }, set selectionType(type) { if (this._selectionType == type) @@ -563,11 +543,11 @@ let screenshotDataSource = } }; -let framesDataSource = +var framesDataSource = { site: null, - collectData: function(wnd, windowURI, callback) + setData: function(windowURI, opener, referrer, frames) { try { @@ -581,40 +561,29 @@ let framesDataSource = } let window = reportElement("window"); - window.setAttribute("url", censorURL(windowURI ? windowURI.spec : wnd.location.href)); - if (wnd.opener && wnd.opener.location.href) - window.setAttribute("opener", censorURL(wnd.opener.location.href)); - if (wnd.document.referrer) - window.setAttribute("referrer", censorURL(wnd.document.referrer)); - this.scanFrames(wnd, window); - - callback(); + window.setAttribute("url", censorURL(windowURI.spec)); + if (opener) + window.setAttribute("opener", censorURL(opener)); + if (referrer) + window.setAttribute("referrer", censorURL(referrer)); + this.addFrames(frames || [], window); }, - scanFrames: function(wnd, xmlList) + addFrames: function(frames, xmlList) { - try + for (let frame of frames) { - for (let i = 0; i < wnd.frames.length; i++) - { - let frame = wnd.frames[i]; - let frameXML = appendElement(xmlList, "frame", { - url: censorURL(frame.location.href) - }); - this.scanFrames(frame, frameXML); - } - } - catch (e) - { - // Don't break if something goes wrong - Cu.reportError(e); + let frameXML = appendElement(xmlList, "frame", { + url: censorURL(frame.url) + }); + this.addFrames(frame.frames, frameXML); } } }; -let errorsDataSource = +var errorsDataSource = { - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { let {addonID} = require("info"); addonID = addonID.replace(/[\{\}]/g, ""); @@ -650,6 +619,11 @@ let errorsDataSource = } 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++) { @@ -657,13 +631,13 @@ let errorsDataSource = let text = message.errorMessage; for (let path in censored) - text = text.replace(path, censored[path], "gi"); + 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(path, censored[path], "gi"); + file = file.replace(str2regexp(path, "gi"), censored[path]); if (file.length > 256) file = file.substr(0, 256) + "..."; @@ -685,11 +659,11 @@ let errorsDataSource = } }; -let extensionsDataSource = +var extensionsDataSource = { data: reportData.createElement("extensions"), - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { try { @@ -727,13 +701,13 @@ let extensionsDataSource = } }; -let subscriptionUpdateDataSource = +var subscriptionUpdateDataSource = { - contentWnd: null, + browser: null, type: null, outdated: null, needUpdate: null, - + subscriptionFilter: function(s) { if (s instanceof DownloadableSubscription) @@ -742,9 +716,9 @@ let subscriptionUpdateDataSource = return false; }, - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { - this.contentWnd = wnd; + this.browser = browser; let now = Date.now() / MILLISECONDS_IN_SECOND; let outdatedThreshold = now - 14 * SECONDS_IN_DAY; let needUpdateThreshold = now - 1 * SECONDS_IN_HOUR; @@ -785,7 +759,7 @@ let subscriptionUpdateDataSource = entry.removeAttribute("hidden"); entry.setAttribute("_url", subscription.url); entry.setAttribute("tooltiptext", subscription.url); - entry.textContent = subscription.title; + entry.textContent = getSubscriptionTitle(subscription); list.appendChild(entry); } } @@ -818,8 +792,14 @@ let subscriptionUpdateDataSource = let filtersRemoved = false; let requests = requestsDataSource.origRequests; for (let i = 0; i < requests.length; i++) - if (requests[i].filter && !requests[i].filter.subscriptions.filter(function(s) !s.disabled).length) + { + if (!requests[i].filter) + continue; + + let filter = Filter.fromText(requests[i].filter); + if (!filter.subscriptions.some(s => !s.disabled)) filtersRemoved = true; + } if (filtersRemoved) { @@ -829,17 +809,17 @@ let subscriptionUpdateDataSource = let nextButton = document.documentElement.getButton("next"); [nextButton.label, nextButton.accessKey] = Utils.splitLabel(E("updatePage").getAttribute("reloadButtonLabel")); - document.documentElement.addEventListener("wizardnext", function(event) + document.documentElement.addEventListener("wizardnext", event => { event.preventDefault(); event.stopPropagation(); window.close(); - this.contentWnd.location.reload(); - }.bind(this), true); + this.browser.reload(); + }, true); } else { - this.collectData(null, null, function() {}); + this.collectData(null, null, null, function() {}); this.needUpdate = []; if (this.outdated.length) { @@ -879,9 +859,9 @@ let subscriptionUpdateDataSource = } } -let issuesDataSource = +var issuesDataSource = { - contentWnd: null, + browser: null, isEnabled: Prefs.enabled, whitelistFilter: null, disabledFilters: [], @@ -902,10 +882,10 @@ let issuesDataSource = return false; }, - collectData: function(wnd, windowURI, callback) + collectData: function(outerWindowID, windowURI, browser, callback) { - this.contentWnd = wnd; - this.whitelistFilter = Policy.isWindowWhitelisted(wnd); + this.browser = browser; + this.whitelistFilter = Policy.isWhitelisted(windowURI.spec); if (!this.whitelistFilter && this.isEnabled) { @@ -927,7 +907,7 @@ let issuesDataSource = if (request.filter) continue; - let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty); + let filter = disabledMatcher.matchesAny(request.location, RegExpFilter.typeMap[request.type], request.docDomain, request.thirdParty); if (filter && !(filter.text in seenFilters)) { this.disabledFilters.push(filter); @@ -952,7 +932,7 @@ let issuesDataSource = if (request.filter) continue; - let filter = disabledMatcher.matchesAny(request.location, request.typeDescr, request.docDomain, request.thirdParty); + let filter = disabledMatcher.matchesAny(request.location, RegExpFilter.typeMap[request.type], request.docDomain, request.thirdParty); if (filter && !(subscription.url in seenSubscriptions)) { this.disabledSubscriptions.push(subscription); @@ -970,7 +950,7 @@ let issuesDataSource = continue; this.numAppliedFilters++; - if (filter.subscriptions.some(function(subscription) subscription instanceof SpecialSubscription)) + if (filter.subscriptions.some(subscription => subscription instanceof SpecialSubscription)) this.ownFilters.push(filter); } } @@ -1018,8 +998,8 @@ let issuesDataSource = let element = template.cloneNode(true); element.removeAttribute("id"); element.removeAttribute("hidden"); - element.firstChild.setAttribute("value", subscription.title); - element.setAttribute("tooltiptext", subscription instanceof DownloadableSubscription ? subscription.url : subscription.title); + element.firstChild.setAttribute("value", getSubscriptionTitle(subscription)); + element.setAttribute("tooltiptext", subscription instanceof DownloadableSubscription ? subscription.url : getSubscriptionTitle(subscription)); element.abpSubscription = subscription; disabledSubscriptionsBox.appendChild(element); } @@ -1081,15 +1061,14 @@ let issuesDataSource = document.documentElement.canRewind = false; document.documentElement.canAdvance = true; - let contentWnd = this.contentWnd; let nextButton = document.documentElement.getButton("next"); [nextButton.label, nextButton.accessKey] = Utils.splitLabel(E("updatePage").getAttribute("reloadButtonLabel")); - document.documentElement.addEventListener("wizardnext", function(event) + document.documentElement.addEventListener("wizardnext", event => { event.preventDefault(); event.stopPropagation(); window.close(); - contentWnd.location.reload(); + this.browser.reload(); }, true); }, @@ -1177,7 +1156,7 @@ let issuesDataSource = }; let dataCollectors = [reportsListDataSource, requestsDataSource, filtersDataSource, subscriptionsDataSource, - screenshotDataSource, framesDataSource, errorsDataSource, extensionsDataSource, + remoteDataSource, errorsDataSource, extensionsDataSource, subscriptionUpdateDataSource, issuesDataSource]; // @@ -1261,7 +1240,7 @@ function initDataCollectorPage() let dataSource = dataCollectors.shift(); Utils.runAsync(function() { - dataSource.collectData(contentWindow, windowURI, initNextDataSource); + dataSource.collectData(outerWindowID, windowURI, browser, initNextDataSource); }); }; @@ -1544,7 +1523,7 @@ function reportSent(event) button.setAttribute("url", link); button.removeAttribute("disabled"); - if (!PrivateBrowsing.enabledForWindow(contentWindow) && !PrivateBrowsing.enabled) + if (!isPrivate) reportsListDataSource.addReport(framesDataSource.site, link); } catch (e) {} E("copyLinkBox").hidden = false; @@ -1557,6 +1536,9 @@ function reportSent(event) function processLinkClick(event) { + if (event.button != 0) + return; + event.preventDefault(); let link = event.target; diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul index 491e3b6..403513d 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/sendReport.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -215,8 +215,11 @@ <label id="emailLabel" control="email" value="&email.label;"/> <textbox id="email" type="email" persist="value" flex="1" maxlength="200" oninput="updateEmail();"/> </hbox> - <checkbox id="anonymousCheckbox" label="&anonymous.label;" oncommand="updateEmail();"/> - <description id="anonymityWarning" visible="false">&anonymity.warning;</description> + <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;"/> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul index 0dc8317..379cbc3 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/settings.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -31,7 +31,7 @@ <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;"/> - <setting id="adblockplus-autoupdate" pref="extensions.adblockplus.subscriptions_autoupdate" type="bool" title="&subscription.update.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 index 0b49068..688c248 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -20,11 +20,13 @@ 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; -var noFlash = false; // Matcher for disabled filters var disabledMatcher = new CombinedMatcher(); @@ -33,6 +35,9 @@ var disabledMatcher = new CombinedMatcher(); 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"); @@ -84,12 +89,18 @@ function init() { wnd.setAttribute(attr, defaults[attr]); } - let {getBrowser, addBrowserLocationListener} = require("appSupport"); - Object.defineProperty(window, "content", { get: () => getBrowser(mainWin).contentWindow }); + let {addBrowserLocationListener} = require("appSupport"); + updateContentLocation(); // Initialize matcher for disabled filters reloadDisabledFilters(); - FilterNotifier.addListener(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 @@ -101,6 +112,9 @@ function init() { // 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 @@ -108,11 +122,42 @@ 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() { - flasher.stop(); requestNotifier.shutdown(); - FilterNotifier.removeListener(reloadDisabledFilters); + 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; @@ -177,15 +222,15 @@ function onSelectionChange() { else E("copy-command").setAttribute("disabled", "true"); - if (item && window.content) + if (item) { let key = item.location + " " + item.type + " " + item.docDomain; - RequestNotifier.storeSelection(window.content, key); + RequestNotifier.storeWindowData(getOuterWindowID(), key); treeView.itemToSelect = null; } - if (!noFlash) - flasher.flash(item ? item.nodes : null); + if (requestNotifier) + requestNotifier.flashNodes(item ? item.ids : null, Prefs.flash_scrolltoitem); } function handleLocationChange() @@ -193,12 +238,18 @@ function handleLocationChange() if (requestNotifier) requestNotifier.shutdown(); + updateContentLocation(); treeView.clearData(); - treeView.itemToSelect = RequestNotifier.getSelection(window.content); - requestNotifier = new RequestNotifier(window.content, function(wnd, node, item, scanComplete) + + let outerWindowID = getOuterWindowID(); + RequestNotifier.retrieveWindowData(outerWindowID, key => + { + treeView.itemToSelect = key; + }); + requestNotifier = new RequestNotifier(outerWindowID, (item, scanComplete) => { if (item) - treeView.addItem(node, item, scanComplete); + treeView.addItem(item, scanComplete); }); cacheStorage = null; } @@ -210,10 +261,17 @@ function setMultilineContent(box, text, noRemove) while (box.firstChild) box.removeChild(box.firstChild); - for (var i = 0; i < text.length; i += 80) + let lines = text.match(/.{1,80}/g); + if (lines.length > 7) { - var description = document.createElement("description"); - description.setAttribute("value", text.substr(i, 80)); + // 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); } } @@ -239,14 +297,12 @@ function fillInTooltip(e) { return; } - let filter = ("filter" in item && item.filter ? item.filter : null); - let size = ("tooltip" in item ? null : getItemSize(item)); + 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("tooltipSizeRow").hidden = !size; E("tooltipDocDomainRow").hidden = ("tooltip" in item || !item.docDomain); E("tooltipFilterRow").hidden = !filter; E("tooltipFilterSourceRow").hidden = !subscriptions.length; @@ -255,19 +311,16 @@ function fillInTooltip(e) { E("tooltipDummy").setAttribute("value", item.tooltip); else { - E("tooltipAddress").parentNode.hidden = (item.typeDescr == "ELEMHIDE"); + E("tooltipAddress").parentNode.hidden = (item.type == "ELEMHIDE"); setMultilineContent(E("tooltipAddress"), item.location); - var type = item.localizedDescr; + var type = localizedTypes.get(item.type); if (filter && filter instanceof WhitelistFilter) type += " " + E("tooltipType").getAttribute("whitelisted"); - else if (filter && item.typeDescr != "ELEMHIDE") + else if (filter && item.type != "ELEMHIDE") type += " " + E("tooltipType").getAttribute("filtered"); E("tooltipType").setAttribute("value", type); - if (size) - E("tooltipSize").setAttribute("value", size.join(" x ")); - E("tooltipDocDomain").setAttribute("value", item.docDomain + " " + (item.thirdParty ? docDomainThirdParty : docDomainFirstParty)); } @@ -289,32 +342,36 @@ function fillInTooltip(e) { while (sourceElement.firstChild) sourceElement.removeChild(sourceElement.firstChild); for (let i = 0; i < subscriptions.length; i++) - setMultilineContent(sourceElement, subscriptions[i].title, true); + 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.typeDescr == "IMAGE"; - showPreview = showPreview && (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter); + 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); - // Cache v2 API is enabled by default starting with Gecko 32 - if (Services.vc.compare(Utils.platformVersion, "32.0a1") >= 0) - { - let {LoadContextInfo} = Cu.import("resource://gre/modules/LoadContextInfo.jsm", null); - let loadContext = content.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsILoadContext); - cacheStorage = Services.cache2.diskCacheStorage(LoadContextInfo.fromLoadContext(loadContext, false), false); - } - else - cacheStorage = Services.cache.createSession("HTTP", Ci.nsICache.STORE_ANYWHERE, true); + 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); @@ -322,35 +379,17 @@ function fillInTooltip(e) { }; try { - if (Ci.nsICacheStorage && cacheStorage instanceof Ci.nsICacheStorage) - { - 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 (!isNew) - showTooltipPreview(); - } - }); - } - else - { - cacheStorage.asyncOpenCacheEntry(item.location, Ci.nsICache.ACCESS_READ, { - onCacheEntryAvailable: function(descriptor, accessGranted, status) - { - if (!descriptor) - return; - descriptor.close(); + 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(); - }, - onCacheEntryDoomed: function(status) - { - } - }); - } + } + }); } catch (e) { @@ -388,14 +427,14 @@ function fillInContext(/**Event*/ e) E("contextDisableFilter").hidden = true; E("contextEnableFilter").hidden = true; E("contextDisableOnSite").hidden = true; - if ("filter" in item && item.filter) + let filter = getFilter(item); + if (filter) { - let filter = item.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(function(subscription) !(subscription instanceof SpecialSubscription))) + if (filter instanceof ActiveFilter && !filter.disabled && filter.subscriptions.length && !filter.subscriptions.some(subscription => !(subscription instanceof SpecialSubscription))) { let domain = null; try { @@ -411,34 +450,18 @@ function fillInContext(/**Event*/ e) } } - E("contextWhitelist").hidden = ("tooltip" in item || !item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter || item.typeDescr == "ELEMHIDE"); + 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" in item && item.filter && !item.filter.disabled); - E("contextEditFilter").setAttribute("disabled", !("filter" in item && item.filter)); - E("contextOpen").setAttribute("disabled", "tooltip" in item || item.typeDescr == "ELEMHIDE"); - E("contextFlash").setAttribute("disabled", "tooltip" in item || !(item.typeDescr in visual) || (item.filter && !item.filter.disabled && !(item.filter instanceof WhitelistFilter))); - E("contextCopyFilter").setAttribute("disabled", !allItems.some(function(item) {return "filter" in item && item.filter})); + 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; } /** - * Resets context menu data once the context menu is closed. - */ -function clearContextMenu(/**Event*/ event) -{ - if (event.eventPhase != event.AT_TARGET) - return; - - { - let menuItem = E("contextDisableOnSite"); - menuItem.item = item; - menuItem.filter = filter; - menuItem.domain = domain; - } -} - -/** * Processed mouse clicks on the item list. * @param {Event} event */ @@ -447,8 +470,9 @@ function handleClick(event) let item = treeView.getItemAt(event.clientX, event.clientY); if (event.button == 0 && treeView.getColumnAt(event.clientX, event.clientY) == "state") { - if (item.filter) - enableFilter(item.filter, item.filter.disabled); + let filter = getFilter(item); + if (filter) + enableFilter(filter, filter.disabled); event.preventDefault(); } else if (event.button == 1) @@ -478,24 +502,27 @@ function openInTab(item, /**Event*/ event) let items = (item ? [item] : treeView.getAllSelectedItems()); for (let item of items) { - if (item && item.typeDescr != "ELEMHIDE") + if (item && item.type != "ELEMHIDE") UI.loadInBrowser(item.location, mainWin, event); } } function doBlock() { var item = treeView.getSelectedItem(); - if (!item || item.typeDescr == "ELEMHIDE") + if (!item || item.type == "ELEMHIDE") return; - var filter = null; - if (item.filter && !item.filter.disabled) - filter = item.filter; - - if (filter && filter instanceof WhitelistFilter) + var filter = getFilter(item); + if (filter && !filter.disabled && filter instanceof WhitelistFilter) return; - openDialog("chrome://adblockplus/content/ui/composer.xul", "_blank", "chrome,centerscreen,resizable,dialog=no,dependent", item.nodes, item.orig); + if (requestNotifier) + { + requestNotifier.storeNodesForEntries(item.ids, (nodesID) => + { + UI.blockItem(window, nodesID, item.orig); + }); + } } function editFilter() @@ -504,13 +531,11 @@ function editFilter() if (treeView.data && !treeView.data.length) item = treeView.getDummyTooltip(); - if (!("filter" in item) || !item.filter) + let filter = getFilter(item); + if (!filter) return; - if (!("location") in item) - item.location = undefined - - UI.openFiltersDialog(item.filter); + UI.openFiltersDialog(filter); } function enableFilter(filter, enable) { @@ -525,8 +550,8 @@ function enableFilter(filter, enable) { function disableOnSite() { let item = treeView.getSelectedItem(); - let filter = item.filter; - if (!(filter instanceof ActiveFilter) || filter.disabled || !filter.subscriptions.length || filter.subscriptions.some(function(subscription) !(subscription instanceof SpecialSubscription))) + let filter = getFilter(item); + if (!(filter instanceof ActiveFilter) || filter.disabled || !filter.subscriptions.length || filter.subscriptions.some(subscription => !(subscription instanceof SpecialSubscription))) return; let domain; @@ -552,7 +577,7 @@ function disableOnSite() let match = /^DOMAIN=(.*)/.exec(options[i]); if (match) { - let domains = match[1].split("|").filter(function(d) d != domain && d != "~" + domain && (d.length <= domain.length || d.lastIndexOf("." + domain) != d.length - domain.length - 1)); + 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; @@ -573,7 +598,7 @@ function disableOnSite() if (match) { let selector = match[2]; - let domains = match[1].toUpperCase().split(",").filter(function(d) d != domain && (d.length <= domain.length || d != "~" + domain && d.lastIndexOf("." + domain) != d.length - domain.length - 1)); + 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; } @@ -591,7 +616,7 @@ function disableOnSite() else if (!newFilter.subscriptions.length) { newFilter.disabled = false; - let subscription = filter.subscriptions.filter(function(s) s instanceof SpecialSubscription)[0]; + let subscription = filter.subscriptions.filter(s => s instanceof SpecialSubscription)[0]; if (subscription) FilterStorage.addFilter(newFilter, subscription, subscription.filters.indexOf(filter)); } @@ -599,7 +624,7 @@ function disableOnSite() // Update display for (let i = 0; i < treeView.allData.length; i++) - if (treeView.allData[i].filter == filter) + if (getFilter(treeView.allData[i]) == filter) treeView.allData[i].filter = null; treeView.boxObject.invalidate(); } @@ -613,14 +638,14 @@ function copyToClipboard() { } function copyFilter() { - var items = treeView.getAllSelectedItems().filter(function(item) {return item.filter}); + 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.text}).join(IO.lineBreak)); + Utils.clipboardHelper.copyString(items.map(function(item) {return item.filter}).join(IO.lineBreak)); } function selectAll() { @@ -666,20 +691,35 @@ function detach(doDetach) myMainWin.document.getElementById("abp-command-sidebar").doCommand(); } -// Returns items size in the document if available -function getItemSize(item) +// Returns item's size if already known, otherwise undefined +function getCachedItemSize(item) { - if (item.filter && !item.filter.disabled && item.filter instanceof BlockingFilter) + if ("size" in item) + return item.size; + + let filter = getFilter(item); + if (filter && !filter.disabled && filter instanceof BlockingFilter) return null; - for (let node of item.nodes) + return undefined; +} + +// Retrieves item's size in the document if available +function getItemSize(item, callback) +{ + let size = getCachedItemSize(item); + if (typeof size != "undefined" || !requestNotifier) { - if (node instanceof HTMLImageElement && (node.naturalWidth || node.naturalHeight)) - return [node.naturalWidth, node.naturalHeight]; - else if (node instanceof HTMLElement && (node.offsetWidth || node.offsetHeight)) - return [node.offsetWidth, node.offsetHeight]; + callback(size); + return; } - return null; + + requestNotifier.retrieveNodeSize(item.ids, function(size) + { + if (size) + item.size = size; + callback(size); + }); } // Sort functions for the item list @@ -697,9 +737,11 @@ function sortByAddressDesc(item1, item2) { } function compareType(item1, item2) { - if (item1.localizedDescr < item2.localizedDescr) + let type1 = localizedTypes.get(item1.type); + let type2 = localizedTypes.get(item2.type); + if (type1 < type2) return -1; - else if (item1.localizedDescr > item2.localizedDescr) + else if (type1 > type2) return 1; else return 0; @@ -710,25 +752,29 @@ function compareFilter(item1, item2) { var hasFilter2 = (item2.filter ? 1 : 0); if (hasFilter1 != hasFilter2) return hasFilter1 - hasFilter2; - else if (hasFilter1 && item1.filter.text < item2.filter.text) + else if (hasFilter1 && item1.filter < item2.filter) return -1; - else if (hasFilter1 && item1.filter.text > item2.filter.text) + else if (hasFilter1 && item1.filter > item2.filter) return 1; else return 0; } -function compareState(item1, item2) { - var state1 = (!item1.filter ? 0 : (item1.filter.disabled ? 1 : (item1.filter instanceof WhitelistFilter ? 2 : 3))); - var state2 = (!item2.filter ? 0 : (item2.filter.disabled ? 1 : (item2.filter instanceof WhitelistFilter ? 2 : 3))); +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) { - var size1 = getItemSize(item1); - size1 = size1 ? size1[0] * size1[1] : 0; +function compareSize(item1, item2) +{ + let size1 = getCachedItemSize(item1); + let size2 = getCachedItemSize(item2); - var size2 = getItemSize(item2); + size1 = size1 ? size1[0] * size1[1] : 0; size2 = size2 ? size2[0] * size2[1] : 0; return size1 - size2; } @@ -749,8 +795,10 @@ function compareDocDomain(item1, item2) function compareFilterSource(item1, item2) { - let subs1 = item1.filter ? item1.filter.subscriptions.map(function(s) s.title).join(", ") : ""; - let subs2 = item2.filter ? item2.filter.subscriptions.map(function(s) s.title).join(", ") : ""; + 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) @@ -865,22 +913,31 @@ var treeView = { if (row >= this.data.length) return ""; if (col == "type") - return this.data[row].localizedDescr; + return localizedTypes.get(this.data[row].type); else if (col == "filter") - return (this.data[row].filter ? this.data[row].filter.text : ""); + return (this.data[row].filter || ""); else if (col == "size") { - let size = getItemSize(this.data[row]); + 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") { - if (!this.data[row].filter) + let filter = getFilter(this.data[row]) + if (!filter) return ""; - return this.data[row].filter.subscriptions.filter(function(s) !s.disabled).map(function(s) s.title).join(", "); + return filter.subscriptions.filter(s => !s.disabled).map(s => getSubscriptionTitle(s)).join(", "); } else return this.data[row].location; @@ -890,11 +947,11 @@ var treeView = { if (row > 0 || (col != "address" && col != "filter")) return ""; if (col == "filter") { - var filter = Policy.isWindowWhitelisted(window.content); + var filter = Policy.isWhitelisted(contentLocation); return filter ? filter.text : ""; } - return (Policy.isWindowWhitelisted(window.content) ? this.whitelistDummy : this.itemsDummy); + return (Policy.isWhitelisted(contentLocation) ? this.whitelistDummy : this.itemsDummy); } }, @@ -933,7 +990,7 @@ var treeView = { if (this.data && this.data.length) { list.push("dummy-false"); - let filter = this.data[row].filter; + let filter = getFilter(this.data[row]); if (filter) list.push("filter-disabled-" + filter.disabled); @@ -944,7 +1001,7 @@ var treeView = { state = "state-whitelisted"; else if (filter instanceof BlockingFilter) state = "state-filtered"; - else if (filter instanceof ElemHideFilter) + else if (filter instanceof ElemHideFilter || filter instanceof ElemHideEmulationFilter) state = "state-hidden"; else if (filter instanceof ElemHideException) state = "state-hiddenexception"; @@ -954,7 +1011,7 @@ var treeView = { list.push("dummy-true"); state = "state-filtered"; - if (this.data && Policy.isWindowWhitelisted(window.content)) + if (this.data && Policy.isWhitelisted(contentLocation)) state = "state-whitelisted"; } list.push(state); @@ -1070,7 +1127,7 @@ var treeView = { this.boxObject.rowCountChanged(0, this.rowCount); }, - addItem: function(/**Node*/ node, /**RequestEntry*/ item, /**Boolean*/ scanComplete) + addItem: function(/**RequestEntry*/ item, /**Boolean*/ scanComplete) { // Merge duplicate entries let key = item.location + " " + item.type + " " + item.docDomain; @@ -1080,21 +1137,25 @@ var treeView = { let existing = this.dataMap[key]; if (item.filter) existing.filter = item.filter; + existing.ids.push(item.id); - existing.nodes.push(node); 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, nodes: [node]}; + 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) - item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty); + { + 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; @@ -1146,10 +1207,15 @@ var treeView = { { for (let item of this.allData) { - if (item.filter instanceof RegExpFilter && item.filter.disabled) + let filter = getFilter(item); + if (filter instanceof RegExpFilter && filter.disabled) delete item.filter; - if (!item.filter) - item.filter = disabledMatcher.matchesAny(item.location, item.typeDescr, item.docDomain, item.thirdParty); + if (!filter) + { + let disabledMatch = disabledMatcher.matchesAny(item.location, RegExpFilter.typeMap[item.type], item.docDomain, item.thirdParty); + if (disabledMatch) + item.filter = disabledMatch.text; + } } this.refilter(); }, @@ -1178,9 +1244,9 @@ var treeView = { return true; return (item.location.toLowerCase().indexOf(this.filter) >= 0 || - (item.filter && item.filter.text.toLowerCase().indexOf(this.filter) >= 0) || - item.typeDescr.toLowerCase().indexOf(this.filter.replace(/-/g, "_")) >= 0 || - item.localizedDescr.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)); @@ -1255,9 +1321,9 @@ var treeView = { if (!this.data || this.data.length) return null; - var filter = Policy.isWindowWhitelisted(window.content); + var filter = Policy.isWhitelisted(contentLocation); if (filter) - return {tooltip: this.whitelistDummyTooltip, filter: filter}; + return {tooltip: this.whitelistDummyTooltip, filter: filter.text}; else return {tooltip: this.itemsDummyTooltip}; }, diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul index 208389d..d77cefb 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebar.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -32,7 +32,6 @@ <script type="application/x-javascript;version=1.7" src="utils.js"/> <script type="application/x-javascript;version=1.7" src="sidebar.js"/> - <script type="application/x-javascript;version=1.7" src="flasher.js"/> <keyset id="sidebarKeys"> <key id="block-key" keycode="VK_ENTER"/> @@ -89,8 +88,8 @@ <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(treeView.getSelectedItem().filter, false)"/> - <menuitem id="contextEnableFilter" labeltempl="&context.enablefilter.label;" oncommand="enableFilter(treeView.getSelectedItem().filter, true)"/> + <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)"/> diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul index 6738177..19fdd64 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/sidebarDetached.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 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 differnew file mode 100644 index 0000000..ce4701f --- /dev/null +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/abb-logo.png 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 differindex f1485e4..1caffd0 100644 --- 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 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 new file mode 100644 index 0000000..4871e66 --- /dev/null +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/common.css @@ -0,0 +1,59 @@ +/* + * 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/features/malware.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/malware.png Binary files differdeleted file mode 100644 index 9b51b63..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/malware.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/social.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/social.png Binary files differdeleted file mode 100644 index a2af1ea..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/social.png +++ /dev/null diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/tracking.png b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/tracking.png Binary files differdeleted file mode 100644 index a8727a9..0000000 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/features/tracking.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 index a3c57d8..fffc91c 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/firstRun.css +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/skin/firstRun.css @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -16,21 +16,21 @@ */ @font-face { - font-family: 'CreteRound'; + 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'); + src: local ("Ø"), + /*local ("Ø") forces using no local font called CreteRound*/ + url(fonts/CreteRound-Regular.otf) format("otf"); } @font-face { - font-family: 'CreteRound'; + 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'); + src: local ("Ø"), + /*local ("Ø") forces using no local font called CreteRound*/ + url(fonts/CreteRound-Italic.otf) format("otf"); } body @@ -79,7 +79,7 @@ header background-image: url(background.png); background-repeat: repeat-x; width: 100%; - padding: 25px 0 0 0; + padding-top: 25px; } header h1 @@ -89,7 +89,7 @@ header h1 color: #57ab5b; text-align: center; margin: 21px auto; - padding: 16px 0 14px 0; + padding: 16px 0px; border: 1px #57ab5b; border-style: dashed none; /* border parallel fix - 957px is the value @@ -99,7 +99,9 @@ header h1 max-width: 957px; } -h1,h2,h3 +h1, +h2, +h3 { font-family: CreteRound, Helvetica, Arial, sans-serif; } @@ -120,7 +122,8 @@ h3 font-size: 22px; color: #7F776B; font-weight: normal; - margin: 0 0 10px 0; + margin-top: 0px; + margin-bottom: 10px; padding: 0; line-height: 24px; } @@ -139,125 +142,125 @@ section { margin: 0 auto; margin-bottom: 30px; - max-width: 760px; + max-width: 960px; background-image: url(background.png); padding: 40px 100px; + box-sizing: border-box; } -section > p +#general { - margin: 15px 0 0 0; + display: table; + padding-left: 0px; + padding-right: 0px; } -#logo +#general > .block { - margin: 0 auto; - height: 128px; - width: 128px; - display: 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; } -#can-do-more +#general > .block:first-child { - max-width: 960px; - padding: 40px 0px 0px 0px; - border-bottom: 4px solid #968D81; + border: none; } -#can-do-more > h2 +#acceptable-ads-block h2 { - margin: 0 100px; + margin-bottom: 34px; } -.feature-malware-image +#abb-promotion-block:lang(fr) { - background-image: url(features/malware.png); - background-repeat: no-repeat; + display: none; } -.feature-social-image +#abb-promotion-block { - background-image: url(features/social.png); - background-repeat: no-repeat; + text-align: center; } -.feature-tracking-image +#abb-promotion-block h2 { - background-image: url(features/tracking.png); - background-repeat: no-repeat; + color: #7795b6; + margin-bottom: 40px; } -#can-do-more-content +#abb-promotion-block a { - margin: 30px 100px 20px 100px; + 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; } -#can-do-more #features +#abb-promotion-block a > div { - border-spacing: 10px; - margin: 0px; - padding: 0px; + display: table-cell; + vertical-align: middle; + padding: 6px; } -#can-do-more .feature:not([hidden]) +#abb-promotion-block .title { - display: block; - list-style-type: none; - padding: 30px 0; - padding-bottom: 20px; - border-top: 1px dashed #c0bebb; + font-size: 21px; + color: #ffffff; + font-weight: bold; } -#can-do-more .feature-image, #can-do-more .feature-description +#abb-promotion-block .subtitle { - display: inline-block; - *display: inline; /* IE6 inline-block fix */ - *zoom: 1; - vertical-align: top; + font-size: 12px; + color: #9ab7d6; } -#can-do-more .feature-description +#abb-promotion-block a:hover { - margin: 0px 0px 0 20px; - width: 625px; - max-width: 85%; + box-shadow: 0px 0px 5px #5D5D5D; } -#can-do-more .feature-description-textblock +#abb-promotion-block a:active { - width: 480px; - max-width: 100%; - margin: 0 40px 0 0; - display: inline-block; + box-shadow: 0px 0px 5px 1px #5D5D5D; } -#can-do-more .feature-description-textblock > span +section > p { - margin: 15px 0 0 0; + margin-top: 15px; } -#can-do-more .feature-image +#logo { - width: 59px; - height: 59px; - margin: 8px 0 10px 20px; + margin: 0 auto; + height: 128px; + width: 128px; + display: block; } #share { background-image: url(background-share.png); - padding: 50px 100px 40px 100px; - max-width: 760px; text-align: center; font-family: CreteRound, Helvetica, Arial, sans-serif; } #share h2 { - color: #fff; - margin: 0 0 30px 0; + margin-bottom: 30px; } +#share h2, #share h2 > a { color: #fff; @@ -283,38 +286,30 @@ section > p border-radius: 30px; } -#donate-block span, #share-block span -{ - margin: 10px 20px 0px 20px; -} - -#donate-block, #share-block +#share > .block { - min-width: 250px; display: inline-block; vertical-align: top; - padding: 5px 0 5px 0; + width: 49%; + padding: 5px 0px; border: 1px dashed #37506d; border-style: none dashed; } -#donate-block +#share > .block:last-child { - width: 50%; + -webkit-border-start-style: none; + -moz-border-start-style: none; } -#share-block +#share > .block > span { - width: 49%; - - -webkit-border-start-style: none; - -moz-border-start-style: none; + margin: 10px 20px; } .share-buttons { - margin: 6px 0 0 0; - cursor: pointer; + margin-top: 6px; vertical-align: top; /* because inline block creates * space if not captured with @@ -435,49 +430,6 @@ section > p height: 82px; } -#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; -} - /* Change order of the blocks for French */ #content:lang(fr) { @@ -491,94 +443,12 @@ section > p display: table-caption; } -.toggle -{ - cursor: pointer; - position: relative; - display: inline-block; - vertical-align: top; - height: 22px; - margin: 32px 0px 7px 0px; - border-radius: 9999px; - border: 1px solid #999; - overflow: hidden; - -moz-user-select: none; - -webkit-user-select: none; - user-select: none; -} - -.toggle:hover -{ - box-shadow: 0px 0px 3px 0px #968d81; -} - -.toggle:active -{ - cursor: wait; -} - -.toggle-on, .toggle-off -{ - min-width: 42px; - height: 100%; - font-size: 11px; - font-weight: 500; - text-align: center; - line-height: 23px; - border-radius: 9999px; -} - -.toggle-on -{ - padding: 0px 30px 0px 10px; - color: rgba(255,255,255, 0.8); - text-shadow: 1px 1px rgba(0,0,0,0.2); - box-shadow: inset 2px 2px 6px rgba(0,0,0,0.2); - background: rgb(69,163,31); -} - -.toggle-off -{ - padding: 0px 10px 0px 30px; - color: rgba(0,0,0,0.6); - text-shadow: 1px 1px rgba(255,255,255,0.2); - background: #cfcfcf; - background: -moz-linear-gradient(top, #cfcfcf 0%, #f5f5f5 100%); - background: -webkit-linear-gradient(top, #cfcfcf 0%,#f5f5f5 100%); - background: linear-gradient(to bottom, #cfcfcf 0%,#f5f5f5 100%); -} - -.toggle-blob -{ - position: absolute; - top: 0px; - right: 0px; - height: 100%; - width: 22px; - border-radius: 50px; - background: #cfcfcf; - background: -moz-linear-gradient(bottom, #cfcfcf 0%, #f5f5f5 100%); - background: -webkit-linear-gradient(bottom, #cfcfcf 0%,#f5f5f5 100%); - background: linear-gradient(to top, #cfcfcf 0%,#f5f5f5 100%); - box-shadow: 1px 1px 2px #888; -} - -.off .toggle-on -{ - margin-top: -22px; -} - -.off .toggle-blob -{ - left: 0px; - right: auto; -} - #donate { height: 21px; display: inline-block; - margin: 15px 0px 2px 0px; + margin-top: 15px; + margin-bottom: 2px; font-size: 16px; color: #003366; cursor: pointer; @@ -599,3 +469,51 @@ footer 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/subscriptionSelection.js b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js index b9129ea..261b710 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -217,7 +217,7 @@ function setCustomSubscription(title, url, mainSubscriptionTitle, mainSubscripti let link = document.createElement("label"); link.className = "text-link"; link.setAttribute("tooltiptext", mainSubscriptionURL); - link.addEventListener("click", function() UI.loadInBrowser(mainSubscriptionURL), false); + link.addEventListener("click", () => UI.loadInBrowser(mainSubscriptionURL), false); link.textContent = mainSubscriptionTitle; messageElement.appendChild(link); messageElement.appendChild(document.createTextNode(afterLink)); @@ -304,5 +304,5 @@ function doAddSubscription(/**String*/ url, /**String*/ title) function hasSubscription(url) { - return FilterStorage.subscriptions.some(function(subscription) subscription instanceof DownloadableSubscription && subscription.url == 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 index f2e1e44..c2383c6 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.xul +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptionSelection.xul @@ -2,7 +2,7 @@ <!-- - This file is part of Adblock Plus <https://adblockplus.org/>, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 diff --git a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml index f6727b2..953f16d 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/subscriptions.xml @@ -2,7 +2,7 @@ <!-- - This file is part of the Adblock Plus web scripts, - - Copyright (C) 2006-2015 Eyeo GmbH + - 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 @@ -23,89 +23,104 @@ url="https://easylist-downloads.adblockplus.org/easylist.txt" homepage="https://easylist.adblockplus.org/" prefixes="en" - author="fanboy, MonztA, Famlam, Khrin"/> + 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"/> + 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="Александър Станев"/> + 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, Jiefei"/> + 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"/> + 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"/> + 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"/> + author="MonztA, Famlam" + type="ads"/> <subscription title="EasyList Hebrew+EasyList" specialization="עברית" url="https://easylist-downloads.adblockplus.org/israellist+easylist.txt" - homepage="https://github.com/AdBlockPlusIsrael/EasyListHebrew" + homepage="https://github.com/ABPIsrael/EasyListHebrew" prefixes="he" - author="BsT"/> + 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"/> + 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"/> + 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="http://latvian-list.site11.com/" + homepage="https://notabug.org/latvian-list/adblock-latvian" prefixes="lv" - author="anonymous74100"/> + 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"/> + 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"/> + 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"/> + author="MenetZ, Zoso" + type="ads"/> <subscription title="RuAdList+EasyList" specialization="русский, українська" url="https://easylist-downloads.adblockplus.org/ruadlist+easylist.txt" - homepage="https://code.google.com/p/ruadlist/" + homepage="https://forums.lanik.us/viewforum.php?f=102" prefixes="ru,uk" - author="Lain_13"/> + 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 index 171fd60..5f8d515 100644 --- a/data/extensions/spyblock@gnu.org/chrome/content/ui/utils.js +++ b/data/extensions/spyblock@gnu.org/chrome/content/ui/utils.js @@ -1,6 +1,6 @@ /* * This file is part of Adblock Plus <https://adblockplus.org/>, - * Copyright (C) 2006-2015 Eyeo GmbH + * 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 @@ -35,10 +35,11 @@ function require(/**String*/ module) var {Policy} = require("contentPolicy"); var {Filter, InvalidFilter, CommentFilter, ActiveFilter, RegExpFilter, - BlockingFilter, WhitelistFilter, ElemHideBase, ElemHideFilter, ElemHideException} = require("filterClasses"); + BlockingFilter, WhitelistFilter, ElemHideBase, ElemHideFilter, + ElemHideException, ElemHideEmulationFilter} = require("filterClasses"); var {FilterNotifier} = require("filterNotifier"); -var {FilterStorage, PrivateBrowsing} = require("filterStorage"); -var {IO} = require("io"); +var {FilterStorage} = require("filterStorage"); +var {IO} = require("legacyIO"); var {defaultMatcher, Matcher, CombinedMatcher} = require("matcher"); var {Prefs} = require("prefs"); var {RequestNotifier} = require("requestNotifier"); @@ -57,6 +58,25 @@ function E(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() |