Repair reuse of templater at different constant-portions
This commit is contained in:
parent
600d9b3c15
commit
7e439b9bb1
|
@ -308,17 +308,17 @@ export type HtmlTemplater =
|
|||
=> ChildNode[];
|
||||
|
||||
export function template(): HtmlTemplater {
|
||||
let instance: HtmlFragmentInstance | null = null;
|
||||
let cache: null | { instance: HtmlFragmentInstance, builder: HtmlFragmentBuilder } = null;
|
||||
return (constantParts, ... variableParts) => {
|
||||
let b = templateCache.get(constantParts);
|
||||
if (b === void 0) {
|
||||
b = new HtmlFragmentBuilder(constantParts);
|
||||
templateCache.set(constantParts, b);
|
||||
}
|
||||
if (instance === null) {
|
||||
instance = b.clone();
|
||||
if (cache === null || cache.builder !== b) {
|
||||
cache = { instance: b.clone(), builder: b };
|
||||
}
|
||||
b.update(instance, variableParts);
|
||||
return instance.container;
|
||||
b.update(cache.instance, variableParts);
|
||||
return cache.instance.container;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
/// SPDX-FileCopyrightText: Copyright © 2024 Tony Garnock-Jones <tonyg@leastfixedpoint.com>
|
||||
|
||||
import { template } from '../src/html';
|
||||
import { HtmlTemplater, template } from '../src/html';
|
||||
import './test-utils';
|
||||
|
||||
function compareHTML(nodes: ChildNode[], expected: string) {
|
||||
|
@ -89,6 +89,18 @@ describe('basic templating', () => {
|
|||
compareHTML(t`<q><x t="${v()}">${ps.map(p => p())}</x></q>`, expected);
|
||||
});
|
||||
|
||||
it('should be callable multiple times with the same syntactic location', () => {
|
||||
// Because the fixed portion of a template string, the TemplateStringsArray, is hashconsed
|
||||
const v = () => 'aaa';
|
||||
const ps = [() => '123', () => '234', () => '345'];
|
||||
const expected = '<q><x t="aaa">123234345</x></q>';
|
||||
const t = template();
|
||||
const f = () => compareHTML(t`<q><x t="${v()}">${ps.map(p => p())}</x></q>`, expected);
|
||||
f();
|
||||
f();
|
||||
f();
|
||||
});
|
||||
|
||||
it('should be callable multiple times with extra items', () => {
|
||||
const v = () => 'aaa';
|
||||
const t = template();
|
||||
|
@ -99,4 +111,16 @@ describe('basic templating', () => {
|
|||
ps.push(() => '3');
|
||||
compareHTML(t`<q><x t="${v()}">${ps.map(p => p())}</x></q>`, '<q><x t="aaa">123</x></q>');
|
||||
});
|
||||
|
||||
it('should be reusable for supplying arguments to itself', () => {
|
||||
const inner = (t: HtmlTemplater) => t`<i>middle</i>`;
|
||||
const t = template();
|
||||
compareHTML(t`<p>n${inner(t)}n</p>`, '<p>n<i>middle</i>n</p>');
|
||||
});
|
||||
|
||||
it('should accept strings', () => {
|
||||
const inner = (_t: HtmlTemplater) => `<i>middle</i>`;
|
||||
const t = template();
|
||||
compareHTML(t`<p>n${inner(t)}n</p>`, '<p>n<i>middle</i>n</p>');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue