Tidy up
This commit is contained in:
parent
a9ea553ca1
commit
b336faff25
|
@ -57,9 +57,59 @@ function followPath(topNodes: ChildNode[], path: number[]): Node {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlaceholderAction = (variableParts: HtmlFragment[], topNodes: ChildNode[]) => void;
|
||||||
|
|
||||||
|
function nodeInserter(n: number, path: number[]): PlaceholderAction {
|
||||||
|
return (vs, topNodes) => {
|
||||||
|
const node = followPath(topNodes, path);
|
||||||
|
function walk(f: HtmlFragment) {
|
||||||
|
if (Array.isArray(f)) {
|
||||||
|
f.forEach(walk);
|
||||||
|
} else {
|
||||||
|
let newNode: Node;
|
||||||
|
switch (typeof f) {
|
||||||
|
case 'string': newNode = document.createTextNode(f); break;
|
||||||
|
case 'number': newNode = document.createTextNode('' + f); break;
|
||||||
|
default: newNode = f; break;
|
||||||
|
}
|
||||||
|
node.parentNode?.insertBefore(newNode, node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
walk(vs[n]);
|
||||||
|
node.parentNode?.removeChild(node);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function attributesInserter(n: number, path: number[]): PlaceholderAction {
|
||||||
|
return (vs, topNodes) => {
|
||||||
|
const node = followPath(topNodes, path);
|
||||||
|
const e = document.createElement('template');
|
||||||
|
e.innerHTML = `<x-dummy ${renderFragment(vs[n], true).join('')}></x-dummy>`;
|
||||||
|
Array.from(e.attributes).forEach(a =>
|
||||||
|
(node as Element).setAttribute(a.name, a.value));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function attributeValueInserter(
|
||||||
|
attrName: string,
|
||||||
|
constantParts: string[],
|
||||||
|
placeholders: number[],
|
||||||
|
path: number[],
|
||||||
|
): PlaceholderAction {
|
||||||
|
return (vs, topNodes) => {
|
||||||
|
const node = followPath(topNodes, path);
|
||||||
|
const pieces = [constantParts[0]];
|
||||||
|
placeholders.forEach((n, i) => {
|
||||||
|
pieces.push(...renderFragment(vs[n], false));
|
||||||
|
pieces.push(constantParts[i + 1]);
|
||||||
|
});
|
||||||
|
(node as Element).setAttribute(attrName, pieces.join(''));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export class HtmlFragmentBuilder {
|
export class HtmlFragmentBuilder {
|
||||||
template: HTMLTemplateElement = document.createElement('template');
|
template: HTMLTemplateElement = document.createElement('template');
|
||||||
placeholderActions: Array<(variableParts: HtmlFragment[], topNodes: ChildNode[]) => void> = [];
|
placeholderActions: PlaceholderAction[] = [];
|
||||||
|
|
||||||
constructor(constantParts: TemplateStringsArray) {
|
constructor(constantParts: TemplateStringsArray) {
|
||||||
const pieces: string[] = [];
|
const pieces: string[] = [];
|
||||||
|
@ -81,9 +131,13 @@ export class HtmlFragmentBuilder {
|
||||||
const n = nextN;
|
const n = nextN;
|
||||||
switch (n.nodeType) {
|
switch (n.nodeType) {
|
||||||
case Node.TEXT_NODE: {
|
case Node.TEXT_NODE: {
|
||||||
const { constantParts, placeholders } = splitByPlaceholders(n.textContent ?? '');
|
const { constantParts, placeholders } =
|
||||||
|
splitByPlaceholders(n.textContent ?? '');
|
||||||
constantParts.forEach((c, i) => {
|
constantParts.forEach((c, i) => {
|
||||||
if (i > 0) n.parentNode?.insertBefore(document.createElement('placeholder'), n);
|
if (i > 0) {
|
||||||
|
const placeholder = document.createElement('x-placeholder');
|
||||||
|
n.parentNode?.insertBefore(placeholder, n);
|
||||||
|
}
|
||||||
n.parentNode?.insertBefore(document.createTextNode(c), n);
|
n.parentNode?.insertBefore(document.createTextNode(c), n);
|
||||||
});
|
});
|
||||||
nextN = n.nextSibling;
|
nextN = n.nextSibling;
|
||||||
|
@ -91,22 +145,7 @@ export class HtmlFragmentBuilder {
|
||||||
placeholders.forEach((n, i) => {
|
placeholders.forEach((n, i) => {
|
||||||
const currentPath = path.slice();
|
const currentPath = path.slice();
|
||||||
currentPath[currentPath.length - 1] = i * 2 + 1;
|
currentPath[currentPath.length - 1] = i * 2 + 1;
|
||||||
this.placeholderActions.push((vs, topNodes) => {
|
this.placeholderActions.push(nodeInserter(n, currentPath));
|
||||||
const node = followPath(topNodes, currentPath);
|
|
||||||
function walk(f: HtmlFragment) {
|
|
||||||
if (Array.isArray(f)) {
|
|
||||||
f.forEach(walk);
|
|
||||||
} else {
|
|
||||||
switch (typeof f) {
|
|
||||||
case 'string': node.parentNode?.insertBefore(document.createTextNode(f), node); break;
|
|
||||||
case 'number': node.parentNode?.insertBefore(document.createTextNode('' + f), node); break;
|
|
||||||
default: node.parentNode?.insertBefore(f, node); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
walk(vs[n]);
|
|
||||||
node.parentNode?.removeChild(node);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
bump(constantParts.length + placeholders.length);
|
bump(constantParts.length + placeholders.length);
|
||||||
break;
|
break;
|
||||||
|
@ -123,25 +162,16 @@ export class HtmlFragmentBuilder {
|
||||||
e.removeAttributeNode(attr);
|
e.removeAttributeNode(attr);
|
||||||
i--;
|
i--;
|
||||||
const n = parseInt(nameIsPlaceholder[1], 10);
|
const n = parseInt(nameIsPlaceholder[1], 10);
|
||||||
this.placeholderActions.push((vs, topNodes) => {
|
this.placeholderActions.push(attributesInserter(n, currentPath));
|
||||||
const node = followPath(topNodes, currentPath);
|
|
||||||
const e = document.createElement('template');
|
|
||||||
e.innerHTML = `<dummy ${renderFragment(vs[n], true).join('')}></dummy>`;
|
|
||||||
Array.from(e.attributes).forEach(a =>
|
|
||||||
(node as Element).setAttribute(a.name, a.value));
|
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const { constantParts, placeholders } = splitByPlaceholders(attr.value);
|
const { constantParts, placeholders } =
|
||||||
|
splitByPlaceholders(attr.value);
|
||||||
if (constantParts.length !== 1) {
|
if (constantParts.length !== 1) {
|
||||||
this.placeholderActions.push((vs, topNodes) => {
|
this.placeholderActions.push(attributeValueInserter(
|
||||||
const node = followPath(topNodes, currentPath);
|
attrName,
|
||||||
const pieces = [constantParts[0]];
|
constantParts,
|
||||||
placeholders.forEach((n, i) => {
|
placeholders,
|
||||||
pieces.push(...renderFragment(vs[n], false));
|
currentPath));
|
||||||
pieces.push(constantParts[i + 1]);
|
|
||||||
});
|
|
||||||
(node as Element).setAttribute(attrName, pieces.join(''));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue