Bug 1427419 - Part 21: Move content state methods from inIDOMUtils to InspectorUtils. r=bz draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 06 Jan 2018 15:08:15 +0800
changeset 716766 6fa77e224bdfef2295110e92aa07cc952f9d3c89
parent 716765 27cf48b312e9fe5256c612ea4b0cf0d57c96c43a
child 716767 d7be1f779edd9a764e89b1323b9128a40c0b54d7
push id94496
push userbmo:cam@mcc.id.au
push dateSat, 06 Jan 2018 07:08:40 +0000
reviewersbz
bugs1427419
milestone59.0a1
Bug 1427419 - Part 21: Move content state methods from inIDOMUtils to InspectorUtils. r=bz MozReview-Commit-ID: KfrUdNU4as3
dom/events/EventStates.h
dom/webidl/InspectorUtils.webidl
layout/inspector/InspectorUtils.h
layout/inspector/inDOMUtils.cpp
layout/inspector/inIDOMUtils.idl
layout/inspector/inLayoutUtils.cpp
layout/inspector/inLayoutUtils.h
layout/inspector/tests/test_bug462787.html
layout/inspector/tests/test_bug462789.html
toolkit/modules/SelectContentHelper.jsm
--- a/dom/events/EventStates.h
+++ b/dom/events/EventStates.h
@@ -145,18 +145,19 @@ public:
    *
    * @return Whether the object has all states from aEventStates
    */
   bool HasAllStates(EventStates aEventStates) const
   {
     return (mStates & aEventStates.mStates) == aEventStates.mStates;
   }
 
-  // We only need that method for inDOMUtils::GetContentState.
-  // If inDOMUtils::GetContentState is removed, this method should be removed.
+  // We only need that method for InspectorUtils::GetContentState.
+  // If InspectorUtils::GetContentState is removed, this method should
+  // be removed.
   InternalType GetInternalValue() const {
     return mStates;
   }
 
   /**
    * Method used to get the appropriate state representation for Servo.
    */
   ServoType ServoValue() const
--- a/dom/webidl/InspectorUtils.webidl
+++ b/dom/webidl/InspectorUtils.webidl
@@ -52,16 +52,22 @@ namespace InspectorUtils {
   const unsigned long TYPE_NUMBER = 10;
   [Throws] boolean cssPropertySupportsType(DOMString property, unsigned long type);
 
   boolean isIgnorableWhitespace(CharacterData dataNode);
   Node? getParentForNode(Node node, boolean showingAnonymousContent);
   [NewObject] NodeList getChildrenForNode(Node node,
                                           boolean showingAnonymousContent);
   sequence<DOMString> getBindingURLs(Element element);
+  [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);
 };
 
 dictionary PropertyNamesOptions {
   boolean includeAliases = false;
 };
 
 dictionary InspectorRGBATuple {
   /*
--- a/layout/inspector/InspectorUtils.h
+++ b/layout/inspector/InspectorUtils.h
@@ -189,16 +189,39 @@ public:
   static already_AddRefed<nsINodeList> GetChildrenForNode(
       nsINode& aNode,
       bool aShowingAnonymousContent);
 
   static void GetBindingURLs(GlobalObject& aGlobal,
                              Element& aElement,
                              nsTArray<nsString>& aResult);
 
+  /**
+   * Setting and removing content state on an element. Both these functions
+   * call EventStateManager::SetContentState internally; the difference is
+   * that for the remove case we simply pass in nullptr for the element.
+   * Use them accordingly.
+   *
+   * When removing the active state, you may optionally also clear the active
+   * document as well by setting aClearActiveDocument
+   *
+   * @return Returns true if the state was set successfully. See more details
+   * in EventStateManager.h SetContentState.
+   */
+  static bool SetContentState(GlobalObject& aGlobal,
+                              Element& aElement,
+                              uint64_t aState,
+                              ErrorResult& aRv);
+  static bool RemoveContentState(GlobalObject& aGlobal,
+                                 Element& aElement,
+                                 uint64_t aState,
+                                 bool aClearActiveDocument,
+                                 ErrorResult& aRv);
+  static uint64_t GetContentState(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
@@ -888,80 +888,68 @@ InspectorUtils::GetBindingURLs(GlobalObj
     nsCOMPtr<nsIURI> bindingURI = binding->PrototypeBinding()->BindingURI();
     bindingURI->GetSpec(spec);
     nsString* resultURI = aResult.AppendElement();
     CopyASCIItoUTF16(spec, *resultURI);
     binding = binding->GetBaseBinding();
   }
 }
 
-} // namespace dom
-} // namespace mozilla
-
-NS_IMETHODIMP
-inDOMUtils::SetContentState(nsIDOMElement* aElement,
-                            EventStates::InternalType aState,
-                            bool* aRetVal)
+/* static */ bool
+InspectorUtils::SetContentState(GlobalObject& aGlobalObject,
+                                Element& aElement,
+                                uint64_t aState,
+                                ErrorResult& aRv)
 {
-  NS_ENSURE_ARG_POINTER(aElement);
-
   RefPtr<EventStateManager> esm =
     inLayoutUtils::GetEventStateManagerFor(aElement);
-  NS_ENSURE_TRUE(esm, NS_ERROR_INVALID_ARG);
+  if (!esm) {
+    aRv.Throw(NS_ERROR_INVALID_ARG);
+    return false;
+  }
 
-  nsCOMPtr<nsIContent> content;
-  content = do_QueryInterface(aElement);
-  NS_ENSURE_TRUE(content, NS_ERROR_INVALID_ARG);
-
-  *aRetVal = esm->SetContentState(content, EventStates(aState));
-  return NS_OK;
+  return esm->SetContentState(&aElement, EventStates(aState));
 }
 
