Archived
1
0
Fork 0
This repository has been archived on 2024-07-25. You can view files and clone it, but cannot push or open issues or pull requests.
paren/lib/str.mjs
Dmitriy Pleshevskiy f577128923 feat: add Nil and false to sync node type
refac: remove maybeWithChildren, use sparse array
2022-03-17 16:34:44 +03:00

50 lines
1.5 KiB
JavaScript

import { isBool, isNil } from "./lang.mjs";
import { Elem, TextNode } from "./nodes.mjs";
export class StrRenderer {
async render(node) {
return encodeNode(await node);
}
}
async function encodeAnyNode(node) {
const syncNode = await node;
return !syncNode
? null
: syncNode instanceof TextNode
? encodeTextNode(syncNode)
: encodeNode(syncNode);
}
function encodeTextNode(node) {
return String(node);
}
async function encodeNode(node) {
const encodedChildren = isNil(node.children)
? undefined
: await Promise.all(node.children.map(encodeAnyNode)).then((children) => children.filter((c) => Boolean(c)));
return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren);
}
function encodeHtmlFragment(children) {
return children?.join("") ?? "";
}
function encodeHtmlElement(tagName, attrs, children) {
const open = `<${tagName} ${encodeAttrs(attrs)}>`;
if (isNil(children))
return open;
return `${open}${children.join("")}</${tagName}>`;
}
function encodeAttrs(attrs) {
if (!attrs)
return "";
return Object.entries(attrs)
.map(([key, value]) => encodeAttr(key, value))
.filter(Boolean)
.join(" ");
}
function encodeAttr(key, value) {
if (isNil(value))
return null;
if (isBool(value))
return value ? key : null;
return `${key}="${value}"`;
}