summaryrefslogtreecommitdiffhomepage
path: root/vhosts/blog/nuldoc-src/dom.ts
diff options
context:
space:
mode:
Diffstat (limited to 'vhosts/blog/nuldoc-src/dom.ts')
-rw-r--r--vhosts/blog/nuldoc-src/dom.ts107
1 files changed, 107 insertions, 0 deletions
diff --git a/vhosts/blog/nuldoc-src/dom.ts b/vhosts/blog/nuldoc-src/dom.ts
new file mode 100644
index 00000000..d8f53d76
--- /dev/null
+++ b/vhosts/blog/nuldoc-src/dom.ts
@@ -0,0 +1,107 @@
+export type Text = {
+ kind: "text";
+ content: string;
+ raw: false;
+};
+
+export type RawHTML = {
+ kind: "text";
+ content: string;
+ raw: true;
+};
+
+export type Element = {
+ kind: "element";
+ name: string;
+ attributes: Map<string, string>;
+ children: Node[];
+};
+
+export type Node = Element | Text | RawHTML;
+
+export function addClass(e: Element, klass: string) {
+ const classes = e.attributes.get("class");
+ if (classes === undefined) {
+ e.attributes.set("class", klass);
+ } else {
+ const classList = classes.split(" ");
+ classList.push(klass);
+ classList.sort();
+ e.attributes.set("class", classList.join(" "));
+ }
+}
+
+export function findFirstChildElement(
+ e: Element,
+ name: string,
+): Element | null {
+ for (const c of e.children) {
+ if (c.kind === "element" && c.name === name) {
+ return c;
+ }
+ }
+ return null;
+}
+
+export function findChildElements(e: Element, name: string): Element[] {
+ const cs = [];
+ for (const c of e.children) {
+ if (c.kind === "element" && c.name === name) {
+ cs.push(c);
+ }
+ }
+ return cs;
+}
+
+export function removeChildElements(e: Element, name: string) {
+ e.children = e.children.filter((c) =>
+ c.kind !== "element" || c.name !== name
+ );
+}
+
+export function innerText(e: Element): string {
+ let t = "";
+ forEachChild(e, (c) => {
+ if (c.kind === "text") {
+ t += c.content;
+ }
+ });
+ return t;
+}
+
+export function forEachChild(e: Element, f: (n: Node) => void) {
+ for (const c of e.children) {
+ f(c);
+ }
+}
+
+export function forEachChildRecursively(e: Element, f: (n: Node) => void) {
+ const g = (c: Node) => {
+ f(c);
+ if (c.kind === "element") {
+ forEachChild(c, g);
+ }
+ };
+ forEachChild(e, g);
+}
+
+export function text(content: string): Text {
+ return {
+ kind: "text",
+ content: content,
+ raw: false,
+ };
+}
+
+export function el(
+ name: string,
+ attrs: [string, string][],
+ ...children: Node[]
+): Element {
+ return {
+ kind: "element",
+ name: name,
+ attributes: new Map(attrs),
+ children: children,
+ };
+}