From 28f61c6ec235701ddeb312057b6af5f91b2969ba Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Sun, 8 Dec 2024 20:35:47 -0500 Subject: [PATCH] Accept `Node` values as Template Parts Related to [github/template-parts#62][] (see [3.2. Template Parts and Custom Template Process Callback][]) Follow-up to [github/template-parts#65][] While the changes made in [#65][] improved support for `Element` parts, the expansion from `string` to `Element | string` was not broadened enough. While all `Element` instances are DOM Nodes, not all DOM Nodes are `Element` instances. For example, this change enables support for [DocumentFragment][] instances (generated from classes like [Range][] or properties like [HTMLTemplateElement.content][]), where prior support resulted in templating the `[object DocumentFragment]` text string instead of the fragment's `Node` instances. [github/template-parts#62]: https://github.com/github/template-parts/issues/62 [3.2. Template Parts and Custom Template Process Callback]: https://github.com/WICG/webcomponents/blob/159b1600bab02fe9cd794825440a98537d53b389/proposals/Template-Instantiation.md#32-template-parts-and-custom-template-process-callback [github/template-parts#65]: https://github.com/github/template-parts/pull/65 [DocumentFragment]: https://developer.mozilla.org/en-US/docs/Web/API/DocumentFragment [HTMLTemplateElement.content]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content --- src/processors.ts | 2 +- src/types.ts | 2 +- test/template-instance.ts | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/processors.ts b/src/processors.ts index 1115516..1f47ec0 100644 --- a/src/processors.ts +++ b/src/processors.ts @@ -19,7 +19,7 @@ export function createProcessor(processPart: PartProcessor): TemplateTypeInit { } export function processPropertyIdentity(part: TemplatePart, value: unknown): void { - part.value = value instanceof Element ? value : String(value) + part.value = value instanceof Node ? value : String(value) } export function processBooleanAttribute(part: TemplatePart, value: unknown): boolean { diff --git a/src/types.ts b/src/types.ts index a5c2520..116cea6 100644 --- a/src/types.ts +++ b/src/types.ts @@ -2,7 +2,7 @@ import type {TemplateInstance} from './template-instance.js' export interface TemplatePart { expression: string - value: Element | string | null + value: Node | string | null } type TemplateProcessCallback = (instance: TemplateInstance, parts: Iterable, params: unknown) => void diff --git a/test/template-instance.ts b/test/template-instance.ts index 55096de..5b5ba07 100644 --- a/test/template-instance.ts +++ b/test/template-instance.ts @@ -36,6 +36,19 @@ describe('template-instance', () => { expect(root.innerHTML).to.equal('') }) + it('applies data to templated DocumentFragment nodes', () => { + const template = document.createElement('template') + const fragment = Object.assign(document.createElement('template'), { + innerHTML: '
Hello world
', + }) + const originalHTML = `{{x}}` + template.innerHTML = originalHTML + const instance = new TemplateInstance(template, {x: fragment.content}) + expect(template.innerHTML).to.equal(originalHTML) + const root = document.createElement('div') + root.appendChild(instance) + expect(root.innerHTML).to.equal(`
Hello world
`) + }) it('can render into partial text nodes', () => { const template = document.createElement('template') const originalHTML = `Hello {{x}}!`