39 lines
1.2 KiB
TypeScript
39 lines
1.2 KiB
TypeScript
import type { AnyNode, Element } from "domhandler";
|
|
import { findAll, findOne } from "domutils";
|
|
import { parseDocument } from "htmlparser2";
|
|
|
|
/** Parse an HTML fragment / document and return the DOM root list. */
|
|
export function parse(html: string): AnyNode[] {
|
|
return parseDocument(html).children;
|
|
}
|
|
|
|
/** Find the first element matching a predicate (deep search). */
|
|
export function findFirst(
|
|
html: string,
|
|
predicate: (el: Element) => boolean
|
|
): Element | null {
|
|
const roots = parse(html);
|
|
return findOne(predicate, roots, true);
|
|
}
|
|
|
|
/** Find every element matching a predicate (deep search). */
|
|
export function findEvery(
|
|
html: string,
|
|
predicate: (el: Element) => boolean
|
|
): Element[] {
|
|
const roots = parse(html);
|
|
return findAll(predicate, roots);
|
|
}
|
|
|
|
/** Extract text content from an element (recursive). */
|
|
export function textOf(el: Element | AnyNode | null | undefined): string {
|
|
if (el === null || el === undefined) return "";
|
|
if ("data" in el && typeof el.data === "string" && el.type === "text") {
|
|
return el.data;
|
|
}
|
|
if ("children" in el && Array.isArray(el.children)) {
|
|
return el.children.map((c) => textOf(c as AnyNode)).join("");
|
|
}
|
|
return "";
|
|
}
|