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: Fixed domain logic and addressed comments Created March 12, 2015, 3:57 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 | « no previous file | 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 filters by domain which they are applied to
+ * @type Object
+ */
+let filtersByDomain = 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);
+ filtersByDomain = Object.create(null);
ElemHide.isDirty = false;
ElemHide.unapply();
},
@@ -131,6 +144,28 @@
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 filtersByDomain))
+ {
+ filtersByDomain[domain] = Object.create(null);
+ filtersByDomain[domain].$length = 0;
+ }
+
+ filtersByDomain[domain][filter.text] = domains[domain];
+ filtersByDomain[domain].$length++;
+ }
+ }
+
let key;
do {
key = Math.random().toFixed(15).substr(5);
@@ -164,6 +199,26 @@
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 filtersByDomain && filter.text in filtersByDomain[domain])
+ {
+ delete filtersByDomain[domain][filter.text];
+ if (!--filtersByDomain[domain].$length)
+ delete filtersByDomain[domain];
+ }
+ }
+ }
+
let key = keyByFilter[filter.text];
delete filterByKey[key];
delete keyByFilter[filter.text];
@@ -372,21 +427,65 @@
},
/**
- * 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)
{
- let result = [];
- for (let key in filterByKey)
+ if (canUseStylesheets)
+ throw new Error("Use of getSelectorsForDomain is limited to platforms which cannot inject stylesheets");
+
+ let selectors = [];
+ domain = domain.toUpperCase();
+
+ if (!specificOnly)
{
- let filter = filterByKey[key];
- if (specificOnly && (!filter.domains || filter.domains[""]))
- continue;
+ let filterTexts = filtersByDomain[""];
+ if (filterTexts)
+ {
+ for (let filterText in filterTexts)
+ {
+ if (filterTexts[filterText] && filterText != "$length")
+ {
+ let filter = Filter.fromText(filterText);
+ if (!this.getException(filter, domain))
+ selectors[selectors.length] = filter.selector;
+ }
+ }
+ }
+ }
Wladimir Palant 2015/06/05 21:58:54 This block duplicates the logic below unnecessaril
Thomas Greiner 2015/06/23 13:28:40 Done.
- if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
- result.push(filter.selector);
+ let ignorableFilters = [];
Wladimir Palant 2015/06/05 21:58:54 Use an object here rather than an array, given tha
Thomas Greiner 2015/06/23 13:28:40 Done.
+ while (true)
+ {
+ if (domain && domain in filtersByDomain)
+ {
+ let filterTexts = filtersByDomain[domain];
+ for (let filterText in filterTexts)
+ {
+ if (ignorableFilters.indexOf(filterText) > -1)
Wladimir Palant 2015/06/05 21:58:54 How about checking for $length immediately? if (f
Thomas Greiner 2015/06/23 13:28:40 Done.
+ continue;
+
+ if (filterTexts[filterText])
+ {
+ if (filterText == "$length")
+ continue;
+
+ let filter = Filter.fromText(filterText);
+ if (!this.getException(filter, domain))
Wladimir Palant 2015/06/05 21:58:54 Calling Filter.fromText() here looks like unnecess
Thomas Greiner 2015/06/23 13:28:40 Done. That's an awesome tip, thanks! Note that th
+ selectors[selectors.length] = filter.selector;
Wladimir Palant 2015/06/05 21:58:54 selectors.push() please. Either way, I think this
Thomas Greiner 2015/06/23 13:28:40 Done.
+ }
+ else
+ ignorableFilters[ignorableFilters.length] = filterText;
+ }
+ }
+
+ let nextDot = domain.indexOf(".");
+ if (nextDot < 0)
+ break;
+ domain = domain.substr(nextDot + 1);
}
- return result;
+
+ return selectors;
}
};
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld