refac(str): improve encoding
This commit is contained in:
parent
bb35ebc23a
commit
87e7f2f40b
2 changed files with 35 additions and 24 deletions
21
lib/str.mjs
21
lib/str.mjs
|
@ -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);
|
||||||
|
}
|
||||||
|
|
38
src/str.mts
38
src/str.mts
|
@ -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);
|
||||||
|
}
|
||||||
|
|
Reference in a new issue