Bug 1451037 - check if shadow host has children when fetching before/after pseudos;r=bgrins
MozReview-Commit-ID: KG6cRlLQiE1
--- 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.