Index: lib/elemHide.js
diff --git a/lib/elemHide.js b/lib/elemHide.js
index 4b25c62d0daf0079b7e8f54f962cf3d4bddf9792..6e2f1b56acbb6e67e79f779503b469f9d8829903 100644
--- a/lib/elemHide.js
+++ b/lib/elemHide.js
@@ -40,6 +40,25 @@ var filterByKey = Object.create(null);
 var keyByFilter = Object.create(null);
 
 /**
+ * Nested lookup table, filter (or false if inactive) by filter text by domain
+ * @type Object
+ */
+var filtersByDomain = Object.create(null);
+
+/**
+ * Indicates whether we are using (and maintaining) the filtersByDomain lookup.
+ * (Will be false for Firefox)
+ * @type Boolean
+ */
+var usingFiltersByDomain = !("nsIStyleSheetService" in Ci);
+
+/**
+ * Object to be used instead when a filter has a blank domains property.
+ */
+var defaultDomains = Object.create(null);
+defaultDomains[""] = true;
+
+/**
  * Lookup table, keys are known element hiding exceptions
  * @type Object
  */
@@ -70,7 +89,7 @@ var ElemHide = exports.ElemHide =
   isDirty: false,
 
   /**
-   * Inidicates whether the element hiding stylesheet is currently applied.
+   * Indicates whether the element hiding stylesheet is currently applied.
    * @type Boolean
    */
   applied: false,
@@ -99,6 +118,7 @@ var ElemHide = exports.ElemHide =
   {
     filterByKey = Object.create(null);
     keyByFilter = Object.create(null);
+    filtersByDomain = Object.create(null);
     knownExceptions = Object.create(null);
     exceptions = Object.create(null);
     ElemHide.isDirty = false;
@@ -134,6 +154,23 @@ var ElemHide = exports.ElemHide =
 
       filterByKey[key] = filter;
       keyByFilter[filter.text] = key;
+
+      if (usingFiltersByDomain)
+      {
+        let domainMatches = filter.domains || defaultDomains;
+        for (let domain in domainMatches)
+        {
+          let filters = filtersByDomain[domain];
+          if (!filters)
+            filters = filtersByDomain[domain] = Object.create(null);
+
+          if (domainMatches[domain])
+            filters[filter.text] = filter;
+          else
+            filters[filter.text] = false;
+        }
+      }
+
       ElemHide.isDirty = true;
     }
   },
@@ -368,22 +405,45 @@ var ElemHide = exports.ElemHide =
   },
 
   /**
-   * 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, must not be
+   * used in Firefox (when usingFiltersByDomain is false).
    */
   getSelectorsForDomain: function(/**String*/ domain, /**Boolean*/ specificOnly)
   {
-    let result = [];
-    let keys = Object.getOwnPropertyNames(filterByKey);
-    for (let key of keys)
+    if (!usingFiltersByDomain)
+      throw new Error("getSelectorsForDomain can not be used in Firefox!");
+
+    let selectors = [];
+
+    let seenFilters = Object.create(null);
+    let currentDomain = domain ? domain.toUpperCase() : "";
+    while (true)
     {
-      let filter = filterByKey[key];
-      if (specificOnly && (!filter.domains || filter.domains[""]))
-        continue;
+      if (specificOnly && currentDomain == "")
+        break;
 
-      if (filter.isActiveOnDomain(domain) && !this.getException(filter, domain))
-        result.push(filter.selector);
+      let filters = filtersByDomain[currentDomain];
+      if (filters)
+      {
+        for (let filterText in filters)
+        {
+          if (filterText in seenFilters)
+            continue;
+          seenFilters[filterText] = true;
+
+          let filter = filters[filterText];
+          if (filter && !this.getException(filter, domain))
+            selectors.push(filter.selector);
+        }
+      }
+
+      if (currentDomain == "")
+        break;
+
+      let nextDot = currentDomain.indexOf(".");
+      currentDomain = nextDot == -1 ? "" : currentDomain.substr(nextDot + 1);
     }
-    return result;
+
+    return selectors;
   }
 };
