diff options
Diffstat (limited to 'node_modules/domhandler')
-rw-r--r-- | node_modules/domhandler/LICENSE | 11 | ||||
-rw-r--r-- | node_modules/domhandler/lib/index.d.ts | 85 | ||||
-rw-r--r-- | node_modules/domhandler/lib/index.d.ts.map | 1 | ||||
-rw-r--r-- | node_modules/domhandler/lib/index.js | 172 | ||||
-rw-r--r-- | node_modules/domhandler/lib/node.d.ts | 220 | ||||
-rw-r--r-- | node_modules/domhandler/lib/node.d.ts.map | 1 | ||||
-rw-r--r-- | node_modules/domhandler/lib/node.js | 444 | ||||
-rw-r--r-- | node_modules/domhandler/package.json | 58 | ||||
-rw-r--r-- | node_modules/domhandler/readme.md | 163 |
9 files changed, 1155 insertions, 0 deletions
diff --git a/node_modules/domhandler/LICENSE b/node_modules/domhandler/LICENSE new file mode 100644 index 0000000..c464f86 --- /dev/null +++ b/node_modules/domhandler/LICENSE @@ -0,0 +1,11 @@ +Copyright (c) Felix Böhm +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/node_modules/domhandler/lib/index.d.ts b/node_modules/domhandler/lib/index.d.ts new file mode 100644 index 0000000..befc7d8 --- /dev/null +++ b/node_modules/domhandler/lib/index.d.ts @@ -0,0 +1,85 @@ +import { Node, Element, DataNode, NodeWithChildren, Document } from "./node"; +export * from "./node"; +export interface DomHandlerOptions { + /** + * Add a `startIndex` property to nodes. + * When the parser is used in a non-streaming fashion, `startIndex` is an integer + * indicating the position of the start of the node in the document. + * + * @default false + */ + withStartIndices?: boolean; + /** + * Add an `endIndex` property to nodes. + * When the parser is used in a non-streaming fashion, `endIndex` is an integer + * indicating the position of the end of the node in the document. + * + * @default false + */ + withEndIndices?: boolean; + /** + * Replace all whitespace with single spaces. + * + * **Note:** Enabling this might break your markup. + * + * @default false + * @deprecated + */ + normalizeWhitespace?: boolean; + /** + * Treat the markup as XML. + * + * @default false + */ + xmlMode?: boolean; +} +interface ParserInterface { + startIndex: number | null; + endIndex: number | null; +} +declare type Callback = (error: Error | null, dom: Node[]) => void; +declare type ElementCallback = (element: Element) => void; +export declare class DomHandler { + /** The elements of the DOM */ + dom: Node[]; + /** The root element for the DOM */ + root: Document; + /** Called once parsing has completed. */ + private readonly callback; + /** Settings for the handler. */ + private readonly options; + /** Callback whenever a tag is closed. */ + private readonly elementCB; + /** Indicated whether parsing has been completed. */ + private done; + /** Stack of open tags. */ + protected tagStack: NodeWithChildren[]; + /** A data node that is still being written to. */ + protected lastNode: DataNode | null; + /** Reference to the parser instance. Used for location information. */ + private parser; + /** + * @param callback Called once parsing has completed. + * @param options Settings for the handler. + * @param elementCB Callback whenever a tag is closed. + */ + constructor(callback?: Callback | null, options?: DomHandlerOptions | null, elementCB?: ElementCallback); + onparserinit(parser: ParserInterface): void; + onreset(): void; + onend(): void; + onerror(error: Error): void; + onclosetag(): void; + onopentag(name: string, attribs: { + [key: string]: string; + }): void; + ontext(data: string): void; + oncomment(data: string): void; + oncommentend(): void; + oncdatastart(): void; + oncdataend(): void; + onprocessinginstruction(name: string, data: string): void; + protected handleCallback(error: Error | null): void; + protected addNode(node: Node): void; +} +export default DomHandler; +//# sourceMappingURL=index.d.ts.map
\ No newline at end of file diff --git a/node_modules/domhandler/lib/index.d.ts.map b/node_modules/domhandler/lib/index.d.ts.map new file mode 100644 index 0000000..c5fe113 --- /dev/null +++ b/node_modules/domhandler/lib/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACH,IAAI,EACJ,OAAO,EACP,QAAQ,EAGR,gBAAgB,EAChB,QAAQ,EAEX,MAAM,QAAQ,CAAC;AAEhB,cAAc,QAAQ,CAAC;AAIvB,MAAM,WAAW,iBAAiB;IAC9B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IAEzB;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAUD,UAAU,eAAe;IACrB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,aAAK,QAAQ,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAC3D,aAAK,eAAe,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAElD,qBAAa,UAAU;IACnB,8BAA8B;IACvB,GAAG,EAAE,IAAI,EAAE,CAAM;IAExB,mCAAmC;IAC5B,IAAI,WAA0B;IAErC,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;IAE3C,gCAAgC;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAE5C,yCAAyC;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;IAEnD,oDAAoD;IACpD,OAAO,CAAC,IAAI,CAAS;IAErB,0BAA0B;IAC1B,SAAS,CAAC,QAAQ,EAAE,gBAAgB,EAAE,CAAe;IAErD,kDAAkD;IAClD,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAQ;IAE3C,uEAAuE;IACvE,OAAO,CAAC,MAAM,CAAgC;IAE9C;;;;OAIG;gBAEC,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,EAC1B,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,EAClC,SAAS,CAAC,EAAE,eAAe;IAiBxB,YAAY,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;IAK3C,OAAO,IAAI,IAAI;IAUf,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI;IAI3B,UAAU,IAAI,IAAI;IAYlB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI;IAOjE,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IA2B1B,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAW7B,YAAY,IAAI,IAAI;IAIpB,YAAY,IAAI,IAAI;IAUpB,UAAU,IAAI,IAAI;IAIlB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAKhE,SAAS,CAAC,cAAc,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,IAAI;IAQnD,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;CAwBtC;AAED,eAAe,UAAU,CAAC"}
\ No newline at end of file diff --git a/node_modules/domhandler/lib/index.js b/node_modules/domhandler/lib/index.js new file mode 100644 index 0000000..5f5bb03 --- /dev/null +++ b/node_modules/domhandler/lib/index.js @@ -0,0 +1,172 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __exportStar = (this && this.__exportStar) || function(m, exports) { + for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.DomHandler = void 0; +var domelementtype_1 = require("domelementtype"); +var node_1 = require("./node"); +__exportStar(require("./node"), exports); +var reWhitespace = /\s+/g; +// Default options +var defaultOpts = { + normalizeWhitespace: false, + withStartIndices: false, + withEndIndices: false, + xmlMode: false, +}; +var DomHandler = /** @class */ (function () { + /** + * @param callback Called once parsing has completed. + * @param options Settings for the handler. + * @param elementCB Callback whenever a tag is closed. + */ + function DomHandler(callback, options, elementCB) { + /** The elements of the DOM */ + this.dom = []; + /** The root element for the DOM */ + this.root = new node_1.Document(this.dom); + /** Indicated whether parsing has been completed. */ + this.done = false; + /** Stack of open tags. */ + this.tagStack = [this.root]; + /** A data node that is still being written to. */ + this.lastNode = null; + /** Reference to the parser instance. Used for location information. */ + this.parser = null; + // Make it possible to skip arguments, for backwards-compatibility + if (typeof options === "function") { + elementCB = options; + options = defaultOpts; + } + if (typeof callback === "object") { + options = callback; + callback = undefined; + } + this.callback = callback !== null && callback !== void 0 ? callback : null; + this.options = options !== null && options !== void 0 ? options : defaultOpts; + this.elementCB = elementCB !== null && elementCB !== void 0 ? elementCB : null; + } + DomHandler.prototype.onparserinit = function (parser) { + this.parser = parser; + }; + // Resets the handler back to starting state + DomHandler.prototype.onreset = function () { + this.dom = []; + this.root = new node_1.Document(this.dom); + this.done = false; + this.tagStack = [this.root]; + this.lastNode = null; + this.parser = null; + }; + // Signals the handler that parsing is done + DomHandler.prototype.onend = function () { + if (this.done) + return; + this.done = true; + this.parser = null; + this.handleCallback(null); + }; + DomHandler.prototype.onerror = function (error) { + this.handleCallback(error); + }; + DomHandler.prototype.onclosetag = function () { + this.lastNode = null; + var elem = this.tagStack.pop(); + if (this.options.withEndIndices) { + elem.endIndex = this.parser.endIndex; + } + if (this.elementCB) + this.elementCB(elem); + }; + DomHandler.prototype.onopentag = function (name, attribs) { + var type = this.options.xmlMode ? domelementtype_1.ElementType.Tag : undefined; + var element = new node_1.Element(name, attribs, undefined, type); + this.addNode(element); + this.tagStack.push(element); + }; + DomHandler.prototype.ontext = function (data) { + var normalizeWhitespace = this.options.normalizeWhitespace; + var lastNode = this.lastNode; + if (lastNode && lastNode.type === domelementtype_1.ElementType.Text) { + if (normalizeWhitespace) { + lastNode.data = (lastNode.data + data).replace(reWhitespace, " "); + } + else { + lastNode.data += data; + } + if (this.options.withEndIndices) { + lastNode.endIndex = this.parser.endIndex; + } + } + else { + if (normalizeWhitespace) { + data = data.replace(reWhitespace, " "); + } + var node = new node_1.Text(data); + this.addNode(node); + this.lastNode = node; + } + }; + DomHandler.prototype.oncomment = function (data) { + if (this.lastNode && this.lastNode.type === domelementtype_1.ElementType.Comment) { + this.lastNode.data += data; + return; + } + var node = new node_1.Comment(data); + this.addNode(node); + this.lastNode = node; + }; + DomHandler.prototype.oncommentend = function () { + this.lastNode = null; + }; + DomHandler.prototype.oncdatastart = function () { + var text = new node_1.Text(""); + var node = new node_1.NodeWithChildren(domelementtype_1.ElementType.CDATA, [text]); + this.addNode(node); + text.parent = node; + this.lastNode = text; + }; + DomHandler.prototype.oncdataend = function () { + this.lastNode = null; + }; + DomHandler.prototype.onprocessinginstruction = function (name, data) { + var node = new node_1.ProcessingInstruction(name, data); + this.addNode(node); + }; + DomHandler.prototype.handleCallback = function (error) { + if (typeof this.callback === "function") { + this.callback(error, this.dom); + } + else if (error) { + throw error; + } + }; + DomHandler.prototype.addNode = function (node) { + var parent = this.tagStack[this.tagStack.length - 1]; + var previousSibling = parent.children[parent.children.length - 1]; + if (this.options.withStartIndices) { + node.startIndex = this.parser.startIndex; + } + if (this.options.withEndIndices) { + node.endIndex = this.parser.endIndex; + } + parent.children.push(node); + if (previousSibling) { + node.prev = previousSibling; + previousSibling.next = node; + } + node.parent = parent; + this.lastNode = null; + }; + return DomHandler; +}()); +exports.DomHandler = DomHandler; +exports.default = DomHandler; diff --git a/node_modules/domhandler/lib/node.d.ts b/node_modules/domhandler/lib/node.d.ts new file mode 100644 index 0000000..cc5ef66 --- /dev/null +++ b/node_modules/domhandler/lib/node.d.ts @@ -0,0 +1,220 @@ +import { ElementType } from "domelementtype"; +/** + * This object will be used as the prototype for Nodes when creating a + * DOM-Level-1-compliant structure. + */ +export declare class Node { + type: ElementType; + /** Parent of the node */ + parent: NodeWithChildren | null; + /** Previous sibling */ + prev: Node | null; + /** Next sibling */ + next: Node | null; + /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ + startIndex: number | null; + /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ + endIndex: number | null; + /** + * `parse5` source code location info. + * + * Available if parsing with parse5 and location info is enabled. + */ + sourceCodeLocation?: { + startOffset: number; + endOffset: number; + startLine: number; + endLine: number; + startColumn: number; + endColumn: number; + }; + /** + * + * @param type The type of the node. + */ + constructor(type: ElementType); + /** + * [DOM spec](https://dom.spec.whatwg.org/#dom-node-nodetype)-compatible + * node {@link type}. + */ + get nodeType(): number; + /** + * Same as {@link parent}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get parentNode(): NodeWithChildren | null; + set parentNode(parent: NodeWithChildren | null); + /** + * Same as {@link prev}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get previousSibling(): Node | null; + set previousSibling(prev: Node | null); + /** + * Same as {@link next}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get nextSibling(): Node | null; + set nextSibling(next: Node | null); + /** + * Clone this node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ + cloneNode<T extends Node>(this: T, recursive?: boolean): T; +} +/** + * A node that contains some data. + */ +export declare class DataNode extends Node { + data: string; + /** + * @param type The type of the node + * @param data The content of the data node + */ + constructor(type: ElementType.Comment | ElementType.Text | ElementType.Directive, data: string); + /** + * Same as {@link data}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get nodeValue(): string; + set nodeValue(data: string); +} +/** + * Text within the document. + */ +export declare class Text extends DataNode { + constructor(data: string); +} +/** + * Comments within the document. + */ +export declare class Comment extends DataNode { + constructor(data: string); +} +/** + * Processing instructions, including doc types. + */ +export declare class ProcessingInstruction extends DataNode { + name: string; + constructor(name: string, data: string); + /** If this is a doctype, the document type name (parse5 only). */ + "x-name"?: string; + /** If this is a doctype, the document type public identifier (parse5 only). */ + "x-publicId"?: string; + /** If this is a doctype, the document type system identifier (parse5 only). */ + "x-systemId"?: string; +} +/** + * A `Node` that can have children. + */ +export declare class NodeWithChildren extends Node { + children: Node[]; + /** + * @param type Type of the node. + * @param children Children of the node. Only certain node types can have children. + */ + constructor(type: ElementType.Root | ElementType.CDATA | ElementType.Script | ElementType.Style | ElementType.Tag, children: Node[]); + /** First child of the node. */ + get firstChild(): Node | null; + /** Last child of the node. */ + get lastChild(): Node | null; + /** + * Same as {@link children}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get childNodes(): Node[]; + set childNodes(children: Node[]); +} +/** + * The root node of the document. + */ +export declare class Document extends NodeWithChildren { + constructor(children: Node[]); + /** [Document mode](https://dom.spec.whatwg.org/#concept-document-limited-quirks) (parse5 only). */ + "x-mode"?: "no-quirks" | "quirks" | "limited-quirks"; +} +/** + * The description of an individual attribute. + */ +interface Attribute { + name: string; + value: string; + namespace?: string; + prefix?: string; +} +/** + * An element within the DOM. + */ +export declare class Element extends NodeWithChildren { + name: string; + attribs: { + [name: string]: string; + }; + /** + * @param name Name of the tag, eg. `div`, `span`. + * @param attribs Object mapping attribute names to attribute values. + * @param children Children of the node. + */ + constructor(name: string, attribs: { + [name: string]: string; + }, children?: Node[], type?: ElementType.Tag | ElementType.Script | ElementType.Style); + /** + * Same as {@link name}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get tagName(): string; + set tagName(name: string); + get attributes(): Attribute[]; + /** Element namespace (parse5 only). */ + namespace?: string; + /** Element attribute namespaces (parse5 only). */ + "x-attribsNamespace"?: Record<string, string>; + /** Element attribute namespace-related prefixes (parse5 only). */ + "x-attribsPrefix"?: Record<string, string>; +} +/** + * @param node Node to check. + * @returns `true` if the node is a `Element`, `false` otherwise. + */ +export declare function isTag(node: Node): node is Element; +/** + * @param node Node to check. + * @returns `true` if the node has the type `CDATA`, `false` otherwise. + */ +export declare function isCDATA(node: Node): node is NodeWithChildren; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Text`, `false` otherwise. + */ +export declare function isText(node: Node): node is Text; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Comment`, `false` otherwise. + */ +export declare function isComment(node: Node): node is DataNode; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +export declare function isDirective(node: Node): node is ProcessingInstruction; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +export declare function isDocument(node: Node): node is Document; +/** + * @param node Node to check. + * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise. + */ +export declare function hasChildren(node: Node): node is NodeWithChildren; +/** + * Clone a node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ +export declare function cloneNode<T extends Node>(node: T, recursive?: boolean): T; +export {}; +//# sourceMappingURL=node.d.ts.map
\ No newline at end of file diff --git a/node_modules/domhandler/lib/node.d.ts.map b/node_modules/domhandler/lib/node.d.ts.map new file mode 100644 index 0000000..03cc02b --- /dev/null +++ b/node_modules/domhandler/lib/node.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
\ No newline at end of file diff --git a/node_modules/domhandler/lib/node.js b/node_modules/domhandler/lib/node.js new file mode 100644 index 0000000..e55445b --- /dev/null +++ b/node_modules/domhandler/lib/node.js @@ -0,0 +1,444 @@ +"use strict"; +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; + return function (d, b) { + if (typeof b !== "function" && b !== null) + throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var __assign = (this && this.__assign) || function () { + __assign = Object.assign || function(t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) + t[p] = s[p]; + } + return t; + }; + return __assign.apply(this, arguments); +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cloneNode = exports.hasChildren = exports.isDocument = exports.isDirective = exports.isComment = exports.isText = exports.isCDATA = exports.isTag = exports.Element = exports.Document = exports.NodeWithChildren = exports.ProcessingInstruction = exports.Comment = exports.Text = exports.DataNode = exports.Node = void 0; +var domelementtype_1 = require("domelementtype"); +var nodeTypes = new Map([ + [domelementtype_1.ElementType.Tag, 1], + [domelementtype_1.ElementType.Script, 1], + [domelementtype_1.ElementType.Style, 1], + [domelementtype_1.ElementType.Directive, 1], + [domelementtype_1.ElementType.Text, 3], + [domelementtype_1.ElementType.CDATA, 4], + [domelementtype_1.ElementType.Comment, 8], + [domelementtype_1.ElementType.Root, 9], +]); +/** + * This object will be used as the prototype for Nodes when creating a + * DOM-Level-1-compliant structure. + */ +var Node = /** @class */ (function () { + /** + * + * @param type The type of the node. + */ + function Node(type) { + this.type = type; + /** Parent of the node */ + this.parent = null; + /** Previous sibling */ + this.prev = null; + /** Next sibling */ + this.next = null; + /** The start index of the node. Requires `withStartIndices` on the handler to be `true. */ + this.startIndex = null; + /** The end index of the node. Requires `withEndIndices` on the handler to be `true. */ + this.endIndex = null; + } + Object.defineProperty(Node.prototype, "nodeType", { + // Read-only aliases + /** + * [DOM spec](https://dom.spec.whatwg.org/#dom-node-nodetype)-compatible + * node {@link type}. + */ + get: function () { + var _a; + return (_a = nodeTypes.get(this.type)) !== null && _a !== void 0 ? _a : 1; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "parentNode", { + // Read-write aliases for properties + /** + * Same as {@link parent}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.parent; + }, + set: function (parent) { + this.parent = parent; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "previousSibling", { + /** + * Same as {@link prev}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.prev; + }, + set: function (prev) { + this.prev = prev; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Node.prototype, "nextSibling", { + /** + * Same as {@link next}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.next; + }, + set: function (next) { + this.next = next; + }, + enumerable: false, + configurable: true + }); + /** + * Clone this node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ + Node.prototype.cloneNode = function (recursive) { + if (recursive === void 0) { recursive = false; } + return cloneNode(this, recursive); + }; + return Node; +}()); +exports.Node = Node; +/** + * A node that contains some data. + */ +var DataNode = /** @class */ (function (_super) { + __extends(DataNode, _super); + /** + * @param type The type of the node + * @param data The content of the data node + */ + function DataNode(type, data) { + var _this = _super.call(this, type) || this; + _this.data = data; + return _this; + } + Object.defineProperty(DataNode.prototype, "nodeValue", { + /** + * Same as {@link data}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.data; + }, + set: function (data) { + this.data = data; + }, + enumerable: false, + configurable: true + }); + return DataNode; +}(Node)); +exports.DataNode = DataNode; +/** + * Text within the document. + */ +var Text = /** @class */ (function (_super) { + __extends(Text, _super); + function Text(data) { + return _super.call(this, domelementtype_1.ElementType.Text, data) || this; + } + return Text; +}(DataNode)); +exports.Text = Text; +/** + * Comments within the document. + */ +var Comment = /** @class */ (function (_super) { + __extends(Comment, _super); + function Comment(data) { + return _super.call(this, domelementtype_1.ElementType.Comment, data) || this; + } + return Comment; +}(DataNode)); +exports.Comment = Comment; +/** + * Processing instructions, including doc types. + */ +var ProcessingInstruction = /** @class */ (function (_super) { + __extends(ProcessingInstruction, _super); + function ProcessingInstruction(name, data) { + var _this = _super.call(this, domelementtype_1.ElementType.Directive, data) || this; + _this.name = name; + return _this; + } + return ProcessingInstruction; +}(DataNode)); +exports.ProcessingInstruction = ProcessingInstruction; +/** + * A `Node` that can have children. + */ +var NodeWithChildren = /** @class */ (function (_super) { + __extends(NodeWithChildren, _super); + /** + * @param type Type of the node. + * @param children Children of the node. Only certain node types can have children. + */ + function NodeWithChildren(type, children) { + var _this = _super.call(this, type) || this; + _this.children = children; + return _this; + } + Object.defineProperty(NodeWithChildren.prototype, "firstChild", { + // Aliases + /** First child of the node. */ + get: function () { + var _a; + return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "lastChild", { + /** Last child of the node. */ + get: function () { + return this.children.length > 0 + ? this.children[this.children.length - 1] + : null; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(NodeWithChildren.prototype, "childNodes", { + /** + * Same as {@link children}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.children; + }, + set: function (children) { + this.children = children; + }, + enumerable: false, + configurable: true + }); + return NodeWithChildren; +}(Node)); +exports.NodeWithChildren = NodeWithChildren; +/** + * The root node of the document. + */ +var Document = /** @class */ (function (_super) { + __extends(Document, _super); + function Document(children) { + return _super.call(this, domelementtype_1.ElementType.Root, children) || this; + } + return Document; +}(NodeWithChildren)); +exports.Document = Document; +/** + * An element within the DOM. + */ +var Element = /** @class */ (function (_super) { + __extends(Element, _super); + /** + * @param name Name of the tag, eg. `div`, `span`. + * @param attribs Object mapping attribute names to attribute values. + * @param children Children of the node. + */ + function Element(name, attribs, children, type) { + if (children === void 0) { children = []; } + if (type === void 0) { type = name === "script" + ? domelementtype_1.ElementType.Script + : name === "style" + ? domelementtype_1.ElementType.Style + : domelementtype_1.ElementType.Tag; } + var _this = _super.call(this, type, children) || this; + _this.name = name; + _this.attribs = attribs; + return _this; + } + Object.defineProperty(Element.prototype, "tagName", { + // DOM Level 1 aliases + /** + * Same as {@link name}. + * [DOM spec](https://dom.spec.whatwg.org)-compatible alias. + */ + get: function () { + return this.name; + }, + set: function (name) { + this.name = name; + }, + enumerable: false, + configurable: true + }); + Object.defineProperty(Element.prototype, "attributes", { + get: function () { + var _this = this; + return Object.keys(this.attribs).map(function (name) { + var _a, _b; + return ({ + name: name, + value: _this.attribs[name], + namespace: (_a = _this["x-attribsNamespace"]) === null || _a === void 0 ? void 0 : _a[name], + prefix: (_b = _this["x-attribsPrefix"]) === null || _b === void 0 ? void 0 : _b[name], + }); + }); + }, + enumerable: false, + configurable: true + }); + return Element; +}(NodeWithChildren)); +exports.Element = Element; +/** + * @param node Node to check. + * @returns `true` if the node is a `Element`, `false` otherwise. + */ +function isTag(node) { + return (0, domelementtype_1.isTag)(node); +} +exports.isTag = isTag; +/** + * @param node Node to check. + * @returns `true` if the node has the type `CDATA`, `false` otherwise. + */ +function isCDATA(node) { + return node.type === domelementtype_1.ElementType.CDATA; +} +exports.isCDATA = isCDATA; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Text`, `false` otherwise. + */ +function isText(node) { + return node.type === domelementtype_1.ElementType.Text; +} +exports.isText = isText; +/** + * @param node Node to check. + * @returns `true` if the node has the type `Comment`, `false` otherwise. + */ +function isComment(node) { + return node.type === domelementtype_1.ElementType.Comment; +} +exports.isComment = isComment; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDirective(node) { + return node.type === domelementtype_1.ElementType.Directive; +} +exports.isDirective = isDirective; +/** + * @param node Node to check. + * @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise. + */ +function isDocument(node) { + return node.type === domelementtype_1.ElementType.Root; +} +exports.isDocument = isDocument; +/** + * @param node Node to check. + * @returns `true` if the node is a `NodeWithChildren` (has children), `false` otherwise. + */ +function hasChildren(node) { + return Object.prototype.hasOwnProperty.call(node, "children"); +} +exports.hasChildren = hasChildren; +/** + * Clone a node, and optionally its children. + * + * @param recursive Clone child nodes as well. + * @returns A clone of the node. + */ +function cloneNode(node, recursive) { + if (recursive === void 0) { recursive = false; } + var result; + if (isText(node)) { + result = new Text(node.data); + } + else if (isComment(node)) { + result = new Comment(node.data); + } + else if (isTag(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_1 = new Element(node.name, __assign({}, node.attribs), children); + children.forEach(function (child) { return (child.parent = clone_1); }); + if (node.namespace != null) { + clone_1.namespace = node.namespace; + } + if (node["x-attribsNamespace"]) { + clone_1["x-attribsNamespace"] = __assign({}, node["x-attribsNamespace"]); + } + if (node["x-attribsPrefix"]) { + clone_1["x-attribsPrefix"] = __assign({}, node["x-attribsPrefix"]); + } + result = clone_1; + } + else if (isCDATA(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_2 = new NodeWithChildren(domelementtype_1.ElementType.CDATA, children); + children.forEach(function (child) { return (child.parent = clone_2); }); + result = clone_2; + } + else if (isDocument(node)) { + var children = recursive ? cloneChildren(node.children) : []; + var clone_3 = new Document(children); + children.forEach(function (child) { return (child.parent = clone_3); }); + if (node["x-mode"]) { + clone_3["x-mode"] = node["x-mode"]; + } + result = clone_3; + } + else if (isDirective(node)) { + var instruction = new ProcessingInstruction(node.name, node.data); + if (node["x-name"] != null) { + instruction["x-name"] = node["x-name"]; + instruction["x-publicId"] = node["x-publicId"]; + instruction["x-systemId"] = node["x-systemId"]; + } + result = instruction; + } + else { + throw new Error("Not implemented yet: ".concat(node.type)); + } + result.startIndex = node.startIndex; + result.endIndex = node.endIndex; + if (node.sourceCodeLocation != null) { + result.sourceCodeLocation = node.sourceCodeLocation; + } + return result; +} +exports.cloneNode = cloneNode; +function cloneChildren(childs) { + var children = childs.map(function (child) { return cloneNode(child, true); }); + for (var i = 1; i < children.length; i++) { + children[i].prev = children[i - 1]; + children[i - 1].next = children[i]; + } + return children; +} diff --git a/node_modules/domhandler/package.json b/node_modules/domhandler/package.json new file mode 100644 index 0000000..e688ec5 --- /dev/null +++ b/node_modules/domhandler/package.json @@ -0,0 +1,58 @@ +{ + "name": "domhandler", + "version": "4.3.0", + "description": "Handler for htmlparser2 that turns pages into a dom", + "author": "Felix Boehm <me@feedic.com>", + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + }, + "license": "BSD-2-Clause", + "main": "lib/index.js", + "types": "lib/index.d.ts", + "sideEffects": false, + "files": [ + "lib" + ], + "scripts": { + "test": "npm run test:jest && npm run lint", + "test:jest": "jest", + "lint": "eslint src", + "format": "prettier --write '**/*.{ts,md,json}'", + "build": "tsc", + "prepare": "npm run build" + }, + "repository": { + "type": "git", + "url": "git://github.com/fb55/domhandler.git" + }, + "keywords": [ + "dom", + "htmlparser2" + ], + "engines": { + "node": ">= 4" + }, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "devDependencies": { + "@types/jest": "^27.0.3", + "@types/node": "^16.11.11", + "@typescript-eslint/eslint-plugin": "^5.5.0", + "@typescript-eslint/parser": "^5.5.0", + "eslint": "^8.3.0", + "eslint-config-prettier": "^8.1.0", + "htmlparser2": "^7.2.0", + "jest": "^27.4.2", + "prettier": "^2.5.0", + "ts-jest": "^27.0.7", + "typescript": "^4.5.2" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node" + }, + "prettier": { + "tabWidth": 4 + } +} diff --git a/node_modules/domhandler/readme.md b/node_modules/domhandler/readme.md new file mode 100644 index 0000000..781eb38 --- /dev/null +++ b/node_modules/domhandler/readme.md @@ -0,0 +1,163 @@ +# domhandler [![Build Status](https://travis-ci.com/fb55/domhandler.svg?branch=master)](https://travis-ci.com/fb55/domhandler) + +The DOM handler creates a tree containing all nodes of a page. +The tree can be manipulated using the [domutils](https://github.com/fb55/domutils) +or [cheerio](https://github.com/cheeriojs/cheerio) libraries and +rendered using [dom-serializer](https://github.com/cheeriojs/dom-serializer) . + +## Usage + +```javascript +const handler = new DomHandler([ <func> callback(err, dom), ] [ <obj> options ]); +// const parser = new Parser(handler[, options]); +``` + +Available options are described below. + +## Example + +```javascript +const { Parser } = require("htmlparser2"); +const { DomHandler } = require("domhandler"); +const rawHtml = + "Xyz <script language= javascript>var foo = '<<bar>>';</script><!--<!-- Waah! -- -->"; +const handler = new DomHandler((error, dom) => { + if (error) { + // Handle error + } else { + // Parsing completed, do something + console.log(dom); + } +}); +const parser = new Parser(handler); +parser.write(rawHtml); +parser.end(); +``` + +Output: + +```javascript +[ + { + data: "Xyz ", + type: "text", + }, + { + type: "script", + name: "script", + attribs: { + language: "javascript", + }, + children: [ + { + data: "var foo = '<bar>';<", + type: "text", + }, + ], + }, + { + data: "<!-- Waah! -- ", + type: "comment", + }, +]; +``` + +## Option: `withStartIndices` + +Add a `startIndex` property to nodes. +When the parser is used in a non-streaming fashion, `startIndex` is an integer +indicating the position of the start of the node in the document. +The default value is `false`. + +## Option: `withEndIndices` + +Add an `endIndex` property to nodes. +When the parser is used in a non-streaming fashion, `endIndex` is an integer +indicating the position of the end of the node in the document. +The default value is `false`. + +## Option: `normalizeWhitespace` _(deprecated)_ + +Replace all whitespace with single spaces. +The default value is `false`. + +**Note:** Enabling this might break your markup. + +For the following examples, this HTML will be used: + +```html +<font> <br />this is the text <font></font></font> +``` + +### Example: `normalizeWhitespace: true` + +```javascript +[ + { + type: "tag", + name: "font", + children: [ + { + data: " ", + type: "text", + }, + { + type: "tag", + name: "br", + }, + { + data: "this is the text ", + type: "text", + }, + { + type: "tag", + name: "font", + }, + ], + }, +]; +``` + +### Example: `normalizeWhitespace: false` + +```javascript +[ + { + type: "tag", + name: "font", + children: [ + { + data: "\n\t", + type: "text", + }, + { + type: "tag", + name: "br", + }, + { + data: "this is the text\n", + type: "text", + }, + { + type: "tag", + name: "font", + }, + ], + }, +]; +``` + +--- + +License: BSD-2-Clause + +## Security contact information + +To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). +Tidelift will coordinate the fix and disclosure. + +## `domhandler` for enterprise + +Available as part of the Tidelift Subscription + +The maintainers of `domhandler` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-domhandler?utm_source=npm-domhandler&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) |