| Index: lib/elemHide.js |
| =================================================================== |
| --- a/lib/elemHide.js |
| +++ b/lib/elemHide.js |
| @@ -23,16 +23,17 @@ Cu.import("resource://gre/modules/Servic |
| let {Utils} = require("utils"); |
| let {IO} = require("io"); |
| let {Prefs} = require("prefs"); |
| let {ElemHideException} = require("filterClasses"); |
| let {FilterNotifier} = require("filterNotifier"); |
| let {AboutHandler} = require("elemHideHitRegistration"); |
| let {TimeLine} = require("timeline"); |
| +let Policy = null; |
| /** |
| * Lookup table, filters by their associated key |
| * @type Object |
| */ |
| let filterByKey = Object.create(null); |
| /** |
| @@ -55,21 +56,35 @@ let exceptions = Object.create(null); |
| /** |
| * Currently applied stylesheet URL |
| * @type nsIURI |
| */ |
| let styleURL = null; |
| /** |
| + * Global stylesheet that should be loaded into content windows. |
| + * @type nsIStyleSheet |
| + */ |
| +let styleSheet = null; |
| + |
| +/** |
| + * Use the new way of injecting styles per window that exists since Firefox 33. |
| + * @type boolean |
| + */ |
| +let useNew = ('preloadSheet' in Utils.styleService); |
| + |
| +/** |
| * Element hiding component |
| * @class |
| */ |
| let ElemHide = exports.ElemHide = |
| { |
| + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), |
| + |
| /** |
| * Indicates whether filters have been added or removed since the last apply() call. |
| * @type Boolean |
| */ |
| isDirty: false, |
| /** |
| * Inidicates whether the element hiding stylesheet is currently applied. |
| @@ -78,36 +93,74 @@ let ElemHide = exports.ElemHide = |
| applied: false, |
| /** |
| * Called on module startup. |
| */ |
| init: function() |
| { |
| TimeLine.enter("Entered ElemHide.init()"); |
| + |
| + if (useNew) { |
| + // Avoid dependency issue. |
| + Policy = require("contentPolicy").Policy; |
| + } |
| + |
| Prefs.addListener(function(name) |
| { |
| if (name == "enabled") |
| ElemHide.apply(); |
| }); |
| - onShutdown.add(function() |
| + |
| + if (useNew) |
| + Services.obs.addObserver(this, "content-document-global-created", true); |
| + |
| + onShutdown.add(() => |
| { |
| ElemHide.unapply(); |
| + if (useNew) |
| + Services.obs.removeObserver(this, "content-document-global-created"); |
| }); |
| 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"); |
| }, |
| + observe: function (subject, topic, data, additional) |
| + { |
| + if (topic != "content-document-global-created") |
| + return; |
| + |
| + if (!Prefs.enabled) |
| + return; |
| + |
| + if (Policy.shouldNeverBlockWindow(subject)) |
| + return; |
| + |
| + if (styleSheet) |
| + { |
| + try |
| + { |
| + let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor) |
| + .getInterface(Ci.nsIDOMWindowUtils); |
| + utils.addSheet(styleSheet, Ci.nsIStyleSheetService.USER_SHEET); |
| + } |
| + catch (e) |
| + { |
| + Cu.reportError(e); |
| + } |
| + } |
| + }, |
| + |
| /** |
| * Removes all known filters |
| */ |
| clear: function() |
| { |
| filterByKey = Object.create(null); |
| keyByFilter = Object.create(null); |
| knownExceptions = Object.create(null); |
| @@ -224,17 +277,18 @@ let ElemHide = exports.ElemHide = |
| if (!ElemHide.isDirty || !Prefs.enabled) |
| { |
| // Nothing changed, looks like we merely got enabled/disabled |
| if (Prefs.enabled && !ElemHide.applied) |
| { |
| try |
| { |
| - Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| + if (!useNew) |
| + Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| ElemHide.applied = true; |
| } |
| catch (e) |
| { |
| Cu.reportError(e); |
| } |
| TimeLine.log("Applying existing stylesheet finished"); |
| } |
| @@ -276,17 +330,20 @@ let ElemHide = exports.ElemHide = |
| ElemHide.unapply(); |
| TimeLine.log("ElemHide.unapply() finished"); |
| if (!noFilters) |
| { |
| try |
| { |
| - Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| + if (!useNew) |
| + Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| + else |
| + styleSheet = Utils.styleService.preloadSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| ElemHide.applied = true; |
| } |
| catch (e) |
| { |
| Cu.reportError(e); |
| } |
| TimeLine.log("Applying stylesheet finished"); |
| } |
| @@ -360,36 +417,28 @@ let ElemHide = exports.ElemHide = |
| * Unapplies current stylesheet URL |
| */ |
| unapply: function() |
| { |
| if (ElemHide.applied) |
| { |
| try |
| { |
| - Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| + if (!useNew) |
| + Utils.styleService.unregisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| } |
| catch (e) |
| { |
| Cu.reportError(e); |
| } |
| ElemHide.applied = false; |
| } |
| }, |
| /** |
| - * Retrieves the currently applied stylesheet URL |
| - * @type String |
| - */ |
| - get styleURL() |
| - { |
| - return ElemHide.applied ? styleURL.spec : null; |
| - }, |
| - |
| - /** |
| * Retrieves an element hiding filter by the corresponding protocol key |
| */ |
| getFilterByKey: function(/**String*/ key) /**Filter*/ |
| { |
| return (key in filterByKey ? filterByKey[key] : null); |
| }, |
| /** |