| Index: lib/elemHide.js |
| =================================================================== |
| --- a/lib/elemHide.js |
| +++ b/lib/elemHide.js |
| @@ -61,16 +61,19 @@ let exceptions = Object.create(null); |
| let styleURL = null; |
| /** |
| * Global stylesheet that should be loaded into content windows. |
| * @type nsIStyleSheet |
| */ |
| let styleSheet = null; |
| +// fixme |
| +let filterByDomain = Object.create(null); |
| + |
| /** |
| * Use new way of injecting styles per Window that exists since Firefox 33. |
| * @type boolean |
| */ |
| let useNew = ('preloadSheet' in Utils.styleService); |
| /** |
| * Element hiding component |
| @@ -136,16 +139,53 @@ let ElemHide = exports.ElemHide = |
| return; |
| if (!Prefs.enabled) |
| return; |
| if (Policy.shouldNeverBlockWindow(subject)) |
| return; |
| + dump(subject.document.documentURIObject.spec + "\n"); |
| + let domain = subject.document.documentURIObject.host; |
| + if (domain.startsWith("www.")) |
| + domain = domain.substring(4); |
| + |
| + dump("domain: " + domain + "\n"); // xxx is elemhide port or subdomain insesitive? |
| + |
| + let list = Object.create(null); |
| + for (let filter of filterByDomain[domain]) |
| + { |
| + dump("filter: " + filter.text + "\n") |
| + dump("key: " + keyByFilter[filter.text] + "\n") |
| + list[keyByFilter[filter.text]] = filter; |
| + } |
| + |
| + if (filterByDomain[domain]) { |
| + // XXX seems to stupid to use a file for this. |
| + // Somehow get this to use a data url or similar |
| + let styleFile = IO.resolveFilePath(Prefs.data_directory); |
| + styleFile.append(domain + ".css"); |
| + styleURL = Services.io.newFileURI(styleFile).QueryInterface(Ci.nsIFileURL); |
| + |
| + IO.writeToFile(styleURL.file, this._generateCSSContent(list, false), function(e) |
| + { |
| + try |
| + { |
| + let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor) |
| + .getInterface(Ci.nsIDOMWindowUtils); |
| + utils.loadSheet(styleURL, Ci.nsIStyleSheetService.USER_SHEET); |
| + } |
| + catch (e) |
| + { |
| + Cu.reportError(e); |
| + } |
| + }); |
| + } |
| + |
| try |
| { |
| let utils = subject.QueryInterface(Ci.nsIInterfaceRequestor) |
| .getInterface(Ci.nsIDOMWindowUtils); |
| utils.addSheet(styleSheet, Ci.nsIStyleSheetService.USER_SHEET); |
| } |
| catch (e) |
| { |
| @@ -157,16 +197,17 @@ let ElemHide = exports.ElemHide = |
| * Removes all known filters |
| */ |
| clear: function() |
| { |
| filterByKey = Object.create(null); |
| keyByFilter = Object.create(null); |
| knownExceptions = Object.create(null); |
| exceptions = Object.create(null); |
| + filterByDomain = Object.create(null); |
| ElemHide.isDirty = false; |
| ElemHide.unapply(); |
| }, |
| /** |
| * Add a new element hiding filter |
| * @param {ElemHideFilter} filter |
| */ |
| @@ -183,16 +224,30 @@ let ElemHide = exports.ElemHide = |
| exceptions[selector].push(filter); |
| knownExceptions[filter.text] = true; |
| } |
| else |
| { |
| if (filter.text in keyByFilter) |
| return; |
| + if (filter.selectorDomain && useNew) |
| + { |
| + let domains = filter.selectorDomain.split(","); |
| + |
| + for (let domain of domains) |
| + { |
| + dump(domain + "\n"); |
| + if (filterByDomain[domain]) |
| + filterByDomain[domain].push(filter); |
| + else |
| + filterByDomain[domain] = [filter]; |
| + } |
| + } |
| + |
| let key; |
| do { |
| key = Math.random().toFixed(15).substr(5); |
| } while (key in filterByKey); |
| filterByKey[key] = filter; |
| keyByFilter[filter.text] = key; |
| ElemHide.isDirty = true; |
| @@ -216,24 +271,33 @@ let ElemHide = exports.ElemHide = |
| list.splice(index, 1); |
| delete knownExceptions[filter.text]; |
| } |
| else |
| { |
| if (!(filter.text in keyByFilter)) |
| return; |
| + // if (filter.selectorDomain && useNew) |
| + // { |
| + // let filters = filterByDomain[filter.selectorDomain]; |
| + // if (Array.isArray(filters)) |
| + // filters.splice(filters.indexOf(filter), 1); |
| + // else |
| + // delete filterByDomain[filter.selectorDomain]; |
| + // } |
| + |
| let key = keyByFilter[filter.text]; |
| delete filterByKey[key]; |
| delete keyByFilter[filter.text]; |
| ElemHide.isDirty = true; |
| } |
| }, |
| - /** |
| + /** |
| * Checks whether an exception rule is registered for a filter on a particular |
| * domain. |
| */ |
| getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideException*/ |
| { |
| let selector = filter.selector; |
| if (!(filter.selector in exceptions)) |
| return null; |
| @@ -294,17 +358,17 @@ let ElemHide = exports.ElemHide = |
| ElemHide.unapply(); |
| TimeLine.log("ElemHide.unapply() finished"); |
| } |
| TimeLine.leave("ElemHide.apply() done (no file changes)"); |
| return; |
| } |
| - IO.writeToFile(styleURL.file, this._generateCSSContent(), function(e) |
| + IO.writeToFile(styleURL.file, this._generateCSSContent(filterByKey, useNew), function(e) |
| { |
| TimeLine.enter("ElemHide.apply() 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)); |
| @@ -351,27 +415,30 @@ let ElemHide = exports.ElemHide = |
| TimeLine.leave("ElemHide.apply() write callback done"); |
| }.bind(this), "ElemHideWrite"); |
| this._applying = true; |
| TimeLine.leave("ElemHide.apply() done", "ElemHideWrite"); |
| }, |
| - _generateCSSContent: function() |
| + _generateCSSContent: function(filters, onlyGlobal) |
| { |
| // Grouping selectors by domains |
| TimeLine.log("start grouping selectors"); |
| let domains = Object.create(null); |
| let hasFilters = false; |
| - for (let key in filterByKey) |
| + for (let key in filters) |
| { |
| - let filter = filterByKey[key]; |
| + let filter = filters[key]; |
| let domain = filter.selectorDomain || ""; |
| + if (onlyGlobal && domain) |
| + continue; |
| + |
| let list; |
| if (domain in domains) |
| list = domains[domain]; |
| else |
| { |
| list = Object.create(null); |
| domains[domain] = list; |
| } |