diff --git a/src/Components/Web.JS/src/Rendering/LogicalElements.ts b/src/Components/Web.JS/src/Rendering/LogicalElements.ts index bd049ea19c27..39bd55ceb2ea 100644 --- a/src/Components/Web.JS/src/Rendering/LogicalElements.ts +++ b/src/Components/Web.JS/src/Rendering/LogicalElements.ts @@ -368,7 +368,8 @@ function appendDomNode(child: Node, parent: LogicalElement) { // This function only puts 'child' into the DOM in the right place relative to 'parent' // It does not update the logical children array of anything if (parent instanceof Element || parent instanceof DocumentFragment) { - parent.appendChild(child); + const domContainer = getLogicalDomNodeContainer(parent); + domContainer.appendChild(child); } else if (parent instanceof Comment) { const parentLogicalNextSibling = getLogicalNextSibling(parent) as any as Node; if (parentLogicalNextSibling) { @@ -385,6 +386,13 @@ function appendDomNode(child: Node, parent: LogicalElement) { } } +function getLogicalDomNodeContainer(parent: Node): Element | DocumentFragment { + if (parent instanceof HTMLTemplateElement) { + return parent.content; + } + return parent as Element | DocumentFragment; +} + // Returns the final node (in depth-first evaluation order) that is a descendant of the logical element. // As such, the entire subtree is between 'element' and 'findLastDomNodeInRange(element)' inclusive. function findLastDomNodeInRange(element: LogicalElement): Node { diff --git a/src/Components/Web.JS/test/LogicalElements.test.ts b/src/Components/Web.JS/test/LogicalElements.test.ts index e45dabea096b..40945676b7af 100644 --- a/src/Components/Web.JS/test/LogicalElements.test.ts +++ b/src/Components/Web.JS/test/LogicalElements.test.ts @@ -2,6 +2,9 @@ import { expect, test, describe } from '@jest/globals'; import { toLogicalElement, insertLogicalChild, + insertLogicalChildBefore, + removeLogicalChild, + emptyLogicalElement, getLogicalChildrenArray, getLogicalChild, LogicalElement, @@ -166,3 +169,121 @@ describe('insertLogicalChild', () => { expect(parent.childNodes[2]).toBe(spanB); }); }); + +describe('HTMLTemplateElement handling (issue #50831)', () => { + test('appendChild via logical element should put children into template.content, not template.childNodes', () => { + // Repro of issue #50831: rendering a