chore: use more sane to-string code

pull/15538/head
paoloricciuti 4 months ago
parent d3ee992593
commit 2e24fdc36e

@ -7,6 +7,9 @@ import { is_void } from '../../../../../utils.js';
* @param {TemplateOperations} items * @param {TemplateOperations} items
*/ */
export function template_to_string(items) { export function template_to_string(items) {
/**
* @type {Array<Element>}
*/
let elements = []; let elements = [];
/** /**
@ -19,41 +22,53 @@ export function template_to_string(items) {
*/ */
let last_current_element; let last_current_element;
for (let instruction of items) { /**
// on push element we add the element to the stack, from this moment on every insert will * @template {Node} T
// happen on the last element in the stack * @param {T} child
if (instruction.kind === 'push_element' && last_current_element) { */
elements_stack.push(last_current_element); function insert(child) {
continue; if (last_current_element) {
} last_current_element.children ??= [];
// we closed one element, we remove it from the stack last_current_element.children.push(child);
if (instruction.kind === 'pop_element') { } else {
elements_stack.pop(); elements.push(/** @type {Element} */ (child));
continue;
} }
/** return child;
* @type {Node | void} }
*/
// @ts-expect-error we can't be here if `swap_current_element` but TS doesn't know that for (let instruction of items) {
const value = map[instruction.kind]( switch (instruction.kind) {
...[ case 'push_element':
// for set prop we need to send the last element (not the one in the stack since elements_stack.push(/** @type {Element} */ (last_current_element));
// it get's added to the stack only after the push_element instruction) break;
...(instruction.kind === 'set_prop' ? [last_current_element] : []), case 'pop_element':
...(instruction.args ?? []) elements_stack.pop();
] last_current_element = elements_stack.at(-1);
); break;
// with set_prop we don't need to do anything else, in all other cases we also need to case 'create_element':
// append the element/node/anchor to the current active element or push it in the elements array last_current_element = insert({
if (instruction.kind !== 'set_prop') { kind: 'element',
if (elements_stack.length >= 1 && value) { element: /** @type {string[]} */ (instruction.args)[0]
map.insert(/** @type {Element} */ (elements_stack.at(-1)), value); });
} else if (value) { break;
elements.push(value); case 'create_text':
} insert({
// keep track of the last created element (it will be pushed to the stack after the props are set) kind: 'text',
if (instruction.kind === 'create_element') { value: /** @type {string[]} */ (instruction.args)[0]
last_current_element = /** @type {Element} */ (value); });
break;
case 'create_anchor':
insert({
kind: 'anchor',
data: instruction.args?.[0]
});
break;
case 'set_prop': {
const el = /** @type {Element} */ (last_current_element);
const [prop, value] = /** @type {string[]} */ (instruction.args);
el.props ??= {};
el.props[prop] = value;
break;
} }
} }
} }
@ -77,70 +92,6 @@ export function template_to_string(items) {
* @typedef { Element | Anchor| Text } Node * @typedef { Element | Anchor| Text } Node
*/ */
/**
*
* @param {string} element
* @returns {Element}
*/
function create_element(element) {
return {
kind: 'element',
element
};
}
/**
* @param {string} data
* @returns {Anchor}
*/
function create_anchor(data) {
return {
kind: 'anchor',
data
};
}
/**
* @param {string} value
* @returns {Text}
*/
function create_text(value) {
return {
kind: 'text',
value
};
}
/**
*
* @param {Element} el
* @param {string} prop
* @param {string} value
*/
function set_prop(el, prop, value) {
el.props ??= {};
el.props[prop] = value;
}
/**
*
* @param {Element} el
* @param {Node} child
* @param {Node} [anchor]
*/
function insert(el, child, anchor) {
el.children ??= [];
el.children.push(child);
}
let map = {
create_element,
create_text,
create_anchor,
set_prop,
insert
};
/** /**
* *
* @param {Node} el * @param {Node} el

Loading…
Cancel
Save