Bug 1427419 - Part 24: Move pseudo-class lock methods from inIDOMUtils to InspectorUtils. r=bz draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 06 Jan 2018 15:08:15 +0800
changeset 716769 78a7c7a43f42dae477536e3e866055d4fe79b0d2
parent 716768 161a63cbd431af40cbe2f815da23bf896b9a740e
child 716770 fd4df4e30e4260339af52476fdf971a90135cee3
push id94496
push userbmo:cam@mcc.id.au
push dateSat, 06 Jan 2018 07:08:40 +0000
reviewersbz
bugs1427419
milestone59.0a1
Bug 1427419 - Part 24: Move pseudo-class lock methods from inIDOMUtils to InspectorUtils. r=bz MozReview-Commit-ID: ItruGMmf5Ih
browser/modules/PluginContent.jsm
browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.jsm
devtools/client/shared/test/test-actor.js
devtools/server/actors/highlighters/utils/markup.js
devtools/server/actors/inspector.js
devtools/server/tests/mochitest/test_inspector-pseudoclass-lock.html
dom/webidl/InspectorUtils.webidl
layout/inspector/InspectorUtils.h
layout/inspector/inDOMUtils.cpp
layout/inspector/inIDOMUtils.idl
layout/inspector/tests/chrome/test_bug708874.xul
toolkit/modules/SelectContentHelper.jsm
--- a/browser/modules/PluginContent.jsm
+++ b/browser/modules/PluginContent.jsm
@@ -10,16 +10,18 @@ var Cu = Components.utils;
 
 this.EXPORTED_SYMBOLS = [ "PluginContent" ];
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/BrowserUtils.jsm");
 
+Cu.importGlobalProperties(["InspectorUtils"]);
+
 XPCOMUtils.defineLazyGetter(this, "gNavigatorBundle", function() {
   const url = "chrome://browser/locale/browser.properties";
   return Services.strings.createBundle(url);
 });
 
 XPCOMUtils.defineLazyModuleGetter(this, "AppConstants",
   "resource://gre/modules/AppConstants.jsm");
 
