Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/elemHide.js

Issue 4529242486341632: Issue 235 - Improved performance of ElemHide.getSelectorsForDomain() (Closed)
Patch Set: Couple of overall improvements Created June 23, 2015, 1:02 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/contentPolicy.js ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
};
« no previous file with comments | « lib/contentPolicy.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld