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; |
} |