import { IScope, Scope } from "./Scope"; import { destroy, isNode, isRendition, isWidget, Rendition } from "./traits"; let _scope = Scope.dummy; const beginRender = async () => { } const endRender = () => { } export const getScope = () => _scope; export const render = async (rendition: () => Rendition, scope = Scope.dummy) => { await beginRender(); const prev = _scope; _scope = scope; try { const node = rendition().getDomNode(); scope.own(() => destroy(node)); return node; } finally { _scope = prev; endRender(); } } /** Renders DOM element for different types of the argument. */ export const getItemDom = (v: unknown, scope: IScope) => { if (typeof v === "string" || typeof v === "number" || v instanceof RegExp || v instanceof Date) { // primitive types converted to the text nodes return document.createTextNode(v.toString()); } else if (isNode(v)) { // nodes are kept as is return v; } else if (isRendition(v)) { // renditions are instantiated return v.getDomNode(scope); } else if (isWidget(v)) { // widgets are converted to it's markup return v.domNode; } else if (typeof v === "boolean" || v === null || v === undefined) { // null | undefined | boolean are removed, converted to comments return document.createComment(`[${typeof v} ${String(v)}]`); } else { // bug: explicit error otherwise throw new Error("Invalid parameter: " + v); } }