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