Renderer.ts
49 lines
| 1.5 KiB
| video/mp2t
|
TypeScriptLexer
cin
|
r96 | import { IScope, Scope } from "./Scope"; | ||
import { destroy, isNode, isRendition, isWidget, Rendition } from "./traits"; | ||||
cin
|
r94 | |||
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(); | ||||
} | ||||
} | ||||
cin
|
r96 | |||
/** 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); | ||||
} | ||||
} | ||||