diff --git a/src/node-template-part.ts b/src/node-template-part.ts index 978840c..413251f 100644 --- a/src/node-template-part.ts +++ b/src/node-template-part.ts @@ -1,9 +1,9 @@ import {TemplatePart} from './types.js' -const parts = new WeakMap() +const parts = new WeakMap() export class NodeTemplatePart implements TemplatePart { constructor( - node: ChildNode, + node: Node, public expression: string, ) { parts.set(this, [node]) @@ -29,14 +29,15 @@ export class NodeTemplatePart implements TemplatePart { return parts.get(this)![parts.get(this)!.length - 1].nextSibling } - replace(...nodes: Array): void { - const normalisedNodes: ChildNode[] = nodes.map(node => { + replace(...nodes: Array): void { + const normalisedNodes: Node[] = nodes.map(node => { if (typeof node === 'string') return new Text(node) return node }) if (!normalisedNodes.length) normalisedNodes.push(new Text('')) - parts.get(this)![0].before(...normalisedNodes) - for (const part of parts.get(this)!) part.remove() + const node = parts.get(this)![0] + for (const normalisedNode of normalisedNodes) node.parentNode?.insertBefore(normalisedNode, node) + for (const part of parts.get(this)!) part.parentNode?.removeChild(part) parts.set(this, normalisedNodes) } } diff --git a/test/template-instance.ts b/test/template-instance.ts index 5b5ba07..4b1242b 100644 --- a/test/template-instance.ts +++ b/test/template-instance.ts @@ -1,6 +1,6 @@ import {expect} from '@open-wc/testing' import {TemplateInstance} from '../src/template-instance' -import type {NodeTemplatePart} from '../src/node-template-part' +import {NodeTemplatePart} from '../src/node-template-part' import {propertyIdentityOrBooleanAttribute, createProcessor} from '../src/processors' describe('template-instance', () => { @@ -238,6 +238,25 @@ describe('template-instance', () => { describe('edge cases', () => { describe('NodeTemplatePart', () => { + it('replace supports a DocumentFragment Node that is not a ChildNode', () => { + const template = Object.assign(document.createElement('template'), { + innerHTML: '
{{a}}
', + }) + const {content} = Object.assign(document.createElement('template'), { + innerHTML: 'after', + }) + const instance = new TemplateInstance( + template, + {a: 'before'}, + createProcessor(part => { + if (part instanceof NodeTemplatePart) part.replace(content) + }), + ) + const root = document.createElement('div') + root.appendChild(instance) + expect(root.innerHTML).to.equal('
after
') + }) + it('replaces an empty replace() call with an empty text node', () => { const template = document.createElement('template') template.innerHTML = `
{{a}}
`