Index: lib/elemHide.js |
=================================================================== |
--- a/lib/elemHide.js |
+++ b/lib/elemHide.js |
@@ -59,6 +59,18 @@ |
let styleURL = null; |
/** |
+ * Lookup table, blocking filter selectors by domain which they are applied to |
Wladimir Palant
2015/06/23 13:57:09
Nit: the word "blocking" makes no sense here.
Thomas Greiner
2015/07/02 09:32:49
Done.
|
+ * @type Object |
+ */ |
+let selectorsByDomain = Object.create(null); |
+ |
+/** |
+ * Indicates whether stylesheets can be used for element hiding |
+ * @type Boolean |
+ */ |
+let canUseStylesheets = ("nsIStyleSheetService" in Ci); |
+ |
+/** |
* Element hiding component |
* @class |
*/ |
@@ -105,6 +117,7 @@ |
keyByFilter = Object.create(null); |
knownExceptions = Object.create(null); |
exceptions = Object.create(null); |
+ selectorsByDomain = Object.create(null); |
ElemHide.isDirty = false; |
ElemHide.unapply(); |
}, |
@@ -131,6 +144,38 @@ |
if (filter.text in keyByFilter) |
return; |
+ if (!canUseStylesheets) |
+ { |
+ let domains = filter.domains; |
+ if (domains === null) |
+ { |
+ domains = Object.create(null); |
+ domains[""] = true; |
+ } |
+ |
+ for (let domain in domains) |
+ { |
+ if (!(domain in selectorsByDomain)) |
+ { |
+ selectorsByDomain[domain] = Object.create(null); |
+ selectorsByDomain[domain].$length = 0; |
+ } |
+ |
+ let selectors = selectorsByDomain[domain]; |
+ if (!(filter.selector in selectors)) |
+ { |
+ selectors[filter.selector] = { |
+ isActive: false, |
+ count: 0 |
+ }; |
+ } |
+ selectors[filter.selector].isActive |= domains[domain]; |
Thomas Greiner
2015/06/23 13:28:41
I made this change here because I noticed that thi
Wladimir Palant
2015/06/23 13:57:09
Unfortunately, the result still isn't correct. Con
Thomas Greiner
2015/06/23 15:11:41
I see your point and please correct me if I'm wron
Wladimir Palant
2015/06/29 09:09:09
The problem is: you would create a behavior here t
Thomas Greiner
2015/06/29 13:03:44
Generally, I might be able to solve this by splitt
Thomas Greiner
2015/07/02 09:32:49
Done. See comment below for further details.
|
+ selectors[filter.selector].count++; |
+ |
+ selectors.$length++; |
+ } |
+ } |
+ |
let key; |
do { |
key = Math.random().toFixed(15).substr(5); |
@@ -164,6 +209,28 @@ |
if (!(filter.text in keyByFilter)) |
return; |
+ if (!canUseStylesheets) |
+ { |
+ let domains = filter.domains; |
+ if (!domains) |
+ { |
+ domains = Object.create(null); |
+ domains[""] = true; |
+ } |
+ |
+ for (let domain in domains) |
+ { |
+ if (domain in selectorsByDomain |
+ && filter.selector in selectorsByDomain[domain] |
+ && !--selectorsByDomain[domain][filter.selector].$length) |
+ { |
+ delete selectorsByDomain[domain][filter.selector]; |
+ if (!--selectorsByDomain[domain].$length) |
+ delete selectorsByDomain[domain]; |
+ } |
+ } |
+ } |
+ |
let key = keyByFilter[filter.text]; |
delete filterByKey[key]; |
delete keyByFilter[filter.text]; |
@@ -175,12 +242,12 @@ |
* Checks whether an exception rule is registered for a filter on a particular |
* domain. |
*/ |
- getException: function(/**Filter*/ filter, /**String*/ docDomain) /**ElemHideException*/ |
+ getException: function(/**String*/ selector, /**String*/ docDomain) /**ElemHideException*/ |
{ |
- if (!(filter.selector in exceptions)) |
+ if (!(selector in exceptions)) |
return null; |
- let list = exceptions[filter.selector]; |
+ let list = exceptions[selector]; |
for (let i = list.length - 1; i >= 0; i--) |
if (list[i].isActiveOnDomain(docDomain)) |
return list[i]; |
@@ -372,22 +439,49 @@ |
}, |
/** |
- * Returns a list of all selectors active on a particular domain (currently |
- * used only in Chrome, Opera and Safari). |
+ * Returns a list of all selectors active on a particular domain (it cannot |
+ * be used in Firefox). |
*/ |
- getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly) |
+ getSelectorsForDomain: function(/**String*/ docDomain, /**Boolean*/ specificOnly) |
{ |
- let result = []; |
- let keys = Object.getOwnPropertyNames(filterByKey); |
- for (let key of keys) |
+ if (canUseStylesheets) |
+ throw new Error("Use of getSelectorsForDomain is limited to platforms which cannot inject stylesheets"); |
+ |
+ let selectors = []; |
+ let domain = docDomain.toUpperCase(); |
+ |
+ let ignoredSelectors = Object.create(null); |
+ while (true) |
{ |
- let filter = filterByKey[key]; |
- if (specificOnly && (!filter.domains || filter.domains[""])) |
- continue; |
+ if (domain in selectorsByDomain && (domain != "" || !specificOnly)) |
+ { |
+ let domainSelectors = selectorsByDomain[domain]; |
+ let filterSelectors = Object.getOwnPropertyNames(domainSelectors); |
+ for (let filterSelector of filterSelectors) |
+ { |
+ if (filterSelector == "$length" || filterSelector in ignoredSelectors) |
+ continue; |
- if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain)) |
- result.push(filter.selector); |
+ if (domainSelectors[filterSelector].isActive) |
+ { |
+ if (!this.getException(filterSelector, docDomain)) |
+ { |
+ selectors.push(filterSelector); |
+ ignoredSelectors[filterSelector] = null; |
+ } |
+ } |
+ else |
+ ignoredSelectors[filterSelector] = null; |
Thomas Greiner
2015/07/02 09:32:49
Basically, all I did was remove the else-case here
|
+ } |
+ } |
+ |
+ if (domain == "") |
+ break; |
+ |
+ let nextDot = domain.indexOf("."); |
+ domain = (nextDot < 0) ? "" : domain.substr(nextDot + 1); |
} |
- return result; |
+ |
+ return selectors; |
} |
}; |