| Index: lib/elemHide.js |
| =================================================================== |
| --- a/lib/elemHide.js |
| +++ b/lib/elemHide.js |
| @@ -19,16 +19,17 @@ |
| * @fileOverview Element hiding implementation. |
| */ |
| Cu.import("resource://gre/modules/Services.jsm"); |
| let {Utils} = require("utils"); |
| let {IO} = require("io"); |
| let {Prefs} = require("prefs"); |
| +let {Policy} = require("contentPolicy"); |
| 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 |
| @@ -61,64 +62,74 @@ let styleURL = null; |
| /** |
| * Element hiding component |
| * @class |
| */ |
| let ElemHide = exports.ElemHide = |
| { |
| /** |
| - * Indicates whether filters have been added or removed since the last apply() call. |
| + * Indicates whether filters have been added or removed since the last saveStylesheet() call. |
| * @type Boolean |
| */ |
| isDirty: false, |
| - /** |
| - * Inidicates whether the element hiding stylesheet is currently applied. |
| - * @type Boolean |
| - */ |
| - applied: false, |
| + QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), |
| /** |
| * Called on module startup. |
| */ |
| init: function() |
| { |
| TimeLine.enter("Entered ElemHide.init()"); |
| - Prefs.addListener(function(name) |
| - { |
| - if (name == "enabled") |
| - ElemHide.apply(); |
| - }); |
| + |
| onShutdown.add(function() |
| { |
| - ElemHide.unapply(); |
| - }); |
| + Services.obs.removeObserver(this, "content-document-global-created"); |
| + }.bind(this)); |
| 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"); |
| + Services.obs.addObserver(this, "content-document-global-created", true); |
| + |
| TimeLine.leave("ElemHide.init() done"); |
| }, |
| /** |
| * Removes all known filters |
| */ |
| clear: function() |
| { |
| filterByKey = {__proto__: null}; |
| keyByFilter = {__proto__: null}; |
| knownExceptions = {__proto__: null}; |
| exceptions = {__proto__: null}; |
| ElemHide.isDirty = false; |
| - ElemHide.unapply(); |
| + }, |
| + |
| + observe: function (subject, topic, data, additional) |
| + { |
| + if (topic != "content-document-global-created") |
| + return; |
| + |
| + if (!Prefs.enabled) |
| + return; |
| + |
| + let process = Policy.processWindow(subject, Policy.type.ELEMHIDE); |
| + dump(subject.document.documentURIObject.spec + " is okay " + process + "\n"); |
| + if (process) |
| + return; |
| + |
| + var windowUtils = subject.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils); |
| + windowUtils.loadSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| }, |
| /** |
| * Add a new element hiding filter |
| * @param {ElemHideFilter} filter |
| */ |
| add: function(filter) |
| { |
| @@ -191,119 +202,102 @@ let ElemHide = exports.ElemHide = |
| let list = exceptions[filter.selector]; |
| for (let i = list.length - 1; i >= 0; i--) |
| if (list[i].isActiveOnDomain(docDomain)) |
| return list[i]; |
| return null; |
| }, |
| + shouldAllowLoad: function(wnd, filter) |
| + { |
| + let uri = wnd.document.documentURIObject; |
| + if (!uri) |
| + return true; |
| + |
| + let domain = uri.host; |
| + if (!filter.isActiveOnDomain(domain)) |
| + return true; |
| + |
| + let exception = ElemHide.getException(filter, domain); |
| + if (exception) |
| + { |
| + // FilterStorage.increaseHitCount(exception, wnd); |
| + // RequestNotifier.addNodeData(node, topWnd, contentType, domain, thirdParty, locationText, exception); |
| + return true; |
| + } |
| + |
| + // RequestNotifier.addNodeData(node, topWnd, contentType, domain, thirdParty, locationText, match); |
| + // if (match) |
| + // FilterStorage.increaseHitCount(match, wnd); |
| + return false; |
| + }, |
| + |
| /** |
| - * Will be set to true if apply() is running (reentrance protection). |
| + * Will be set to true if saveStylesheet() is running (reentrance protection). |
| * @type Boolean |
| */ |
| _applying: false, |
| /** |
| - * Will be set to true if an apply() call arrives while apply() is already |
| - * running (delayed execution). |
| + * Will be set to true if an saveStylesheet() call arrives while saveStylesheet() |
| + * is already running (delayed execution). |
| * @type Boolean |
| */ |
| _needsApply: false, |
| /** |
| - * Generates stylesheet URL and applies it globally |
| + * Generates stylesheet URL. |
| */ |
| - apply: function() |
| + saveStylesheet: function() |
| { |
| if (this._applying) |
| { |
| this._needsApply = true; |
| return; |
| } |
| - TimeLine.enter("Entered ElemHide.apply()"); |
| - |
| - 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); |
| - ElemHide.applied = true; |
| - } |
| - catch (e) |
| - { |
| - 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; |
| - } |
| + TimeLine.enter("Entered ElemHide.saveStylesheet()"); |
| IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e) |
| { |
| - TimeLine.enter("ElemHide.apply() write callback"); |
| + TimeLine.enter("ElemHide.saveStylesheet() write callback"); |
| this._applying = false; |
| // _generateCSSContent is throwing NS_ERROR_NOT_AVAILABLE to indicate that |
| // there are no filters. If that exception is passed through XPCOM we will |
| // see a proper exception here, otherwise a number. |
| let noFilters = (e == Cr.NS_ERROR_NOT_AVAILABLE || (e && e.result == Cr.NS_ERROR_NOT_AVAILABLE)); |
| if (noFilters) |
| { |
| e = null; |
| IO.removeFile(styleURL.file, function(e) {}); |
| } |
| else if (e) |
| + { |
| Cu.reportError(e); |
| + } |
| if (this._needsApply) |
| { |
| this._needsApply = false; |
| - this.apply(); |
| + this.saveStylesheet(); |
| } |
| else if (!e) |
| { |
| ElemHide.isDirty = false; |
| - ElemHide.unapply(); |
| - TimeLine.log("ElemHide.unapply() finished"); |
| - |
| - if (!noFilters) |
| - { |
| - try |
| - { |
| - Utils.styleService.loadAndRegisterSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| - ElemHide.applied = true; |
| - } |
| - catch (e) |
| - { |
| - Cu.reportError(e); |
| - } |
| - TimeLine.log("Applying stylesheet finished"); |
| - } |
| - |
| FilterNotifier.triggerListeners("elemhideupdate"); |
| } |
| - TimeLine.leave("ElemHide.apply() write callback done"); |
| + TimeLine.leave("ElemHide.saveStylesheet() write callback done"); |
| }.bind(this), "ElemHideWrite"); |
| this._applying = true; |
| - TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); |
| + TimeLine.leave("ElemHide.saveStylesheet() done", "ElemHideWrite"); |
| }, |
| _generateCSSContent: function() |
| { |
| // Grouping selectors by domains |
| TimeLine.log("start grouping selectors"); |
| let domains = {__proto__: null}; |
| let hasFilters = false; |
| @@ -352,44 +346,16 @@ let ElemHide = exports.ElemHide = |
| for (let selector in list) |
| yield selector.replace(/[^\x01-\x7F]/g, escapeChar) + "{" + cssTemplate.replace("%ID%", list[selector]) + "}"; |
| yield '}'; |
| } |
| }, |
| /** |
| - * Unapplies current stylesheet URL |
| - */ |
| - unapply: function() |
| - { |
| - if (ElemHide.applied) |
| - { |
| - try |
| - { |
| - 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); |
| }, |
| /** |