From f6ab0f37695cf9060de03302a631405395e768ac Mon Sep 17 00:00:00 2001 From: Sean Doyle Date: Sun, 11 Dec 2022 23:22:49 -0500 Subject: [PATCH] Extend `processPropertyIdentity` to handle Element Closes [github/template-parts#62][] Extends the `processPropertyIdentity` function from the `processors` module to pass-through `Element` instances, instead of coercing them through calls to `String()`. In order to accommodate that change, this commit also extends the `TemplatePart` interface to accept `Element` instances for its `value:` property. The change to the `createTreeWalker` invocation within `collectParts` was highlighted by TypeScript, as the final `boolean` argument doesn't conform to the [createTreeWalker][] signature. It was a necessary change to build the project and execute the test suite locally. [github/template-parts#62]: https://github.com/github/template-parts/issues/62 [createTreeWalker]: https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker --- src/processors.ts | 2 +- src/template-instance.ts | 2 +- src/types.ts | 2 +- test/template-instance.ts | 13 +++++++++++++ 4 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/processors.ts b/src/processors.ts index d50c06c..0c2cb7c 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 = String(value) + part.value = value instanceof Element ? value : String(value) } export function processBooleanAttribute(part: TemplatePart, value: unknown): boolean { diff --git a/src/template-instance.ts b/src/template-instance.ts index ddf8910..4e6ce0c 100644 --- a/src/template-instance.ts +++ b/src/template-instance.ts @@ -5,7 +5,7 @@ import {propertyIdentity} from './processors.js' import {TemplatePart, TemplateTypeInit} from './types.js' function* collectParts(el: DocumentFragment): Generator { - const walker = el.ownerDocument.createTreeWalker(el, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null, false) + const walker = el.ownerDocument.createTreeWalker(el, NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT, null) let node while ((node = walker.nextNode())) { if (node instanceof Element && node.hasAttributes()) { diff --git a/src/types.ts b/src/types.ts index 1170530..a5c2520 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: string | null + value: Element | string | null } type TemplateProcessCallback = (instance: TemplateInstance, parts: Iterable, params: unknown) => void diff --git a/test/template-instance.ts b/test/template-instance.ts index b4f65af..1c5e8ea 100644 --- a/test/template-instance.ts +++ b/test/template-instance.ts @@ -14,6 +14,19 @@ describe('template-instance', () => { root.appendChild(instance) expect(root.innerHTML).to.equal(`Hello world`) }) + it('applies data to templated element nodes', () => { + const template = document.createElement('template') + const element = Object.assign(document.createElement('div'), { + innerHTML: 'Hello world' + }) + const originalHTML = `{{x}}` + template.innerHTML = originalHTML + const instance = new TemplateInstance(template, {x: element}) + 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}}!`