Use local svgo.cmd wrapper binary
Switch SVG optimizer resolution from bin/svgo-cli.exe to bin/svgo.cmd. Update unit tests to validate the new local binary path behavior. Co-Authored-By: Abacus.AI CLI <agent@abacus.ai>
This commit is contained in:
+71
@@ -0,0 +1,71 @@
|
||||
import type { AnyNode } from "domhandler";
|
||||
/**
|
||||
* The medium of a media item.
|
||||
*
|
||||
* @category Feeds
|
||||
*/
|
||||
export type FeedItemMediaMedium = "image" | "audio" | "video" | "document" | "executable";
|
||||
/**
|
||||
* The type of a media item.
|
||||
*
|
||||
* @category Feeds
|
||||
*/
|
||||
export type FeedItemMediaExpression = "sample" | "full" | "nonstop";
|
||||
/**
|
||||
* A media item of a feed entry.
|
||||
*
|
||||
* @category Feeds
|
||||
*/
|
||||
export interface FeedItemMedia {
|
||||
medium: FeedItemMediaMedium | undefined;
|
||||
isDefault: boolean;
|
||||
url?: string;
|
||||
fileSize?: number;
|
||||
type?: string;
|
||||
expression?: FeedItemMediaExpression;
|
||||
bitrate?: number;
|
||||
framerate?: number;
|
||||
samplingrate?: number;
|
||||
channels?: number;
|
||||
duration?: number;
|
||||
height?: number;
|
||||
width?: number;
|
||||
lang?: string;
|
||||
}
|
||||
/**
|
||||
* An entry of a feed.
|
||||
*
|
||||
* @category Feeds
|
||||
*/
|
||||
export interface FeedItem {
|
||||
id?: string;
|
||||
title?: string;
|
||||
link?: string;
|
||||
description?: string;
|
||||
pubDate?: Date;
|
||||
media: FeedItemMedia[];
|
||||
}
|
||||
/**
|
||||
* The root of a feed.
|
||||
*
|
||||
* @category Feeds
|
||||
*/
|
||||
export interface Feed {
|
||||
type: string;
|
||||
id?: string;
|
||||
title?: string;
|
||||
link?: string;
|
||||
description?: string;
|
||||
updated?: Date;
|
||||
author?: string;
|
||||
items: FeedItem[];
|
||||
}
|
||||
/**
|
||||
* Get the feed object from the root of a DOM tree.
|
||||
*
|
||||
* @category Feeds
|
||||
* @param doc - The DOM to to extract the feed from.
|
||||
* @returns The feed.
|
||||
*/
|
||||
export declare function getFeed(doc: AnyNode[]): Feed | null;
|
||||
//# sourceMappingURL=feeds.d.ts.map
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
import { textContent } from "./stringify.js";
|
||||
import { getElementsByTagName } from "./legacy.js";
|
||||
/**
|
||||
* Get the feed object from the root of a DOM tree.
|
||||
*
|
||||
* @category Feeds
|
||||
* @param doc - The DOM to to extract the feed from.
|
||||
* @returns The feed.
|
||||
*/
|
||||
export function getFeed(doc) {
|
||||
const feedRoot = getOneElement(isValidFeed, doc);
|
||||
return !feedRoot
|
||||
? null
|
||||
: feedRoot.name === "feed"
|
||||
? getAtomFeed(feedRoot)
|
||||
: getRssFeed(feedRoot);
|
||||
}
|
||||
/**
|
||||
* Parse an Atom feed.
|
||||
*
|
||||
* @param feedRoot The root of the feed.
|
||||
* @returns The parsed feed.
|
||||
*/
|
||||
function getAtomFeed(feedRoot) {
|
||||
var _a;
|
||||
const childs = feedRoot.children;
|
||||
const feed = {
|
||||
type: "atom",
|
||||
items: getElementsByTagName("entry", childs).map((item) => {
|
||||
var _a;
|
||||
const { children } = item;
|
||||
const entry = { media: getMediaElements(children) };
|
||||
addConditionally(entry, "id", "id", children);
|
||||
addConditionally(entry, "title", "title", children);
|
||||
const href = (_a = getOneElement("link", children)) === null || _a === void 0 ? void 0 : _a.attribs["href"];
|
||||
if (href) {
|
||||
entry.link = href;
|
||||
}
|
||||
const description = fetch("summary", children) || fetch("content", children);
|
||||
if (description) {
|
||||
entry.description = description;
|
||||
}
|
||||
const pubDate = fetch("updated", children);
|
||||
if (pubDate) {
|
||||
entry.pubDate = new Date(pubDate);
|
||||
}
|
||||
return entry;
|
||||
}),
|
||||
};
|
||||
addConditionally(feed, "id", "id", childs);
|
||||
addConditionally(feed, "title", "title", childs);
|
||||
const href = (_a = getOneElement("link", childs)) === null || _a === void 0 ? void 0 : _a.attribs["href"];
|
||||
if (href) {
|
||||
feed.link = href;
|
||||
}
|
||||
addConditionally(feed, "description", "subtitle", childs);
|
||||
const updated = fetch("updated", childs);
|
||||
if (updated) {
|
||||
feed.updated = new Date(updated);
|
||||
}
|
||||
addConditionally(feed, "author", "email", childs, true);
|
||||
return feed;
|
||||
}
|
||||
/**
|
||||
* Parse a RSS feed.
|
||||
*
|
||||
* @param feedRoot The root of the feed.
|
||||
* @returns The parsed feed.
|
||||
*/
|
||||
function getRssFeed(feedRoot) {
|
||||
var _a, _b;
|
||||
const childs = (_b = (_a = getOneElement("channel", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : [];
|
||||
const feed = {
|
||||
type: feedRoot.name.substr(0, 3),
|
||||
id: "",
|
||||
items: getElementsByTagName("item", feedRoot.children).map((item) => {
|
||||
const { children } = item;
|
||||
const entry = { media: getMediaElements(children) };
|
||||
addConditionally(entry, "id", "guid", children);
|
||||
addConditionally(entry, "title", "title", children);
|
||||
addConditionally(entry, "link", "link", children);
|
||||
addConditionally(entry, "description", "description", children);
|
||||
const pubDate = fetch("pubDate", children) || fetch("dc:date", children);
|
||||
if (pubDate)
|
||||
entry.pubDate = new Date(pubDate);
|
||||
return entry;
|
||||
}),
|
||||
};
|
||||
addConditionally(feed, "title", "title", childs);
|
||||
addConditionally(feed, "link", "link", childs);
|
||||
addConditionally(feed, "description", "description", childs);
|
||||
const updated = fetch("lastBuildDate", childs);
|
||||
if (updated) {
|
||||
feed.updated = new Date(updated);
|
||||
}
|
||||
addConditionally(feed, "author", "managingEditor", childs, true);
|
||||
return feed;
|
||||
}
|
||||
const MEDIA_KEYS_STRING = ["url", "type", "lang"];
|
||||
const MEDIA_KEYS_INT = [
|
||||
"fileSize",
|
||||
"bitrate",
|
||||
"framerate",
|
||||
"samplingrate",
|
||||
"channels",
|
||||
"duration",
|
||||
"height",
|
||||
"width",
|
||||
];
|
||||
/**
|
||||
* Get all media elements of a feed item.
|
||||
*
|
||||
* @param where Nodes to search in.
|
||||
* @returns Media elements.
|
||||
*/
|
||||
function getMediaElements(where) {
|
||||
return getElementsByTagName("media:content", where).map((elem) => {
|
||||
const { attribs } = elem;
|
||||
const media = {
|
||||
medium: attribs["medium"],
|
||||
isDefault: !!attribs["isDefault"],
|
||||
};
|
||||
for (const attrib of MEDIA_KEYS_STRING) {
|
||||
if (attribs[attrib]) {
|
||||
media[attrib] = attribs[attrib];
|
||||
}
|
||||
}
|
||||
for (const attrib of MEDIA_KEYS_INT) {
|
||||
if (attribs[attrib]) {
|
||||
media[attrib] = parseInt(attribs[attrib], 10);
|
||||
}
|
||||
}
|
||||
if (attribs["expression"]) {
|
||||
media.expression = attribs["expression"];
|
||||
}
|
||||
return media;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Get one element by tag name.
|
||||
*
|
||||
* @param tagName Tag name to look for
|
||||
* @param node Node to search in
|
||||
* @returns The element or null
|
||||
*/
|
||||
function getOneElement(tagName, node) {
|
||||
return getElementsByTagName(tagName, node, true, 1)[0];
|
||||
}
|
||||
/**
|
||||
* Get the text content of an element with a certain tag name.
|
||||
*
|
||||
* @param tagName Tag name to look for.
|
||||
* @param where Node to search in.
|
||||
* @param recurse Whether to recurse into child nodes.
|
||||
* @returns The text content of the element.
|
||||
*/
|
||||
function fetch(tagName, where, recurse = false) {
|
||||
return textContent(getElementsByTagName(tagName, where, recurse, 1)).trim();
|
||||
}
|
||||
/**
|
||||
* Adds a property to an object if it has a value.
|
||||
*
|
||||
* @param obj Object to be extended
|
||||
* @param prop Property name
|
||||
* @param tagName Tag name that contains the conditionally added property
|
||||
* @param where Element to search for the property
|
||||
* @param recurse Whether to recurse into child nodes.
|
||||
*/
|
||||
function addConditionally(obj, prop, tagName, where, recurse = false) {
|
||||
const val = fetch(tagName, where, recurse);
|
||||
if (val)
|
||||
obj[prop] = val;
|
||||
}
|
||||
/**
|
||||
* Checks if an element is a feed root node.
|
||||
*
|
||||
* @param value The name of the element to check.
|
||||
* @returns Whether an element is a feed root node.
|
||||
*/
|
||||
function isValidFeed(value) {
|
||||
return value === "rss" || value === "feed" || value === "rdf:RDF";
|
||||
}
|
||||
//# sourceMappingURL=feeds.js.map
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
import { AnyNode } from "domhandler";
|
||||
/**
|
||||
* Given an array of nodes, remove any member that is contained by another
|
||||
* member.
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodes Nodes to filter.
|
||||
* @returns Remaining nodes that aren't contained by other nodes.
|
||||
*/
|
||||
export declare function removeSubsets(nodes: AnyNode[]): AnyNode[];
|
||||
/**
|
||||
* @category Helpers
|
||||
* @see {@link http://dom.spec.whatwg.org/#dom-node-comparedocumentposition}
|
||||
*/
|
||||
export declare const enum DocumentPosition {
|
||||
DISCONNECTED = 1,
|
||||
PRECEDING = 2,
|
||||
FOLLOWING = 4,
|
||||
CONTAINS = 8,
|
||||
CONTAINED_BY = 16
|
||||
}
|
||||
/**
|
||||
* Compare the position of one node against another node in any other document,
|
||||
* returning a bitmask with the values from {@link DocumentPosition}.
|
||||
*
|
||||
* Document order:
|
||||
* > There is an ordering, document order, defined on all the nodes in the
|
||||
* > document corresponding to the order in which the first character of the
|
||||
* > XML representation of each node occurs in the XML representation of the
|
||||
* > document after expansion of general entities. Thus, the document element
|
||||
* > node will be the first node. Element nodes occur before their children.
|
||||
* > Thus, document order orders element nodes in order of the occurrence of
|
||||
* > their start-tag in the XML (after expansion of entities). The attribute
|
||||
* > nodes of an element occur after the element and before its children. The
|
||||
* > relative order of attribute nodes is implementation-dependent.
|
||||
*
|
||||
* Source:
|
||||
* http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodeA The first node to use in the comparison
|
||||
* @param nodeB The second node to use in the comparison
|
||||
* @returns A bitmask describing the input nodes' relative position.
|
||||
*
|
||||
* See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
|
||||
* a description of these values.
|
||||
*/
|
||||
export declare function compareDocumentPosition(nodeA: AnyNode, nodeB: AnyNode): number;
|
||||
/**
|
||||
* Sort an array of nodes based on their relative position in the document,
|
||||
* removing any duplicate nodes. If the array contains nodes that do not belong
|
||||
* to the same document, sort order is unspecified.
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodes Array of DOM nodes.
|
||||
* @returns Collection of unique nodes, sorted in document order.
|
||||
*/
|
||||
export declare function uniqueSort<T extends AnyNode>(nodes: T[]): T[];
|
||||
//# sourceMappingURL=helpers.d.ts.map
|
||||
+136
@@ -0,0 +1,136 @@
|
||||
import { hasChildren } from "domhandler";
|
||||
/**
|
||||
* Given an array of nodes, remove any member that is contained by another
|
||||
* member.
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodes Nodes to filter.
|
||||
* @returns Remaining nodes that aren't contained by other nodes.
|
||||
*/
|
||||
export function removeSubsets(nodes) {
|
||||
let idx = nodes.length;
|
||||
/*
|
||||
* Check if each node (or one of its ancestors) is already contained in the
|
||||
* array.
|
||||
*/
|
||||
while (--idx >= 0) {
|
||||
const node = nodes[idx];
|
||||
/*
|
||||
* Remove the node if it is not unique.
|
||||
* We are going through the array from the end, so we only
|
||||
* have to check nodes that preceed the node under consideration in the array.
|
||||
*/
|
||||
if (idx > 0 && nodes.lastIndexOf(node, idx - 1) >= 0) {
|
||||
nodes.splice(idx, 1);
|
||||
continue;
|
||||
}
|
||||
for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) {
|
||||
if (nodes.includes(ancestor)) {
|
||||
nodes.splice(idx, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
/**
|
||||
* @category Helpers
|
||||
* @see {@link http://dom.spec.whatwg.org/#dom-node-comparedocumentposition}
|
||||
*/
|
||||
export var DocumentPosition;
|
||||
(function (DocumentPosition) {
|
||||
DocumentPosition[DocumentPosition["DISCONNECTED"] = 1] = "DISCONNECTED";
|
||||
DocumentPosition[DocumentPosition["PRECEDING"] = 2] = "PRECEDING";
|
||||
DocumentPosition[DocumentPosition["FOLLOWING"] = 4] = "FOLLOWING";
|
||||
DocumentPosition[DocumentPosition["CONTAINS"] = 8] = "CONTAINS";
|
||||
DocumentPosition[DocumentPosition["CONTAINED_BY"] = 16] = "CONTAINED_BY";
|
||||
})(DocumentPosition || (DocumentPosition = {}));
|
||||
/**
|
||||
* Compare the position of one node against another node in any other document,
|
||||
* returning a bitmask with the values from {@link DocumentPosition}.
|
||||
*
|
||||
* Document order:
|
||||
* > There is an ordering, document order, defined on all the nodes in the
|
||||
* > document corresponding to the order in which the first character of the
|
||||
* > XML representation of each node occurs in the XML representation of the
|
||||
* > document after expansion of general entities. Thus, the document element
|
||||
* > node will be the first node. Element nodes occur before their children.
|
||||
* > Thus, document order orders element nodes in order of the occurrence of
|
||||
* > their start-tag in the XML (after expansion of entities). The attribute
|
||||
* > nodes of an element occur after the element and before its children. The
|
||||
* > relative order of attribute nodes is implementation-dependent.
|
||||
*
|
||||
* Source:
|
||||
* http://www.w3.org/TR/DOM-Level-3-Core/glossary.html#dt-document-order
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodeA The first node to use in the comparison
|
||||
* @param nodeB The second node to use in the comparison
|
||||
* @returns A bitmask describing the input nodes' relative position.
|
||||
*
|
||||
* See http://dom.spec.whatwg.org/#dom-node-comparedocumentposition for
|
||||
* a description of these values.
|
||||
*/
|
||||
export function compareDocumentPosition(nodeA, nodeB) {
|
||||
const aParents = [];
|
||||
const bParents = [];
|
||||
if (nodeA === nodeB) {
|
||||
return 0;
|
||||
}
|
||||
let current = hasChildren(nodeA) ? nodeA : nodeA.parent;
|
||||
while (current) {
|
||||
aParents.unshift(current);
|
||||
current = current.parent;
|
||||
}
|
||||
current = hasChildren(nodeB) ? nodeB : nodeB.parent;
|
||||
while (current) {
|
||||
bParents.unshift(current);
|
||||
current = current.parent;
|
||||
}
|
||||
const maxIdx = Math.min(aParents.length, bParents.length);
|
||||
let idx = 0;
|
||||
while (idx < maxIdx && aParents[idx] === bParents[idx]) {
|
||||
idx++;
|
||||
}
|
||||
if (idx === 0) {
|
||||
return DocumentPosition.DISCONNECTED;
|
||||
}
|
||||
const sharedParent = aParents[idx - 1];
|
||||
const siblings = sharedParent.children;
|
||||
const aSibling = aParents[idx];
|
||||
const bSibling = bParents[idx];
|
||||
if (siblings.indexOf(aSibling) > siblings.indexOf(bSibling)) {
|
||||
if (sharedParent === nodeB) {
|
||||
return DocumentPosition.FOLLOWING | DocumentPosition.CONTAINED_BY;
|
||||
}
|
||||
return DocumentPosition.FOLLOWING;
|
||||
}
|
||||
if (sharedParent === nodeA) {
|
||||
return DocumentPosition.PRECEDING | DocumentPosition.CONTAINS;
|
||||
}
|
||||
return DocumentPosition.PRECEDING;
|
||||
}
|
||||
/**
|
||||
* Sort an array of nodes based on their relative position in the document,
|
||||
* removing any duplicate nodes. If the array contains nodes that do not belong
|
||||
* to the same document, sort order is unspecified.
|
||||
*
|
||||
* @category Helpers
|
||||
* @param nodes Array of DOM nodes.
|
||||
* @returns Collection of unique nodes, sorted in document order.
|
||||
*/
|
||||
export function uniqueSort(nodes) {
|
||||
nodes = nodes.filter((node, i, arr) => !arr.includes(node, i + 1));
|
||||
nodes.sort((a, b) => {
|
||||
const relative = compareDocumentPosition(a, b);
|
||||
if (relative & DocumentPosition.PRECEDING) {
|
||||
return -1;
|
||||
}
|
||||
else if (relative & DocumentPosition.FOLLOWING) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
return nodes;
|
||||
}
|
||||
//# sourceMappingURL=helpers.js.map
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export * from "./stringify.js";
|
||||
export * from "./traversal.js";
|
||||
export * from "./manipulation.js";
|
||||
export * from "./querying.js";
|
||||
export * from "./legacy.js";
|
||||
export * from "./helpers.js";
|
||||
export * from "./feeds.js";
|
||||
/** @deprecated Use these methods from `domhandler` directly. */
|
||||
export { isTag, isCDATA, isText, isComment, isDocument, hasChildren, } from "domhandler";
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
export * from "./stringify.js";
|
||||
export * from "./traversal.js";
|
||||
export * from "./manipulation.js";
|
||||
export * from "./querying.js";
|
||||
export * from "./legacy.js";
|
||||
export * from "./helpers.js";
|
||||
export * from "./feeds.js";
|
||||
/** @deprecated Use these methods from `domhandler` directly. */
|
||||
export { isTag, isCDATA, isText, isComment, isDocument, hasChildren, } from "domhandler";
|
||||
//# sourceMappingURL=index.js.map
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
import { AnyNode, Element } from "domhandler";
|
||||
import type { ElementType } from "domelementtype";
|
||||
/**
|
||||
* An object with keys to check elements against. If a key is `tag_name`,
|
||||
* `tag_type` or `tag_contains`, it will check the value against that specific
|
||||
* value. Otherwise, it will check an attribute with the key's name.
|
||||
*
|
||||
* @category Legacy Query Functions
|
||||
*/
|
||||
export interface TestElementOpts {
|
||||
tag_name?: string | ((name: string) => boolean);
|
||||
tag_type?: string | ((name: string) => boolean);
|
||||
tag_contains?: string | ((data?: string) => boolean);
|
||||
[attributeName: string]: undefined | string | ((attributeValue: string) => boolean);
|
||||
}
|
||||
/**
|
||||
* 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 declare function testElement(options: TestElementOpts, node: AnyNode): boolean;
|
||||
/**
|
||||
* 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 declare function getElements(options: TestElementOpts, nodes: AnyNode | AnyNode[], recurse: boolean, limit?: number): AnyNode[];
|
||||
/**
|
||||
* 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 declare function getElementById(id: string | ((id: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean): Element | null;
|
||||
/**
|
||||
* 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 declare function getElementsByTagName(tagName: string | ((name: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): Element[];
|
||||
/**
|
||||
* Returns all nodes with the supplied `className`.
|
||||
*
|
||||
* @category Legacy Query Functions
|
||||
* @param className Class 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 `className`.
|
||||
*/
|
||||
export declare function getElementsByClassName(className: string | ((name: string) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): Element[];
|
||||
/**
|
||||
* 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 declare function getElementsByTagType(type: ElementType | ((type: ElementType) => boolean), nodes: AnyNode | AnyNode[], recurse?: boolean, limit?: number): AnyNode[];
|
||||
//# sourceMappingURL=legacy.d.ts.map
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
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 `className`.
|
||||
*
|
||||
* @category Legacy Query Functions
|
||||
* @param className Class 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 `className`.
|
||||
*/
|
||||
export function getElementsByClassName(className, nodes, recurse = true, limit = Infinity) {
|
||||
return filter(getAttribCheck("class", className), 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
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
import type { ChildNode, ParentNode } from "domhandler";
|
||||
/**
|
||||
* Remove an element from the dom
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to be removed
|
||||
*/
|
||||
export declare function removeElement(elem: ChildNode): void;
|
||||
/**
|
||||
* Replace an element in the dom
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to be replaced
|
||||
* @param replacement The element to be added
|
||||
*/
|
||||
export declare function replaceElement(elem: ChildNode, replacement: ChildNode): void;
|
||||
/**
|
||||
* Append a child to an element.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param parent The element to append to.
|
||||
* @param child The element to be added as a child.
|
||||
*/
|
||||
export declare function appendChild(parent: ParentNode, child: ChildNode): void;
|
||||
/**
|
||||
* Append an element after another.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to append after.
|
||||
* @param next The element be added.
|
||||
*/
|
||||
export declare function append(elem: ChildNode, next: ChildNode): void;
|
||||
/**
|
||||
* Prepend a child to an element.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param parent The element to prepend before.
|
||||
* @param child The element to be added as a child.
|
||||
*/
|
||||
export declare function prependChild(parent: ParentNode, child: ChildNode): void;
|
||||
/**
|
||||
* Prepend an element before another.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to prepend before.
|
||||
* @param prev The element be added.
|
||||
*/
|
||||
export declare function prepend(elem: ChildNode, prev: ChildNode): void;
|
||||
//# sourceMappingURL=manipulation.d.ts.map
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Remove an element from the dom
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to be removed
|
||||
*/
|
||||
export function removeElement(elem) {
|
||||
if (elem.prev)
|
||||
elem.prev.next = elem.next;
|
||||
if (elem.next)
|
||||
elem.next.prev = elem.prev;
|
||||
if (elem.parent) {
|
||||
const childs = elem.parent.children;
|
||||
const childsIndex = childs.lastIndexOf(elem);
|
||||
if (childsIndex >= 0) {
|
||||
childs.splice(childsIndex, 1);
|
||||
}
|
||||
}
|
||||
elem.next = null;
|
||||
elem.prev = null;
|
||||
elem.parent = null;
|
||||
}
|
||||
/**
|
||||
* Replace an element in the dom
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to be replaced
|
||||
* @param replacement The element to be added
|
||||
*/
|
||||
export function replaceElement(elem, replacement) {
|
||||
const prev = (replacement.prev = elem.prev);
|
||||
if (prev) {
|
||||
prev.next = replacement;
|
||||
}
|
||||
const next = (replacement.next = elem.next);
|
||||
if (next) {
|
||||
next.prev = replacement;
|
||||
}
|
||||
const parent = (replacement.parent = elem.parent);
|
||||
if (parent) {
|
||||
const childs = parent.children;
|
||||
childs[childs.lastIndexOf(elem)] = replacement;
|
||||
elem.parent = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Append a child to an element.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param parent The element to append to.
|
||||
* @param child The element to be added as a child.
|
||||
*/
|
||||
export function appendChild(parent, child) {
|
||||
removeElement(child);
|
||||
child.next = null;
|
||||
child.parent = parent;
|
||||
if (parent.children.push(child) > 1) {
|
||||
const sibling = parent.children[parent.children.length - 2];
|
||||
sibling.next = child;
|
||||
child.prev = sibling;
|
||||
}
|
||||
else {
|
||||
child.prev = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Append an element after another.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to append after.
|
||||
* @param next The element be added.
|
||||
*/
|
||||
export function append(elem, next) {
|
||||
removeElement(next);
|
||||
const { parent } = elem;
|
||||
const currNext = elem.next;
|
||||
next.next = currNext;
|
||||
next.prev = elem;
|
||||
elem.next = next;
|
||||
next.parent = parent;
|
||||
if (currNext) {
|
||||
currNext.prev = next;
|
||||
if (parent) {
|
||||
const childs = parent.children;
|
||||
childs.splice(childs.lastIndexOf(currNext), 0, next);
|
||||
}
|
||||
}
|
||||
else if (parent) {
|
||||
parent.children.push(next);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Prepend a child to an element.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param parent The element to prepend before.
|
||||
* @param child The element to be added as a child.
|
||||
*/
|
||||
export function prependChild(parent, child) {
|
||||
removeElement(child);
|
||||
child.parent = parent;
|
||||
child.prev = null;
|
||||
if (parent.children.unshift(child) !== 1) {
|
||||
const sibling = parent.children[1];
|
||||
sibling.prev = child;
|
||||
child.next = sibling;
|
||||
}
|
||||
else {
|
||||
child.next = null;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Prepend an element before another.
|
||||
*
|
||||
* @category Manipulation
|
||||
* @param elem The element to prepend before.
|
||||
* @param prev The element be added.
|
||||
*/
|
||||
export function prepend(elem, prev) {
|
||||
removeElement(prev);
|
||||
const { parent } = elem;
|
||||
if (parent) {
|
||||
const childs = parent.children;
|
||||
childs.splice(childs.indexOf(elem), 0, prev);
|
||||
}
|
||||
if (elem.prev) {
|
||||
elem.prev.next = prev;
|
||||
}
|
||||
prev.parent = parent;
|
||||
prev.prev = elem.prev;
|
||||
prev.next = elem;
|
||||
elem.prev = prev;
|
||||
}
|
||||
//# sourceMappingURL=manipulation.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"type":"module"}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
import { Element, AnyNode, ParentNode } from "domhandler";
|
||||
/**
|
||||
* Search a node and its children for nodes passing a test function. If `node` is not an array, it will be wrapped in one.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param node Node to search. Will be included in the result set if it matches.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @param limit Maximum number of nodes to return.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export declare function filter(test: (elem: AnyNode) => boolean, node: AnyNode | AnyNode[], recurse?: boolean, limit?: number): AnyNode[];
|
||||
/**
|
||||
* Search an array of nodes and their children for nodes passing a test function.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @param limit Maximum number of nodes to return.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export declare function find(test: (elem: AnyNode) => boolean, nodes: AnyNode[] | ParentNode, recurse: boolean, limit: number): AnyNode[];
|
||||
/**
|
||||
* Finds the first element inside of an array that matches a test function. This is an alias for `Array.prototype.find`.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns The first node in the array that passes `test`.
|
||||
* @deprecated Use `Array.prototype.find` directly.
|
||||
*/
|
||||
export declare function findOneChild<T>(test: (elem: T) => boolean, nodes: T[]): T | undefined;
|
||||
/**
|
||||
* Finds one element in a tree that passes a test.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Node or array of nodes to search.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @returns The first node that passes `test`.
|
||||
*/
|
||||
export declare function findOne(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode, recurse?: boolean): Element | null;
|
||||
/**
|
||||
* Checks if a tree of nodes contains at least one node passing a test.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns Whether a tree of nodes contains at least one node passing the test.
|
||||
*/
|
||||
export declare function existsOne(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode): boolean;
|
||||
/**
|
||||
* Search an array of nodes and their children for elements passing a test function.
|
||||
*
|
||||
* Same as `find`, but limited to elements and with less options, leading to reduced complexity.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export declare function findAll(test: (elem: Element) => boolean, nodes: AnyNode[] | ParentNode): Element[];
|
||||
//# sourceMappingURL=querying.d.ts.map
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
import { isTag, hasChildren } from "domhandler";
|
||||
/**
|
||||
* Search a node and its children for nodes passing a test function. If `node` is not an array, it will be wrapped in one.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param node Node to search. Will be included in the result set if it matches.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @param limit Maximum number of nodes to return.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export function filter(test, node, recurse = true, limit = Infinity) {
|
||||
return find(test, Array.isArray(node) ? node : [node], recurse, limit);
|
||||
}
|
||||
/**
|
||||
* Search an array of nodes and their children for nodes passing a test function.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @param limit Maximum number of nodes to return.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export function find(test, nodes, recurse, limit) {
|
||||
const result = [];
|
||||
/** Stack of the arrays we are looking at. */
|
||||
const nodeStack = [Array.isArray(nodes) ? nodes : [nodes]];
|
||||
/** Stack of the indices within the arrays. */
|
||||
const indexStack = [0];
|
||||
for (;;) {
|
||||
// First, check if the current array has any more elements to look at.
|
||||
if (indexStack[0] >= nodeStack[0].length) {
|
||||
// If we have no more arrays to look at, we are done.
|
||||
if (indexStack.length === 1) {
|
||||
return result;
|
||||
}
|
||||
// Otherwise, remove the current array from the stack.
|
||||
nodeStack.shift();
|
||||
indexStack.shift();
|
||||
// Loop back to the start to continue with the next array.
|
||||
continue;
|
||||
}
|
||||
const elem = nodeStack[0][indexStack[0]++];
|
||||
if (test(elem)) {
|
||||
result.push(elem);
|
||||
if (--limit <= 0)
|
||||
return result;
|
||||
}
|
||||
if (recurse && hasChildren(elem) && elem.children.length > 0) {
|
||||
/*
|
||||
* Add the children to the stack. We are depth-first, so this is
|
||||
* the next array we look at.
|
||||
*/
|
||||
indexStack.unshift(0);
|
||||
nodeStack.unshift(elem.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Finds the first element inside of an array that matches a test function. This is an alias for `Array.prototype.find`.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns The first node in the array that passes `test`.
|
||||
* @deprecated Use `Array.prototype.find` directly.
|
||||
*/
|
||||
export function findOneChild(test, nodes) {
|
||||
return nodes.find(test);
|
||||
}
|
||||
/**
|
||||
* Finds one element in a tree that passes a test.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Node or array of nodes to search.
|
||||
* @param recurse Also consider child nodes.
|
||||
* @returns The first node that passes `test`.
|
||||
*/
|
||||
export function findOne(test, nodes, recurse = true) {
|
||||
const searchedNodes = Array.isArray(nodes) ? nodes : [nodes];
|
||||
for (let i = 0; i < searchedNodes.length; i++) {
|
||||
const node = searchedNodes[i];
|
||||
if (isTag(node) && test(node)) {
|
||||
return node;
|
||||
}
|
||||
if (recurse && hasChildren(node) && node.children.length > 0) {
|
||||
const found = findOne(test, node.children, true);
|
||||
if (found)
|
||||
return found;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Checks if a tree of nodes contains at least one node passing a test.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns Whether a tree of nodes contains at least one node passing the test.
|
||||
*/
|
||||
export function existsOne(test, nodes) {
|
||||
return (Array.isArray(nodes) ? nodes : [nodes]).some((node) => (isTag(node) && test(node)) ||
|
||||
(hasChildren(node) && existsOne(test, node.children)));
|
||||
}
|
||||
/**
|
||||
* Search an array of nodes and their children for elements passing a test function.
|
||||
*
|
||||
* Same as `find`, but limited to elements and with less options, leading to reduced complexity.
|
||||
*
|
||||
* @category Querying
|
||||
* @param test Function to test nodes on.
|
||||
* @param nodes Array of nodes to search.
|
||||
* @returns All nodes passing `test`.
|
||||
*/
|
||||
export function findAll(test, nodes) {
|
||||
const result = [];
|
||||
const nodeStack = [Array.isArray(nodes) ? nodes : [nodes]];
|
||||
const indexStack = [0];
|
||||
for (;;) {
|
||||
if (indexStack[0] >= nodeStack[0].length) {
|
||||
if (nodeStack.length === 1) {
|
||||
return result;
|
||||
}
|
||||
// Otherwise, remove the current array from the stack.
|
||||
nodeStack.shift();
|
||||
indexStack.shift();
|
||||
// Loop back to the start to continue with the next array.
|
||||
continue;
|
||||
}
|
||||
const elem = nodeStack[0][indexStack[0]++];
|
||||
if (isTag(elem) && test(elem))
|
||||
result.push(elem);
|
||||
if (hasChildren(elem) && elem.children.length > 0) {
|
||||
indexStack.unshift(0);
|
||||
nodeStack.unshift(elem.children);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=querying.js.map
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
import { AnyNode } from "domhandler";
|
||||
import { DomSerializerOptions } from "dom-serializer";
|
||||
/**
|
||||
* @category Stringify
|
||||
* @deprecated Use the `dom-serializer` module directly.
|
||||
* @param node Node to get the outer HTML of.
|
||||
* @param options Options for serialization.
|
||||
* @returns `node`'s outer HTML.
|
||||
*/
|
||||
export declare function getOuterHTML(node: AnyNode | ArrayLike<AnyNode>, options?: DomSerializerOptions): string;
|
||||
/**
|
||||
* @category Stringify
|
||||
* @deprecated Use the `dom-serializer` module directly.
|
||||
* @param node Node to get the inner HTML of.
|
||||
* @param options Options for serialization.
|
||||
* @returns `node`'s inner HTML.
|
||||
*/
|
||||
export declare function getInnerHTML(node: AnyNode, options?: DomSerializerOptions): string;
|
||||
/**
|
||||
* Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @deprecated Use `textContent` instead.
|
||||
* @param node Node to get the inner text of.
|
||||
* @returns `node`'s inner text.
|
||||
*/
|
||||
export declare function getText(node: AnyNode | AnyNode[]): string;
|
||||
/**
|
||||
* Get a node's text content. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @param node Node to get the text content of.
|
||||
* @returns `node`'s text content.
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent}
|
||||
*/
|
||||
export declare function textContent(node: AnyNode | AnyNode[]): string;
|
||||
/**
|
||||
* Get a node's inner text, ignoring `<script>` and `<style>` tags. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @param node Node to get the inner text of.
|
||||
* @returns `node`'s inner text.
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText}
|
||||
*/
|
||||
export declare function innerText(node: AnyNode | AnyNode[]): string;
|
||||
//# sourceMappingURL=stringify.d.ts.map
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
import { isTag, isCDATA, isText, hasChildren, isComment, } from "domhandler";
|
||||
import renderHTML from "dom-serializer";
|
||||
import { ElementType } from "domelementtype";
|
||||
/**
|
||||
* @category Stringify
|
||||
* @deprecated Use the `dom-serializer` module directly.
|
||||
* @param node Node to get the outer HTML of.
|
||||
* @param options Options for serialization.
|
||||
* @returns `node`'s outer HTML.
|
||||
*/
|
||||
export function getOuterHTML(node, options) {
|
||||
return renderHTML(node, options);
|
||||
}
|
||||
/**
|
||||
* @category Stringify
|
||||
* @deprecated Use the `dom-serializer` module directly.
|
||||
* @param node Node to get the inner HTML of.
|
||||
* @param options Options for serialization.
|
||||
* @returns `node`'s inner HTML.
|
||||
*/
|
||||
export function getInnerHTML(node, options) {
|
||||
return hasChildren(node)
|
||||
? node.children.map((node) => getOuterHTML(node, options)).join("")
|
||||
: "";
|
||||
}
|
||||
/**
|
||||
* Get a node's inner text. Same as `textContent`, but inserts newlines for `<br>` tags. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @deprecated Use `textContent` instead.
|
||||
* @param node Node to get the inner text of.
|
||||
* @returns `node`'s inner text.
|
||||
*/
|
||||
export function getText(node) {
|
||||
if (Array.isArray(node))
|
||||
return node.map(getText).join("");
|
||||
if (isTag(node))
|
||||
return node.name === "br" ? "\n" : getText(node.children);
|
||||
if (isCDATA(node))
|
||||
return getText(node.children);
|
||||
if (isText(node))
|
||||
return node.data;
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* Get a node's text content. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @param node Node to get the text content of.
|
||||
* @returns `node`'s text content.
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent}
|
||||
*/
|
||||
export function textContent(node) {
|
||||
if (Array.isArray(node))
|
||||
return node.map(textContent).join("");
|
||||
if (hasChildren(node) && !isComment(node)) {
|
||||
return textContent(node.children);
|
||||
}
|
||||
if (isText(node))
|
||||
return node.data;
|
||||
return "";
|
||||
}
|
||||
/**
|
||||
* Get a node's inner text, ignoring `<script>` and `<style>` tags. Ignores comments.
|
||||
*
|
||||
* @category Stringify
|
||||
* @param node Node to get the inner text of.
|
||||
* @returns `node`'s inner text.
|
||||
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Node/innerText}
|
||||
*/
|
||||
export function innerText(node) {
|
||||
if (Array.isArray(node))
|
||||
return node.map(innerText).join("");
|
||||
if (hasChildren(node) && (node.type === ElementType.Tag || isCDATA(node))) {
|
||||
return innerText(node.children);
|
||||
}
|
||||
if (isText(node))
|
||||
return node.data;
|
||||
return "";
|
||||
}
|
||||
//# sourceMappingURL=stringify.js.map
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
import { AnyNode, ChildNode, Element, ParentNode } from "domhandler";
|
||||
/**
|
||||
* Get a node's children.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Node to get the children of.
|
||||
* @returns `elem`'s children, or an empty array.
|
||||
*/
|
||||
export declare function getChildren(elem: AnyNode): ChildNode[];
|
||||
export declare function getParent(elem: AnyNode): ParentNode | null;
|
||||
/**
|
||||
* Gets an elements siblings, including the element itself.
|
||||
*
|
||||
* Attempts to get the children through the element's parent first. If we don't
|
||||
* have a parent (the element is a root node), we walk the element's `prev` &
|
||||
* `next` to get all remaining nodes.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to get the siblings of.
|
||||
* @returns `elem`'s siblings, including `elem`.
|
||||
*/
|
||||
export declare function getSiblings(elem: AnyNode): AnyNode[];
|
||||
/**
|
||||
* Gets an attribute from an element.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to check.
|
||||
* @param name Attribute name to retrieve.
|
||||
* @returns The element's attribute value, or `undefined`.
|
||||
*/
|
||||
export declare function getAttributeValue(elem: Element, name: string): string | undefined;
|
||||
/**
|
||||
* Checks whether an element has an attribute.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to check.
|
||||
* @param name Attribute name to look for.
|
||||
* @returns Returns whether `elem` has the attribute `name`.
|
||||
*/
|
||||
export declare function hasAttrib(elem: Element, name: string): boolean;
|
||||
/**
|
||||
* Get the tag name of an element.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the name for.
|
||||
* @returns The tag name of `elem`.
|
||||
*/
|
||||
export declare function getName(elem: Element): string;
|
||||
/**
|
||||
* Returns the next element sibling of a node.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the next sibling of.
|
||||
* @returns `elem`'s next sibling that is a tag, or `null` if there is no next
|
||||
* sibling.
|
||||
*/
|
||||
export declare function nextElementSibling(elem: AnyNode): Element | null;
|
||||
/**
|
||||
* Returns the previous element sibling of a node.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the previous sibling of.
|
||||
* @returns `elem`'s previous sibling that is a tag, or `null` if there is no
|
||||
* previous sibling.
|
||||
*/
|
||||
export declare function prevElementSibling(elem: AnyNode): Element | null;
|
||||
//# sourceMappingURL=traversal.d.ts.map
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
import { isTag, hasChildren, } from "domhandler";
|
||||
/**
|
||||
* Get a node's children.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Node to get the children of.
|
||||
* @returns `elem`'s children, or an empty array.
|
||||
*/
|
||||
export function getChildren(elem) {
|
||||
return hasChildren(elem) ? elem.children : [];
|
||||
}
|
||||
/**
|
||||
* Get a node's parent.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Node to get the parent of.
|
||||
* @returns `elem`'s parent node, or `null` if `elem` is a root node.
|
||||
*/
|
||||
export function getParent(elem) {
|
||||
return elem.parent || null;
|
||||
}
|
||||
/**
|
||||
* Gets an elements siblings, including the element itself.
|
||||
*
|
||||
* Attempts to get the children through the element's parent first. If we don't
|
||||
* have a parent (the element is a root node), we walk the element's `prev` &
|
||||
* `next` to get all remaining nodes.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to get the siblings of.
|
||||
* @returns `elem`'s siblings, including `elem`.
|
||||
*/
|
||||
export function getSiblings(elem) {
|
||||
const parent = getParent(elem);
|
||||
if (parent != null)
|
||||
return getChildren(parent);
|
||||
const siblings = [elem];
|
||||
let { prev, next } = elem;
|
||||
while (prev != null) {
|
||||
siblings.unshift(prev);
|
||||
({ prev } = prev);
|
||||
}
|
||||
while (next != null) {
|
||||
siblings.push(next);
|
||||
({ next } = next);
|
||||
}
|
||||
return siblings;
|
||||
}
|
||||
/**
|
||||
* Gets an attribute from an element.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to check.
|
||||
* @param name Attribute name to retrieve.
|
||||
* @returns The element's attribute value, or `undefined`.
|
||||
*/
|
||||
export function getAttributeValue(elem, name) {
|
||||
var _a;
|
||||
return (_a = elem.attribs) === null || _a === void 0 ? void 0 : _a[name];
|
||||
}
|
||||
/**
|
||||
* Checks whether an element has an attribute.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem Element to check.
|
||||
* @param name Attribute name to look for.
|
||||
* @returns Returns whether `elem` has the attribute `name`.
|
||||
*/
|
||||
export function hasAttrib(elem, name) {
|
||||
return (elem.attribs != null &&
|
||||
Object.prototype.hasOwnProperty.call(elem.attribs, name) &&
|
||||
elem.attribs[name] != null);
|
||||
}
|
||||
/**
|
||||
* Get the tag name of an element.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the name for.
|
||||
* @returns The tag name of `elem`.
|
||||
*/
|
||||
export function getName(elem) {
|
||||
return elem.name;
|
||||
}
|
||||
/**
|
||||
* Returns the next element sibling of a node.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the next sibling of.
|
||||
* @returns `elem`'s next sibling that is a tag, or `null` if there is no next
|
||||
* sibling.
|
||||
*/
|
||||
export function nextElementSibling(elem) {
|
||||
let { next } = elem;
|
||||
while (next !== null && !isTag(next))
|
||||
({ next } = next);
|
||||
return next;
|
||||
}
|
||||
/**
|
||||
* Returns the previous element sibling of a node.
|
||||
*
|
||||
* @category Traversal
|
||||
* @param elem The element to get the previous sibling of.
|
||||
* @returns `elem`'s previous sibling that is a tag, or `null` if there is no
|
||||
* previous sibling.
|
||||
*/
|
||||
export function prevElementSibling(elem) {
|
||||
let { prev } = elem;
|
||||
while (prev !== null && !isTag(prev))
|
||||
({ prev } = prev);
|
||||
return prev;
|
||||
}
|
||||
//# sourceMappingURL=traversal.js.map
|
||||
Reference in New Issue
Block a user