Index: lib/elemHide.js
===================================================================
--- a/lib/elemHide.js
+++ b/lib/elemHide.js
@@ -18,17 +18,17 @@
 "use strict";
 
 /**
  * @fileOverview Element hiding implementation.
  */
 
 const {ElemHideExceptions} = require("./elemHideExceptions");
 const {filterNotifier} = require("./filterNotifier");
-const {normalizeHostname, suffixes} = require("./domain");
+const {normalizeHostname, domainSuffixes} = require("./url");
 const {Cache} = require("./caching");
 
 /**
  * The maximum number of selectors in a CSS rule. This is used by
  * <code>{@link createStyleSheet}</code> to split up a long list of selectors
  * into multiple rules.
  * @const {number}
  * @default
@@ -161,17 +161,17 @@
  * @returns {Array.<string>} The list of selectors.
  */
 function getConditionalSelectors(domain, specificOnly)
 {
   let selectors = [];
 
   let excluded = new Set();
 
-  for (let currentDomain of suffixes(domain, !specificOnly))
+  for (let currentDomain of domainSuffixes(domain, !specificOnly))
   {
     let filters = filtersByDomain.get(currentDomain);
     if (filters)
     {
       for (let [filter, isIncluded] of filters)
       {
         if (!isIncluded)
         {
Index: lib/filterClasses.js
===================================================================
--- a/lib/filterClasses.js
+++ b/lib/filterClasses.js
@@ -18,17 +18,17 @@
 "use strict";
 
 /**
  * @fileOverview Definition of Filter class and its subclasses.
  */
 
 const {extend} = require("./coreUtils");
 const {filterToRegExp} = require("./common");
-const {normalizeHostname, suffixes} = require("./domain");
+const {normalizeHostname, domainSuffixes} = require("./url");
 const {filterNotifier} = require("./filterNotifier");
 
 const resources = require("../data/resources.json");
 
 /**
  * Map of internal resources for URL rewriting.
  * @type {Map.<string,string>}
  */
@@ -601,17 +601,17 @@
     if (!domains)
       return true;
 
     // If the document has no host name, match only if the filter
     // isn't restricted to specific domains
     if (!docDomain)
       return domains.get("");
 
-    for (docDomain of suffixes(normalizeHostname(docDomain)))
+    for (docDomain of domainSuffixes(normalizeHostname(docDomain)))
     {
       let isDomainIncluded = domains.get(docDomain);
       if (typeof isDomainIncluded != "undefined")
         return isDomainIncluded;
     }
 
     return domains.get("");
   },
Index: lib/matcher.js
===================================================================
--- a/lib/matcher.js
+++ b/lib/matcher.js
@@ -18,17 +18,17 @@
 "use strict";
 
 /**
  * @fileOverview Matcher class implementing matching addresses against
  *               a list of filters.
  */
 
 const {RegExpFilter, WhitelistFilter} = require("./filterClasses");
-const {normalizeHostname, suffixes} = require("./domain");
+const {normalizeHostname, domainSuffixes} = require("./url");
 const {Cache} = require("./caching");
 
 /**
  * Regular expression for matching a keyword in a filter.
  * @type {RegExp}
  */
 const keywordRegExp = /[^a-z0-9%*][a-z0-9%]{3,}(?=[^a-z0-9%*])/;
 
@@ -497,18 +497,19 @@
           collection.push(filtersByDomain);
         }
 
         return null;
       }
 
       let excluded = new Set();
 
-      for (let suffix of suffixes(docDomain ? normalizeHostname(docDomain) : "",
-                                  !specificOnly))
+      for (let suffix of domainSuffixes(docDomain ?
+                                          normalizeHostname(docDomain) : "",
+                                        !specificOnly))
       {
         let filters = filtersByDomain.get(suffix);
         if (filters)
         {
           for (let [filter, include] of filters.entries())
           {
             if (!include)
             {
Index: lib/url.js
===================================================================
rename from lib/domain.js
rename to lib/url.js
--- a/lib/domain.js
+++ b/lib/url.js
@@ -59,31 +59,31 @@
  * <code>com</code>, 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, includeBlank = false)
+function* domainSuffixes(domain, includeBlank = false)
 {
   while (domain != "")
   {
     yield domain;
 
     let dotIndex = domain.indexOf(".");
     domain = dotIndex == -1 ? "" : domain.substr(dotIndex + 1);
   }
 
   if (includeBlank)
     yield "";
 }
 
-exports.suffixes = suffixes;
+exports.domainSuffixes = domainSuffixes;
 
 /**
  * Checks whether the given hostname is a domain.
  *
  * @param {string} hostname
  * @returns {boolean}
  */
 function isDomain(hostname)
@@ -98,22 +98,22 @@
 }
 
 /**
  * Gets the base domain for the given hostname.
  *
  * @param {string} hostname
  * @returns {string}
  */
-function getDomain(hostname)
+function getBaseDomain(hostname)
 {
   let slices = [];
   let cutoff = NaN;
 
-  for (let suffix of suffixes(hostname))
+  for (let suffix of domainSuffixes(hostname))
   {
     slices.push(suffix);
 
     let offset = publicSuffixMap.get(suffix);
 
     if (typeof offset != "undefined")
     {
       cutoff = slices.length - 1 - offset;
@@ -125,17 +125,17 @@
     return slices.length > 2 ? slices[slices.length - 2] : hostname;
 
   if (cutoff <= 0)
     return hostname;
 
   return slices[cutoff];
 }
 
-exports.getDomain = getDomain;
+exports.getBaseDomain = getBaseDomain;
 
 /**
  * Checks whether a request's origin is different from its document's origin.
  *
  * @param {URL} url The request URL.
  * @param {string} documentHostname The IDNA-encoded hostname of the document.
  *
  * @returns {boolean}
@@ -151,12 +151,12 @@
     documentHostname = documentHostname.replace(/\.+$/, "");
 
   if (requestHostname == documentHostname)
     return false;
 
   if (!isDomain(requestHostname) || !isDomain(documentHostname))
     return true;
 
-  return getDomain(requestHostname) != getDomain(documentHostname);
+  return getBaseDomain(requestHostname) != getBaseDomain(documentHostname);
 }
 
 exports.isThirdParty = isThirdParty;
Index: test/url.js
===================================================================
rename from test/domain.js
rename to test/url.js
--- a/test/domain.js
+++ b/test/url.js
@@ -19,29 +19,30 @@
 
 // Only starting NodeJS 10 that URL is in the global space.
 const {URL} = require("url");
 const {createSandbox} = require("./_common");
 
 const publicSuffixes = require("../data/publicSuffixList.json");
 
 let normalizeHostname = null;
+let domainSuffixes = null;
 let isThirdParty = null;
-let getDomain = null;
+let getBaseDomain = null;
 
 exports.setUp = function(callback)
 {
   let sandboxedRequire = createSandbox({
     extraExports: {
-      domain: ["getDomain"]
+      domain: ["getBaseDomain"]
     }
   });
   (
-    {normalizeHostname, isThirdParty,
-     getDomain} = sandboxedRequire("../lib/domain")
+    {normalizeHostname, domainSuffixes, isThirdParty,
+     getBaseDomain} = sandboxedRequire("../lib/url")
   );
 
   callback();
 };
 
 function hostnameToURL(hostname)
 {
   return new URL("http://" + hostname);
@@ -82,16 +83,57 @@
   test.equal(normalizeHostname("2001:0db8:85a3:0000:0000:8a2e:0370:7334."),
              "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
   test.equal(normalizeHostname("2001:0DB8:85A3:0000:0000:8A2E:0370:7334"),
              "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
 
   test.done();
 };
 
+exports.testDomainSuffixes = function(test)
+{
+  test.deepEqual([...domainSuffixes("localhost")], ["localhost"]);
+  test.deepEqual([...domainSuffixes("example.com")], ["example.com", "com"]);
+  test.deepEqual([...domainSuffixes("www.example.com")],
+                 ["www.example.com", "example.com", "com"]);
+  test.deepEqual([...domainSuffixes("www.example.co.in")],
+                 ["www.example.co.in", "example.co.in", "co.in", "in"]);
+
+  // With blank.
+  test.deepEqual([...domainSuffixes("localhost", true)], ["localhost", ""]);
+  test.deepEqual([...domainSuffixes("example.com", true)],
+                 ["example.com", "com", ""]);
+  test.deepEqual([...domainSuffixes("www.example.com", true)],
+                 ["www.example.com", "example.com", "com", ""]);
+  test.deepEqual([...domainSuffixes("www.example.co.in", true)],
+                 ["www.example.co.in", "example.co.in", "co.in", "in", ""]);
+
+  // Quirks and edge cases.
+  test.deepEqual([...domainSuffixes("")], []);
+  test.deepEqual([...domainSuffixes(".")], ["."]);
+  test.deepEqual([...domainSuffixes(".localhost")],
+                 [".localhost", "localhost"]);
+  test.deepEqual([...domainSuffixes(".example.com")],
+                 [".example.com", "example.com", "com"]);
+  test.deepEqual([...domainSuffixes("localhost.")],
+                 ["localhost."]);
+  test.deepEqual([...domainSuffixes("example.com.")],
+                 ["example.com.", "com."]);
+  test.deepEqual([...domainSuffixes("..localhost")],
+                 ["..localhost", ".localhost", "localhost"]);
+  test.deepEqual([...domainSuffixes("..example..com")],
+                 ["..example..com", ".example..com", "example..com", ".com",
+                  "com"]);
+  test.deepEqual([...domainSuffixes("localhost..")], ["localhost..", "."]);
+  test.deepEqual([...domainSuffixes("example..com..")],
+                 ["example..com..", ".com..", "com..", "."]);
+
+  test.done();
+};
+
 exports.testIsThirdParty = function(test)
 {
   testThirdParty(test, "foo", "foo", false, "same domain isn't third-party");
   testThirdParty(test, "foo", "bar", true, "different domain is third-party");
   testThirdParty(test, "foo.com", "foo.com", false,
                  "same domain with TLD (.com) isn't third-party");
   testThirdParty(test, "foo.com", "bar.com", true,
                  "same TLD (.com) but different domain is third-party");
@@ -151,17 +193,17 @@
   testThirdParty(test, "xn--f-1gaa.com", "f\u00f6\u00f6.com", false,
                  "same IDN isn't third-party");
   testThirdParty(test, "example.com..", "example.com....", false,
                  "traling dots are ignored");
 
   test.done();
 };
 
-exports.testGetDomain = function(test)
+exports.testGetBaseDomain = function(test)
 {
   let parts = ["aaa", "bbb", "ccc", "ddd", "eee"];
   let levels = 3;
 
   for (let suffix in publicSuffixes)
   {
     let offset = publicSuffixes[suffix];
 
@@ -172,40 +214,43 @@
     for (let i = 0; i < offset + levels; i++)
     {
       let hostname = parts.slice(0, i).join(".");
       hostname += (hostname ? "." : "") + suffix;
 
       let expected = parts.slice(Math.max(0, i - offset), i).join(".");
       expected += (expected ? "." : "") + suffix;
 
-      test.equal(getDomain(hostname), expected,
-                 `getDomain("${hostname}") == "${expected}"` +
+      test.equal(getBaseDomain(hostname), expected,
+                 `getBaseDomain("${hostname}") == "${expected}"` +
                  ` with {suffix: "${suffix}", offset: ${offset}}`);
     }
   }
 
   // Unknown suffixes.
   test.equal(typeof publicSuffixes["localhost"], "undefined");
   test.equal(typeof publicSuffixes["localhost.localdomain"], "undefined");
 
-  test.equal(getDomain("localhost"), "localhost");
-  test.equal(getDomain("localhost.localdomain"), "localhost.localdomain");
-  test.equal(getDomain("mail.localhost.localdomain"), "localhost.localdomain");
-  test.equal(getDomain("www.example.localhost.localdomain"),
+  test.equal(getBaseDomain("localhost"), "localhost");
+  test.equal(getBaseDomain("localhost.localdomain"), "localhost.localdomain");
+  test.equal(
+    getBaseDomain("mail.localhost.localdomain"),
+    "localhost.localdomain"
+  );
+  test.equal(getBaseDomain("www.example.localhost.localdomain"),
              "localhost.localdomain");
 
   // Unknown suffixes that overlap partly with known suffixes.
   test.equal(typeof publicSuffixes["example.com"], "undefined");
   test.equal(typeof publicSuffixes["africa.com"], "number");
   test.equal(typeof publicSuffixes["compute.amazonaws.com"], "number");
 
-  test.equal(getDomain("example.com"), "example.com");
-  test.equal(getDomain("mail.example.com"), "example.com");
-  test.equal(getDomain("secure.mail.example.com"), "example.com");
+  test.equal(getBaseDomain("example.com"), "example.com");
+  test.equal(getBaseDomain("mail.example.com"), "example.com");
+  test.equal(getBaseDomain("secure.mail.example.com"), "example.com");
 
   // Cascading offsets.
 
   // If these sanity checks fail, look for other examles of cascading offsets
   // from the public suffix list.
   test.equal(
     typeof publicSuffixes[
       "images.example.s3.dualstack.us-east-1.amazonaws.com"
@@ -220,27 +265,32 @@
   test.equal(typeof publicSuffixes["dualstack.us-east-1.amazonaws.com"],
              "undefined");
   test.equal(typeof publicSuffixes["example.us-east-1.amazonaws.com"],
              "undefined");
   test.equal(publicSuffixes["us-east-1.amazonaws.com"], 1);
   test.equal(typeof publicSuffixes["example.amazonaws.com"], "undefined");
   test.equal(typeof publicSuffixes["amazonaws.com"], "undefined");
 
-  test.equal(getDomain("images.example.s3.dualstack.us-east-1.amazonaws.com"),
+  test.equal(
+    getBaseDomain("images.example.s3.dualstack.us-east-1.amazonaws.com"),
+    "example.s3.dualstack.us-east-1.amazonaws.com"
+  );
+  test.equal(getBaseDomain("example.s3.dualstack.us-east-1.amazonaws.com"),
             "example.s3.dualstack.us-east-1.amazonaws.com");
-  test.equal(getDomain("example.s3.dualstack.us-east-1.amazonaws.com"),
-            "example.s3.dualstack.us-east-1.amazonaws.com");
-  test.equal(getDomain("s3.dualstack.us-east-1.amazonaws.com"),
+  test.equal(getBaseDomain("s3.dualstack.us-east-1.amazonaws.com"),
             "s3.dualstack.us-east-1.amazonaws.com");
-  test.equal(getDomain("dualstack.us-east-1.amazonaws.com"),
+  test.equal(getBaseDomain("dualstack.us-east-1.amazonaws.com"),
             "dualstack.us-east-1.amazonaws.com");
-  test.equal(getDomain("example.us-east-1.amazonaws.com"),
+  test.equal(getBaseDomain("example.us-east-1.amazonaws.com"),
             "example.us-east-1.amazonaws.com");
-  test.equal(getDomain("us-east-1.amazonaws.com"), "us-east-1.amazonaws.com");
-  test.equal(getDomain("example.amazonaws.com"), "amazonaws.com");
-  test.equal(getDomain("amazonaws.com"), "amazonaws.com");
+  test.equal(
+    getBaseDomain("us-east-1.amazonaws.com"),
+    "us-east-1.amazonaws.com"
+  );
+  test.equal(getBaseDomain("example.amazonaws.com"), "amazonaws.com");
+  test.equal(getBaseDomain("amazonaws.com"), "amazonaws.com");
 
   // Edge case.
-  test.equal(getDomain(""), "");
+  test.equal(getBaseDomain(""), "");
 
   test.done();
 };