-NS_IMETHODIMP
-inDOMUtils::RemoveContentState(nsIDOMElement* aElement,
-                               EventStates::InternalType aState,
-                               bool aClearActiveDocument,
-                               bool* aRetVal)
+/* static */ bool
+InspectorUtils::RemoveContentState(GlobalObject& aGlobalObject,
+                                   Element& aElement,
+                                   uint64_t aState,
+                                   bool aClearActiveDocument,
+                                   ErrorResult& aRv)
 {
-  NS_ENSURE_ARG_POINTER(aElement);
-
   RefPtr<EventStateManager> esm =
     inLayoutUtils::GetEventStateManagerFor(aElement);
-  NS_ENSURE_TRUE(esm, NS_ERROR_INVALID_ARG);
+  if (!esm) {
+    aRv.Throw(NS_ERROR_INVALID_ARG);
+    return false;
+  }
 
-  *aRetVal = esm->SetContentState(nullptr, EventStates(aState));
+  bool result = esm->SetContentState(nullptr, EventStates(aState));
 
   if (aClearActiveDocument && EventStates(aState) == NS_EVENT_STATE_ACTIVE) {
     EventStateManager* activeESM = static_cast<EventStateManager*>(
       EventStateManager::GetActiveEventStateManager());
     if (activeESM == esm) {
       EventStateManager::ClearGlobalActiveContent(nullptr);
     }
   }
 
-  return NS_OK;
+  return result;
 }
 
-NS_IMETHODIMP
-inDOMUtils::GetContentState(nsIDOMElement* aElement,
-                            EventStates::InternalType* aState)
+/* static */ uint64_t
+InspectorUtils::GetContentState(GlobalObject& aGlobalObject,
+                                Element& aElement)
 {
-  *aState = 0;
-  nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
-  NS_ENSURE_ARG_POINTER(content);
-
   // NOTE: if this method is removed,
   // please remove GetInternalValue from EventStates
-  *aState = content->AsElement()->State().GetInternalValue();
-  return NS_OK;
+  return aElement.State().GetInternalValue();
 }
 
