Ability to generate non-HTML sublanguages, e.g. SVG
This commit is contained in:
parent
83cc561cce
commit
6f07bfafae
|
@ -30,9 +30,11 @@ export function isFlattenInto(x: any): x is FlattenInto {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HtmlFragments implements FlattenInto {
|
export class HtmlFragments implements FlattenInto {
|
||||||
|
readonly contextElementName: string | undefined;
|
||||||
readonly pieces: Array<HtmlFragment>;
|
readonly pieces: Array<HtmlFragment>;
|
||||||
|
|
||||||
constructor(pieces: Array<HtmlFragment> = []) {
|
constructor(pieces: Array<HtmlFragment> = [], contextElementName?: string) {
|
||||||
|
this.contextElementName = contextElementName;
|
||||||
this.pieces = pieces;
|
this.pieces = pieces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +56,12 @@ export class HtmlFragments implements FlattenInto {
|
||||||
nodes(): Array<ChildNode> {
|
nodes(): Array<ChildNode> {
|
||||||
let n = document.createElement('template');
|
let n = document.createElement('template');
|
||||||
const nodeMap: PlaceholderNodeMap = {};
|
const nodeMap: PlaceholderNodeMap = {};
|
||||||
n.innerHTML = this.toString(nodeMap);
|
const source = this.toString(nodeMap);
|
||||||
|
if (this.contextElementName !== void 0) {
|
||||||
|
n.innerHTML = `<${this.contextElementName}>${source}</${this.contextElementName}>`;
|
||||||
|
} else {
|
||||||
|
n.innerHTML = source;
|
||||||
|
}
|
||||||
for (const p of Array.from(n.querySelectorAll('placeholder'))) {
|
for (const p of Array.from(n.querySelectorAll('placeholder'))) {
|
||||||
const e = nodeMap[p.id];
|
const e = nodeMap[p.id];
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -62,7 +69,11 @@ export class HtmlFragments implements FlattenInto {
|
||||||
p.remove();
|
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) {
|
toString(nodeMap?: PlaceholderNodeMap) {
|
||||||
|
@ -120,25 +131,27 @@ export function join(pieces: Array<HtmlFragment>, separator: HtmlFragment): Arra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function template(
|
export function makeTemplate(contextElementName?: string)
|
||||||
constantParts: TemplateStringsArray,
|
: (constantParts: TemplateStringsArray, ... variableParts: Array<HtmlFragment>) => HtmlFragments {
|
||||||
... variableParts: Array<HtmlFragment>): HtmlFragments
|
return (constantParts: TemplateStringsArray, ... variableParts: Array<HtmlFragment>) => {
|
||||||
{
|
const pieces: Array<HtmlFragment> = [];
|
||||||
const pieces: Array<HtmlFragment> = [];
|
function pushConst(i: number) {
|
||||||
function pushConst(i: number) {
|
const r = constantParts.raw[i].trimLeft();
|
||||||
const r = constantParts.raw[i].trimLeft();
|
if (r) pieces.push(r);
|
||||||
if (r) pieces.push(r);
|
}
|
||||||
}
|
pushConst(0);
|
||||||
pushConst(0);
|
variableParts.forEach((vp, vpIndex) => {
|
||||||
variableParts.forEach((vp, vpIndex) => {
|
flattenInto(pieces, vp, { escapeStrings: true });
|
||||||
flattenInto(pieces, vp, { escapeStrings: true });
|
pushConst(vpIndex + 1);
|
||||||
pushConst(vpIndex + 1);
|
});
|
||||||
});
|
return new HtmlFragments(pieces, contextElementName);
|
||||||
return new HtmlFragments(pieces);
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function raw(str: string) {
|
export const template = makeTemplate();
|
||||||
return new HtmlFragments([str]);
|
|
||||||
|
export function raw(str: string, contextElementName?: string) {
|
||||||
|
return new HtmlFragments([str], contextElementName);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default template;
|
export default template;
|
||||||
|
|
Loading…
Reference in New Issue