diff --git a/core/node.test.ts b/core/node.test.ts index a249b7e..e69556d 100644 --- a/core/node.test.ts +++ b/core/node.test.ts @@ -1,6 +1,6 @@ import { assertEquals, assertInstanceOf } from "testing/asserts.ts"; -import { E, Elem, F, Fragment, TextNode } from "./node.ts"; +import { Elem, Fragment, TextNode } from "./node.ts"; Deno.test({ name: "should create text node from string", @@ -26,23 +26,6 @@ Deno.test({ }, }); -Deno.test({ - name: "should create fragment via util", - fn: () => { - const el = E("p", [], "hello world"); - const innerFrag = F(["inner"]); - const frag = F(["hello", innerFrag, "world", el]); - - assertInstanceOf(frag, Fragment); - assertEquals(frag.children, [ - new TextNode("hello"), - new TextNode("inner"), - new TextNode("world"), - el, - ]); - }, -}); - Deno.test({ name: "should create element", fn: () => { @@ -54,15 +37,3 @@ Deno.test({ assertEquals(el.children, [child]); }, }); - -Deno.test({ - name: "should create element via util", - fn: () => { - const child = E("p", [], "hello world"); - const el = E("div", { class: "hello" }, [child]); - - assertEquals(el.tagName, "div"); - assertEquals(el.attrs, { class: "hello" }); - assertEquals(el.children, [child]); - }, -}); diff --git a/core/node.ts b/core/node.ts index 3f868b4..d3f1933 100644 --- a/core/node.ts +++ b/core/node.ts @@ -1,4 +1,4 @@ -import { isNotSkip, isNum, isStr, Nilable, Skipable, toArr } from "./utils.ts"; +import { Nilable } from "./utils.ts"; export type Attrs = Record; export type AnyNode = Fragment | FragmentNode; @@ -72,41 +72,3 @@ export class Elem { this.#children = children ?? []; } } - -export function F(children: Skipable[]): Fragment { - return new Fragment( - children.filter(isNotSkip).flatMap((c) => - normFragmentChild(normElemChild(c)) - ), - ); -} - -type EAttrs = Attrs | Attrs[]; -type ETextNode = string | number | TextNode; -type EChild = ETextNode | Fragment | Elem; - -export function E( - tagName: ElemTagName, - attrs: EAttrs, - children?: ETextNode | Skipable[], -): Elem { - return new Elem( - tagName, - mergeAttrs(attrs ?? []), - toArr(children ?? []).filter(isNotSkip).map(normElemChild), - ); -} - -function mergeAttrs(attrs: EAttrs): Attrs { - return !Array.isArray(attrs) - ? attrs - : attrs.reduce((acc, attrs) => ({ ...acc, ...attrs }), {} as Attrs); -} - -function normFragmentChild(node: AnyNode): FragmentNode | FragmentNode[] { - return isFragment(node) ? node.children : node; -} - -function normElemChild(node: EChild): AnyNode { - return isStr(node) || isNum(node) ? new TextNode(String(node)) : node; -} diff --git a/ren/node.test.ts b/ren/node.test.ts new file mode 100644 index 0000000..b5dc121 --- /dev/null +++ b/ren/node.test.ts @@ -0,0 +1,34 @@ +import { assertEquals, assertInstanceOf } from "testing/asserts.ts"; +import { Elem, Fragment, TextNode } from "../core/node.ts"; + +import { E, F } from "./node.ts"; + +Deno.test({ + name: "should create fragment via util", + fn: () => { + const el = E("p", [], "hello world"); + const innerFrag = F(["inner"]); + const frag = F(["hello", innerFrag, "world", el]); + + assertInstanceOf(frag, Fragment); + assertEquals(frag.children, [ + new TextNode("hello"), + new TextNode("inner"), + new TextNode("world"), + el, + ]); + }, +}); + +Deno.test({ + name: "should create element via util", + fn: () => { + const child = E("p", [], "hello world"); + const el = E("div", { class: "hello" }, [child]); + + assertInstanceOf(el, Elem); + assertEquals(el.tagName, "div"); + assertEquals(el.attrs, { class: "hello" }); + assertEquals(el.children, [child]); + }, +}); diff --git a/ren/node.ts b/ren/node.ts new file mode 100644 index 0000000..e083070 --- /dev/null +++ b/ren/node.ts @@ -0,0 +1,49 @@ +import { + AnyNode, + Attrs, + Elem, + ElemTagName, + Fragment, + FragmentNode, + isFragment, + TextNode, +} from "../core/node.ts"; +import { isNotSkip, isNum, isStr, Skipable, toArr } from "../core/utils.ts"; + +export function F(children: Skipable[]): Fragment { + return new Fragment( + children.filter(isNotSkip).flatMap((c) => + normFragmentChild(normElemChild(c)) + ), + ); +} + +type EAttrs = Attrs | Attrs[]; +type ETextNode = string | number | TextNode; +type EChild = ETextNode | Fragment | Elem; + +export function E( + tagName: ElemTagName, + attrs: EAttrs, + children?: ETextNode | Skipable[], +): Elem { + return new Elem( + tagName, + mergeAttrs(attrs ?? []), + toArr(children ?? []).filter(isNotSkip).map(normElemChild), + ); +} + +function mergeAttrs(attrs: EAttrs): Attrs { + return !Array.isArray(attrs) + ? attrs + : attrs.reduce((acc, attrs) => ({ ...acc, ...attrs }), {} as Attrs); +} + +function normFragmentChild(node: AnyNode): FragmentNode | FragmentNode[] { + return isFragment(node) ? node.children : node; +} + +function normElemChild(node: EChild): AnyNode { + return isStr(node) || isNum(node) ? new TextNode(String(node)) : node; +}