/// import { PropertyStore } from "./PropertyStore.js"; export class XNode { public static create( // eslint-disable-next-line @typescript-eslint/ban-types name: string | Function, attribs: Record, ... nodes: (XNode | string)[]): XNode { if (typeof name === "function") { return name(attribs ?? {}, ... nodes); } return new XNode(name, attribs, nodes); } static render(root: HTMLElement | ShadowRoot, node: XNode) { return node.render(root as any); } static append(root: HTMLElement | ShadowRoot, node: XNode) { return node.appendTo(root as any); } private constructor( public readonly name: string, public readonly attributes: Record, public readonly children: (XNode | string)[] ) { } public appendTo(parent: HTMLElement, doc: Document = parent.ownerDocument ?? document) { const element = doc.createElement(this.name); this.render(element); parent.appendChild(element); return element; } public render(root: HTMLElement) { const { attributes, children } = this; if (attributes) { for (const key in attributes) { if (Object.prototype.hasOwnProperty.call(attributes, key)) { PropertyStore.setProperty(root, key, attributes[key]); } } } if (children) { for (const iterator of children.flat(2)) { switch(typeof iterator) { case "object": const child = root.ownerDocument.createElement(iterator.name); iterator.render(child); root.appendChild(child); continue; case "boolean": if(!iterator) { continue; } break; } root.append(iterator?.toString()); } } return root; } public renderToString(nest = "") { const { name, attributes, children } = this; let a = ""; if (attributes) { for (const key in attributes) { if (Object.prototype.hasOwnProperty.call(attributes, key)) { const element = attributes[key]; a += ` ${key}=${JSON.stringify(element)}`; } } } if (this.children) { for (const child of this.children) { if (typeof child === "string") { children.push(child); continue; } if (!child) { continue; } children.push(child.renderToString(nest + "\t")); } } if (!name) { return `\n${nest}\t${children.join("\n\t")}`; } return `${nest}<${name}${a}>\n${nest}\t${children.join("\n\t")}\n${nest}`; } }