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

Unified Diff: lib/elemHide.js

Issue 29349187: Issue 4167 - getSelectorsForDomain criteria + keys (Closed)
Patch Set: Only store one filter key per unconditional selector Created Sept. 19, 2016, 4:51 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 | test/elemHide.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/elemHide.js
diff --git a/lib/elemHide.js b/lib/elemHide.js
index 2c81a2324f579247d53eca5eeb6ac459210a937a..c3df791db5e5b8420560e90b796bdfd37c254f5b 100644
--- a/lib/elemHide.js
+++ b/lib/elemHide.js
@@ -36,14 +36,6 @@ var filterByKey = [];
var keyByFilter = Object.create(null);
/**
- * Indicates whether we are using the getSelectorsForDomain function and
- * therefore mainting the required filtersByDomain, filtersBySelector and
- * unconditionalSelectors lookups. (Will be false for Firefox)
- * @type Boolean
- */
-var usingGetSelectorsForDomain = !("nsIStyleSheetService" in Ci);
-
-/**
* Nested lookup table, filter (or false if inactive) by filter key by domain.
* (Only contains filters that aren't unconditionally matched for all domains.)
* @type Object
@@ -51,19 +43,26 @@ var usingGetSelectorsForDomain = !("nsIStyleSheetService" in Ci);
var filtersByDomain = Object.create(null);
/**
- * Lookup table, filters by selector. (Only contains filters that have a
+ * Lookup table, filters key by selector. (Only contains filters that have a
* selector that is unconditionally matched for all domains.)
*/
-var filtersBySelector = Object.create(null);
+var filterKeyBySelector = Object.create(null);
/**
- * This array caches the keys of filtersBySelector table (selectors which
+ * This array caches the keys of filterKeyBySelector table (selectors which
* unconditionally apply on all domains). It will be null if the cache needs to
* be rebuilt.
*/
var unconditionalSelectors = null;
/**
+ * This array caches the values of filterKeyBySelector table (filterIds for
+ * selectors which unconditionally apply on all domains). It will be null if the
+ * cache needs to be rebuilt.
+ */
+var unconditionalFilterKeys = null;
+
+/**
* Object to be used instead when a filter has a blank domains property.
*/
var defaultDomains = Object.create(null);
@@ -95,16 +94,15 @@ var ElemHide = exports.ElemHide =
filterByKey = [];
keyByFilter = Object.create(null);
filtersByDomain = Object.create(null);
- filtersBySelector = Object.create(null);
- unconditionalSelectors = null;
+ filterKeyBySelector = Object.create(null);
+ unconditionalSelectors = unconditionalFilterKeys = null;
knownExceptions = Object.create(null);
exceptions = Object.create(null);
FilterNotifier.emit("elemhideupdate");
},
- _addToFiltersByDomain: function(filter)
+ _addToFiltersByDomain: function(key, filter)
{
- let key = keyByFilter[filter.text];
let domains = filter.domains || defaultDomains;
for (let domain in domains)
{
@@ -135,19 +133,15 @@ var ElemHide = exports.ElemHide =
exceptions[selector] = [];
exceptions[selector].push(filter);
- if (usingGetSelectorsForDomain)
+ // If this is the first exception for a previously unconditionally
+ // applied element hiding selector we need to take care to update the
+ // lookups.
+ let filterKey = filterKeyBySelector[selector];
+ if (filterKey)
{
- // If this is the first exception for a previously unconditionally
- // applied element hiding selector we need to take care to update the
- // lookups.
- let unconditionalFilters = filtersBySelector[selector];
- if (unconditionalFilters)
- {
- for (let f of unconditionalFilters)
- this._addToFiltersByDomain(f);
- delete filtersBySelector[selector];
- unconditionalSelectors = null;
- }
+ this._addToFiltersByDomain(filterKey, filterByKey[filterKey]);
+ delete filterKeyBySelector[selector];
+ unconditionalSelectors = unconditionalFilterKeys = null;
}
knownExceptions[filter.text] = true;
@@ -160,27 +154,16 @@ var ElemHide = exports.ElemHide =
let key = filterByKey.push(filter) - 1;
keyByFilter[filter.text] = key;
- if (usingGetSelectorsForDomain)
+ if (!(filter.domains || filter.selector in exceptions))
{
- if (!(filter.domains || filter.selector in exceptions))
- {
- // The new filter's selector is unconditionally applied to all domains
- let filters = filtersBySelector[filter.selector];
- if (filters)
- {
- filters.push(filter);
- }
- else
- {
- filtersBySelector[filter.selector] = [filter];
- unconditionalSelectors = null;
- }
- }
- else
- {
- // The new filter's selector only applies to some domains
- this._addToFiltersByDomain(filter);
- }
+ // The new filter's selector is unconditionally applied to all domains
+ filterKeyBySelector[filter.selector] = key;
+ unconditionalSelectors = unconditionalFilterKeys = null;
+ }
+ else
+ {
+ // The new filter's selector only applies to some domains
+ this._addToFiltersByDomain(key, filter);
}
}
@@ -213,31 +196,19 @@ var ElemHide = exports.ElemHide =
delete filterByKey[key];
delete keyByFilter[filter.text];
- if (usingGetSelectorsForDomain)
+ if (filter.selector in filterKeyBySelector)
{
- let filters = filtersBySelector[filter.selector];
- if (filters)
- {
- if (filters.length > 1)
- {
- let index = filters.indexOf(filter);
- filters.splice(index, 1);
- }
- else
- {
- delete filtersBySelector[filter.selector];
- unconditionalSelectors = null;
- }
- }
- else
+ delete filterKeyBySelector[filter.selector];
+ unconditionalSelectors = unconditionalFilterKeys = null;
+ }
+ else
+ {
+ let domains = filter.domains || defaultDomains;
+ for (let domain in domains)
{
- let domains = filter.domains || defaultDomains;
- for (let domain in domains)
- {
- let filters = filtersByDomain[domain];
- if (filters)
- delete filters[key];
- }
+ let filters = filtersByDomain[domain];
+ if (filters)
+ delete filters[key];
}
}
}
@@ -265,7 +236,7 @@ var ElemHide = exports.ElemHide =
/**
* Retrieves an element hiding filter by the corresponding protocol key
*/
- getFilterByKey: function(/**String*/ key) /**Filter*/
+ getFilterByKey: function(/**Number*/ key) /**Filter*/
{
return (key in filterByKey ? filterByKey[key] : null);
},
@@ -298,17 +269,50 @@ var ElemHide = exports.ElemHide =
},
/**
- * Returns a list of all selectors active on a particular domain, must not be
- * used in Firefox (when usingGetSelectorsForDomain is false).
+ * Returns a list of selectors that apply on each website unconditionally.
+ * @returns {String[]}
*/
- getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
+ getUnconditionalSelectors: function()
{
- if (!usingGetSelectorsForDomain)
- throw new Error("getSelectorsForDomain can not be used in Firefox!");
-
if (!unconditionalSelectors)
- unconditionalSelectors = Object.keys(filtersBySelector);
- let selectors = specificOnly ? [] : unconditionalSelectors.slice();
+ unconditionalSelectors = Object.keys(filterKeyBySelector);
+ return unconditionalSelectors.slice();
+ },
+
+ /**
+ * Returns a list of all selectors active on a particular domain.
+ * Returns a list of filterKeys for selectors that apply on each website
+ * unconditionally.
+ * @returns {Number[]}
+ */
+ getUnconditionalFilterKeys: function()
+ {
+ if (!unconditionalFilterKeys)
+ {
+ let selectors = this.getUnconditionalSelectors();
+ unconditionalFilterKeys = [];
+ for (let selector of selectors)
+ unconditionalFilterKeys.push(filterKeyBySelector[selector]);
+ }
+ return unconditionalFilterKeys.slice();
+ },
+
+ /**
+ * Returns a list of all selectors active on a particular domain. Optionally
+ * a list of corresponding filter keys for the selectors can be returned too.
+ */
+ getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly,
+ /**Boolean*/ noUnconditional,
+ /**Boolean*/ provideFilterKeys)
+ {
+ let filterKeys = [];
+ let selectors = [];
+ if (!specificOnly && !noUnconditional)
+ {
+ selectors = this.getUnconditionalSelectors();
+ if (provideFilterKeys)
+ filterKeys = this.getUnconditionalFilterKeys();
+ }
let seenFilters = Object.create(null);
let currentDomain = domain ? domain.toUpperCase() : "";
@@ -328,7 +332,11 @@ var ElemHide = exports.ElemHide =
let filter = filters[filterKey];
if (filter && !this.getException(filter, domain))
+ {
selectors.push(filter.selector);
+ // It is faster to always push the key, even if not required.
+ filterKeys.push(filterKey);
+ }
}
}
@@ -339,6 +347,9 @@ var ElemHide = exports.ElemHide =
currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
}
- return selectors;
+ if (provideFilterKeys)
+ return [selectors, filterKeys];
+ else
+ return selectors;
}
};
« no previous file with comments | « no previous file | test/elemHide.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld