import { isTag, isText } from "domhandler"; import { filter, findOne } from "./querying.js"; /** * A map of functions to check nodes against. */ const Checks = { tag_name(name) { if (typeof name === "function") { return (elem) => isTag(elem) && name(elem.name); } else if (name === "*") { return isTag; } return (elem) => isTag(elem) && elem.name === name; }, tag_type(type) { if (typeof type === "function") { return (elem) => type(elem.type); } return (elem) => elem.type === type; }, tag_contains(data) { if (typeof data === "function") { return (elem) => isText(elem) && data(elem.data); } return (elem) => isText(elem) && elem.data === data; }, }; /** * Returns a function to check whether a node has an attribute with a particular * value. * * @param attrib Attribute to check. * @param value Attribute value to look for. * @returns A function to check whether the a node has an attribute with a * particular value. */ function getAttribCheck(attrib, value) { if (typeof value === "function") { return (elem) => isTag(elem) && value(elem.attribs[attrib]); } return (elem) => isTag(elem) && elem.attribs[attrib] === value; } /** * Returns a function that returns `true` if either of the input functions * returns `true` for a node. * * @param a First function to combine. * @param b Second function to combine. * @returns A function taking a node and returning `true` if either of the input * functions returns `true` for the node. */ function combineFuncs(a, b) { return (elem) => a(elem) || b(elem); } /** * Returns a function that executes all checks in `options` and returns `true` * if any of them match a node. * * @param options An object describing nodes to look for. * @returns A function that executes all checks in `options` and returns `true` * if any of them match a node. */ function compileTest(options) { const funcs = Object.keys(options).map((key) => { const value = options[key]; return Object.prototype.hasOwnProperty.call(Checks, key) ? Checks[key](value) : getAttribCheck(key, value); }); return funcs.length === 0 ? null : funcs.reduce(combineFuncs); } /** * Checks whether a node matches the description in `options`. * * @category Legacy Query Functions * @param options An object describing nodes to look for. * @param node The element to test. * @returns Whether the element matches the description in `options`. */ export function testElement(options, node) { const test = compileTest(options); return test ? test(node) : true; } /** * Returns all nodes that match `options`. * * @category Legacy Query Functions * @param options An object describing nodes to look for. * @param nodes Nodes to search through. * @param recurse Also consider child nodes. * @param limit Maximum number of nodes to return. * @returns All nodes that match `options`. */ export function getElements(options, nodes, recurse, limit = Infinity) { const test = compileTest(options); return test ? filter(test, nodes, recurse, limit) : []; } /** * Returns the node with the supplied ID. * * @category Legacy Query Functions * @param id The unique ID attribute value to look for. * @param nodes Nodes to search through. * @param recurse Also consider child nodes. * @returns The node with the supplied ID. */ export function getElementById(id, nodes, recurse = true) { if (!Array.isArray(nodes)) nodes = [nodes]; return findOne(getAttribCheck("id", id), nodes, recurse); } /** * Returns all nodes with the supplied `tagName`. * * @category Legacy Query Functions * @param tagName Tag name to search for. * @param nodes Nodes to search through. * @param recurse Also consider child nodes. * @param limit Maximum number of nodes to return. * @returns All nodes with the supplied `tagName`. */ export function getElementsByTagName(tagName, nodes, recurse = true, limit = Infinity) { return filter(Checks["tag_name"](tagName), nodes, recurse, limit); } /** * Returns all nodes with the supplied `type`. * * @category Legacy Query Functions * @param type Element type to look for. * @param nodes Nodes to search through. * @param recurse Also consider child nodes. * @param limit Maximum number of nodes to return. * @returns All nodes with the supplied `type`. */ export function getElementsByTagType(type, nodes, recurse = true, limit = Infinity) { return filter(Checks["tag_type"](type), nodes, recurse, limit); } //# sourceMappingURL=legacy.js.map