-namespace mozilla {
-namespace dom {
-
 /* static */ already_AddRefed<nsStyleContext>
 InspectorUtils::GetCleanStyleContextForElement(dom::Element* aElement,
                                                nsAtom* aPseudo)
 {
   MOZ_ASSERT(aElement);
 
   nsIDocument* doc = aElement->GetComposedDoc();
   if (!doc) {
--- a/layout/inspector/inIDOMUtils.idl
+++ b/layout/inspector/inIDOMUtils.idl
@@ -15,34 +15,16 @@ interface nsIDOMNode;
 interface nsIDOMNodeList;
 interface nsIDOMFontFaceList;
 interface nsIDOMRange;
 interface nsIDOMCSSStyleSheet;
 
 [scriptable, uuid(362e98c3-82c2-4ad8-8dcb-00e8e4eab497)]
 interface inIDOMUtils : nsISupports
 {
-  // content state utilities
-  unsigned long long getContentState(in nsIDOMElement aElement);
-  /**
-   * Setting and removing content state on an element. Both these functions
-   * calling EventStateManager::SetContentState internally, the difference is
-   * that for the remove case we simply pass in nullptr for the element.
-   * Use them accordingly.
-   *
-   * When removing the active state, you may optionally also clear the active
-   * document as well by setting aClearActiveDocument
-   *
-   * @return Returns true if the state was set successfully. See more details
-   * in EventStateManager.h SetContentState.
-   */
-  bool setContentState(in nsIDOMElement aElement, in unsigned long long aState);
-  bool removeContentState(in nsIDOMElement aElement, in unsigned long long aState,
-                          [optional] in bool aClearActiveDocument);
-
   nsIDOMFontFaceList getUsedFontFaces(in nsIDOMRange aRange);
 
   /**
    * Get the names of all the supported pseudo-elements.
    * Pseudo-elements which are only accepted in UA style sheets are
    * not included.
    *
    * @param {unsigned long} aCount the number of items returned
--- a/layout/inspector/inLayoutUtils.cpp
+++ b/layout/inspector/inLayoutUtils.cpp
@@ -17,30 +17,20 @@
 #include "mozilla/EventStateManager.h"
 #include "mozilla/dom/Element.h"
 
 using namespace mozilla;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 EventStateManager*
-inLayoutUtils::GetEventStateManagerFor(nsIDOMElement *aElement)
+inLayoutUtils::GetEventStateManagerFor(Element& aElement)
 {
-  NS_PRECONDITION(aElement, "Passing in a null element is bad");
-
-  nsCOMPtr<nsIDOMDocument> domDoc;
-  aElement->GetOwnerDocument(getter_AddRefs(domDoc));
-  nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
-
-  if (!doc) {
-    NS_WARNING("Could not get an nsIDocument!");
-    return nullptr;
-  }
-
-  nsIPresShell *shell = doc->GetShell();
+  nsIDocument* doc = aElement.OwnerDoc();
+  nsIPresShell* shell = doc->GetShell();
   if (!shell)
     return nullptr;
 
   return shell->GetPresContext()->EventStateManager();
 }
 
 nsIDOMDocument*
 inLayoutUtils::GetSubDocumentFor(nsIDOMNode* aNode)
--- a/layout/inspector/inLayoutUtils.h
+++ b/layout/inspector/inLayoutUtils.h
@@ -4,25 +4,28 @@
  * 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/. */
 
 #ifndef __inLayoutUtils_h__
 #define __inLayoutUtils_h__
 
 class nsIDocument;
 class nsIDOMDocument;
-class nsIDOMElement;
 class nsIDOMNode;
+class nsINode;
 
 namespace mozilla {
 class EventStateManager;
+namespace dom {
+class Element;
+} // namespace dom
 } // namespace mozilla
 
 class inLayoutUtils
 {
 public:
-  static mozilla::EventStateManager*
-           GetEventStateManagerFor(nsIDOMElement *aElement);
+  static mozilla::EventStateManager* GetEventStateManagerFor(
+      mozilla::dom::Element& aElement);
   static nsIDOMDocument* GetSubDocumentFor(nsIDOMNode* aNode);
   static nsINode* GetContainerFor(const nsIDocument& aDoc);
 };
 
 #endif // __inLayoutUtils_h__
--- a/layout/inspector/tests/test_bug462787.html
+++ b/layout/inspector/tests/test_bug462787.html
@@ -17,20 +17,16 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 462787 **/
 
 const InspectorUtils = SpecialPowers.InspectorUtils;
 
 function do_test() {
-  const INVALID_POINTER = SpecialPowers.Cr.NS_ERROR_INVALID_POINTER;
-
-  var utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
-                             .getService(SpecialPowers.Ci.inIDOMUtils);
   try {
     InspectorUtils.getCSSStyleRules(null);
     ok(false, "expected an exception"); 
   }
   catch(e) {
     is(e.name, "TypeError", "got the expected exception");
   }
 
@@ -54,40 +50,37 @@ function do_test() {
     InspectorUtils.getParentForNode(null, true);
     ok(false, "expected an exception");
   }
   catch(e) {
     is(e.name, "TypeError", "got the expected exception");
   }
 
   try {
-    utils.getBindingURLs(null); 
+    InspectorUtils.getBindingURLs(null); 
     ok(false, "expected an exception"); 
   }
   catch(e) {
-    e = SpecialPowers.wrap(e);
     is(e.name, "TypeError", "got the expected exception");
   }
 
   try {
-    utils.getContentState(null); 
+    InspectorUtils.getContentState(null); 
     ok(false, "expected an exception"); 
   }
   catch(e) {
-    e = SpecialPowers.wrap(e);
-    is(e.result, INVALID_POINTER, "got the expected exception");
+    is(e.name, "TypeError", "got the expected exception");
   }
 
   try {
-    utils.setContentState(null, false); 
+    InspectorUtils.setContentState(null, false); 
     ok(false, "expected an exception"); 
   }
   catch(e) {
-    e = SpecialPowers.wrap(e);
-    is(e.result, INVALID_POINTER, "got the expected exception");
+    is(e.name, "TypeError", "got the expected exception");
   }
 
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(do_test);
 
--- a/layout/inspector/tests/test_bug462789.html
+++ b/layout/inspector/tests/test_bug462789.html
@@ -17,22 +17,18 @@ https://bugzilla.mozilla.org/show_bug.cg
 <pre id="test">
 <script type="application/javascript">
 
 /** Test for Bug 462789 **/
 
 const InspectorUtils = SpecialPowers.InspectorUtils;
 
 function do_test() {
-  const ERROR_INVALID_ARG = 0x80070057;
   const DOCUMENT_NODE_TYPE = 9;
 
-  var utils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"]
-                             .getService(SpecialPowers.Ci.inIDOMUtils);
-
   var iframe = document.getElementById("bug462789_iframe");
   var docElement = iframe.contentDocument.documentElement;
   var body = docElement.children[1];
   var rule = iframe.contentDocument.styleSheets[0].cssRules[0];
   var text = body.firstChild;
 
   try {
     var res = InspectorUtils.getCSSStyleRules(docElement);
@@ -65,30 +61,21 @@ function do_test() {
   try {
     var res = InspectorUtils.getBindingURLs(docElement);
     ok(Array.isArray(SpecialPowers.unwrap(res)), "getBindingURLs result type");
     is(res.length, 0, "getBindingURLs array length");
   }
   catch(e) { ok(false, "got an unexpected exception:" + e); }
 
   try {
-    utils.getContentState(docElement);
+    InspectorUtils.getContentState(docElement);
     ok(true, "Should not throw"); 
   }
   catch(e) { ok(false, "Got an exception: " + e); }
 
-  try {
-    utils.setContentState(docElement, false);
-    ok(false, "expected an exception"); 
-  }
-  catch(e) {
-    e = SpecialPowers.wrap(e);
-    is(e.result, ERROR_INVALID_ARG, "got the expected exception");
-  }
-
   SimpleTest.finish();
 }
 
 SimpleTest.waitForExplicitFinish();
 addLoadEvent(do_test);
 
 </script>
 </pre>
--- a/toolkit/modules/SelectContentHelper.jsm
+++ b/toolkit/modules/SelectContentHelper.jsm
@@ -12,16 +12,18 @@ Cu.import("resource://gre/modules/XPCOMU
 
 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
 
 const SUPPORTED_PROPERTIES = [
   "color",
   "background-color",
   "text-shadow",
 ];
@@ -276,19 +278,18 @@ this.SelectContentHelper.prototype = {
           // - If the user pressed ESC key or clicks outside the dropdown,
           //   we fire nothing as the selected option is unchanged.
           if (this.closedWithClickOn) {
             this.dispatchMouseEvent(win, selectedOption, "mousedown");
             this.dispatchMouseEvent(win, selectedOption, "mouseup");
           }
 
           // Clear active document no matter user selects via keyboard or mouse
-          DOMUtils.removeContentState(this.element,
-                                      kStateActive,
-                                      /* aClearActiveDocument */ true);
+          InspectorUtils.removeContentState(this.element, kStateActive,
+                                            /* aClearActiveDocument */ true);
 
           // Fire input and change events when selected option changes
           if (this.initialSelection !== selectedOption) {
             let inputEvent = new win.UIEvent("input", {
               bubbles: true,
             });
             this.element.dispatchEvent(inputEvent);
 
@@ -303,29 +304,29 @@ this.SelectContentHelper.prototype = {
             this.dispatchMouseEvent(win, selectedOption, "click");
           }
 
           this.uninit();
           break;
         }
 
       case "Forms:MouseOver":
-        DOMUtils.setContentState(this.element, kStateHover);
+        InspectorUtils.setContentState(this.element, kStateHover);
         break;
 
       case "Forms:MouseOut":
-        DOMUtils.removeContentState(this.element, kStateHover);
+        InspectorUtils.removeContentState(this.element, kStateHover);
         break;
 
       case "Forms:MouseUp":
         let win = this.element.ownerGlobal;
         if (message.data.onAnchor) {
           this.dispatchMouseEvent(win, this.element, "mouseup");
         }
-        DOMUtils.removeContentState(this.element, kStateActive);
+        InspectorUtils.removeContentState(this.element, kStateActive);
         if (message.data.onAnchor) {
           this.dispatchMouseEvent(win, this.element, "click");
         }
         break;
 
       case "Forms:SearchFocused":
         this._closeAfterBlur = false;
         break;