Bug 1451037 - check if shadow host has children when fetching before/after pseudos;r=bgrins draft
authorJulian Descottes <jdescottes@mozilla.com>
Wed, 04 Apr 2018 11:59:19 +0200
changeset 777129 1b4a9d3da2f118f74c42db40b62c75e7aa04d0c8
parent 776948 00bdc9451be6557ccce1492b9b966d4435615380
push id105086
push userjdescottes@mozilla.com
push dateWed, 04 Apr 2018 10:05:03 +0000
reviewersbgrins
bugs1451037
milestone61.0a1
Bug 1451037 - check if shadow host has children when fetching before/after pseudos;r=bgrins MozReview-Commit-ID: KG6cRlLQiE1
devtools/client/inspector/markup/test/browser_markup_shadowdom.js
devtools/server/actors/inspector/walker.js
--- a/devtools/client/inspector/markup/test/browser_markup_shadowdom.js
+++ b/devtools/client/inspector/markup/test/browser_markup_shadowdom.js
@@ -197,8 +197,35 @@ add_task(async function() {
           ::after
       ::before
       class="light-dom"
       ::after`;
 
   let {inspector} = await openInspectorForURL(TEST_URL);
   await checkTreeFromRootSelector(EXPECTED_TREE, "test-component", inspector);
 });
+
+add_task(async function() {
+  await enableWebComponents();
+
+  // Test empty web components are still displayed correctly.
+
+  const TEST_URL = `data:text/html;charset=utf-8,
+    <test-component></test-component>
+
+    <script>
+      "use strict";
+      customElements.define("test-component", class extends HTMLElement {
+        constructor() {
+          super();
+          let shadowRoot = this.attachShadow({mode: "open"});
+          shadowRoot.innerHTML = "";
+        }
+      });
+    </script>`;
+
+  const EXPECTED_TREE = `
+    test-component
+      #shadow-root`;
+
+  let {inspector} = await openInspectorForURL(TEST_URL);
+  await checkTreeFromRootSelector(EXPECTED_TREE, "test-component", inspector);
+});
--- a/devtools/server/actors/inspector/walker.js
+++ b/devtools/server/actors/inspector/walker.js
@@ -701,45 +701,40 @@ var WalkerActor = protocol.ActorClassWit
       hasLast = nodes[nodes.length - 1].rawNode == lastChild;
     } else {
       // If nodes is still an empty array, we are on a host element with a shadow root but
       // no direct children.
       hasFirst = hasLast = true;
     }
 
     if (isShadowHost) {
-      let {before, after} = this._getBeforeAfterElements(node.rawNode);
+      // Use anonymous walkers to fetch ::before / ::after pseudo elements
+      let firstChildWalker = this.getDocumentWalker(node.rawNode);
+      let first = firstChildWalker.firstChild();
+      let hasBefore = first && this._ref(first).isBeforePseudoElement;
+
+      let lastChildWalker = this.getDocumentWalker(node.rawNode);
+      let last = lastChildWalker.lastChild();
+      let hasAfter = last && this._ref(last).isAfterPseudoElement;
+
       nodes = [
         // #shadow-root
         this._ref(node.rawNode.shadowRoot),
         // ::before
-        ...(before ? [before] : []),
+        ...(hasBefore ? [this._ref(first)] : []),
         // shadow host direct children
         ...nodes,
         // ::after
-        ...(after ? [after] : []),
+        ...(hasAfter ? [this._ref(last)] : []),
       ];
     }
 
     return { hasFirst, hasLast, nodes };
   },
 
-  _getBeforeAfterElements: function(node) {
-    let firstChildWalker = this.getDocumentWalker(node);
-    let before = this._ref(firstChildWalker.firstChild());
-
-    let lastChildWalker = this.getDocumentWalker(node);
-    let after = this._ref(lastChildWalker.lastChild());
-
-    return {
-      before: before.isBeforePseudoElement ? before : undefined,
-      after: after.isAfterPseudoElement ? after : undefined,
-    };
-  },
-
   /**
    * Get the next sibling of a given node.  Getting nodes one at a time
    * might be inefficient, be careful.
    *
    * @param object options
    *    Named options:
    *    `whatToShow`: A bitmask of node types that should be included.  See
    *       https://developer.mozilla.org/en-US/docs/Web/API/NodeFilter.