diff --git a/packages/@lwc/integration-karma/test/light-dom/root/index.spec.js b/packages/@lwc/integration-karma/test/light-dom/root/index.spec.js index 7055e5f3a9..ad5e11ce10 100644 --- a/packages/@lwc/integration-karma/test/light-dom/root/index.spec.js +++ b/packages/@lwc/integration-karma/test/light-dom/root/index.spec.js @@ -78,5 +78,7 @@ describe('root light element', () => { expect(nodes['x-list'].querySelector('button')).toEqual(nodes.button); expect(nodes['x-list'].getElementsByTagName('button')[0]).toEqual(nodes.button); expect(nodes['x-list'].getElementsByClassName('button')[0]).toEqual(nodes.button); + expect(nodes['x-list'].childNodes[0]).toEqual(nodes.button); + expect(nodes['x-list'].children[0]).toEqual(nodes.button); }); }); diff --git a/packages/@lwc/synthetic-shadow/src/faux-shadow/element.ts b/packages/@lwc/synthetic-shadow/src/faux-shadow/element.ts index 528d32f838..97c9b9d8a2 100644 --- a/packages/@lwc/synthetic-shadow/src/faux-shadow/element.ts +++ b/packages/@lwc/synthetic-shadow/src/faux-shadow/element.ts @@ -92,7 +92,11 @@ function shadowRootGetterPatched(this: Element): ShadowRoot | null { function childrenGetterPatched(this: Element): HTMLCollectionOf { const owner = getNodeOwner(this); - const childNodes = isNull(owner) ? [] : getAllMatches(owner, getFilteredChildNodes(this)); + const filteredChildNodes = getFilteredChildNodes(this); + // No need to filter by owner for non-shadowed nodes + const childNodes = isNull(owner) + ? filteredChildNodes + : getAllMatches(owner, filteredChildNodes); return createStaticHTMLCollection( ArrayFilter.call(childNodes, (node: Node | Element) => node instanceof Element) ); diff --git a/packages/@lwc/synthetic-shadow/src/faux-shadow/node.ts b/packages/@lwc/synthetic-shadow/src/faux-shadow/node.ts index 493ee5b644..e1a7a89595 100644 --- a/packages/@lwc/synthetic-shadow/src/faux-shadow/node.ts +++ b/packages/@lwc/synthetic-shadow/src/faux-shadow/node.ts @@ -173,7 +173,11 @@ function cloneNodePatched(this: Node, deep?: boolean): Node { function childNodesGetterPatched(this: Node): NodeListOf { if (isSyntheticShadowHost(this)) { const owner = getNodeOwner(this); - const childNodes = isNull(owner) ? [] : getAllMatches(owner, getFilteredChildNodes(this)); + const filteredChildNodes = getFilteredChildNodes(this); + // No need to filter by owner for non-shadowed nodes + const childNodes = isNull(owner) + ? filteredChildNodes + : getAllMatches(owner, filteredChildNodes); return createStaticNodeList(childNodes); } // nothing to do here since this does not have a synthetic shadow attached to it diff --git a/packages/@lwc/synthetic-shadow/src/shared/node-ownership.ts b/packages/@lwc/synthetic-shadow/src/shared/node-ownership.ts index 63ddd73b56..eac9d58502 100644 --- a/packages/@lwc/synthetic-shadow/src/shared/node-ownership.ts +++ b/packages/@lwc/synthetic-shadow/src/shared/node-ownership.ts @@ -58,6 +58,8 @@ export function getNodeNearestOwnerKey(node: Node): number | undefined { } host = parentNodeGetter.call(host) as ShadowedNode | null; + // Elements slotted from top level light DOM into synthetic shadow + // reach the slot tag from the shadow element first if (!isNull(host) && isSyntheticSlotElement(host)) { return undefined; }