@@ -514,20 +516,18 @@ PluginContent.prototype = {
     }
 
     let plugin = event.target;
 
     if (eventType == "PluginPlaceholderReplaced") {
       plugin.removeAttribute("href");
       let overlay = this.getPluginUI(plugin, "main");
       this.setVisibility(plugin, overlay, OVERLAY_DISPLAY.FULL);
-      let inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
-                          .getService(Ci.inIDOMUtils);
-      // Add psuedo class so our styling will take effect
-      inIDOMUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
+      // Add pseudo class so our styling will take effect
+      InspectorUtils.addPseudoClassLock(plugin, "-moz-handler-clicktoplay");
       overlay.addEventListener("click", this, true);
       return;
     }
 
     if (!(plugin instanceof Ci.nsIObjectLoadingContent))
       return;
 
     if (eventType == "PluginBindingAttached") {
--- a/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.jsm
+++ b/browser/tools/mozscreenshots/mozscreenshots/extension/configurations/Tabs.jsm
@@ -12,16 +12,18 @@ const CUST_TAB = "chrome://browser/skin/
 const PREFS_TAB = "chrome://browser/skin/settings.svg";
 const DEFAULT_FAVICON_TAB = `data:text/html,<meta%20charset="utf-8"><title>No%20favicon</title>`;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://testing-common/TestUtils.jsm");
 Cu.import("resource://testing-common/BrowserTestUtils.jsm");
 
+Cu.importGlobalProperties(["InspectorUtils"]);
+
 this.Tabs = {
   init(libDir) {},
 
   configurations: {
     fiveTabs: {
       selectors: ["#tabbrowser-tabs"],
       async applyConfig() {
         fiveTabsHelper();
@@ -184,20 +186,19 @@ function closeAllButOneTab(url = "about:
   gBrowser.selectedBrowser.loadURI(url);
   if (gBrowser.selectedTab.pinned)
     gBrowser.unpinTab(gBrowser.selectedTab);
   let newTabButton = browserWindow.document.getAnonymousElementByAttribute(browserWindow.gBrowser.tabContainer, "class", "tabs-newtab-button toolbarbutton-1");
   hoverTab(newTabButton, false);
 }
 
 function hoverTab(tab, hover = true) {
-  const inIDOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
   if (hover) {
-    inIDOMUtils.addPseudoClassLock(tab, ":hover");
+    InspectorUtils.addPseudoClassLock(tab, ":hover");
   } else {
-    inIDOMUtils.clearPseudoClassLocks(tab);
+    InspectorUtils.clearPseudoClassLocks(tab);
   }
   // XXX TODO: this isn't necessarily testing what we ship
   if (tab.nextElementSibling)
     tab.nextElementSibling.setAttribute("afterhovered", hover || null);
   if (tab.previousElementSibling)
     tab.previousElementSibling.setAttribute("beforehovered", hover || null);
 }
--- a/devtools/client/shared/test/test-actor.js
+++ b/devtools/client/shared/test/test-actor.js
@@ -13,19 +13,19 @@ const {
   getRect, getElementFromPoint, getAdjustedQuads, getWindowDimensions
 } = require("devtools/shared/layout/utils");
 const defer = require("devtools/shared/defer");
 const {Task} = require("devtools/shared/task");
 const {
   isContentStylesheet,
   getCSSStyleRules
 } = require("devtools/shared/inspector/css-logic");
-const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
 const loader = Cc["@mozilla.org/moz/jssubscript-loader;1"]
                  .getService(Ci.mozIJSSubScriptLoader);
+const InspectorUtils = require("InspectorUtils");
 
 // Set up a dummy environment so that EventUtils works. We need to be careful to
 // pass a window object into each EventUtils method we call rather than having
 // it rely on the |window| global.
 let EventUtils = {};
 EventUtils.window = {};
 EventUtils.parent = {};
 /* eslint-disable camelcase */
@@ -541,17 +541,17 @@ var TestActor = exports.TestActor = prot
   /**
    * Check that an element currently has a pseudo-class lock.
    * @param {String} selector The node selector to get the pseudo-class from
    * @param {String} pseudo The pseudoclass to check for
    * @return {Boolean}
    */
   hasPseudoClassLock: function (selector, pseudo) {
     let node = this._querySelector(selector);
-    return DOMUtils.hasPseudoClassLock(node, pseudo);
+    return InspectorUtils.hasPseudoClassLock(node, pseudo);
   },
 
   loadAndWaitForCustomEvent: function (url) {
     return new Promise(resolve => {
       // Wait for DOMWindowCreated first, as listening on the current outerwindow
       // doesn't allow receiving test-page-processing-done.
       this.tabActor.chromeEventHandler.addEventListener("DOMWindowCreated", () => {
         this.content.addEventListener(
--- a/devtools/server/actors/highlighters/utils/markup.js
+++ b/devtools/server/actors/highlighters/utils/markup.js
@@ -1,39 +1,38 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use strict";
 
-const { Cc, Ci, Cu, Cr } = require("chrome");
+const { Ci, Cu, Cr } = require("chrome");
 const { getCurrentZoom, getWindowDimensions, getViewportDimensions,
   getRootBindingParent, loadSheet } = require("devtools/shared/layout/utils");
 const EventEmitter = require("devtools/shared/event-emitter");
+const InspectorUtils = require("InspectorUtils");
 
 const lazyContainer = {};
 
 loader.lazyRequireGetter(lazyContainer, "CssLogic",
   "devtools/server/css-logic", true);
 exports.getComputedStyle = (node) =>
   lazyContainer.CssLogic.getComputedStyle(node);
 
 exports.getBindingElementAndPseudo = (node) =>
   lazyContainer.CssLogic.getBindingElementAndPseudo(node);
 
-loader.lazyGetter(lazyContainer, "DOMUtils", () =>
-  Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils));
 exports.hasPseudoClassLock = (...args) =>
-  lazyContainer.DOMUtils.hasPseudoClassLock(...args);
+  InspectorUtils.hasPseudoClassLock(...args);
 
 exports.addPseudoClassLock = (...args) =>
-  lazyContainer.DOMUtils.addPseudoClassLock(...args);
+  InspectorUtils.addPseudoClassLock(...args);
 
 exports.removePseudoClassLock = (...args) =>
-  lazyContainer.DOMUtils.removePseudoClassLock(...args);
+  InspectorUtils.removePseudoClassLock(...args);
 
 const SVG_NS = "http://www.w3.org/2000/svg";
 const XHTML_NS = "http://www.w3.org/1999/xhtml";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 const STYLESHEET_URI = "resource://devtools/server/actors/" +
                        "highlighters.css";
 
 const _tokens = Symbol("classList/tokens");
--- a/devtools/server/actors/inspector.js
+++ b/devtools/server/actors/inspector.js
@@ -53,16 +53,17 @@
 const {Cc, Ci, Cu} = require("chrome");
 const Services = require("Services");
 const protocol = require("devtools/shared/protocol");
 const {LongStringActor} = require("devtools/server/actors/string");
 const promise = require("promise");
 const defer = require("devtools/shared/defer");
 const {Task} = require("devtools/shared/task");
 const EventEmitter = require("devtools/shared/event-emitter");
+const InspectorUtils = require("InspectorUtils");
 
 const {walkerSpec, inspectorSpec} = require("devtools/shared/specs/inspector");
 const {nodeSpec, nodeListSpec} = require("devtools/shared/specs/node");
 
 loader.lazyRequireGetter(this, "DevToolsUtils", "devtools/shared/DevToolsUtils");
 loader.lazyRequireGetter(this, "AsyncUtils", "devtools/shared/async-utils");
 loader.lazyRequireGetter(this, "CssLogic", "devtools/server/css-logic", true);
 loader.lazyRequireGetter(this, "findCssSelector", "devtools/shared/inspector/css-logic", true);
@@ -422,17 +423,17 @@ var NodeActor = exports.NodeActor = prot
   },
 
   writePseudoClassLocks: function () {
     if (this.rawNode.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
       return undefined;
     }
     let ret = undefined;
     for (let pseudo of PSEUDO_CLASSES) {
-      if (DOMUtils.hasPseudoClassLock(this.rawNode, pseudo)) {
+      if (InspectorUtils.hasPseudoClassLock(this.rawNode, pseudo)) {
         ret = ret || [];
         ret.push(pseudo);
       }
     }
     return ret;
   },
 
   /**
@@ -1838,17 +1839,17 @@ var WalkerActor = protocol.ActorClassWit
   addPseudoClassLock: function (node, pseudo, options = {}) {
     if (isNodeDead(node)) {
       return;
     }
 
     // There can be only one node locked per pseudo, so dismiss all existing
     // ones
     for (let locked of this._activePseudoClassLocks) {
-      if (DOMUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
+      if (InspectorUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
         this._removePseudoClassLock(locked, pseudo);
       }
     }
 
     let enabled = options.enabled === undefined ||
                   options.enabled;
     this._addPseudoClassLock(node, pseudo, enabled);
 
@@ -1871,17 +1872,17 @@ var WalkerActor = protocol.ActorClassWit
       pseudoClassLocks: node.writePseudoClassLocks()
     });
   },
 
   _addPseudoClassLock: function (node, pseudo, enabled) {
     if (node.rawNode.nodeType !== Ci.nsIDOMNode.ELEMENT_NODE) {
       return false;
     }
-    DOMUtils.addPseudoClassLock(node.rawNode, pseudo, enabled);
+    InspectorUtils.addPseudoClassLock(node.rawNode, pseudo, enabled);
     this._activePseudoClassLocks.add(node);
     this._queuePseudoClassMutation(node);
     return true;
   },
 
   hideNode: function (node) {
     if (isNodeDead(node)) {
       return;
@@ -1919,17 +1920,17 @@ var WalkerActor = protocol.ActorClassWit
     }
 
     this._removePseudoClassLock(node, pseudo);
 
     // Remove pseudo class for children as we don't want to allow
     // turning it on for some childs without setting it on some parents
     for (let locked of this._activePseudoClassLocks) {
       if (node.rawNode.contains(locked.rawNode) &&
-          DOMUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
+          InspectorUtils.hasPseudoClassLock(locked.rawNode, pseudo)) {
         this._removePseudoClassLock(locked, pseudo);
       }
     }
 
     if (!options.parents) {
       return;
     }
 
@@ -1940,17 +1941,17 @@ var WalkerActor = protocol.ActorClassWit
       this._removePseudoClassLock(curNode, pseudo);
     }
   },
 
   _removePseudoClassLock: function (node, pseudo) {
     if (node.rawNode.nodeType != Ci.nsIDOMNode.ELEMENT_NODE) {
       return false;
     }
-    DOMUtils.removePseudoClassLock(node.rawNode, pseudo);
+    InspectorUtils.removePseudoClassLock(node.rawNode, pseudo);
     if (!node.writePseudoClassLocks()) {
       this._activePseudoClassLocks.delete(node);
     }
 
     this._queuePseudoClassMutation(node);
     return true;
   },
 
@@ -1959,22 +1960,22 @@ var WalkerActor = protocol.ActorClassWit
    * @param {NodeActor} node Optional node to clear pseudo-classes on
    */
   clearPseudoClassLocks: function (node) {
     if (node && isNodeDead(node)) {
       return;
     }
 
     if (node) {
-      DOMUtils.clearPseudoClassLocks(node.rawNode);
+      InspectorUtils.clearPseudoClassLocks(node.rawNode);
       this._activePseudoClassLocks.delete(node);
       this._queuePseudoClassMutation(node);
     } else {
       for (let locked of this._activePseudoClassLocks) {
-        DOMUtils.clearPseudoClassLocks(locked.rawNode);
+        InspectorUtils.clearPseudoClassLocks(locked.rawNode);
         this._activePseudoClassLocks.delete(locked);
         this._queuePseudoClassMutation(locked);
       }
     }
   },
 
   /**
    * Get a node's innerHTML property.
@@ -3396,12 +3397,8 @@ var imageToImageData = Task.async(functi
     data: imageData,
     size: {
       naturalWidth: imgWidth,
       naturalHeight: imgHeight,
       resized: resizeRatio !== 1
     }
   };
 });
-
-loader.lazyGetter(this, "DOMUtils", function () {
-  return Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
-});
--- a/devtools/server/tests/mochitest/test_inspector-pseudoclass-lock.html
+++ b/devtools/server/tests/mochitest/test_inspector-pseudoclass-lock.html
@@ -8,19 +8,16 @@ https://bugzilla.mozilla.org/show_bug.cg
   <title>Test for Bug </title>
 
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
   <script type="application/javascript" src="inspector-helpers.js"></script>
   <script type="application/javascript">
 "use strict";
 
-const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
-                           .getService(Components.interfaces.inIDOMUtils);
-
 const KNOWN_PSEUDOCLASSES = [":hover", ":active", ":focus"];
 
 window.onload = function () {
   SimpleTest.waitForExplicitFinish();
   runNextTest();
 };
 
 let gInspectee = null;
@@ -61,26 +58,27 @@ function checkChange(change, expectation
 
   is(target.pseudoClassLocks.length, expectation.pseudos.length,
      "Expect " + expectation.pseudos.length + " pseudoclass locks.");
   for (let i = 0; i < expectation.pseudos.length; i++) {
     let pseudo = expectation.pseudos[i];
     let enabled = expectation.enabled === undefined ? true : expectation.enabled[i];
     ok(target.hasPseudoClassLock(pseudo), "Expect lock: " + pseudo);
     let rawNode = target.rawNode();
-    ok(DOMUtils.hasPseudoClassLock(rawNode, pseudo), "Expect lock in dom: " + pseudo);
+    ok(InspectorUtils.hasPseudoClassLock(rawNode, pseudo),
+       "Expect lock in dom: " + pseudo);
 
     is(rawNode.matches(pseudo), enabled,
        `Target should match pseudoclass, '${pseudo}', if enabled (with .matches())`);
   }
 
   for (let pseudo of KNOWN_PSEUDOCLASSES) {
     if (!expectation.pseudos.some(expected => pseudo === expected)) {
       ok(!target.hasPseudoClassLock(pseudo), "Don't expect lock: " + pseudo);
-      ok(!DOMUtils.hasPseudoClassLock(target.rawNode(), pseudo),
+      ok(!InspectorUtils.hasPseudoClassLock(target.rawNode(), pseudo),
          "Don't expect lock in dom: " + pseudo);
     }
   }
 }
 
 function checkMutations(mutations, expectations) {
   is(mutations.length, expectations.length, "Should get the right number of mutations.");
   for (let i = 0; i < mutations.length; i++) {
@@ -167,17 +165,17 @@ addTest(function testPseudoClassLock() {
         nodeName: "DIV",
         pseudos: [":hover", ":active"],
         enabled: [false, true]
       });
     }).then(() => {
       // Now shut down the walker and make sure that clears up the remaining lock.
       return gWalker.release();
     }).then(() => {
-      ok(!DOMUtils.hasPseudoClassLock(contentNode, ":active"),
+      ok(!InspectorUtils.hasPseudoClassLock(contentNode, ":active"),
          "Pseudoclass should have been removed during destruction.");
       teardown();
     }).then(runNextTest));
   });
 });
 
   </script>
 </head>
--- a/dom/webidl/InspectorUtils.webidl
+++ b/dom/webidl/InspectorUtils.webidl
@@ -60,16 +60,22 @@ namespace InspectorUtils {
   [Throws] void setContentState(Element element, unsigned long long state);
   [Throws] void removeContentState(
       Element element,
       unsigned long long state,
       optional boolean clearActiveDocument = false);
   unsigned long long getContentState(Element element);
   [NewObject, Throws] sequence<InspectorFontFace> getUsedFontFaces(Range range);
   sequence<DOMString> getCSSPseudoElementNames();
+  void addPseudoClassLock(Element element,
+                          DOMString pseudoClass,
+                          optional boolean enabled = true);
+  void removePseudoClassLock(Element element, DOMString pseudoClass);
+  boolean hasPseudoClassLock(Element element, DOMString pseudoClass);
+  void clearPseudoClassLocks(Element element);
 };
 
 dictionary PropertyNamesOptions {
   boolean includeAliases = false;
 };
 
 dictionary InspectorRGBATuple {
   /*
--- a/layout/inspector/InspectorUtils.h
+++ b/layout/inspector/InspectorUtils.h
@@ -226,16 +226,32 @@ public:
   /**
    * Get the names of all the supported pseudo-elements.
    * Pseudo-elements which are only accepted in UA style sheets are
    * not included.
    */
   static void GetCSSPseudoElementNames(GlobalObject& aGlobal,
                                        nsTArray<nsString>& aResult);
 
+  // pseudo-class style locking methods. aPseudoClass must be a valid pseudo-class
+  // selector string, e.g. ":hover". ":any-link" and non-event-state
+  // pseudo-classes are ignored. aEnabled sets whether the psuedo-class
+  // should be locked to on or off.
+  static void AddPseudoClassLock(GlobalObject& aGlobal,
+                                 Element& aElement,
+                                 const nsAString& aPseudoClass,
+                                 bool aEnabled);
+  static void RemovePseudoClassLock(GlobalObject& aGlobal,
+                                    Element& aElement,
+                                    const nsAString& aPseudoClass);
+  static bool HasPseudoClassLock(GlobalObject& aGlobal,
+                                 Element& aElement,
+                                 const nsAString& aPseudoClass);
+  static void ClearPseudoClassLocks(GlobalObject& aGlobal, Element& aElement);
+
 private:
   static already_AddRefed<nsStyleContext>
     GetCleanStyleContextForElement(Element* aElement, nsAtom* aPseudo);
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -1040,85 +1040,66 @@ InspectorUtils::GetCSSPseudoElementNames
     CSSPseudoElementType type = static_cast<CSSPseudoElementType>(i);
     if (nsCSSPseudoElements::IsEnabled(type, CSSEnabledState::eForAllContent)) {
       nsAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type);
       aResult.AppendElement(nsDependentAtomString(atom));
     }
   }
 }
 
-} // namespace dom
-} // namespace mozilla
-
-NS_IMETHODIMP
-inDOMUtils::AddPseudoClassLock(nsIDOMElement *aElement,
-                               const nsAString &aPseudoClass,
-                               bool aEnabled,
-                               uint8_t aArgc)
+/* static */ void
+InspectorUtils::AddPseudoClassLock(GlobalObject& aGlobalObject,
+                                   Element& aElement,
+                                   const nsAString& aPseudoClass,
+                                   bool aEnabled)
 {
   EventStates state = GetStatesForPseudoClass(aPseudoClass);
   if (state.IsEmpty()) {
-    return NS_OK;
+    return;
   }
 
-  nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
-  NS_ENSURE_ARG_POINTER(element);
-
-  element->LockStyleStates(state, aArgc > 0 ? aEnabled : true);
-
-  return NS_OK;
+  aElement.LockStyleStates(state, aEnabled);
 }
 
-NS_IMETHODIMP
-inDOMUtils::RemovePseudoClassLock(nsIDOMElement *aElement,
-                                  const nsAString &aPseudoClass)
+/* static */ void
+InspectorUtils::RemovePseudoClassLock(GlobalObject& aGlobal,
+                                      Element& aElement,
+                                      const nsAString& aPseudoClass)
 {
   EventStates state = GetStatesForPseudoClass(aPseudoClass);
   if (state.IsEmpty()) {
-    return NS_OK;
+    return;
   }
 
-  nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
-  NS_ENSURE_ARG_POINTER(element);
-
-  element->UnlockStyleStates(state);
-
-  return NS_OK;
+  aElement.UnlockStyleStates(state);
 }
 
-NS_IMETHODIMP
-inDOMUtils::HasPseudoClassLock(nsIDOMElement *aElement,
-                               const nsAString &aPseudoClass,
-                               bool *_retval)
+/* static */ bool
+InspectorUtils::HasPseudoClassLock(GlobalObject& aGlobalObject,
+                                   Element& aElement,
+                                   const nsAString& aPseudoClass)
 {
   EventStates state = GetStatesForPseudoClass(aPseudoClass);
   if (state.IsEmpty()) {
-    *_retval = false;
-    return NS_OK;
+    return false;
   }
 
-  nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
-  NS_ENSURE_ARG_POINTER(element);
-
-  EventStates locks = element->LockedStyleStates().mLocks;
-
-  *_retval = locks.HasAllStates(state);
-  return NS_OK;
+  EventStates locks = aElement.LockedStyleStates().mLocks;
+  return locks.HasAllStates(state);
 }
 
-NS_IMETHODIMP
-inDOMUtils::ClearPseudoClassLocks(nsIDOMElement *aElement)
+/* static */ void
+InspectorUtils::ClearPseudoClassLocks(GlobalObject& aGlobalObject,
+                                      Element& aElement)
 {
-  nsCOMPtr<mozilla::dom::Element> element = do_QueryInterface(aElement);
-  NS_ENSURE_ARG_POINTER(element);
+  aElement.ClearStyleStateLocks();
+}
 
-  element->ClearStyleStateLocks();
-
-  return NS_OK;
-}
+} // namespace dom
+} // namespace mozilla
 
 NS_IMETHODIMP
 inDOMUtils::ParseStyleSheet(nsIDOMCSSStyleSheet *aSheet,
                             const nsAString& aInput)
 {
   RefPtr<CSSStyleSheet> geckoSheet = do_QueryObject(aSheet);
   if (geckoSheet) {
     NS_ENSURE_ARG_POINTER(geckoSheet);
--- a/layout/inspector/inIDOMUtils.idl
+++ b/layout/inspector/inIDOMUtils.idl
@@ -15,27 +15,16 @@ interface nsIDOMNode;
 interface nsIDOMNodeList;
 interface nsIDOMFontFaceList;
 interface nsIDOMRange;
 interface nsIDOMCSSStyleSheet;
 
 [scriptable, uuid(362e98c3-82c2-4ad8-8dcb-00e8e4eab497)]
 interface inIDOMUtils : nsISupports
 {
-  // pseudo-class style locking methods. aPseudoClass must be a valid pseudo-class
-  // selector string, e.g. ":hover". ":any-link" and non-event-state
-  // pseudo-classes are ignored. aEnabled sets whether the psuedo-class
-  // should be locked to on or off.
-  [optional_argc] void addPseudoClassLock(in nsIDOMElement aElement,
-                                          in DOMString aPseudoClass,
-                                          [optional] in boolean aEnabled);
-  void removePseudoClassLock(in nsIDOMElement aElement, in DOMString aPseudoClass);
-  bool hasPseudoClassLock(in nsIDOMElement aElement, in DOMString aPseudoClass);
-  void clearPseudoClassLocks(in nsIDOMElement aElement);
-
   /**
    * Parse CSS and update the style sheet in place.
    *
    * @param DOMCSSStyleSheet aSheet
    * @param DOMString aInput
    *        The new source string for the style sheet.
    */
   void parseStyleSheet(in nsIDOMCSSStyleSheet aSheet, in DOMString aInput);
--- a/layout/inspector/tests/chrome/test_bug708874.xul
+++ b/layout/inspector/tests/chrome/test_bug708874.xul
@@ -9,18 +9,16 @@ https://bugzilla.mozilla.org/show_bug.cg
         xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
         onload="RunTests();">
   <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
   <script type="application/javascript">
   <![CDATA[
 
 /** Test for Bug 708874 - API for locking pseudo-class state of an element **/
 
-var DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]
-               .getService(Components.interfaces.inIDOMUtils);
 var DOMWindowUtils = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
                      .getInterface(Components.interfaces.nsIDOMWindowUtils);
 
 var defaultColor = "rgb(0, 0, 0)";
 var disabledColor = "rgb(40, 0, 0)";
 
 function RunTests() {
   testLockEnabled();
@@ -32,29 +30,29 @@ function RunTests() {
 }
 
 function testLockEnabled() {
   var button = document.getElementById("test-button");
 
   /* starting state is enabled */
   button.removeAttribute("disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), false,
      "doesn't have lock at start");
 
   is(window.getComputedStyle(button).color, defaultColor,
      "color is default color before locking on");
 
   is(button.matches(":disabled"), false,
      "doesn't match selector at start");
 
   /* lock */
-  DOMUtils.addPseudoClassLock(button, ":disabled");
+  InspectorUtils.addPseudoClassLock(button, ":disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), true,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), true,
      "hasPseudoClassLock is true after locking");
 
   is(window.getComputedStyle(button).color, disabledColor,
      ":disabled style applied after adding lock");
 
   is(button.matches(":disabled"), true,
      "matches selector after adding lock");
 
@@ -63,19 +61,19 @@ function testLockEnabled() {
 
   is(window.getComputedStyle(button).color, disabledColor,
      ":disabled style still applied after really disabling");
 
   is(button.matches(":disabled"), true,
     "matches selector after adding lock");
 
   /* remove lock */
-  DOMUtils.removePseudoClassLock(button, ":disabled");
+  InspectorUtils.removePseudoClassLock(button, ":disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), false,
      "hasPseudoClassLock is false after removing on lock");
 
   is(window.getComputedStyle(button).color, disabledColor,
      ":disabled style still applied after removing lock");
 
   is(button.matches(":disabled"), true,
      "matches selector after removing lock");
 
@@ -91,29 +89,29 @@ function testLockEnabled() {
 
 
 function testLockDisabled() {
   var button = document.getElementById("test-button");
 
   /* starting state is disabled */
   button.setAttribute("disabled", "disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), false,
      "doesn't have lock at start");
 
   is(window.getComputedStyle(button).color, disabledColor,
      "color is :disabled color before locking");
 
   is(button.matches(":disabled"), true,
     "matches selector before locking");
 
   /* lock */
-  DOMUtils.addPseudoClassLock(button, ":disabled");
+  InspectorUtils.addPseudoClassLock(button, ":disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), true,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), true,
      "hasPseudoClassLock is true after locking");
 
   is(window.getComputedStyle(button).color, disabledColor,
      ":disabled style still applied after adding on lock");
 
   is(button.matches(":disabled"), true,
    "matches selector after locking");
 
@@ -122,19 +120,19 @@ function testLockDisabled() {
 
   is(window.getComputedStyle(button).color, disabledColor,
      ":disabled style applied after enabling");
 
   is(button.matches(":disabled"), true,
    "matches selector after enabling with lock on");
 
   /* remove lock */
-  DOMUtils.removePseudoClassLock(button, ":disabled");
+  InspectorUtils.removePseudoClassLock(button, ":disabled");
 
-  is(DOMUtils.hasPseudoClassLock(button, ":disabled"), false,
+  is(InspectorUtils.hasPseudoClassLock(button, ":disabled"), false,
      "hasPseudoClassLock is false after removing on lock");
 
   is(window.getComputedStyle(button).color, defaultColor,
      "default style applied after removing lock");
 
   is(button.matches(":disabled"), false,
      "doesn't match selector after unlocking");
 
@@ -149,45 +147,45 @@ function testLockDisabled() {
 }
 
 function testVisited() {
   var link = document.getElementById("test-link");
   var visitedColor = "rgb(20, 0, 0)";
   var unvisitedColor = "rgb(30, 0, 0)";
 
   /* lock visited */
-  DOMUtils.addPseudoClassLock(link, ":visited");
+  InspectorUtils.addPseudoClassLock(link, ":visited");
 
-  is(DOMUtils.hasPseudoClassLock(link, ":visited"), true,
+  is(InspectorUtils.hasPseudoClassLock(link, ":visited"), true,
      "hasPseudoClassLock is true after adding lock");
 
   var color = DOMWindowUtils.getVisitedDependentComputedStyle(link,
                 null, "color");
   is(color, visitedColor, "color is :visited color after locking");
 
   /* lock unvisited */
-  DOMUtils.addPseudoClassLock(link, ":link");
+  InspectorUtils.addPseudoClassLock(link, ":link");
 
-  is(DOMUtils.hasPseudoClassLock(link, ":link"), true,
+  is(InspectorUtils.hasPseudoClassLock(link, ":link"), true,
      "hasPseudoClassLock is true after adding :link lock");
 
-  is(DOMUtils.hasPseudoClassLock(link, ":visited"), false,
+  is(InspectorUtils.hasPseudoClassLock(link, ":visited"), false,
      "hasPseudoClassLock is false for :visited after adding :link lock");
 
   var color = DOMWindowUtils.getVisitedDependentComputedStyle(link,
                  null, "color");
   is(color, unvisitedColor, "color is :link color after locking :link");
 
   /* lock visited back on */
-  DOMUtils.addPseudoClassLock(link, ":visited");
+  InspectorUtils.addPseudoClassLock(link, ":visited");
 
-  is(DOMUtils.hasPseudoClassLock(link, ":visited"), true,
+  is(InspectorUtils.hasPseudoClassLock(link, ":visited"), true,
     "hasPseudoClassLock is true after adding :visited lock");
 
-  is(DOMUtils.hasPseudoClassLock(link, ":link"), false,
+  is(InspectorUtils.hasPseudoClassLock(link, ":link"), false,
     "hasPseudoClassLock is false for :link after adding :visited lock");
 
   var color = DOMWindowUtils.getVisitedDependentComputedStyle(link,
                null, "color");
   is(color, visitedColor, "color is :visited color after locking back on");
 }
 
 function testMultiple() {
@@ -207,35 +205,35 @@ function testMultiple() {
     ":focus": {
       property: "font-weight",
       value: "800",
       defaultValue: "400"
     }
   };
 
   for (var pseudo in styles) {
-    DOMUtils.addPseudoClassLock(div, pseudo);
+    InspectorUtils.addPseudoClassLock(div, pseudo);
   }
 
   for (var pseudo in styles) {
-    is(DOMUtils.hasPseudoClassLock(div, pseudo), true,
+    is(InspectorUtils.hasPseudoClassLock(div, pseudo), true,
        "hasPseudoClassLock is true after locking");
 
     var style = styles[pseudo];
     is(window.getComputedStyle(div).getPropertyValue(style.property),
        style.value, "style for pseudo-class is applied after locking");
 
     is(div.matches(pseudo), true,
        "matches selector after locking");
   }
 
-  DOMUtils.clearPseudoClassLocks(div);
+  InspectorUtils.clearPseudoClassLocks(div);
 
   for (var pseudo in styles) {
-    is(DOMUtils.hasPseudoClassLock(div, pseudo), false,
+    is(InspectorUtils.hasPseudoClassLock(div, pseudo), false,
        "hasPseudoClassLock is false after clearing");
 
     is(window.getComputedStyle(div).getPropertyValue(style.property),
        style.defaultValue, "style is back to default after clearing");
 
     is(div.matches(pseudo), false,
       "doesn't match selector after unlocking");
   }
@@ -244,33 +242,33 @@ function testMultiple() {
 function testInvalid() {
   var div = document.getElementById("test-div");
   var pseudos = ["not a valid pseudo-class", ":ny-link", ":first-child"];
 
   for (var i = 0; i < pseudos.length; i++) {
     var pseudo = pseudos[i];
 
     // basically make sure these don't crash the browser.
-    DOMUtils.addPseudoClassLock(div, pseudo);
+    InspectorUtils.addPseudoClassLock(div, pseudo);
 
-    is(DOMUtils.hasPseudoClassLock(div, pseudo), false);
+    is(InspectorUtils.hasPseudoClassLock(div, pseudo), false);
 
-    DOMUtils.removePseudoClassLock(div, pseudo);
+    InspectorUtils.removePseudoClassLock(div, pseudo);
   }
 }
 
 function testNotElement() {
   for (var value of [null, undefined, {}]) {
-    SimpleTest.doesThrow(() => DOMUtils.hasPseudoClassLock(value, ":hover"),
+    SimpleTest.doesThrow(() => InspectorUtils.hasPseudoClassLock(value, ":hover"),
                          "hasPseudoClassLock should throw for " + value);
-    SimpleTest.doesThrow(() => DOMUtils.addPseudoClassLock(value, ":hover"),
+    SimpleTest.doesThrow(() => InspectorUtils.addPseudoClassLock(value, ":hover"),
                          "addPseudoClassLock should throw for " + value);
-    SimpleTest.doesThrow(() => DOMUtils.removePseudoClassLock(value, ":hover"),
+    SimpleTest.doesThrow(() => InspectorUtils.removePseudoClassLock(value, ":hover"),
                          "removePseudoClassLock should throw for " + value);
-    SimpleTest.doesThrow(() => DOMUtils.clearPseudoClassLocks(value),
+    SimpleTest.doesThrow(() => InspectorUtils.clearPseudoClassLocks(value),
                          "clearPseudoClassLocks should throw for " + value);
   }
 }
   ]]>
   </script>
 
   <body xmlns="http://www.w3.org/1999/xhtml">
     <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=708874"
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -7,18 +7,16 @@
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
 XPCOMUtils.defineLazyModuleGetter(this, "BrowserUtils",
                                   "resource://gre/modules/BrowserUtils.jsm");
-XPCOMUtils.defineLazyServiceGetter(this, "DOMUtils",
-                                   "@mozilla.org/inspector/dom-utils;1", "inIDOMUtils");
 XPCOMUtils.defineLazyModuleGetter(this, "DeferredTask",
                                   "resource://gre/modules/DeferredTask.jsm");
 
 Cu.importGlobalProperties(["InspectorUtils"]);
 
 const kStateActive = 0x00000001; // NS_EVENT_STATE_ACTIVE
 const kStateHover = 0x00000004; // NS_EVENT_STATE_HOVER
 
@@ -136,37 +134,37 @@ this.SelectContentHelper.prototype = {
 
   _setupPseudoClassStyles() {
     if (this._pseudoStylesSetup) {
       throw new Error("pseudo styles must not be set up yet");
     }
     // Do all of the things that change style at once, before we read
     // any styles.
     this._pseudoStylesSetup = true;
-    DOMUtils.addPseudoClassLock(this.element, ":focus");
+    InspectorUtils.addPseudoClassLock(this.element, ":focus");
     let lockedDescendants = this._lockedDescendants = this.element.querySelectorAll(":checked");
     for (let child of lockedDescendants) {
       // Selected options have the :checked pseudo-class, which
       // we want to disable before calculating the computed
       // styles since the user agent styles alter the styling
       // based on :checked.
-      DOMUtils.addPseudoClassLock(child, ":checked", false);
+      InspectorUtils.addPseudoClassLock(child, ":checked", false);
     }
   },
 
   _clearPseudoClassStyles() {
     if (!this._pseudoStylesSetup) {
       throw new Error("pseudo styles must be set up already");
     }
     // Undo all of the things that change style at once, after we're
     // done reading styles.
-    DOMUtils.clearPseudoClassLocks(this.element);
+    InspectorUtils.clearPseudoClassLocks(this.element);
     let lockedDescendants = this._lockedDescendants;
     for (let child of lockedDescendants) {
-      DOMUtils.clearPseudoClassLocks(child);
+      InspectorUtils.clearPseudoClassLocks(child);
     }
     this._lockedDescendants = null;
     this._pseudoStylesSetup = false;
   },
 
   _getBoundingContentRect() {
     return BrowserUtils.getElementBoundingScreenRect(this.element);
   },