Archived
1
0
Fork 0

refac(str): improve encoding

This commit is contained in:
Dmitriy Pleshevskiy 2022-03-18 22:14:42 +03:00
parent bb35ebc23a
commit 87e7f2f40b
2 changed files with 35 additions and 24 deletions

View file

@ -18,27 +18,24 @@ function encodeTextNode(node) {
function encodeNode(node) { function encodeNode(node) {
const encodedChildren = isNil(node.children) const encodedChildren = isNil(node.children)
? undefined ? undefined
: node.children.map(encodeAnyNode).filter((c) => Boolean(c)); : node.children.map(encodeAnyNode);
return node instanceof Elem return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren) ? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren); : encodeHtmlFragment(encodedChildren);
} }
function encodeHtmlFragment(children) { function encodeHtmlFragment(children) {
return children?.join("") ?? ""; return concat(children ?? []);
} }
function encodeHtmlElement(tagName, attrs, children) { function encodeHtmlElement(tagName, attrs, children) {
const open = `<${tagName} ${encodeAttrs(attrs)}>`; const open = `<${join(" ", [tagName, encodeAttrs(attrs)])}>`;
if (isNil(children)) if (isNil(children))
return open; return open;
return `${open}${children.join("")}</${tagName}>`; return `${open}${concat(children)}</${tagName}>`;
} }
function encodeAttrs(attrs) { function encodeAttrs(attrs) {
if (!attrs) if (!attrs)
return ""; return null;
return Object.entries(attrs) return join(" ", Object.entries(attrs).map(([key, value]) => encodeAttr(key, value)));
.map(([key, value]) => encodeAttr(key, value))
.filter(Boolean)
.join(" ");
} }
function encodeAttr(key, value) { function encodeAttr(key, value) {
if (isNil(value)) if (isNil(value))
@ -47,3 +44,9 @@ function encodeAttr(key, value) {
return value ? key : null; return value ? key : null;
return `${key}="${value}"`; return `${key}="${value}"`;
} }
function concat(arr) {
return join("", arr);
}
function join(sep, arr) {
return arr.filter(Boolean).join(sep);
}

View file

@ -1,6 +1,6 @@
import { Renderer } from "./types.mjs"; import { Renderer } from "./types.mjs";
import { isBool, isNil, Nullable } from "./lang.mjs"; import { isBool, isNil, Nilable, Nullable } from "./lang.mjs";
import { AnyNode, Elem, Frag, TextNode } from "./nodes.mjs"; import { AnyNode, Elem, ElemAttrs, Frag, TextNode } from "./nodes.mjs";
export class StrRenderer implements Renderer<string> { export class StrRenderer implements Renderer<string> {
render(node: Elem): string { render(node: Elem): string {
@ -23,33 +23,33 @@ function encodeTextNode(node: TextNode): string {
function encodeNode(node: Elem | Frag): string { function encodeNode(node: Elem | Frag): string {
const encodedChildren = isNil(node.children) const encodedChildren = isNil(node.children)
? undefined ? undefined
: node.children.map(encodeAnyNode).filter((c): c is string => Boolean(c)); : node.children.map(encodeAnyNode);
return node instanceof Elem return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren) ? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren); : encodeHtmlFragment(encodedChildren);
} }
function encodeHtmlFragment(children?: string[]): string { function encodeHtmlFragment(children?: Nilable<string>[]): string {
return children?.join("") ?? ""; return concat(children ?? []);
} }
function encodeHtmlElement( function encodeHtmlElement(
tagName: string, tagName: string,
attrs?: Record<string, unknown>, attrs?: ElemAttrs,
children?: string[] children?: Nilable<string>[]
): string { ): string {
const open = `<${tagName} ${encodeAttrs(attrs)}>`; const open = `<${join(" ", [tagName, encodeAttrs(attrs)])}>`;
if (isNil(children)) return open; if (isNil(children)) return open;
return `${open}${children.join("")}</${tagName}>`; return `${open}${concat(children)}</${tagName}>`;
} }
function encodeAttrs(attrs?: Record<string, unknown>): Nullable<string> { function encodeAttrs(attrs?: ElemAttrs): Nullable<string> {
if (!attrs) return ""; if (!attrs) return null;
return Object.entries(attrs) return join(
.map(([key, value]) => encodeAttr(key, value)) " ",
.filter(Boolean) Object.entries(attrs).map(([key, value]) => encodeAttr(key, value))
.join(" "); );
} }
function encodeAttr(key: string, value: unknown): Nullable<string> { function encodeAttr(key: string, value: unknown): Nullable<string> {
@ -57,3 +57,11 @@ function encodeAttr(key: string, value: unknown): Nullable<string> {
if (isBool(value)) return value ? key : null; if (isBool(value)) return value ? key : null;
return `${key}="${value}"`; return `${key}="${value}"`;
} }
function concat(arr: Nilable<string>[]): string {
return join("", arr);
}
function join(sep: string, arr: Nilable<string>[]): string {
return arr.filter(Boolean).join(sep);
}