add possibility to wrap node
This commit is contained in:
parent
f1d6a2e989
commit
c3014d690b
4 changed files with 32 additions and 15 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,8 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
# editors
|
|
||||||
!/.vscode
|
|
||||||
|
|
||||||
# makefile
|
# makefile
|
||||||
!/makefile
|
!/makefile
|
||||||
|
|
||||||
|
|
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
@ -1,3 +0,0 @@
|
||||||
{
|
|
||||||
"editor.tabSize": 2
|
|
||||||
}
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { assertEquals } from "testing/asserts.ts";
|
import { assertEquals } from "testing/asserts.ts";
|
||||||
import { E, F, TextNode } from "../core/node.ts";
|
import { TextNode } from "../core/node.ts";
|
||||||
|
import { E, F } from "./node.ts";
|
||||||
|
|
||||||
import { StrRenderer } from "./str.ts";
|
import { StrRenderer } from "./str.ts";
|
||||||
|
|
||||||
|
@ -131,3 +132,15 @@ Deno.test({
|
||||||
assertEquals(res, "<!doctype html><body></body>");
|
assertEquals(res, "<!doctype html><body></body>");
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Deno.test({
|
||||||
|
name: "should wrap node",
|
||||||
|
fn: () => {
|
||||||
|
const layout = E("body", [], []);
|
||||||
|
|
||||||
|
const ren = new StrRenderer({ wrapNode: (node) => E("html", [], [node]) });
|
||||||
|
const res = ren.render(layout);
|
||||||
|
|
||||||
|
assertEquals(res, "<!doctype html><html><body></body></html>");
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
26
ren/str.ts
26
ren/str.ts
|
@ -14,27 +14,37 @@ import { Renderer } from "./types.ts";
|
||||||
interface StrRendererOpts {
|
interface StrRendererOpts {
|
||||||
doctype?: string;
|
doctype?: string;
|
||||||
forceRenderDoctype?: boolean;
|
forceRenderDoctype?: boolean;
|
||||||
|
wrapNode?: (node: AnyNode) => AnyNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class StrRenderer implements Renderer<string> {
|
export class StrRenderer implements Renderer<string> {
|
||||||
#opts: StrRendererOpts;
|
#doctype: string;
|
||||||
|
#forceRenderDoctype: boolean;
|
||||||
|
#wrapNode: (node: AnyNode) => AnyNode;
|
||||||
|
|
||||||
constructor(opts?: StrRendererOpts) {
|
constructor(opts?: StrRendererOpts) {
|
||||||
this.#opts = opts ?? {};
|
this.#doctype = opts?.doctype ?? "html";
|
||||||
|
this.#forceRenderDoctype = opts?.forceRenderDoctype ?? false;
|
||||||
|
this.#wrapNode = opts?.wrapNode ?? identity;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(node: AnyNode): string {
|
render(node: AnyNode): string {
|
||||||
const shouldRenderDoctype = this.#opts.forceRenderDoctype ||
|
const wrappedNode = this.#wrapNode(node);
|
||||||
(isElem(node) && node.tagName === "html");
|
const shouldRenderDoctype = this.#forceRenderDoctype ||
|
||||||
|
(isElem(wrappedNode) && wrappedNode.tagName === "html");
|
||||||
return concat([
|
return concat([
|
||||||
shouldRenderDoctype && encodeDoctype(this.#opts.doctype),
|
shouldRenderDoctype && encodeDoctype(this.#doctype),
|
||||||
encodeAnyNode(node),
|
encodeAnyNode(wrappedNode),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function encodeDoctype(value?: string): string {
|
function identity<T>(val: T): T {
|
||||||
return `<!doctype ${value ?? "html"}>`;
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeDoctype(value: string): string {
|
||||||
|
return `<!doctype ${value}>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function encodeAnyNode(node: AnyNode): string {
|
function encodeAnyNode(node: AnyNode): string {
|
||||||
|
|
Reference in a new issue