Index: lib/domain.js
===================================================================
--- a/lib/domain.js
+++ b/lib/domain.js
@@ -41,29 +41,37 @@
/**
* Yields all suffixes for a domain. For example, given the domain
* www.example.com
, this function yields
* www.example.com
, example.com
, and
* com
, in that order.
*
* @param {string} domain The domain.
+ * @param {boolean} [includeBlank] Whether to include the blank suffix at the
+ * end.
+ *
* @yields {string} The next suffix for the domain.
*/
-function* suffixes(domain)
+function* suffixes(domain, includeBlank = false)
{
while (domain != "")
{
yield domain;
let dotIndex = domain.indexOf(".");
domain = dotIndex == -1 ? "" : domain.substr(dotIndex + 1);
}
+
+ if (includeBlank)
+ yield "";
}
+exports.suffixes = suffixes;
+
/**
* Checks whether the given hostname is a domain.
*
* @param {string} hostname
* @returns {boolean}
*/
function isDomain(hostname)
{
Index: lib/elemHide.js
===================================================================
--- a/lib/elemHide.js
+++ b/lib/elemHide.js
@@ -18,16 +18,17 @@
"use strict";
/**
* @fileOverview Element hiding implementation.
*/
const {ElemHideExceptions} = require("./elemHideExceptions");
const {filterNotifier} = require("./filterNotifier");
+const {suffixes} = require("./domain");
/**
* The maximum number of selectors in a CSS rule. This is used by
* {@link createStyleSheet}
to split up a long list of selectors
* into multiple rules.
* @const {number}
* @default
*/
@@ -164,25 +165,19 @@
*
* @returns {Array.} The list of selectors.
*/
function getConditionalSelectors(domain, specificOnly)
{
let selectors = [];
let excluded = new Set();
- let currentDomain = domain;
- // This code is a performance hot-spot, which is why we've made certain
- // micro-optimisations. Please be careful before making changes.
- while (true)
+ for (let currentDomain of suffixes(domain, !specificOnly))
{
- if (specificOnly && currentDomain == "")
- break;
-
let filters = filtersByDomain.get(currentDomain);
if (filters)
{
for (let [filter, isIncluded] of filters)
{
if (!isIncluded)
{
excluded.add(filter);
@@ -193,22 +188,16 @@
if ((excluded.size == 0 || !excluded.has(filter)) &&
!ElemHideExceptions.getException(selector, domain))
{
selectors.push(selector);
}
}
}
}
-
- if (currentDomain == "")
- break;
-
- let nextDot = currentDomain.indexOf(".");
- currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
}
return selectors;
}
/**
* Returns the default style sheet that applies on all domains.
* @returns {string}
Index: lib/filterClasses.js
===================================================================
--- a/lib/filterClasses.js
+++ b/lib/filterClasses.js
@@ -16,19 +16,21 @@
*/
"use strict";
/**
* @fileOverview Definition of Filter class and its subclasses.
*/
-const {filterNotifier} = require("./filterNotifier");
const {extend} = require("./coreUtils");
const {filterToRegExp} = require("./common");
+const {suffixes} = require("./domain");
+const {filterNotifier} = require("./filterNotifier");
+
const resources = require("../data/resources.json");
/**
* Map of internal resources for URL rewriting.
* @type {Map.}
*/
let resourceMap = new Map(
Object.keys(resources).map(key => [key, resources[key]])
@@ -604,27 +606,23 @@
if (!docDomain)
return domains.get("");
if (docDomain[docDomain.length - 1] == ".")
docDomain = docDomain.replace(/\.+$/, "");
docDomain = docDomain.toLowerCase();
- while (true)
+ for (docDomain of suffixes(docDomain))
{
let isDomainIncluded = domains.get(docDomain);
if (typeof isDomainIncluded != "undefined")
return isDomainIncluded;
+ }
- let nextDot = docDomain.indexOf(".");
- if (nextDot < 0)
- break;
- docDomain = docDomain.substr(nextDot + 1);
- }
return domains.get("");
},
/**
* Checks whether this filter is active only on a domain and its subdomains.
* @param {string} docDomain
* @return {boolean}
*/