diff --git a/packages/html/src/html.ts b/packages/html/src/html.ts index 2575c52..611f2f7 100644 --- a/packages/html/src/html.ts +++ b/packages/html/src/html.ts @@ -30,9 +30,11 @@ export function isFlattenInto(x: any): x is FlattenInto { } export class HtmlFragments implements FlattenInto { + readonly contextElementName: string | undefined; readonly pieces: Array; - constructor(pieces: Array = []) { + constructor(pieces: Array = [], contextElementName?: string) { + this.contextElementName = contextElementName; this.pieces = pieces; } @@ -54,7 +56,12 @@ export class HtmlFragments implements FlattenInto { nodes(): Array { let n = document.createElement('template'); const nodeMap: PlaceholderNodeMap = {}; - n.innerHTML = this.toString(nodeMap); + const source = this.toString(nodeMap); + if (this.contextElementName !== void 0) { + n.innerHTML = `<${this.contextElementName}>${source}`; + } else { + n.innerHTML = source; + } for (const p of Array.from(n.querySelectorAll('placeholder'))) { const e = nodeMap[p.id]; if (e) { @@ -62,7 +69,11 @@ export class HtmlFragments implements FlattenInto { p.remove(); } } - return Array.from(n.content.childNodes); + if (this.contextElementName !== void 0) { + return Array.from(n.content.firstElementChild!.childNodes); + } else { + return Array.from(n.content.childNodes); + } } toString(nodeMap?: PlaceholderNodeMap) { @@ -120,25 +131,27 @@ export function join(pieces: Array, separator: HtmlFragment): Arra } } -export function template( - constantParts: TemplateStringsArray, - ... variableParts: Array): HtmlFragments -{ - const pieces: Array = []; - function pushConst(i: number) { - const r = constantParts.raw[i].trimLeft(); - if (r) pieces.push(r); - } - pushConst(0); - variableParts.forEach((vp, vpIndex) => { - flattenInto(pieces, vp, { escapeStrings: true }); - pushConst(vpIndex + 1); - }); - return new HtmlFragments(pieces); -}; +export function makeTemplate(contextElementName?: string) +: (constantParts: TemplateStringsArray, ... variableParts: Array) => HtmlFragments { + return (constantParts: TemplateStringsArray, ... variableParts: Array) => { + const pieces: Array = []; + function pushConst(i: number) { + const r = constantParts.raw[i].trimLeft(); + if (r) pieces.push(r); + } + pushConst(0); + variableParts.forEach((vp, vpIndex) => { + flattenInto(pieces, vp, { escapeStrings: true }); + pushConst(vpIndex + 1); + }); + return new HtmlFragments(pieces, contextElementName); + }; +} -export function raw(str: string) { - return new HtmlFragments([str]); +export const template = makeTemplate(); + +export function raw(str: string, contextElementName?: string) { + return new HtmlFragments([str], contextElementName); } export default template;