Bug 1427419 - Part 19: Move inIDOMUtils.getChildrenForNode to InspectorUtils. r=bz draft
authorCameron McCormack <cam@mcc.id.au>
Sat, 06 Jan 2018 15:08:15 +0800
changeset 716764 32871dcf0c52d69278e2e1fd9e3ef285397e28d8
parent 716763 e05fc71f5ec4a1a2dbfdb87c9227d496ab7991ca
child 716765 27cf48b312e9fe5256c612ea4b0cf0d57c96c43a
push id94496
push userbmo:cam@mcc.id.au
push dateSat, 06 Jan 2018 07:08:40 +0000
reviewersbz
bugs1427419
milestone59.0a1
Bug 1427419 - Part 19: Move inIDOMUtils.getChildrenForNode to InspectorUtils. r=bz MozReview-Commit-ID: 5AznAfpZIuN
dom/webidl/InspectorUtils.webidl
layout/inspector/InspectorUtils.h
layout/inspector/inDOMUtils.cpp
layout/inspector/inDOMView.cpp
layout/inspector/inDOMView.h
layout/inspector/inIDOMUtils.idl
layout/inspector/tests/test_bug609549.xhtml
mobile/android/tests/browser/robocop/testVideoControls.js
toolkit/content/tests/widgets/head.js
toolkit/content/tests/widgets/test_videocontrols_audio.html
toolkit/content/tests/widgets/test_videocontrols_iframe_fullscreen.html
--- a/dom/webidl/InspectorUtils.webidl
+++ b/dom/webidl/InspectorUtils.webidl
@@ -49,16 +49,18 @@ namespace InspectorUtils {
   const unsigned long TYPE_GRADIENT = 7;
   const unsigned long TYPE_TIMING_FUNCTION = 8;
   const unsigned long TYPE_IMAGE_RECT = 9;
   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);
 };
 
 dictionary PropertyNamesOptions {
   boolean includeAliases = false;
 };
 
 dictionary InspectorRGBATuple {
   /*
--- a/layout/inspector/InspectorUtils.h
+++ b/layout/inspector/InspectorUtils.h
@@ -174,16 +174,27 @@ public:
                                    bool aShowingAnonymousContent);
   static nsINode* GetParentForNode(GlobalObject& aGlobalObject,
                                    nsINode& aNode,
                                    bool aShowingAnonymousContent)
   {
     return GetParentForNode(aNode, aShowingAnonymousContent);
   }
 
+  static already_AddRefed<nsINodeList> GetChildrenForNode(
+      GlobalObject& aGlobalObject,
+      nsINode& aNode,
+      bool aShowingAnonymousContent)
+  {
+    return GetChildrenForNode(aNode, aShowingAnonymousContent);
+  }
+  static already_AddRefed<nsINodeList> GetChildrenForNode(
+      nsINode& aNode,
+      bool aShowingAnonymousContent);
+
 private:
   static already_AddRefed<nsStyleContext>
     GetCleanStyleContextForElement(Element* aElement, nsAtom* aPseudo);
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -155,47 +155,35 @@ InspectorUtils::GetParentForNode(nsINode
   if (!parent) {
     // Ok, just get the normal DOM parent node
     return aNode.GetParentNode();
   }
 
   return parent;
 }
 
-} // namespace dom
-} // namespace mozilla
-
-NS_IMETHODIMP
-inDOMUtils::GetChildrenForNode(nsIDOMNode* aNode,
-                               bool aShowingAnonymousContent,
-                               nsIDOMNodeList** aChildren)
+/* static */ already_AddRefed<nsINodeList>
+InspectorUtils::GetChildrenForNode(nsINode& aNode,
+                                   bool aShowingAnonymousContent)
 {
-  NS_ENSURE_ARG_POINTER(aNode);
-  NS_PRECONDITION(aChildren, "Must have an out parameter");
-
-  nsCOMPtr<nsIDOMNodeList> kids;
+  nsCOMPtr<nsINodeList> kids;
 
   if (aShowingAnonymousContent) {
-    nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
-    if (content) {
-      kids = content->GetChildren(nsIContent::eAllChildren);
+    if (aNode.IsContent()) {
+      kids = aNode.AsContent()->GetChildren(nsIContent::eAllChildren);
     }
   }
 
   if (!kids) {
-    aNode->GetChildNodes(getter_AddRefs(kids));
+    kids = aNode.ChildNodes();
   }
 
-  kids.forget(aChildren);
-  return NS_OK;
+  return kids.forget();
 }
 
-namespace mozilla {
-namespace dom {
-
 /* static */ void
 InspectorUtils::GetCSSStyleRules(GlobalObject& aGlobalObject,
                                  Element& aElement,
                                  const nsAString& aPseudo,
                                  nsTArray<RefPtr<css::Rule>>& aResult)
 {
   RefPtr<nsAtom> pseudoElt;
   if (!aPseudo.IsEmpty()) {
--- a/layout/inspector/inDOMView.cpp
+++ b/layout/inspector/inDOMView.cpp
@@ -1186,27 +1186,21 @@ inDOMView::GetChildNodesFor(nsIDOMNode* 
       element->GetAttributes(getter_AddRefs(attrs));
       if (attrs) {
         AppendAttrsToArray(attrs, aResult);
       }
     }
   }
 
   if (mWhatToShow & nsIDOMNodeFilter::SHOW_ELEMENT) {
-    nsCOMPtr<nsIDOMNodeList> kids;
-    if (!mDOMUtils) {
-      mDOMUtils = services::GetInDOMUtils();
-      if (!mDOMUtils) {
-        return NS_ERROR_FAILURE;
-      }
-    }
+    nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+    MOZ_ASSERT(node);
 
-    mDOMUtils->GetChildrenForNode(aNode, mShowAnonymous,
-                                  getter_AddRefs(kids));
-
+    nsCOMPtr<nsINodeList> kids =
+      InspectorUtils::GetChildrenForNode(*node, mShowAnonymous);
     if (kids) {
       AppendKidsToArray(kids, aResult);
     }
   }
 
   if (mShowSubDocuments) {
     nsCOMPtr<nsIDOMNode> domdoc =
       do_QueryInterface(inLayoutUtils::GetSubDocumentFor(aNode));
@@ -1223,27 +1217,22 @@ inDOMView::GetRealPreviousSibling(nsIDOM
 {
   // XXXjrh: This won't work for some cases during some situations where XBL insertion points
   // are involved.  Fix me!
   aNode->GetPreviousSibling(aSibling);
   return NS_OK;
 }
 
 nsresult
-inDOMView::AppendKidsToArray(nsIDOMNodeList* aKids,
+inDOMView::AppendKidsToArray(nsINodeList* aKids,
                              nsCOMArray<nsIDOMNode>& aArray)
 {
-  uint32_t l = 0;
-  aKids->GetLength(&l);
-  nsCOMPtr<nsIDOMNode> kid;
-  uint16_t nodeType = 0;
-
-  for (uint32_t i = 0; i < l; ++i) {
-    aKids->Item(i, getter_AddRefs(kid));
-    kid->GetNodeType(&nodeType);
+  for (uint32_t i = 0, len = aKids->Length(); i < len; ++i) {
+    nsIContent* kid = aKids->Item(i);
+    uint16_t nodeType = kid->NodeType();
 
     NS_ASSERTION(nodeType && nodeType <= nsIDOMNode::NOTATION_NODE,
                  "Unknown node type. "
                  "Were new types added to the spec?");
     // As of DOM Level 2 Core and Traversal, each NodeFilter constant
     // is defined as the lower nth bit in the NodeFilter bitmask,
     // where n is the numeric constant of the nodeType it represents.
     // If this invariant ever changes, we will need to update the
@@ -1257,17 +1246,18 @@ inDOMView::AppendKidsToArray(nsIDOMNodeL
         nsCOMPtr<nsIContent> content = do_QueryInterface(kid);
         auto data = static_cast<nsGenericDOMDataNode*>(content.get());
         NS_ASSERTION(data, "Does not implement nsIDOMCharacterData!");
         if (InspectorUtils::IsIgnorableWhitespace(*data)) {
           continue;
         }
       }
 
-      aArray.AppendElement(kid.forget());
+      nsCOMPtr<nsIDOMNode> node = do_QueryInterface(kid);
+      aArray.AppendElement(node.forget());
     }
   }
 
   return NS_OK;
 }
 
 nsresult
 inDOMView::AppendAttrsToArray(nsIDOMMozNamedAttrMap* aAttributes,
--- a/layout/inspector/inDOMView.h
+++ b/layout/inspector/inDOMView.h
@@ -77,17 +77,17 @@ protected:
   nsresult NodeToRow(nsIDOMNode* aNode, int32_t* aRow);
 
   void InsertLinkAfter(inDOMViewNode* aNode, inDOMViewNode* aInsertAfter);
   void InsertLinkBefore(inDOMViewNode* aNode, inDOMViewNode* aInsertBefore);
   void RemoveLink(inDOMViewNode* aNode);
   void ReplaceLink(inDOMViewNode* aNewNode, inDOMViewNode* aOldNode);
 
   nsresult GetChildNodesFor(nsIDOMNode* aNode, nsCOMArray<nsIDOMNode>& aResult);
-  nsresult AppendKidsToArray(nsIDOMNodeList* aKids, nsCOMArray<nsIDOMNode>& aArray);
+  nsresult AppendKidsToArray(nsINodeList* aKids, nsCOMArray<nsIDOMNode>& aArray);
   nsresult AppendAttrsToArray(nsIDOMMozNamedAttrMap* aKids, nsCOMArray<nsIDOMNode>& aArray);
   nsresult GetFirstDescendantOf(inDOMViewNode* aNode, int32_t aRow, int32_t* aResult);
   nsresult GetLastDescendantOf(inDOMViewNode* aNode, int32_t aRow, int32_t* aResult);
   nsresult GetRealPreviousSibling(nsIDOMNode* aNode, nsIDOMNode* aRealParent, nsIDOMNode** aSibling);
 };
 
 // {FB5C1775-1BBD-4b9c-ABB0-AE7ACD29E87E}
 #define IN_DOMVIEW_CID \
--- a/layout/inspector/inIDOMUtils.idl
+++ b/layout/inspector/inIDOMUtils.idl
@@ -15,19 +15,16 @@ interface nsIDOMNode;
 interface nsIDOMNodeList;
 interface nsIDOMFontFaceList;
 interface nsIDOMRange;
 interface nsIDOMCSSStyleSheet;
 
 [scriptable, uuid(362e98c3-82c2-4ad8-8dcb-00e8e4eab497)]
 interface inIDOMUtils : nsISupports
 {
-  nsIDOMNodeList getChildrenForNode(in nsIDOMNode aNode,
-                                    in boolean aShowingAnonymousContent);
-
   // XBL utilities
   nsIArray getBindingURLs(in nsIDOMElement aElement);
 
   // 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
--- a/layout/inspector/tests/test_bug609549.xhtml
+++ b/layout/inspector/tests/test_bug609549.xhtml
@@ -24,40 +24,41 @@ https://bugzilla.mozilla.org/show_bug.cg
 </div>
 <pre id="test">
 <script type="application/javascript">
 <![CDATA[
 
 /** Test for Bug 609549 **/
 SimpleTest.waitForExplicitFinish();
 
+const InspectorUtils = SpecialPowers.InspectorUtils;
+
 addLoadEvent(function() {
-  var domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
-                   getService(SpecialPowers.Ci.inIDOMUtils);
-  ok("getChildrenForNode" in domUtils, "domUtils has no getChildrenForNode");
-  var withoutAnons = SpecialPowers.unwrap(domUtils.getChildrenForNode($("bound"), false));
+  ok("getChildrenForNode" in InspectorUtils, "InspectorUtils has no getChildrenForNode");
+  var withoutAnons =
+    SpecialPowers.unwrap(InspectorUtils.getChildrenForNode($("bound"), false));
 
   is(withoutAnons.length, $("bound").childNodes.length,
      "withoutAnons should be the same length as childNodes");
   is(withoutAnons[0], $("p"), "didn't get paragraph - without anons");
   is(withoutAnons[1], $("sandwiched"),
      "didn't get sandwiched span - without anons");
 
-  var withAnons = domUtils.getChildrenForNode($("bound"), true);
+  var withAnons = InspectorUtils.getChildrenForNode($("bound"), true);
 
   is(withAnons.length, 4, "bad withAnons.length");
   is(withAnons[0].getAttribute("anonid"), "box-A",
      "didn't get anonymous box-A");
   is(withAnons[1].getAttribute("anonid"), "box-B",
      "didn't get anonymous box-B");
   is(withAnons[2].getAttribute("anonid"), "box-C",
      "didn't get anonymous box-C");
   is(withAnons[3].id, "p", "didn't get paragraph - with anons");
 
-  var bKids = domUtils.getChildrenForNode(withAnons[1], true);
+  var bKids = InspectorUtils.getChildrenForNode(withAnons[1], true);
   is(bKids.length, 1, "bKids.length is bad");
   is(SpecialPowers.unwrap(bKids[0]), $("sandwiched"),
      "didn't get sandwiched span inserted into box-B");
 
   SimpleTest.finish();
 });
 
 ]]>
--- a/mobile/android/tests/browser/robocop/testVideoControls.js
+++ b/mobile/android/tests/browser/robocop/testVideoControls.js
@@ -5,16 +5,18 @@
 
 "use strict";
 
 var { classes: Cc, interfaces: Ci, utils: Cu } = Components;
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/SimpleServiceDiscovery.jsm");
 
+Cu.importGlobalProperties(["InspectorUtils"]);
+
 // The chrome window
 var chromeWin;
 
 // Track the <browser> where the tests are happening
 var browser;
 
 // The document of the video_controls web content
 var contentDocument;
@@ -53,18 +55,17 @@ add_test(function test_webm() {
 add_test(function test_ogg() {
   // Load the test video
   video.src = "http://mochi.test:8888/tests/robocop/video-pattern.ogg";
 
   Services.tm.dispatchToMainThread(testLoad);
 });
 
 function getButtonByAttribute(aName, aValue) {
-  let domUtil = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
-  let kids = domUtil.getChildrenForNode(video, true);
+  let kids = InspectorUtils.getChildrenForNode(video, true);
   let videocontrols = kids[1];
   return contentDocument.getAnonymousElementByAttribute(videocontrols, aName, aValue);
 }
 
 function getPixelColor(aCanvas, aX, aY) {
   let cx = aCanvas.getContext("2d");
   let pixel = cx.getImageData(aX, aY, 1, 1);
   return {
--- a/toolkit/content/tests/widgets/head.js
+++ b/toolkit/content/tests/widgets/head.js
@@ -1,10 +1,12 @@
 "use strict";
 
+const InspectorUtils = SpecialPowers.InspectorUtils;
+
 var tests = [];
 
 function waitForCondition(condition, nextTest, errorMsg) {
   var tries = 0;
   var interval = setInterval(function() {
     if (tries >= 30) {
       ok(false, errorMsg);
       moveOn();
@@ -20,24 +22,22 @@ function waitForCondition(condition, nex
       moveOn();
     }
     tries++;
   }, 100);
   var moveOn = function() { clearInterval(interval); nextTest(); };
 }
 
 function getAnonElementWithinVideoByAttribute(video, aName, aValue) {
-  const domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
-    getService(SpecialPowers.Ci.inIDOMUtils);
   // <videocontrols> is the second anonymous child node of <video>, but
   // the first child node of <audio>.
   const videoControlIndex = video.nodeName == "VIDEO" ? 1 : 0;
-  const videoControl = domUtils.getChildrenForNode(video, true)[videoControlIndex];
+  const videoControl = InspectorUtils.getChildrenForNode(video, true)[videoControlIndex];
 
-  return SpecialPowers.wrap(videoControl.ownerDocument)
+  return videoControl.ownerDocument
     .getAnonymousElementByAttribute(videoControl, aName, aValue);
 }
 
 function executeTests() {
   return tests
     .map(fn => () => new Promise(fn))
     .reduce((promise, task) => promise.then(task), Promise.resolve());
 }
--- a/toolkit/content/tests/widgets/test_videocontrols_audio.html
+++ b/toolkit/content/tests/widgets/test_videocontrols_audio.html
@@ -11,27 +11,27 @@
 
 <div id="content">
   <video id="video" controls preload="metadata"></video>
 </div>
 
 <pre id="test">
 <script class="testbody" type="application/javascript">
 
-  var domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
-    getService(SpecialPowers.Ci.inIDOMUtils);
+  const InspectorUtils = SpecialPowers.InspectorUtils;
 
   function findElementByAttribute(element, aName, aValue) {
     if (!("getAttribute" in element)) {
       return false;
     }
     if (element.getAttribute(aName) === aValue) {
       return element;
     }
-    let children = domUtils.getChildrenForNode(element, true);
+    let children =
+      InspectorUtils.getChildrenForNode(element, true);
     for (let child of children) {
       var result = findElementByAttribute(child, aName, aValue);
       if (result) {
         return result;
       }
     }
     return false;
   }
--- a/toolkit/content/tests/widgets/test_videocontrols_iframe_fullscreen.html
+++ b/toolkit/content/tests/widgets/test_videocontrols_iframe_fullscreen.html
@@ -13,36 +13,38 @@
 <iframe id="ifr1"></iframe>
 <iframe id="ifr2" allowfullscreen></iframe>
 </div>
 
 <pre id="test">
 <script clas="testbody" type="application/javascript">
   SimpleTest.waitForExplicitFinish();
 
-  const domUtils = SpecialPowers.Cc["@mozilla.org/inspector/dom-utils;1"].
-    getService(SpecialPowers.Ci.inIDOMUtils);
-  const iframe1 = SpecialPowers.wrap(document.getElementById("ifr1"));
-  const iframe2 = SpecialPowers.wrap(document.getElementById("ifr2"));
+  const InspectorUtils = SpecialPowers.InspectorUtils;
+
+  const iframe1 = document.getElementById("ifr1");
+  const iframe2 = document.getElementById("ifr2");
   const testCases = [];
 
   function checkIframeFullscreenAvailable(ifr) {
     const available = ifr.hasAttribute("allowfullscreen");
     let video;
 
     return () => new Promise(resolve => {
       ifr.srcdoc = `<video id="video" controls preload="auto"></video>`;
       ifr.addEventListener("load", resolve);
     }).then(() => new Promise(resolve => {
       video = ifr.contentDocument.getElementById("video");
       video.src = "seek_with_sound.ogg";
       video.addEventListener("loadedmetadata", resolve);
     })).then(() => new Promise(resolve => {
-      const videoControl = domUtils.getChildrenForNode(video, true)[1];
-      const controlBar = video.ownerDocument.getAnonymousElementByAttribute(
+      const children = InspectorUtils.getChildrenForNode(video, true);
+      const videoControl = children[1];
+      const doc = SpecialPowers.wrap(video.ownerDocument);
+      const controlBar = doc.getAnonymousElementByAttribute(
         videoControl, "class", "controlBar");
 
       is(controlBar.getAttribute("fullscreen-unavailable") == "true", !available, "The controlbar should have an attribute marking whether fullscreen is available that corresponds to if the iframe has the allowfullscreen attribute.");
       resolve();
     }));
   }
 
   function start() {