diff options
Diffstat (limited to 'data/extensions/spyblock@gnu.org/lib')
30 files changed, 849 insertions, 606 deletions
diff --git a/data/extensions/spyblock@gnu.org/lib/Public.jsm b/data/extensions/spyblock@gnu.org/lib/Public.jsm index 0f96bcb..ddd2389 100644 --- a/data/extensions/spyblock@gnu.org/lib/Public.jsm +++ b/data/extensions/spyblock@gnu.org/lib/Public.jsm @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 diff --git a/data/extensions/spyblock@gnu.org/lib/antiadblockInit.js b/data/extensions/spyblock@gnu.org/lib/antiadblockInit.js index d8b29ca..d4ef326 100644 --- a/data/extensions/spyblock@gnu.org/lib/antiadblockInit.js +++ b/data/extensions/spyblock@gnu.org/lib/antiadblockInit.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -46,10 +46,17 @@ exports.initAntiAdblockNotification = function initAntiAdblockNotification() { let urlFilters = []; for (let filter of subscription.filters) + { if (filter instanceof ActiveFilter) + { for (let domain in filter.domains) - if (domain && urlFilters.indexOf(domain) == -1) - urlFilters.push(domain); + { + let urlFilter = "||" + domain + "^"; + if (domain && filter.domains[domain] && urlFilters.indexOf(urlFilter) == -1) + urlFilters.push(urlFilter); + } + } + } notification.urlFilters = urlFilters; Notification.addNotification(notification); Notification.addQuestionListener(notification.id, notificationListener); diff --git a/data/extensions/spyblock@gnu.org/lib/appSupport.js b/data/extensions/spyblock@gnu.org/lib/appSupport.js index 67c6248..992d568 100644 --- a/data/extensions/spyblock@gnu.org/lib/appSupport.js +++ b/data/extensions/spyblock@gnu.org/lib/appSupport.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -359,6 +359,14 @@ switch (application) return (browser ? browser.currentURI : null); } }; + + // for Seamonkey we have to ignore same document flag because of + // bug #1035171 (https://bugzilla.mozilla.org/show_bug.cgi?id=1035171) + let origAddBrowserLocationListener = exports.addBrowserLocationListener; + exports.addBrowserLocationListener = function sm_addBrowserLocationListener(window, callback, ignoreSameDoc) + { + origAddBrowserLocationListener(window, callback, false); + }; exports.contentContextMenu = ["contentAreaContextMenu", "mailContext"]; @@ -694,7 +702,11 @@ switch (application) this.window = window; this.callback = callback; this.onSelect = this.onSelect.bind(this); - this.attach(); + this.attach = this.attach.bind(this); + if (window.BrowserApp.deck) + this.attach(); + else + window.addEventListener("UIReady", this.attach, false); }; BrowserChangeListener.prototype = { window: null, @@ -722,8 +734,8 @@ switch (application) attach: function() { + this.window.removeEventListener("UIReady", this.attach, false); this.onSelect(); - this.window.BrowserApp.deck.addEventListener("TabSelect", this.onSelect, false); }, detach: function() diff --git a/data/extensions/spyblock@gnu.org/lib/contentPolicy.js b/data/extensions/spyblock@gnu.org/lib/contentPolicy.js index 084ebc5..4f2247e 100644 --- a/data/extensions/spyblock@gnu.org/lib/contentPolicy.js +++ b/data/extensions/spyblock@gnu.org/lib/contentPolicy.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -22,7 +22,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -let {TimeLine} = require("timeline"); let {Utils} = require("utils"); let {Prefs} = require("prefs"); let {FilterStorage} = require("filterStorage"); @@ -90,8 +89,6 @@ let Policy = exports.Policy = */ init: function() { - TimeLine.enter("Entered content policy initialization"); - // type constant by type description and type description by type constant let iface = Ci.nsIContentPolicy; for (let typeName of contentTypes) @@ -120,12 +117,8 @@ let Policy = exports.Policy = for (let scheme of Prefs.whitelistschemes.toLowerCase().split(" ")) this.whitelistSchemes[scheme] = true; - TimeLine.log("done initializing types"); - // Generate class identifier used to collapse node and register corresponding // stylesheet. - TimeLine.log("registering global stylesheet"); - let offset = "a".charCodeAt(0); for (let i = 0; i < 20; i++) collapsedClass += String.fromCharCode(offset + Math.random() * 26); @@ -137,10 +130,7 @@ let Policy = exports.Policy = onShutdown.add(function() { Utils.styleService.unregisterSheet(collapseStyle, Ci.nsIStyleSheetService.USER_SHEET); - }) - TimeLine.log("done registering stylesheet"); - - TimeLine.leave("Done initializing content policy"); + }); }, /** @@ -160,44 +150,25 @@ let Policy = exports.Policy = let privatenode=false; Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm"); - if (PrivateBrowsingUtils.isWindowPrivate(wnd)) + if (PrivateBrowsingUtils.isContentWindowPrivate(wnd)) privatenode=true; let originWindow = Utils.getOriginWindow(wnd); let wndLocation = originWindow.location.href; let docDomain = getHostname(wndLocation); let match = null; + let [sitekey, sitekeyWnd] = getSitekey(wnd); if (!match && Prefs.enabled) { let testWnd = wnd; + let testSitekey = sitekey; + let testSitekeyWnd = sitekeyWnd; let parentWndLocation = getWindowLocation(testWnd); while (true) { let testWndLocation = parentWndLocation; parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); - match = Policy.isWhitelisted(testWndLocation, parentWndLocation); - - if (!(match instanceof WhitelistFilter)) - { - let keydata = (testWnd.document && testWnd.document.documentElement ? testWnd.document.documentElement.getAttribute("data-adblockkey") : null); - if (keydata && keydata.indexOf("_") >= 0) - { - let [key, signature] = keydata.split("_", 2); - let keyMatch = defaultMatcher.matchesByKey(testWndLocation, key.replace(/=/g, ""), docDomain); - if (keyMatch && Utils.crypto) - { - // Website specifies a key that we know but is the signature valid? - let uri = Services.io.newURI(testWndLocation, null, null); - let params = [ - uri.path.replace(/#.*/, ""), // REQUEST_URI - uri.asciiHost, // HTTP_HOST - Utils.httpProtocol.userAgent // HTTP_USER_AGENT - ]; - if (Utils.verifySignature(key, signature, params.join("\0"))) - match = keyMatch; - } - } - } + match = Policy.isWhitelisted(testWndLocation, parentWndLocation, testSitekey); if (match instanceof WhitelistFilter) { @@ -208,8 +179,10 @@ let Policy = exports.Policy = if (testWnd.parent == testWnd) break; - else - testWnd = testWnd.parent; + + if (testWnd == testSitekeyWnd) + [testSitekey, testSitekeyWnd] = getSitekey(testWnd.parent); + testWnd = testWnd.parent; } } @@ -231,7 +204,7 @@ let Policy = exports.Policy = let testWndLocation = parentWndLocation; parentWndLocation = (testWnd == testWnd.parent ? testWndLocation : getWindowLocation(testWnd.parent)); let parentDocDomain = getHostname(parentWndLocation); - match = defaultMatcher.matchesAny(testWndLocation, "ELEMHIDE", parentDocDomain, false); + match = defaultMatcher.matchesAny(testWndLocation, "ELEMHIDE", parentDocDomain, false, sitekey); if (match instanceof WhitelistFilter) { FilterStorage.increaseHitCount(match, wnd); @@ -256,7 +229,7 @@ let Policy = exports.Policy = if (exception) { FilterStorage.increaseHitCount(exception, wnd); - RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, thirdParty, locationText, exception); + RequestNotifier.addNodeData(node, topWnd, contentType, docDomain, false, locationText, exception); return true; } } @@ -265,7 +238,7 @@ let Policy = exports.Policy = if (!match && Prefs.enabled) { - match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty, privatenode); + match = defaultMatcher.matchesAny(locationText, Policy.typeDescr[contentType] || "", docDomain, thirdParty, sitekey, privatenode); if (match instanceof BlockingFilter && node.ownerDocument && !(contentType in Policy.nonVisual)) { let prefCollapse = (match.collapse != null ? match.collapse : !Prefs.fastcollapse); @@ -303,9 +276,10 @@ let Policy = exports.Policy = * Checks whether a page is whitelisted. * @param {String} url * @param {String} [parentUrl] location of the parent page + * @param {String} [sitekey] public key provided on the page * @return {Filter} filter that matched the URL or null if not whitelisted */ - isWhitelisted: function(url, parentUrl) + isWhitelisted: function(url, parentUrl, sitekey) { if (!url) return null; @@ -323,12 +297,12 @@ let Policy = exports.Policy = if (index >= 0) url = url.substring(0, index); - let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUrl), false); + let result = defaultMatcher.matchesAny(url, "DOCUMENT", getHostname(parentUrl), false, sitekey); return (result instanceof WhitelistFilter ? result : null); }, /** - * Checks whether the page loaded in a window is whitelisted. + * Checks whether the page loaded in a window is whitelisted for indication in the UI. * @param wnd {nsIDOMWindow} * @return {Filter} matching exception rule or null if not whitelisted */ @@ -337,11 +311,12 @@ let Policy = exports.Policy = return Policy.isWhitelisted(getWindowLocation(wnd)); }, - /** * Asynchronously re-checks filters for given nodes. + * @param {Node[]} nodes + * @param {RequestEntry} entry */ - refilterNodes: function(/**Node[]*/ nodes, /**RequestEntry*/ entry) + refilterNodes: function(nodes, entry) { // Ignore nodes that have been blocked already if (entry.filter && !(entry.filter instanceof WhitelistFilter)) @@ -696,6 +671,47 @@ function getHostname(/**String*/ url) /**String*/ } /** + * Retrieves the sitekey of a window. + */ +function getSitekey(wnd) +{ + let sitekey = null; + + while (true) + { + if (wnd.document && wnd.document.documentElement) + { + let keydata = wnd.document.documentElement.getAttribute("data-adblockkey"); + if (keydata && keydata.indexOf("_") >= 0) + { + let [key, signature] = keydata.split("_", 2); + key = key.replace(/=/g, ""); + + // Website specifies a key but is the signature valid? + let uri = Services.io.newURI(getWindowLocation(wnd), null, null); + let host = uri.asciiHost; + if (uri.port > 0) + host += ":" + uri.port; + let params = [ + uri.path.replace(/#.*/, ""), // REQUEST_URI + host, // HTTP_HOST + Utils.httpProtocol.userAgent // HTTP_USER_AGENT + ]; + if (Utils.verifySignature(key, signature, params.join("\0"))) + return [key, wnd]; + } + } + + if (wnd === wnd.parent) + break; + + wnd = wnd.parent; + } + + return [sitekey, wnd]; +} + +/** * Retrieves the location of a window. * @param wnd {nsIDOMWindow} * @return {String} window location or null on failure diff --git a/data/extensions/spyblock@gnu.org/lib/customizableUI.js b/data/extensions/spyblock@gnu.org/lib/customizableUI.js index 7db7425..ee250fa 100644 --- a/data/extensions/spyblock@gnu.org/lib/customizableUI.js +++ b/data/extensions/spyblock@gnu.org/lib/customizableUI.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 diff --git a/data/extensions/spyblock@gnu.org/lib/downloader.js b/data/extensions/spyblock@gnu.org/lib/downloader.js index d1ef209..320a754 100644 --- a/data/extensions/spyblock@gnu.org/lib/downloader.js +++ b/data/extensions/spyblock@gnu.org/lib/downloader.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -191,13 +191,18 @@ Downloader.prototype = url += "&"; else url += "?"; + // We limit the download count to 4+ to keep the request anonymized + let downloadCount = downloadable.downloadCount; + if (downloadCount > 4) + downloadCount = "4+"; url += "addonName=" + encodeURIComponent(addonName) + "&addonVersion=" + encodeURIComponent(addonVersion) + "&application=" + encodeURIComponent(application) + "&applicationVersion=" + encodeURIComponent(applicationVersion) + "&platform=" + encodeURIComponent(platform) + "&platformVersion=" + encodeURIComponent(platformVersion) + - "&lastVersion=" + encodeURIComponent(downloadable.lastVersion); + "&lastVersion=" + encodeURIComponent(downloadable.lastVersion) + + "&downloadCount=" + encodeURIComponent(downloadCount); return url; }, @@ -291,6 +296,8 @@ Downloader.prototype = return; } + downloadable.downloadCount++; + this.onDownloadSuccess(downloadable, request.responseText, errorCallback, function redirectCallback(url) { if (redirects >= this.maxRedirects) @@ -378,4 +385,10 @@ Downloadable.prototype = * @type Integer */ hardExpiration: 0, + + /** + * Number indicating how often the object was downloaded. + * @type Integer + */ + downloadCount: 0, }; diff --git a/data/extensions/spyblock@gnu.org/lib/elemHide.js b/data/extensions/spyblock@gnu.org/lib/elemHide.js index df17a0f..b762040 100644 --- a/data/extensions/spyblock@gnu.org/lib/elemHide.js +++ b/data/extensions/spyblock@gnu.org/lib/elemHide.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -27,31 +27,30 @@ let {Prefs} = require("prefs"); let {ElemHideException} = require("filterClasses"); let {FilterNotifier} = require("filterNotifier"); let {AboutHandler} = require("elemHideHitRegistration"); -let {TimeLine} = require("timeline"); /** * Lookup table, filters by their associated key * @type Object */ -let filterByKey = {__proto__: null}; +let filterByKey = Object.create(null); /** * Lookup table, keys of the filters by filter text * @type Object */ -let keyByFilter = {__proto__: null}; +let keyByFilter = Object.create(null); /** * Lookup table, keys are known element hiding exceptions * @type Object */ -let knownExceptions = {__proto__: null}; +let knownExceptions = Object.create(null); /** * Lookup table, lists of element hiding exceptions by selector * @type Object */ -let exceptions = {__proto__: null}; +let exceptions = Object.create(null); /** * Currently applied stylesheet URL @@ -82,7 +81,6 @@ let ElemHide = exports.ElemHide = */ init: function() { - TimeLine.enter("Entered ElemHide.init()"); Prefs.addListener(function(name) { if (name == "enabled") @@ -93,14 +91,9 @@ let ElemHide = exports.ElemHide = ElemHide.unapply(); }); - TimeLine.log("done adding prefs listener"); - let styleFile = IO.resolveFilePath(Prefs.data_directory); styleFile.append("elemhide.css"); styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); - TimeLine.log("done determining stylesheet URL"); - - TimeLine.leave("ElemHide.init() done"); }, /** @@ -108,10 +101,10 @@ let ElemHide = exports.ElemHide = */ clear: function() { - filterByKey = {__proto__: null}; - keyByFilter = {__proto__: null}; - knownExceptions = {__proto__: null}; - exceptions = {__proto__: null}; + filterByKey = Object.create(null); + keyByFilter = Object.create(null); + knownExceptions = Object.create(null); + exceptions = Object.create(null); ElemHide.isDirty = false; ElemHide.unapply(); }, @@ -184,7 +177,6 @@ let ElemHide = exports.ElemHide = */ getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideException*/ { - let selector = filter.selector; if (!(filter.selector in exceptions)) return null; @@ -220,8 +212,6 @@ let ElemHide = exports.ElemHide = return; } - TimeLine.enter("Entered ElemHide.apply()"); - if (!ElemHide.isDirty || !Prefs.enabled) { // Nothing changed, looks like we merely got enabled/disabled @@ -236,21 +226,17 @@ let ElemHide = exports.ElemHide = { Cu.reportError(e); } - TimeLine.log("Applying existing stylesheet finished"); } else if (!Prefs.enabled && ElemHide.applied) { ElemHide.unapply(); - TimeLine.log("ElemHide.unapply() finished"); } - TimeLine.leave("ElemHide.apply() done (no file changes)"); return; } IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e) { - TimeLine.enter("ElemHide.apply() write callback"); this._applying = false; // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that @@ -275,7 +261,6 @@ let ElemHide = exports.ElemHide = ElemHide.isDirty = false; ElemHide.unapply(); - TimeLine.log("ElemHide.unapply() finished"); if (!noFilters) { @@ -288,24 +273,19 @@ let ElemHide = exports.ElemHide = { Cu.reportError(e); } - TimeLine.log("Applying stylesheet finished"); } FilterNotifier.triggerListeners("elemhideupdate"); } - TimeLine.leave("ElemHide.apply() write callback done"); - }.bind(this), "ElemHideWrite"); + }.bind(this)); this._applying = true; - - TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); }, _generateCSSContent: function() { // Grouping selectors by domains - TimeLine.log("start grouping selectors"); - let domains = {__proto__: null}; + let domains = Object.create(null); let hasFilters = false; for (let key in filterByKey) { @@ -317,13 +297,12 @@ let ElemHide = exports.ElemHide = list = domains[domain]; else { - list = {__proto__: null}; + list = Object.create(null); domains[domain] = list; } list[filter.selector] = key; hasFilters = true; } - TimeLine.log("done grouping selectors"); if (!hasFilters) throw Cr.NS_ERROR_NOT_AVAILABLE; @@ -402,13 +381,7 @@ let ElemHide = exports.ElemHide = for (let key in filterByKey) { let filter = filterByKey[key]; - - // it is important to always access filter.domains - // here, even if it isn't used, in order to - // workaround WebKit bug 132872, also see #419 - let domains = filter.domains; - - if (specificOnly && (!domains || domains[""])) + if (specificOnly && (!filter.domains || filter.domains[""])) continue; if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) diff --git a/data/extensions/spyblock@gnu.org/lib/elemHideHitRegistration.js b/data/extensions/spyblock@gnu.org/lib/elemHideHitRegistration.js index a05f6df..74661a9 100644 --- a/data/extensions/spyblock@gnu.org/lib/elemHideHitRegistration.js +++ b/data/extensions/spyblock@gnu.org/lib/elemHideHitRegistration.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -70,7 +70,7 @@ let AboutHandler = exports.AboutHandler = newChannel: function(uri) { - let match = /\?(\d+)/.exec(uri.path) + let match = /\?(\d+)/.exec(uri.path); if (!match) throw Cr.NS_ERROR_FAILURE; @@ -126,7 +126,11 @@ HitRegistrationChannel.prototype = { { let {Policy} = require("contentPolicy"); let {ElemHide} = require("elemHide"); - let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy'/></bindings>"; + + // This dummy binding below won't have any effect on the element. For + // elements that should be hidden however we don't return any binding at + // all, this makes Gecko stop constructing the node - it cannot be shown. + let data = "<bindings xmlns='http://www.mozilla.org/xbl'><binding id='dummy' bindToUntrustedContent='true'/></bindings>"; let filter = ElemHide.getFilterByKey(this.key); if (filter) { diff --git a/data/extensions/spyblock@gnu.org/lib/ext_background.js b/data/extensions/spyblock@gnu.org/lib/ext_background.js new file mode 100644 index 0000000..2a50142 --- /dev/null +++ b/data/extensions/spyblock@gnu.org/lib/ext_background.js @@ -0,0 +1,102 @@ +/* + * 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/>. + */ + +let {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", null); +let {Services} = Cu.import("resource://gre/modules/Services.jsm", null); +let { + _MessageProxy: MessageProxy, + _EventTarget: EventTarget, + _getSender: getSender +} = require("ext_common"); +exports.onMessage = new EventTarget(); + +let messageProxy = new MessageProxy( + Cc["@mozilla.org/globalmessagemanager;1"] + .getService(Ci.nsIMessageListenerManager), + exports.onMessage); +onShutdown.add(function() +{ + messageProxy._disconnect(); +}); + +function Page(sender) +{ + this._sender = sender; +} +Page.prototype = { + sendMessage: function(message) + { + if (this._sender) + this._sender.sendAsyncMessage("AdblockPlus:Message", {payload: message}); + } +}; +exports.Page = Page; + +function PageMap() +{ + this._map = new Map(); + + Services.obs.addObserver(this, "message-manager-disconnect", true); + onShutdown.add(function() + { + Services.obs.removeObserver(this, "message-manager-disconnect"); + }.bind(this)); +} +PageMap.prototype = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), + + observe: function(subject, topic, data) + { + if (topic == "message-manager-disconnect") + this._map.delete(subject); + }, + + keys: function() + { + let result = []; + for (let sender of this._map.keys()) + result.push(new Page(sender)); + return result; + }, + + get: function(page) + { + return this._map.get(page._sender); + }, + + set: function(page, value) + { + if (page._sender) + this._map.set(page._sender, value); + }, + + has: function(page) + { + return this._map.has(page._sender); + }, + + delete: function(page) + { + this._map.delete(page._sender); + } +}; +exports.PageMap = PageMap; + +exports.showOptions = function() +{ + require("ui").UI.openFiltersDialog(); +}; diff --git a/data/extensions/spyblock@gnu.org/lib/ext_common.js b/data/extensions/spyblock@gnu.org/lib/ext_common.js new file mode 100644 index 0000000..129f232 --- /dev/null +++ b/data/extensions/spyblock@gnu.org/lib/ext_common.js @@ -0,0 +1,159 @@ +/* + * 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/>. + */ + +(function(global) +{ + const Ci = Components.interfaces; + + 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 getSender = global.ext._getSender = function(origin) + { + if (origin instanceof Ci.nsIDOMXULElement) + return origin.messageManager; + else if (origin instanceof Ci.nsIMessageSender) + return origin; + else + return null; + }; + + var MessageProxy = global.ext._MessageProxy = function(messageManager, messageTarget) + { + this._messageManager = messageManager; + this._messageTarget = messageTarget; + this._callbacks = new Map(); + this._responseCallbackCounter = 0; + + 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); + }, + + _sendResponse: function(sender, callbackId, message) + { + var response = { + callbackId: callbackId + }; + if (typeof response != "undefined") + response.payload = message; + sender.sendAsyncMessage("AdblockPlus:Response", response); + }, + + _handleRequest: function(message) + { + var sender = getSender(message.target); + var request = message.data; + + var sent = false; + var sendResponse; + if (sender && "callbackId" in request) + { + sendResponse = function(message) + { + this._sendResponse(sender, request.callbackId, message); + sent = true; + }.bind(this); + } + 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) + { + var response = message.data; + var callback = this._callbacks.get(response.callbackId); + if (callback) + { + this._callbacks.delete(response.callbackId); + if ("payload" in response) + callback(response.payload); + } + }, + + sendMessage: function(message, responseCallback) + { + if (!(this._messageManager instanceof Ci.nsIMessageSender)) + throw new Error("Not implemented"); + + var request = { + payload: message + }; + if (responseCallback) + { + request.callbackId = ++this._responseCallbackCounter; + this._callbacks.set(request.callbackId, responseCallback); + } + + this._messageManager.sendAsyncMessage("AdblockPlus:Message", request); + } + }; + + 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 = []; + + for (var i = 0; i < this._listeners.length; i++) + results.push(this._listeners[i].apply(null, arguments)); + + return results; + } + }; + + if (typeof exports == "object") + exports = global.ext; +})(this); diff --git a/data/extensions/spyblock@gnu.org/lib/filterClasses.js b/data/extensions/spyblock@gnu.org/lib/filterClasses.js index cb3a5b1..a0dfaf0 100644 --- a/data/extensions/spyblock@gnu.org/lib/filterClasses.js +++ b/data/extensions/spyblock@gnu.org/lib/filterClasses.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -68,7 +68,7 @@ Filter.prototype = * Cache for known filters, maps string representation to filter objects. * @type Object */ -Filter.knownFilters = {__proto__: null}; +Filter.knownFilters = Object.create(null); /** * Regular expression that element hiding filters should match @@ -109,7 +109,7 @@ Filter.fromText = function(text) Filter.knownFilters[ret.text] = ret; return ret; -} +}; /** * Deserializes a filter @@ -130,7 +130,7 @@ Filter.fromObject = function(obj) ret._lastHit = parseInt(obj.lastHit) || 0; } return ret; -} +}; /** * Removes unnecessary whitespaces from filter text, will only return null if @@ -147,17 +147,17 @@ Filter.normalize = function(/**String*/ text) /**String*/ if (/^\s*!/.test(text)) { // Don't remove spaces inside comments - return text.replace(/^\s+/, "").replace(/\s+$/, ""); + return text.trim(); } else if (Filter.elemhideRegExp.test(text)) { // Special treatment for element hiding filters, right side is allowed to contain spaces let [, domain, separator, selector] = /^(.*?)(#\@?#?)(.*)$/.exec(text); - return domain.replace(/\s/g, "") + separator + selector.replace(/^\s+/, "").replace(/\s+$/, ""); + return domain.replace(/\s/g, "") + separator + selector.trim(); } else return text.replace(/\s/g, ""); -} +}; /** * Class for invalid filters @@ -215,7 +215,7 @@ CommentFilter.prototype = /** * Abstract base class for filters that can get hits * @param {String} text see Filter() - * @param {String} domains (optional) Domains that the filter is restricted to separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" + * @param {String} [domains] Domains that the filter is restricted to separated by domainSeparator e.g. "foo.com|bar.com|~baz.com" * @constructor * @augments Filter */ @@ -324,6 +324,12 @@ ActiveFilter.prototype = */ get domains() { + // Despite this property being cached, the getter is called + // several times on Safari, due to WebKit bug 132872 + let prop = Object.getOwnPropertyDescriptor(this, "domains"); + if (prop) + return prop.value; + let domains = null; if (this.domainSource) @@ -366,7 +372,7 @@ ActiveFilter.prototype = } if (!domains) - domains = {__proto__: null}; + domains = Object.create(null); domains[domain] = include; } @@ -381,10 +387,24 @@ ActiveFilter.prototype = }, /** + * Array containing public keys of websites that this filter should apply to + * @type Array of String + */ + sitekeys: null, + + /** * Checks whether this filter is active on a domain. + * @param {String} docDomain domain name of the document that loads the URL + * @param {String} [sitekey] public key provided by the document + * @return {Boolean} true in case of the filter being active */ - isActiveOnDomain: function(/**String*/ docDomain) /**Boolean*/ + isActiveOnDomain: function(docDomain, sitekey) { + // Sitekeys are case-sensitive so we shouldn't convert them to upper-case to avoid false + // positives here. Instead we need to change the way filter options are parsed. + if (this.sitekeys && (!sitekey || this.sitekeys.indexOf(sitekey.toUpperCase()) < 0)) + return false; + // If no domains are set the rule matches everywhere if (!this.domains) return true; @@ -451,16 +471,17 @@ ActiveFilter.prototype = * Abstract base class for RegExp-based filters * @param {String} text see Filter() * @param {String} regexpSource filter part that the regular expression should be build from - * @param {Number} contentType (optional) Content types the filter applies to, combination of values from RegExpFilter.typeMap - * @param {Boolean} matchCase (optional) Defines whether the filter should distinguish between lower and upper case letters - * @param {String} domains (optional) Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" - * @param {Boolean} thirdParty (optional) Defines whether the filter should apply to third-party or first-party content only + * @param {Number} [contentType] Content types the filter applies to, combination of values from RegExpFilter.typeMap + * @param {Boolean} [matchCase] Defines whether the filter should distinguish between lower and upper case letters + * @param {String} [domains] Domains that the filter is restricted to, e.g. "foo.com|bar.com|~baz.com" + * @param {Boolean} [thirdParty] Defines whether the filter should apply to third-party or first-party content only + * @param {String} [sitekeys] Public keys of websites that this filter should apply to * @constructor * @augments ActiveFilter */ -function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty) +function RegExpFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { - ActiveFilter.call(this, text, domains); + ActiveFilter.call(this, text, domains, sitekeys); if (contentType != null) this.contentType = contentType; @@ -468,12 +489,14 @@ function RegExpFilter(text, regexpSource, contentType, matchCase, domains, third this.matchCase = matchCase; if (thirdParty != null) this.thirdParty = thirdParty; + if (sitekeys != null) + this.sitekeySource = sitekeys; if (regexpSource.length >= 2 && regexpSource[0] == "/" && regexpSource[regexpSource.length - 1] == "/") { // The filter is a regular expression - convert it immediately to catch syntax errors let regexp = new RegExp(regexpSource.substr(1, regexpSource.length - 2), this.matchCase ? "" : "i"); - this.__defineGetter__("regexp", () => regexp); + Object.defineProperty(this, "regexp", {value: regexp}); } else { @@ -514,6 +537,12 @@ RegExpFilter.prototype = */ get regexp() { + // Despite this property being cached, the getter is called + // several times on Safari, due to WebKit bug 132872 + let prop = Object.getOwnPropertyDescriptor(this, "regexp"); + if (prop) + return prop.value; + // Remove multiple wildcards let source = this.regexpSource .replace(/\*+/g, "*") // remove multiple wildcards @@ -529,10 +558,8 @@ RegExpFilter.prototype = .replace(/(\.\*)$/, ""); // remove trailing wildcards let regexp = new RegExp(source, this.matchCase ? "" : "i"); - - delete this.regexpSource; - this.__defineGetter__("regexp", () => regexp); - return this.regexp; + Object.defineProperty(this, "regexp", {value: regexp}); + return regexp; }, /** * Content types the filter applies to, combination of values from RegExpFilter.typeMap @@ -551,14 +578,45 @@ RegExpFilter.prototype = thirdParty: null, /** + * String that the sitekey property should be generated from + * @type String + */ + sitekeySource: null, + + /** + * Array containing public keys of websites that this filter should apply to + * @type Array of String + */ + get sitekeys() + { + // Despite this property being cached, the getter is called + // several times on Safari, due to WebKit bug 132872 + let prop = Object.getOwnPropertyDescriptor(this, "sitekeys"); + if (prop) + return prop.value; + + let sitekeys = null; + + if (this.sitekeySource) + { + sitekeys = this.sitekeySource.split("|"); + this.sitekeySource = null; + } + + Object.defineProperty(this, "sitekeys", {value: sitekeys, enumerable: true}); + return this.sitekeys; + }, + + /** * Tests whether the URL matches this filter * @param {String} location URL to be tested * @param {String} contentType content type identifier of the URL * @param {String} docDomain domain name of the document that loads the URL * @param {Boolean} thirdParty should be true if the URL is a third-party request + * @param {String} sitekey public key provided by the document * @return {Boolean} true in case of a match */ - matches: function(location, contentType, docDomain, thirdParty, privatenode) + matches: function(location, contentType, docDomain, thirdParty, sitekey, privatenode) { if(this.subscriptions[0]) @@ -566,10 +624,9 @@ RegExpFilter.prototype = if (privatenode==false) return false; - if (this.regexp.test(location) && - (RegExpFilter.typeMap[contentType] & this.contentType) != 0 && + if ((RegExpFilter.typeMap[contentType] & this.contentType) != 0 && (this.thirdParty == null || this.thirdParty == thirdParty) && - this.isActiveOnDomain(docDomain)) + this.isActiveOnDomain(docDomain, sitekey) && this.regexp.test(location)) { return true; } @@ -578,9 +635,10 @@ RegExpFilter.prototype = } }; -RegExpFilter.prototype.__defineGetter__("0", function() +// Required to optimize Matcher, see also RegExpFilter.prototype.length +Object.defineProperty(RegExpFilter.prototype, "0", { - return this; + get: function() { return this; } }); /** @@ -600,7 +658,7 @@ RegExpFilter.fromText = function(text) let contentType = null; let matchCase = null; let domains = null; - let siteKeys = null; + let sitekeys = null; let thirdParty = null; let collapse = null; let options; @@ -646,7 +704,7 @@ RegExpFilter.fromText = function(text) else if (option == "~COLLAPSE") collapse = false; else if (option == "SITEKEY" && typeof value != "undefined") - siteKeys = value.split(/\|/); + sitekeys = value; else return new InvalidFilter(origText, "Unknown option " + option.toLowerCase()); } @@ -660,21 +718,19 @@ RegExpFilter.fromText = function(text) contentType = RegExpFilter.prototype.contentType; contentType &= ~RegExpFilter.typeMap.DOCUMENT; } - if (!blocking && siteKeys) - contentType = RegExpFilter.typeMap.DOCUMENT; try { if (blocking) - return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, collapse); + return new BlockingFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys, collapse); else - return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, siteKeys); + return new WhitelistFilter(origText, text, contentType, matchCase, domains, thirdParty, sitekeys); } catch (e) { return new InvalidFilter(origText, e); } -} +}; /** * Maps type strings like "SCRIPT" or "OBJECT" to bit masks @@ -712,13 +768,14 @@ RegExpFilter.prototype.contentType &= ~(RegExpFilter.typeMap.ELEMHIDE | RegExpFi * @param {Boolean} matchCase see RegExpFilter() * @param {String} domains see RegExpFilter() * @param {Boolean} thirdParty see RegExpFilter() + * @param {String} sitekeys see RegExpFilter() * @param {Boolean} collapse defines whether the filter should collapse blocked content, can be null * @constructor * @augments RegExpFilter */ -function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, collapse) +function BlockingFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys, collapse) { - RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty); + RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys); this.collapse = collapse; } @@ -743,34 +800,25 @@ BlockingFilter.prototype = * @param {Boolean} matchCase see RegExpFilter() * @param {String} domains see RegExpFilter() * @param {Boolean} thirdParty see RegExpFilter() - * @param {String[]} siteKeys public keys of websites that this filter should apply to + * @param {String} sitekeys see RegExpFilter() * @constructor * @augments RegExpFilter */ -function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, siteKeys) +function WhitelistFilter(text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys) { - RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty); - - if (siteKeys != null) - this.siteKeys = siteKeys; + RegExpFilter.call(this, text, regexpSource, contentType, matchCase, domains, thirdParty, sitekeys); } exports.WhitelistFilter = WhitelistFilter; WhitelistFilter.prototype = { - __proto__: RegExpFilter.prototype, - - /** - * List of public keys of websites that this filter should apply to - * @type String[] - */ - siteKeys: null -} + __proto__: RegExpFilter.prototype +}; /** * Base class for element hiding filters * @param {String} text see Filter() - * @param {String} domains (optional) Host names or domains the filter should be restricted to + * @param {String} [domains] Host names or domains the filter should be restricted to * @param {String} selector CSS selector for the HTML elements that should be hidden * @constructor * @augments ActiveFilter @@ -865,7 +913,7 @@ ElemHideBase.fromText = function(text, domain, isException, tagName, attrRules, return new ElemHideException(text, domain, selector); else return new ElemHideFilter(text, domain, selector); -} +}; /** * Class for element hiding filters diff --git a/data/extensions/spyblock@gnu.org/lib/filterListener.js b/data/extensions/spyblock@gnu.org/lib/filterListener.js index 1687a26..e993a44 100644 --- a/data/extensions/spyblock@gnu.org/lib/filterListener.js +++ b/data/extensions/spyblock@gnu.org/lib/filterListener.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -22,7 +22,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -let {TimeLine} = require("timeline"); let {FilterStorage} = require("filterStorage"); let {FilterNotifier} = require("filterNotifier"); let {ElemHide} = require("elemHide"); @@ -103,8 +102,6 @@ let HistoryPurgeObserver = */ function init() { - TimeLine.enter("Entered filter listener initialization()"); - FilterNotifier.addListener(function(action, item, newValue, oldValue) { let match = /^(\w+)\.(.*)/.exec(action); @@ -122,16 +119,11 @@ function init() flushElemHide = function() {}; // No global stylesheet in Chrome & Co. FilterStorage.loadFromDisk(); - TimeLine.log("done initializing data structures"); - Services.obs.addObserver(HistoryPurgeObserver, "browser:purge-session-history", true); onShutdown.add(function() { Services.obs.removeObserver(HistoryPurgeObserver, "browser:purge-session-history"); }); - TimeLine.log("done adding observers"); - - TimeLine.leave("Filter listener initialization done"); } init(); diff --git a/data/extensions/spyblock@gnu.org/lib/filterNotifier.js b/data/extensions/spyblock@gnu.org/lib/filterNotifier.js index 010081e..80d6769 100644 --- a/data/extensions/spyblock@gnu.org/lib/filterNotifier.js +++ b/data/extensions/spyblock@gnu.org/lib/filterNotifier.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 diff --git a/data/extensions/spyblock@gnu.org/lib/filterStorage.js b/data/extensions/spyblock@gnu.org/lib/filterStorage.js index 546f788..dd8aea7 100644 --- a/data/extensions/spyblock@gnu.org/lib/filterStorage.js +++ b/data/extensions/spyblock@gnu.org/lib/filterStorage.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -29,7 +29,6 @@ let {Filter, ActiveFilter} = require("filterClasses"); let {Subscription, SpecialSubscription, ExternalSubscription} = require("subscriptionClasses"); let {FilterNotifier} = require("filterNotifier"); let {Utils} = require("utils"); -let {TimeLine} = require("timeline"); /** * Version number of the filter storage file format. @@ -85,8 +84,9 @@ let FilterStorage = exports.FilterStorage = if (!file) Cu.reportError("Adblock Plus: Failed to resolve filter file location from extensions.adblockplus.patternsfile preference"); - this.__defineGetter__("sourceFile", () => file); - return this.sourceFile; + // Property is configurable because of the test suite. + Object.defineProperty(this, "sourceFile", {value: file, configurable: true}); + return file; }, /** @@ -99,7 +99,7 @@ let FilterStorage = exports.FilterStorage = * Map of properties listed in the filter storage file before the sections * start. Right now this should be only the format version. */ - fileProperties: {__proto__: null}, + fileProperties: Object.create(null), /** * List of filter subscriptions containing all filters @@ -111,7 +111,7 @@ let FilterStorage = exports.FilterStorage = * Map of subscriptions already on the list, by their URL/identifier * @type Object */ - knownSubscriptions: {__proto__: null}, + knownSubscriptions: Object.create(null), /** * Finds the filter group that a filter should be added to by default. Will @@ -368,17 +368,13 @@ let FilterStorage = exports.FilterStorage = if (this._loading) return; - TimeLine.enter("Entered FilterStorage.loadFromDisk()"); this._loading = true; let readFile = function(sourceFile, backupIndex) { - TimeLine.enter("FilterStorage.loadFromDisk() -> readFile()"); - let parser = new INIParser(); IO.readFromFile(sourceFile, parser, function(e) { - TimeLine.enter("FilterStorage.loadFromDisk() read callback"); if (!e && parser.subscriptions.length == 0) { // No filter subscriptions in the file, this isn't right. @@ -406,21 +402,18 @@ let FilterStorage = exports.FilterStorage = else doneReading(parser); }); - TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); return; } } doneReading(parser); - }.bind(this), "FilterStorageRead"); - - TimeLine.leave("FilterStorage.loadFromDisk() <- readFile()", "FilterStorageRead"); + }.bind(this)); }.bind(this); var doneReading = function(parser) { // Old special groups might have been converted, remove them if they are empty let specialMap = {"~il~": true, "~wl~": true, "~fl~": true, "~eh~": true}; - let knownSubscriptions = {__proto__: null}; + let knownSubscriptions = Object.create(null); for (let i = 0; i < parser.subscriptions.length; i++) { let subscription = parser.subscriptions[i]; @@ -444,7 +437,6 @@ let FilterStorage = exports.FilterStorage = this.addFilter(filter, null, undefined, true); } } - TimeLine.log("Initializing data done, triggering observers") this._loading = false; FilterNotifier.triggerListeners("load"); @@ -452,7 +444,6 @@ let FilterStorage = exports.FilterStorage = if (sourceFile != this.sourceFile) this.saveToDisk(); - TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); }.bind(this); let explicitFile; @@ -473,8 +464,6 @@ let FilterStorage = exports.FilterStorage = this.firstRun = true; this._loading = false; FilterNotifier.triggerListeners("load"); - - TimeLine.leave("FilterStorage.loadFromDisk() read callback done"); } else readFile(sourceFile, 0); @@ -485,8 +474,6 @@ let FilterStorage = exports.FilterStorage = else callback(true); } - - TimeLine.leave("FilterStorage.loadFromDisk() done"); }, _generateFilterData: function(subscriptions) @@ -494,7 +481,7 @@ let FilterStorage = exports.FilterStorage = yield "# Adblock Plus preferences"; yield "version=" + formatVersion; - let saved = {__proto__: null}; + let saved = Object.create(null); let buf = []; // Save filter data @@ -568,8 +555,6 @@ let FilterStorage = exports.FilterStorage = return; } - TimeLine.enter("Entered FilterStorage.saveToDisk()"); - // Make sure the file's parent directory exists try { targetFile.parent.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); @@ -577,10 +562,8 @@ let FilterStorage = exports.FilterStorage = let writeFilters = function() { - TimeLine.enter("FilterStorage.saveToDisk() -> writeFilters()"); IO.writeToFile(targetFile, this._generateFilterData(subscriptions), function(e) { - TimeLine.enter("FilterStorage.saveToDisk() write callback"); if (!explicitFile) this._saving = false; @@ -594,9 +577,7 @@ let FilterStorage = exports.FilterStorage = } else FilterNotifier.triggerListeners("save"); - TimeLine.leave("FilterStorage.saveToDisk() write callback done"); - }.bind(this), "FilterStorageWrite"); - TimeLine.leave("FilterStorage.saveToDisk() -> writeFilters()", "FilterStorageWrite"); + }.bind(this)); }.bind(this); let checkBackupRequired = function(callbackNotRequired, callbackRequired) @@ -628,16 +609,13 @@ let FilterStorage = exports.FilterStorage = let removeLastBackup = function(part1, part2) { - TimeLine.enter("FilterStorage.saveToDisk() -> removeLastBackup()"); let file = targetFile.clone(); file.leafName = part1 + "-backup" + Prefs.patternsbackups + part2; IO.removeFile(file, (e) => renameBackup(part1, part2, Prefs.patternsbackups - 1)); - TimeLine.leave("FilterStorage.saveToDisk() <- removeLastBackup()"); }.bind(this); let renameBackup = function(part1, part2, index) { - TimeLine.enter("FilterStorage.saveToDisk() -> renameBackup()"); if (index > 0) { let fromFile = targetFile.clone(); @@ -654,7 +632,6 @@ let FilterStorage = exports.FilterStorage = IO.copyFile(targetFile, toFile, writeFilters); } - TimeLine.leave("FilterStorage.saveToDisk() <- renameBackup()"); }.bind(this); // Do not persist external subscriptions @@ -663,8 +640,6 @@ let FilterStorage = exports.FilterStorage = this._saving = true; checkBackupRequired(writeFilters, removeLastBackup); - - TimeLine.leave("FilterStorage.saveToDisk() done"); }, /** @@ -794,8 +769,8 @@ function INIParser() { this.fileProperties = this.curObj = {}; this.subscriptions = []; - this.knownFilters = {__proto__: null}; - this.knownSubscriptions = {__proto__: null}; + this.knownFilters = Object.create(null); + this.knownSubscriptions = Object.create(null); } INIParser.prototype = { diff --git a/data/extensions/spyblock@gnu.org/lib/io.js b/data/extensions/spyblock@gnu.org/lib/io.js index ea362b7..5e60b54 100644 --- a/data/extensions/spyblock@gnu.org/lib/io.js +++ b/data/extensions/spyblock@gnu.org/lib/io.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -24,12 +24,11 @@ let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", null); let {OS} = Cu.import("resource://gre/modules/osfile.jsm", null); let {Task} = Cu.import("resource://gre/modules/Task.jsm", null); -let {TimeLine} = require("timeline"); let {Prefs} = require("prefs"); let {Utils} = require("utils"); let firstRead = true; -const BUFFER_SIZE = 0x8000; // 32kB +const BUFFER_SIZE = 0x80000; // 512kB let IO = exports.IO = { @@ -39,9 +38,8 @@ let IO = exports.IO = get lineBreak() { let lineBreak = (Services.appinfo.OS == "WINNT" ? "\r\n" : "\n"); - delete IO.lineBreak; - IO.__defineGetter__("lineBreak", () => lineBreak); - return IO.lineBreak; + Object.defineProperty(this, "lineBreak", {value: lineBreak}); + return lineBreak; }, /** @@ -71,7 +69,7 @@ let IO = exports.IO = * each line read and with a null parameter once the read operation is done. * The callback will be called when the operation is done. */ - readFromFile: function(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback, /**String*/ timeLineID) + readFromFile: function(/**nsIFile*/ file, /**Object*/ listener, /**Function*/ callback) { try { @@ -82,11 +80,6 @@ let IO = exports.IO = let onProgress = function(data) { - if (timeLineID) - { - TimeLine.asyncStart(timeLineID); - } - let index = (processing ? -1 : Math.max(data.lastIndexOf("\n"), data.lastIndexOf("\r"))); if (index >= 0) { @@ -126,11 +119,6 @@ let IO = exports.IO = } else buffer += data; - - if (timeLineID) - { - TimeLine.asyncEnd(timeLineID); - } }; let onSuccess = function() @@ -142,21 +130,10 @@ let IO = exports.IO = return; } - if (timeLineID) - { - TimeLine.asyncStart(timeLineID); - } - if (buffer !== "") listener.process(buffer); listener.process(null); - if (timeLineID) - { - TimeLine.asyncEnd(timeLineID); - TimeLine.asyncDone(timeLineID); - } - callback(null); }; @@ -170,15 +147,9 @@ let IO = exports.IO = } callback(e); - - if (timeLineID) - { - TimeLine.asyncDone(timeLineID); - } }; let decoder = new TextDecoder(); - let array = new Uint8Array(BUFFER_SIZE); Task.spawn(function() { if (firstRead && Services.vc.compare(Utils.platformVersion, "23.0a1") <= 0) @@ -201,19 +172,15 @@ let IO = exports.IO = firstRead = false; let f = yield OS.File.open(file.path, {read: true}); - let numBytes; - do + while (true) { - numBytes = yield f.readTo(array); - if (numBytes) - { - let data = decoder.decode(numBytes == BUFFER_SIZE ? - array : - array.subarray(0, numBytes), {stream: true}); - onProgress(data); - } - } while (numBytes); + let array = yield f.read(BUFFER_SIZE); + if (!array.length) + break; + let data = decoder.decode(array, {stream: true}); + onProgress(data); + } yield f.close(); }.bind(this)).then(onSuccess, onError); } @@ -227,7 +194,7 @@ let IO = exports.IO = * Writes string data to a file in UTF-8 format asynchronously. The callback * will be called when the write operation is done. */ - writeToFile: function(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback, /**String*/ timeLineID) + writeToFile: function(/**nsIFile*/ file, /**Iterator*/ data, /**Function*/ callback) { try { diff --git a/data/extensions/spyblock@gnu.org/lib/keySelector.js b/data/extensions/spyblock@gnu.org/lib/keySelector.js index 20847d9..01d9cd0 100644 --- a/data/extensions/spyblock@gnu.org/lib/keySelector.js +++ b/data/extensions/spyblock@gnu.org/lib/keySelector.js @@ -1,19 +1,6 @@ -/* - * This file is part of the Adblock Plus build tools, - * Copyright (C) 2006-2014 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/>. - */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Cu.import("resource://gre/modules/Services.jsm"); diff --git a/data/extensions/spyblock@gnu.org/lib/main.js b/data/extensions/spyblock@gnu.org/lib/main.js index f18cc05..fa84d9e 100644 --- a/data/extensions/spyblock@gnu.org/lib/main.js +++ b/data/extensions/spyblock@gnu.org/lib/main.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -22,24 +22,14 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -let {TimeLine} = require("timeline"); - -TimeLine.enter("Adblock Plus startup"); registerPublicAPI(); -TimeLine.log("Done registering public API"); require("filterListener"); -TimeLine.log("Done loading filter listener"); require("contentPolicy"); -TimeLine.log("Done loading content policy"); require("synchronizer"); -TimeLine.log("Done loading subscription synchronizer"); require("notification"); -TimeLine.log("Done loading notification downloader"); require("sync"); -TimeLine.log("Done loading sync support"); +require("messageResponder"); require("ui"); -TimeLine.log("Done loading UI integration code"); -TimeLine.leave("Started up"); function registerPublicAPI() { diff --git a/data/extensions/spyblock@gnu.org/lib/matcher.js b/data/extensions/spyblock@gnu.org/lib/matcher.js index 908b0b8..59ef1e7 100644 --- a/data/extensions/spyblock@gnu.org/lib/matcher.js +++ b/data/extensions/spyblock@gnu.org/lib/matcher.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -49,8 +49,8 @@ Matcher.prototype = { */ clear: function() { - this.filterByKeyword = {__proto__: null}; - this.keywordByFilter = {__proto__: null}; + this.filterByKeyword = Object.create(null); + this.keywordByFilter = Object.create(null); }, /** @@ -165,13 +165,13 @@ Matcher.prototype = { /** * Checks whether the entries for a particular keyword match a URL */ - _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty, privatenode) + _checkEntryMatch: function(keyword, location, contentType, docDomain, thirdParty, sitekey, privatenode) { let list = this.filterByKeyword[keyword]; for (let i = 0; i < list.length; i++) { let filter = list[i]; - if (filter.matches(location, contentType, docDomain, thirdParty,privatenode)) + if (filter.matches(location, contentType, docDomain, thirdParty, sitekey, privatenode)) return filter; } return null; @@ -183,9 +183,10 @@ Matcher.prototype = { * @param {String} contentType content type identifier of the URL * @param {String} docDomain domain name of the document that loads the URL * @param {Boolean} thirdParty should be true if the URL is a third-party request + * @param {String} sitekey public key provided by the document * @return {RegExpFilter} matching filter or null */ - matchesAny: function(location, contentType, docDomain, thirdParty) + matchesAny: function(location, contentType, docDomain, thirdParty, sitekey) { let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); if (candidates === null) @@ -196,7 +197,7 @@ Matcher.prototype = { let substr = candidates[i]; if (substr in this.filterByKeyword) { - let result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty); + let result = this._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey); if (result) return result; } @@ -215,8 +216,7 @@ function CombinedMatcher() { this.blacklist = new Matcher(); this.whitelist = new Matcher(); - this.keys = {__proto__: null}; - this.resultCache = {__proto__: null}; + this.resultCache = Object.create(null); } exports.CombinedMatcher = CombinedMatcher; @@ -241,12 +241,6 @@ CombinedMatcher.prototype = whitelist: null, /** - * Exception rules that are limited by public keys, mapped by the corresponding keys. - * @type Object - */ - keys: null, - - /** * Lookup table of previous matchesAny results * @type Object */ @@ -265,8 +259,7 @@ CombinedMatcher.prototype = { this.blacklist.clear(); this.whitelist.clear(); - this.keys = {__proto__: null}; - this.resultCache = {__proto__: null}; + this.resultCache = Object.create(null); this.cacheEntries = 0; }, @@ -276,21 +269,13 @@ CombinedMatcher.prototype = add: function(filter) { if (filter instanceof WhitelistFilter) - { - if (filter.siteKeys) - { - for (let i = 0; i < filter.siteKeys.length; i++) - this.keys[filter.siteKeys[i]] = filter.text; - } - else - this.whitelist.add(filter); - } + this.whitelist.add(filter); else this.blacklist.add(filter); if (this.cacheEntries > 0) { - this.resultCache = {__proto__: null}; + this.resultCache = Object.create(null); this.cacheEntries = 0; } }, @@ -301,21 +286,13 @@ CombinedMatcher.prototype = remove: function(filter) { if (filter instanceof WhitelistFilter) - { - if (filter.siteKeys) - { - for (let i = 0; i < filter.siteKeys.length; i++) - delete this.keys[filter.siteKeys[i]]; - } - else - this.whitelist.remove(filter); - } + this.whitelist.remove(filter); else this.blacklist.remove(filter); if (this.cacheEntries > 0) { - this.resultCache = {__proto__: null}; + this.resultCache = Object.create(null); this.cacheEntries = 0; } }, @@ -370,7 +347,7 @@ CombinedMatcher.prototype = * simultaneously. For parameters see Matcher.matchesAny(). * @see Matcher#matchesAny */ - matchesAnyInternal: function(location, contentType, docDomain, thirdParty, privatenode) + matchesAnyInternal: function(location, contentType, docDomain, thirdParty, sitekey, privatenode) { let candidates = location.toLowerCase().match(/[a-z0-9%]{3,}/g); if (candidates === null) @@ -383,12 +360,12 @@ CombinedMatcher.prototype = let substr = candidates[i]; if (substr in this.whitelist.filterByKeyword) { - let result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, privatenode); + let result = this.whitelist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey, privatenode); if (result) return result; } if (substr in this.blacklist.filterByKeyword && blacklistHit === null) - blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, privatenode); + blacklistHit = this.blacklist._checkEntryMatch(substr, location, contentType, docDomain, thirdParty, sitekey, privatenode); } return blacklistHit; }, @@ -396,19 +373,19 @@ CombinedMatcher.prototype = /** * @see Matcher#matchesAny */ - matchesAny: function(location, contentType, docDomain, thirdParty, privatenode) + matchesAny: function(location, contentType, docDomain, thirdParty, sitekey, privatenode) { - let key = location + " " + contentType + " " + docDomain + " " + thirdParty; + let key = location + " " + contentType + " " + docDomain + " " + thirdParty + " " + sitekey; if (!privatenode){ if (key in this.resultCache) return this.resultCache[key]; } - let result = this.matchesAnyInternal(location, contentType, docDomain, thirdParty, privatenode); + let result = this.matchesAnyInternal(location, contentType, docDomain, thirdParty, sitekey, privatenode); if (this.cacheEntries >= CombinedMatcher.maxCacheEntries) { - this.resultCache = {__proto__: null}; + this.resultCache = Object.create(null); this.cacheEntries = 0; } @@ -418,24 +395,6 @@ CombinedMatcher.prototype = } return result; - }, - - /** - * Looks up whether any filters match the given website key. - */ - matchesByKey: function(/**String*/ location, /**String*/ key, /**String*/ docDomain) - { - key = key.toUpperCase(); - if (key in this.keys) - { - let filter = Filter.knownFilters[this.keys[key]]; - if (filter && filter.matches(location, "DOCUMENT", docDomain, false)) - return filter; - else - return null; - } - else - return null; } } diff --git a/data/extensions/spyblock@gnu.org/lib/messageResponder.js b/data/extensions/spyblock@gnu.org/lib/messageResponder.js new file mode 100644 index 0000000..0f5ff0e --- /dev/null +++ b/data/extensions/spyblock@gnu.org/lib/messageResponder.js @@ -0,0 +1,180 @@ +/* + * 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/>. + */ + +(function(global) +{ + if (!global.ext) + global.ext = require("ext_background"); + + var Utils = require("utils").Utils; + var FilterStorage = require("filterStorage").FilterStorage; + var FilterNotifier = require("filterNotifier").FilterNotifier; + var defaultMatcher = require("matcher").defaultMatcher; + var BlockingFilter = require("filterClasses").BlockingFilter; + var Synchronizer = require("synchronizer").Synchronizer; + + var subscriptionClasses = require("subscriptionClasses"); + var Subscription = subscriptionClasses.Subscription; + var DownloadableSubscription = subscriptionClasses.DownloadableSubscription; + var SpecialSubscription = subscriptionClasses.SpecialSubscription; + + var subscriptionKeys = ["disabled", "homepage", "lastSuccess", "title", "url", "downloadStatus"]; + function convertSubscription(subscription) + { + var result = {}; + for (var i = 0; i < subscriptionKeys.length; i++) + result[subscriptionKeys[i]] = subscription[subscriptionKeys[i]] + return result; + } + + var changeListeners = null; + var messageTypes = { + "app": "app.listen", + "filter": "filters.listen", + "subscription": "subscriptions.listen" + }; + + function onFilterChange(action) + { + var parts = action.split(".", 2); + var type; + if (parts.length == 1) + { + type = "app"; + action = parts[0]; + } + else + { + type = parts[0]; + action = parts[1]; + } + + if (!messageTypes.hasOwnProperty(type)) + return; + + var args = Array.prototype.slice.call(arguments, 1).map(function(arg) + { + if (arg instanceof Subscription) + return convertSubscription(arg); + else + return arg; + }); + + var pages = changeListeners.keys(); + for (var i = 0; i < pages.length; i++) + { + var filters = changeListeners.get(pages[i]); + if (filters[type] && filters[type].indexOf(action) >= 0) + { + pages[i].sendMessage({ + type: messageTypes[type], + action: action, + args: args + }); + } + } + }; + + global.ext.onMessage.addListener(function(message, sender, callback) + { + switch (message.type) + { + case "app.get": + if (message.what == "issues") + { + var info = require("info"); + callback({ + seenDataCorruption: "seenDataCorruption" in global ? global.seenDataCorruption : false, + filterlistsReinitialized: "filterlistsReinitialized" in global ? global.filterlistsReinitialized : false, + legacySafariVersion: (info.platform == "safari" && ( + Services.vc.compare(info.platformVersion, "6.0") < 0 || // beforeload breaks websites in Safari 5 + Services.vc.compare(info.platformVersion, "6.1") == 0 || // extensions are broken in 6.1 and 7.0 + Services.vc.compare(info.platformVersion, "7.0") == 0)) + }); + } + else if (message.what == "doclink") + callback(Utils.getDocLink(message.link)); + else if (message.what == "localeInfo") + { + var bidiDir; + if ("chromeRegistry" in Utils) + bidiDir = Utils.chromeRegistry.isLocaleRTL("adblockplus") ? "rtl" : "ltr"; + else + bidiDir = ext.i18n.getMessage("@@bidi_dir"); + + callback({locale: Utils.appLocale, bidiDir: bidiDir}); + } + else + callback(null); + break; + case "app.open": + if (message.what == "options") + ext.showOptions(); + break; + case "subscriptions.get": + var subscriptions = FilterStorage.subscriptions.filter(function(s) + { + if (message.ignoreDisabled && s.disabled) + return false; + if (s instanceof DownloadableSubscription && message.downloadable) + return true; + if (s instanceof SpecialSubscription && message.special) + return true; + return false; + }); + callback(subscriptions.map(convertSubscription)); + break; + case "filters.blocked": + var filter = defaultMatcher.matchesAny(message.url, message.requestType, message.docDomain, message.thirdParty); + callback(filter instanceof BlockingFilter); + break; + case "subscriptions.toggle": + var subscription = Subscription.fromURL(message.url); + if (subscription.url in FilterStorage.knownSubscriptions && !subscription.disabled) + FilterStorage.removeSubscription(subscription); + else + { + subscription.disabled = false; + subscription.title = message.title; + subscription.homepage = message.homepage; + FilterStorage.addSubscription(subscription); + if (!subscription.lastDownload) + Synchronizer.execute(subscription); + } + break; + case "subscriptions.listen": + if (!changeListeners) + { + changeListeners = new global.ext.PageMap(); + FilterNotifier.addListener(onFilterChange); + } + + var filters = changeListeners.get(sender.page); + if (!filters) + { + filters = Object.create(null); + changeListeners.set(sender.page, filters); + } + + if (message.filter) + filters.subscription = message.filter; + else + delete filters.subscription; + break; + } + }); +})(this); diff --git a/data/extensions/spyblock@gnu.org/lib/notification.js b/data/extensions/spyblock@gnu.org/lib/notification.js index 06e949e..1fa8eed 100644 --- a/data/extensions/spyblock@gnu.org/lib/notification.js +++ b/data/extensions/spyblock@gnu.org/lib/notification.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -21,7 +21,6 @@ Cu.import("resource://gre/modules/Services.jsm"); -let {TimeLine} = require("timeline"); let {Prefs} = require("prefs"); let {Downloader, Downloadable, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); let {Utils} = require("utils"); @@ -81,8 +80,6 @@ let Notification = exports.Notification = */ init: function() { - TimeLine.enter("Entered Notification.init()"); - downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY, CHECK_INTERVAL); onShutdown.add(function() { @@ -92,8 +89,6 @@ let Notification = exports.Notification = downloader.onExpirationChange = this._onExpirationChange.bind(this); downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); downloader.onDownloadError = this._onDownloadError.bind(this); - - TimeLine.leave("Notification.init() done"); }, /** @@ -112,6 +107,8 @@ let Notification = exports.Notification = downloadable.softExpiration = Prefs.notificationdata.softExpiration; if (typeof Prefs.notificationdata.hardExpiration === "number") downloadable.hardExpiration = Prefs.notificationdata.hardExpiration; + if (typeof Prefs.notificationdata.downloadCount === "number") + downloadable.downloadCount = Prefs.notificationdata.downloadCount; yield downloadable; }, @@ -149,6 +146,7 @@ let Notification = exports.Notification = Prefs.notificationdata.lastError = 0; Prefs.notificationdata.downloadStatus = "synchronize_ok"; [Prefs.notificationdata.softExpiration, Prefs.notificationdata.hardExpiration] = downloader.processExpirationInterval(EXPIRATION_INTERVAL); + Prefs.notificationdata.downloadCount = downloadable.downloadCount; saveNotificationData(); }, diff --git a/data/extensions/spyblock@gnu.org/lib/objectTabs.js b/data/extensions/spyblock@gnu.org/lib/objectTabs.js index 7b1c1af..bcf4362 100644 --- a/data/extensions/spyblock@gnu.org/lib/objectTabs.js +++ b/data/extensions/spyblock@gnu.org/lib/objectTabs.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -226,8 +226,10 @@ var objTabs = /** * Makes the tab element visible. + * @param {Element} element + * @param {RequestEntry} data */ - _showTab: function(/**Element*/ element, /**RequestEntry*/ data) + _showTab: function(element, data) { let {UI} = require("ui"); if (!UI.overlay) @@ -420,8 +422,11 @@ var objTabs = /** * Called whenever a timer fires. + * @param {nsISupport} subject + * @param {string} topic + * @param {string} data */ - observe: function(/**nsISupport*/ subject, /**String*/ topic, /**String*/ data) + observe: function(subject, topic, data) { if (subject == this.positionTimer) { diff --git a/data/extensions/spyblock@gnu.org/lib/prefs.js b/data/extensions/spyblock@gnu.org/lib/prefs.js index e1b6ae0..ab1cc5c 100644 --- a/data/extensions/spyblock@gnu.org/lib/prefs.js +++ b/data/extensions/spyblock@gnu.org/lib/prefs.js @@ -1,19 +1,6 @@ -/* - * This file is part of the Adblock Plus build tools, - * Copyright (C) 2006-2014 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/>. - */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); diff --git a/data/extensions/spyblock@gnu.org/lib/requestNotifier.js b/data/extensions/spyblock@gnu.org/lib/requestNotifier.js index 2ee9ec3..8b9ca30 100644 --- a/data/extensions/spyblock@gnu.org/lib/requestNotifier.js +++ b/data/extensions/spyblock@gnu.org/lib/requestNotifier.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -27,6 +27,7 @@ let {BlockingFilter, WhitelistFilter, ElemHideBase, ElemHideFilter, ElemHideExce let nodeData = new WeakMap(); let windowStats = new WeakMap(); let windowSelection = new WeakMap(); +let requestEntryMaxId = 0; let setEntry, hasEntry, getEntry; // Last issue(Bug 982561) preventing us from using WeakMap fixed for FF version 32 @@ -134,8 +135,11 @@ RequestNotifier.prototype = /** * Notifies listener about a new request. + * @param {Window} wnd + * @param {Node} node + * @param {RequestEntry} entry */ - notifyListener: function(/**Window*/ wnd, /**Node*/ node, /**RequestEntry*/ entry) + notifyListener: function(wnd, node, entry) { this.listener.call(this.listenerObj, wnd, node, entry, this.scanComplete); }, @@ -244,16 +248,19 @@ RequestNotifier.getDataForNode = function(node, noParent, type, location) let data = getEntry(nodeData, node); if (typeof data != "undefined") { + let entry = null; // Look for matching entry for (let k in data) { - let entry = data[k]; - if ((typeof type == "undefined" || entry.type == type) && - (typeof location == "undefined" || entry.location == location)) + if ((!entry || entry.id < data[k].id) && + (typeof type == "undefined" || data[k].type == type) && + (typeof location == "undefined" || data[k].location == location)) { - return [node, entry]; + entry = data[k]; } } + if (entry) + return [node, entry]; } // If we don't have any match on this node then maybe its parent will do @@ -278,6 +285,7 @@ function RequestEntry(node, topWnd, contentType, docDomain, thirdParty, location this.thirdParty = thirdParty; this.location = location; this.filter = filter; + this.id = ++requestEntryMaxId; this.attachToNode(node); @@ -319,6 +327,11 @@ function RequestEntry(node, topWnd, contentType, docDomain, thirdParty, location RequestEntry.prototype = { /** + * id of request (used to determine last entry attached to a node) + * @type integer + */ + id: 0, + /** * Content type of the request (one of the nsIContentPolicy constants) * @type Integer */ diff --git a/data/extensions/spyblock@gnu.org/lib/subscriptionClasses.js b/data/extensions/spyblock@gnu.org/lib/subscriptionClasses.js index 13dceaf..6ba15f5 100644 --- a/data/extensions/spyblock@gnu.org/lib/subscriptionClasses.js +++ b/data/extensions/spyblock@gnu.org/lib/subscriptionClasses.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -122,7 +122,7 @@ Subscription.prototype = }, /** - * Serializes the filter to an array of strings for writing out on the disk. + * Serializes the subscription to an array of strings for writing out on the disk. * @param {Array of String} buffer buffer to push the serialization results into */ serialize: function(buffer) @@ -154,7 +154,7 @@ Subscription.prototype = * Cache for known filter subscriptions, maps URL to subscription objects. * @type Object */ -Subscription.knownSubscriptions = {__proto__: null}; +Subscription.knownSubscriptions = Object.create(null); /** * Returns a subscription from its URL, creates a new one if necessary. @@ -176,7 +176,7 @@ Subscription.fromURL = function(url) { return new SpecialSubscription(url); } -} +}; /** * Deserializes a subscription @@ -196,17 +196,17 @@ Subscription.fromObject = function(obj) if ("downloadStatus" in obj) result._downloadStatus = obj.downloadStatus; if ("lastSuccess" in obj) - result.lastSuccess = parseInt(obj.lastSuccess) || 0; + result.lastSuccess = parseInt(obj.lastSuccess, 10) || 0; if ("lastCheck" in obj) - result._lastCheck = parseInt(obj.lastCheck) || 0; + result._lastCheck = parseInt(obj.lastCheck, 10) || 0; if ("expires" in obj) - result.expires = parseInt(obj.expires) || 0; + result.expires = parseInt(obj.expires, 10) || 0; if ("softExpiration" in obj) - result.softExpiration = parseInt(obj.softExpiration) || 0; + result.softExpiration = parseInt(obj.softExpiration, 10) || 0; if ("errors" in obj) - result._errors = parseInt(obj.errors) || 0; + result._errors = parseInt(obj.errors, 10) || 0; if ("version" in obj) - result.version = parseInt(obj.version) || 0; + result.version = parseInt(obj.version, 10) || 0; if ("requiredVersion" in obj) { let {addonVersion} = require("info"); @@ -217,7 +217,9 @@ Subscription.fromObject = function(obj) if ("homepage" in obj) result._homepage = obj.homepage; if ("lastDownload" in obj) - result._lastDownload = parseInt(obj.lastDownload) || 0; + result._lastDownload = parseInt(obj.lastDownload, 10) || 0; + if ("downloadCount" in obj) + result.downloadCount = parseInt(obj.downloadCount, 10) || 0; } catch (e) { @@ -250,7 +252,7 @@ Subscription.fromObject = function(obj) result._disabled = (obj.disabled == "true"); return result; -} +}; /** * Class for special filter subscriptions (user's filters) @@ -329,7 +331,7 @@ SpecialSubscription.create = function(title) { url = "~user~" + Math.round(Math.random()*1000000); } while (url in Subscription.knownSubscriptions); - return new SpecialSubscription(url, title) + return new SpecialSubscription(url, title); }; /** @@ -425,7 +427,7 @@ RegularSubscription.prototype = }; /** - * Class for filter subscriptions updated by externally (by other extension) + * Class for filter subscriptions updated externally (by other extension) * @param {String} url see Subscription() * @param {String} [title] see Subscription() * @constructor @@ -451,7 +453,7 @@ ExternalSubscription.prototype = }; /** - * Class for filter subscriptions updated by externally (by other extension) + * Class for filter subscriptions updated externally (by other extension) * @param {String} url see Subscription() * @param {String} [title] see Subscription() * @constructor @@ -564,6 +566,12 @@ DownloadableSubscription.prototype = upgradeRequired: false, /** + * Number indicating how often the object was downloaded. + * @type Number + */ + downloadCount: 0, + + /** * Should be true if the Privatemode: header is set to true in the subscription * @type Boolean */ @@ -591,6 +599,8 @@ DownloadableSubscription.prototype = buffer.push("version=" + this.version); if (this.requiredVersion) buffer.push("requiredVersion=" + this.requiredVersion); + if (this.downloadCount) + buffer.push("downloadCount=" + this.downloadCount); if (this.privateMode) buffer.push("privateMode=" + this.privateMode); } diff --git a/data/extensions/spyblock@gnu.org/lib/sync.js b/data/extensions/spyblock@gnu.org/lib/sync.js index 05eeced..a250e81 100644 --- a/data/extensions/spyblock@gnu.org/lib/sync.js +++ b/data/extensions/spyblock@gnu.org/lib/sync.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -250,7 +250,7 @@ ABPStore.prototype = let data = record.cleartext.subscriptions; // First make sure we have the same subscriptions on both sides - let seenSubscription = {__proto__: null}; + let seenSubscription = Object.create(null); for (let remoteSubscription of data) { seenSubscription[remoteSubscription.url] = true; @@ -292,7 +292,7 @@ ABPStore.prototype = } // Now sync the custom filters - let seenFilter = {__proto__: null}; + let seenFilter = Object.create(null); for (let remoteSubscription of data) { if (!("filters" in remoteSubscription)) diff --git a/data/extensions/spyblock@gnu.org/lib/synchronizer.js b/data/extensions/spyblock@gnu.org/lib/synchronizer.js index b9f9e29..2304895 100644 --- a/data/extensions/spyblock@gnu.org/lib/synchronizer.js +++ b/data/extensions/spyblock@gnu.org/lib/synchronizer.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -22,7 +22,6 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); -let {TimeLine} = require("timeline"); let {Downloader, Downloadable, MILLIS_IN_SECOND, MILLIS_IN_MINUTE, MILLIS_IN_HOUR, MILLIS_IN_DAY} = require("downloader"); let {Filter, CommentFilter} = require("filterClasses"); @@ -54,8 +53,6 @@ let Synchronizer = exports.Synchronizer = */ init: function() { - TimeLine.enter("Entered Synchronizer.init()"); - downloader = new Downloader(this._getDownloadables.bind(this), INITIAL_DELAY, CHECK_INTERVAL); onShutdown.add(function() { @@ -66,8 +63,6 @@ let Synchronizer = exports.Synchronizer = downloader.onDownloadStarted = this._onDownloadStarted.bind(this); downloader.onDownloadSuccess = this._onDownloadSuccess.bind(this); downloader.onDownloadError = this._onDownloadError.bind(this); - - TimeLine.leave("Synchronizer.init() done"); }, /** @@ -118,6 +113,7 @@ let Synchronizer = exports.Synchronizer = result.softExpiration = subscription.softExpiration * MILLIS_IN_SECOND; result.hardExpiration = subscription.expires * MILLIS_IN_SECOND; result.manual = manual; + result.downloadCount = subscription.downloadCount; result.privateMode = subscription.privateMode; return result; }, @@ -202,6 +198,7 @@ let Synchronizer = exports.Synchronizer = // The download actually succeeded subscription.lastSuccess = subscription.lastDownload = Math.round(Date.now() / MILLIS_IN_SECOND); subscription.downloadStatus = "synchronize_ok"; + subscription.downloadCount = downloadable.downloadCount; subscription.errors = 0; // Remove lines containing parameters diff --git a/data/extensions/spyblock@gnu.org/lib/timeline.js b/data/extensions/spyblock@gnu.org/lib/timeline.js deleted file mode 100644 index 18c10fb..0000000 --- a/data/extensions/spyblock@gnu.org/lib/timeline.js +++ /dev/null @@ -1,155 +0,0 @@ -/* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH - * - * Adblock Plus is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - * - * Adblock Plus is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. - */ - -/** - * @fileOverview Debugging module used for load time measurements. - */ - -let nestingCounter = 0; -let firstTimeStamp = null; -let lastTimeStamp = null; - -let asyncActions = {__proto__: null}; - -/** - * Time logging module, used to measure startup time of Adblock Plus (development builds only). - * @class - */ -let TimeLine = exports.TimeLine = { - /** - * Logs an event to console together with the time it took to get there. - */ - log: function(/**String*/ message, /**Boolean*/ _forceDisplay) - { - if (!_forceDisplay && nestingCounter <= 0) - return; - - let now = Date.now(); - let diff = lastTimeStamp ? Math.round(now - lastTimeStamp) : "first event"; - lastTimeStamp = now; - - // Indent message depending on current nesting level - for (let i = 0; i < nestingCounter; i++) - message = "* " + message; - - // Pad message with spaces - let padding = []; - for (let i = message.toString().length; i < 80; i++) - padding.push(" "); - dump("[" + now + "] ABP timeline: " + message + padding.join("") + "\t (" + diff + ")\n"); - }, - - /** - * Called to indicate that application entered a block that needs to be timed. - */ - enter: function(/**String*/ message) - { - if (nestingCounter <= 0) - firstTimeStamp = Date.now(); - - this.log(message, true); - nestingCounter = (nestingCounter <= 0 ? 1 : nestingCounter + 1); - }, - - /** - * Called when application exited a block that TimeLine.enter() was called for. - * @param {String} message message to be logged - * @param {String} [asyncAction] identifier of a pending async action - */ - leave: function(message, asyncAction) - { - if (typeof asyncAction != "undefined") - message += " (async action pending)"; - - nestingCounter--; - this.log(message, true); - - if (nestingCounter <= 0) - { - if (firstTimeStamp !== null) - dump("ABP timeline: Total time elapsed: " + Math.round(Date.now() - firstTimeStamp) + "\n"); - firstTimeStamp = null; - lastTimeStamp = null; - } - - if (typeof asyncAction != "undefined") - { - if (asyncAction in asyncActions) - dump("ABP timeline: Warning: Async action " + asyncAction + " already executing\n"); - asyncActions[asyncAction] = {start: Date.now(), total: 0}; - } - }, - - /** - * Called when the application starts processing of an async action. - */ - asyncStart: function(/**String*/ asyncAction) - { - if (asyncAction in asyncActions) - { - let action = asyncActions[asyncAction]; - if ("currentStart" in action) - dump("ABP timeline: Warning: Processing reentered for async action " + asyncAction + "\n"); - action.currentStart = Date.now(); - } - else - dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); - }, - - /** - * Called when the application finishes processing of an async action. - */ - asyncEnd: function(/**String*/ asyncAction) - { - if (asyncAction in asyncActions) - { - let action = asyncActions[asyncAction]; - if ("currentStart" in action) - { - action.total += Date.now() - action.currentStart; - delete action.currentStart; - } - else - dump("ABP timeline: Warning: Processing not entered for async action " + asyncAction + "\n"); - } - else - dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); - }, - - /** - * Called when an async action is done and its time can be logged. - */ - asyncDone: function(/**String*/ asyncAction) - { - if (asyncAction in asyncActions) - { - let action = asyncActions[asyncAction]; - let now = Date.now(); - let diff = now - action.start; - if ("currentStart" in action) - dump("ABP timeline: Warning: Still processing for async action " + asyncAction + "\n"); - - let message = "Async action " + asyncAction + " done"; - let padding = []; - for (let i = message.toString().length; i < 80; i++) - padding.push(" "); - dump("[" + now + "] ABP timeline: " + message + padding.join("") + "\t (" + action.total + "/" + diff + ")\n"); - } - else - dump("ABP timeline: Warning: Async action " + asyncAction + " is unknown\n"); - } -}; diff --git a/data/extensions/spyblock@gnu.org/lib/ui.js b/data/extensions/spyblock@gnu.org/lib/ui.js index 668e356..2910337 100644 --- a/data/extensions/spyblock@gnu.org/lib/ui.js +++ b/data/extensions/spyblock@gnu.org/lib/ui.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -159,7 +159,8 @@ let optionsObserver = return; let currentSubscription = FilterStorage.subscriptions.filter((subscription) => subscription instanceof DownloadableSubscription && - subscription.url != Prefs.subscriptions_exceptionsurl); + subscription.url != Prefs.subscriptions_exceptionsurl && + subscription.url != Prefs.subscriptions_antiadblockurl); currentSubscription = (currentSubscription.length ? currentSubscription[0] : null); let subscriptions =request.responseXML.getElementsByTagName("subscription"); @@ -504,6 +505,11 @@ let UI = exports.UI = { Prefs.currentVersion = addonVersion; this.addSubscription(window, prevVersion); + + // The "Hide placeholders" option has been removed from the UI in 2.6.6.3881 + // So we reset the option for users updating from older versions. + if (prevVersion && Services.vc.compare(prevVersion, "2.6.6.3881") < 0) + Prefs.fastcollapse = false; } }, @@ -830,12 +836,12 @@ let UI = exports.UI = FilterStorage.addSubscription(subscription); Synchronizer.execute(subscription); - let subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/third-party.txt"); + subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/third-party.txt"); subscription.disabled = false; FilterStorage.addSubscription(subscription); Synchronizer.execute(subscription); - let subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/javascript.txt"); + subscription = Subscription.fromURL("http://gnuzilla.gnu.org/filters/javascript.txt"); subscription.disabled = true; FilterStorage.addSubscription(subscription); Synchronizer.execute(subscription); @@ -967,12 +973,12 @@ let UI = exports.UI = mainSubscriptionURL = null; // Trim spaces in title and URL - title = title.replace(/^\s+/, "").replace(/\s+$/, ""); - url = url.replace(/^\s+/, "").replace(/\s+$/, ""); + title = title.trim(); + url = url.trim(); if (mainSubscriptionURL) { - mainSubscriptionTitle = mainSubscriptionTitle.replace(/^\s+/, "").replace(/\s+$/, ""); - mainSubscriptionURL = mainSubscriptionURL.replace(/^\s+/, "").replace(/\s+$/, ""); + mainSubscriptionTitle = mainSubscriptionTitle.trim(); + mainSubscriptionURL = mainSubscriptionURL.trim(); } // Verify that the URL is valid @@ -1548,7 +1554,6 @@ let UI = exports.UI = setChecked(prefix + "disabled", !Prefs.enabled); setChecked(prefix + "frameobjects", Prefs.frameobjects); - setChecked(prefix + "slowcollapse", !Prefs.fastcollapse); setChecked(prefix + "savestats", Prefs.savestats); let {defaultToolbarPosition, statusbarPosition} = require("appSupport"); @@ -1903,8 +1908,10 @@ let UI = exports.UI = let messageElement = window.document.getElementById("abp-notification-message"); messageElement.innerHTML = ""; let docLinks = []; - for (let link of notification.links) - docLinks.push(Utils.getDocLink(link)); + if (notification.links) + for (let link of notification.links) + docLinks.push(Utils.getDocLink(link)); + insertMessage(messageElement, texts.message, docLinks); messageElement.addEventListener("click", function(event) @@ -1955,7 +1962,6 @@ let eventHandlers = [ ["abp-command-togglesitewhitelist", "command", function() { UI.toggleFilter(siteWhitelist); }], ["abp-command-togglepagewhitelist", "command", function() { UI.toggleFilter(pageWhitelist); }], ["abp-command-toggleobjtabs", "command", UI.togglePref.bind(UI, "frameobjects")], - ["abp-command-togglecollapse", "command", UI.togglePref.bind(UI, "fastcollapse")], ["abp-command-togglesavestats", "command", UI.toggleSaveStats.bind(UI)], ["abp-command-togglesync", "command", UI.toggleSync.bind(UI)], ["abp-command-toggleshowintoolbar", "command", UI.toggleToolbarIcon.bind(UI)], diff --git a/data/extensions/spyblock@gnu.org/lib/utils.js b/data/extensions/spyblock@gnu.org/lib/utils.js index a18cebe..13f4876 100644 --- a/data/extensions/spyblock@gnu.org/lib/utils.js +++ b/data/extensions/spyblock@gnu.org/lib/utils.js @@ -1,6 +1,6 @@ /* - * This file is part of Adblock Plus <http://adblockplus.org/>, - * Copyright (C) 2006-2014 Eyeo GmbH + * 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 @@ -73,8 +73,8 @@ let Utils = exports.Utils = { Cu.reportError(e); } - Utils.__defineGetter__("appLocale", () => locale); - return Utils.appLocale; + Object.defineProperty(this, "appLocale", {value: locale}); + return locale; }, /** @@ -83,8 +83,8 @@ let Utils = exports.Utils = get platformVersion() { let platformVersion = Services.appinfo.platformVersion; - Utils.__defineGetter__("platformVersion", () => platformVersion); - return Utils.platformVersion; + Object.defineProperty(this, "platformVersion", {value: platformVersion}); + return platformVersion; }, /** @@ -215,8 +215,10 @@ let Utils = exports.Utils = * Posts an action to the event queue of the current thread to run it * asynchronously. Any additional parameters to this function are passed * as parameters to the callback. + * @param {function} callback + * @param {object} thisPtr */ - runAsync: function(/**Function*/ callback, /**Object*/ thisPtr) + runAsync: function(callback, thisPtr) { let params = Array.prototype.slice.call(arguments, 2); let runnable = { @@ -400,8 +402,12 @@ let Utils = exports.Utils = /** * Verifies RSA signature. The public key and signature should be base64-encoded. + * @param {string} key + * @param {string} signature + * @param {string} data + * @return {boolean} */ - verifySignature: function(/**String*/ key, /**String*/ signature, /**String*/ data) /**Boolean*/ + verifySignature: function(key, signature, data) { if (!Utils.crypto) return false; @@ -539,7 +545,7 @@ let Utils = exports.Utils = function Cache(/**Integer*/ size) { this._ringBuffer = new Array(size); - this.data = {__proto__: null}; + this.data = Object.create(null); } exports.Cache = Cache; @@ -593,7 +599,7 @@ Cache.prototype = clear: function() { this._ringBuffer = new Array(this._ringBuffer.length); - this.data = {__proto__: null}; + this.data = Object.create(null); } } @@ -631,7 +637,12 @@ XPCOMUtils.defineLazyGetter(Utils, "crypto", function() catch (e) { // It seems that on Mac OS X the full path name needs to be specified - let file = Services.dirsvc.get("GreD", Ci.nsILocalFile); + let file; + // Gecko 35 added GreBinD key, see https://bugzilla.mozilla.org/show_bug.cgi?id=1077099 + if (Services.dirsvc.has("GreBinD")) + file = Services.dirsvc.get("GreBinD", Ci.nsILocalFile); + else + file = Services.dirsvc.get("GreD", Ci.nsILocalFile); file.append(ctypes.libraryName("nss3")); nsslib = ctypes.open(file.path); } diff --git a/data/extensions/spyblock@gnu.org/lib/windowObserver.js b/data/extensions/spyblock@gnu.org/lib/windowObserver.js index eb0b13a..7d34f8a 100644 --- a/data/extensions/spyblock@gnu.org/lib/windowObserver.js +++ b/data/extensions/spyblock@gnu.org/lib/windowObserver.js @@ -1,19 +1,6 @@ -/* - * This file is part of the Adblock Plus build tools, - * Copyright (C) 2006-2014 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/>. - */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -48,7 +35,7 @@ function WindowObserver(listener, when) if (windows.indexOf(element) < 0) windows.push(element); } - + for (let i = 0; i < windows.length; i++) { let window = windows[i].QueryInterface(Ci.nsIDOMWindow); |