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:
+76
@@ -0,0 +1,76 @@
|
||||
import { ChildNode, Element, DataNode, Document, ParentNode } from "./node.js";
|
||||
export * from "./node.js";
|
||||
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;
|
||||
/**
|
||||
* Treat the markup as XML.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
xmlMode?: boolean;
|
||||
}
|
||||
interface ParserInterface {
|
||||
startIndex: number | null;
|
||||
endIndex: number | null;
|
||||
}
|
||||
declare type Callback = (error: Error | null, dom: ChildNode[]) => void;
|
||||
declare type ElementCallback = (element: Element) => void;
|
||||
export declare class DomHandler {
|
||||
/** The elements of the DOM */
|
||||
dom: ChildNode[];
|
||||
/** 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: ParentNode[];
|
||||
/** 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: ChildNode): void;
|
||||
}
|
||||
export default DomHandler;
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
import { ElementType } from "domelementtype";
|
||||
import { Element, Text, Comment, CDATA, Document, ProcessingInstruction, } from "./node.js";
|
||||
export * from "./node.js";
|
||||
// Default options
|
||||
const defaultOpts = {
|
||||
withStartIndices: false,
|
||||
withEndIndices: false,
|
||||
xmlMode: false,
|
||||
};
|
||||
export class DomHandler {
|
||||
/**
|
||||
* @param callback Called once parsing has completed.
|
||||
* @param options Settings for the handler.
|
||||
* @param elementCB Callback whenever a tag is closed.
|
||||
*/
|
||||
constructor(callback, options, elementCB) {
|
||||
/** The elements of the DOM */
|
||||
this.dom = [];
|
||||
/** The root element for the DOM */
|
||||
this.root = new 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;
|
||||
}
|
||||
onparserinit(parser) {
|
||||
this.parser = parser;
|
||||
}
|
||||
// Resets the handler back to starting state
|
||||
onreset() {
|
||||
this.dom = [];
|
||||
this.root = new Document(this.dom);
|
||||
this.done = false;
|
||||
this.tagStack = [this.root];
|
||||
this.lastNode = null;
|
||||
this.parser = null;
|
||||
}
|
||||
// Signals the handler that parsing is done
|
||||
onend() {
|
||||
if (this.done)
|
||||
return;
|
||||
this.done = true;
|
||||
this.parser = null;
|
||||
this.handleCallback(null);
|
||||
}
|
||||
onerror(error) {
|
||||
this.handleCallback(error);
|
||||
}
|
||||
onclosetag() {
|
||||
this.lastNode = null;
|
||||
const elem = this.tagStack.pop();
|
||||
if (this.options.withEndIndices) {
|
||||
elem.endIndex = this.parser.endIndex;
|
||||
}
|
||||
if (this.elementCB)
|
||||
this.elementCB(elem);
|
||||
}
|
||||
onopentag(name, attribs) {
|
||||
const type = this.options.xmlMode ? ElementType.Tag : undefined;
|
||||
const element = new Element(name, attribs, undefined, type);
|
||||
this.addNode(element);
|
||||
this.tagStack.push(element);
|
||||
}
|
||||
ontext(data) {
|
||||
const { lastNode } = this;
|
||||
if (lastNode && lastNode.type === ElementType.Text) {
|
||||
lastNode.data += data;
|
||||
if (this.options.withEndIndices) {
|
||||
lastNode.endIndex = this.parser.endIndex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
const node = new Text(data);
|
||||
this.addNode(node);
|
||||
this.lastNode = node;
|
||||
}
|
||||
}
|
||||
oncomment(data) {
|
||||
if (this.lastNode && this.lastNode.type === ElementType.Comment) {
|
||||
this.lastNode.data += data;
|
||||
return;
|
||||
}
|
||||
const node = new Comment(data);
|
||||
this.addNode(node);
|
||||
this.lastNode = node;
|
||||
}
|
||||
oncommentend() {
|
||||
this.lastNode = null;
|
||||
}
|
||||
oncdatastart() {
|
||||
const text = new Text("");
|
||||
const node = new CDATA([text]);
|
||||
this.addNode(node);
|
||||
text.parent = node;
|
||||
this.lastNode = text;
|
||||
}
|
||||
oncdataend() {
|
||||
this.lastNode = null;
|
||||
}
|
||||
onprocessinginstruction(name, data) {
|
||||
const node = new ProcessingInstruction(name, data);
|
||||
this.addNode(node);
|
||||
}
|
||||
handleCallback(error) {
|
||||
if (typeof this.callback === "function") {
|
||||
this.callback(error, this.dom);
|
||||
}
|
||||
else if (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
addNode(node) {
|
||||
const parent = this.tagStack[this.tagStack.length - 1];
|
||||
const 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;
|
||||
}
|
||||
}
|
||||
export default DomHandler;
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
import { ElementType } from "domelementtype";
|
||||
interface SourceCodeLocation {
|
||||
/** One-based line index of the first character. */
|
||||
startLine: number;
|
||||
/** One-based column index of the first character. */
|
||||
startCol: number;
|
||||
/** Zero-based first character index. */
|
||||
startOffset: number;
|
||||
/** One-based line index of the last character. */
|
||||
endLine: number;
|
||||
/** One-based column index of the last character. Points directly *after* the last character. */
|
||||
endCol: number;
|
||||
/** Zero-based last character index. Points directly *after* the last character. */
|
||||
endOffset: number;
|
||||
}
|
||||
interface TagSourceCodeLocation extends SourceCodeLocation {
|
||||
startTag?: SourceCodeLocation;
|
||||
endTag?: SourceCodeLocation;
|
||||
}
|
||||
export declare type ParentNode = Document | Element | CDATA;
|
||||
export declare type ChildNode = Text | Comment | ProcessingInstruction | Element | CDATA | Document;
|
||||
export declare type AnyNode = ParentNode | ChildNode;
|
||||
/**
|
||||
* This object will be used as the prototype for Nodes when creating a
|
||||
* DOM-Level-1-compliant structure.
|
||||
*/
|
||||
export declare abstract class Node {
|
||||
/** The type of the node. */
|
||||
abstract readonly type: ElementType;
|
||||
/** Parent of the node */
|
||||
parent: ParentNode | null;
|
||||
/** Previous sibling */
|
||||
prev: ChildNode | null;
|
||||
/** Next sibling */
|
||||
next: ChildNode | 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?: SourceCodeLocation | null;
|
||||
/**
|
||||
* [DOM spec](https://dom.spec.whatwg.org/#dom-node-nodetype)-compatible
|
||||
* node {@link type}.
|
||||
*/
|
||||
abstract readonly nodeType: number;
|
||||
/**
|
||||
* Same as {@link parent}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get parentNode(): ParentNode | null;
|
||||
set parentNode(parent: ParentNode | null);
|
||||
/**
|
||||
* Same as {@link prev}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get previousSibling(): ChildNode | null;
|
||||
set previousSibling(prev: ChildNode | null);
|
||||
/**
|
||||
* Same as {@link next}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get nextSibling(): ChildNode | null;
|
||||
set nextSibling(next: ChildNode | 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 abstract class DataNode extends Node {
|
||||
data: string;
|
||||
/**
|
||||
* @param data The content of the data node
|
||||
*/
|
||||
constructor(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 {
|
||||
type: ElementType.Text;
|
||||
get nodeType(): 3;
|
||||
}
|
||||
/**
|
||||
* Comments within the document.
|
||||
*/
|
||||
export declare class Comment extends DataNode {
|
||||
type: ElementType.Comment;
|
||||
get nodeType(): 8;
|
||||
}
|
||||
/**
|
||||
* Processing instructions, including doc types.
|
||||
*/
|
||||
export declare class ProcessingInstruction extends DataNode {
|
||||
name: string;
|
||||
type: ElementType.Directive;
|
||||
constructor(name: string, data: string);
|
||||
get nodeType(): 1;
|
||||
/** 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 abstract class NodeWithChildren extends Node {
|
||||
children: ChildNode[];
|
||||
/**
|
||||
* @param children Children of the node. Only certain node types can have children.
|
||||
*/
|
||||
constructor(children: ChildNode[]);
|
||||
/** First child of the node. */
|
||||
get firstChild(): ChildNode | null;
|
||||
/** Last child of the node. */
|
||||
get lastChild(): ChildNode | null;
|
||||
/**
|
||||
* Same as {@link children}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get childNodes(): ChildNode[];
|
||||
set childNodes(children: ChildNode[]);
|
||||
}
|
||||
export declare class CDATA extends NodeWithChildren {
|
||||
type: ElementType.CDATA;
|
||||
get nodeType(): 4;
|
||||
}
|
||||
/**
|
||||
* The root node of the document.
|
||||
*/
|
||||
export declare class Document extends NodeWithChildren {
|
||||
type: ElementType.Root;
|
||||
get nodeType(): 9;
|
||||
/** [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;
|
||||
};
|
||||
type: ElementType.Tag | ElementType.Script | ElementType.Style;
|
||||
/**
|
||||
* @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?: ChildNode[], type?: ElementType.Tag | ElementType.Script | ElementType.Style);
|
||||
get nodeType(): 1;
|
||||
/**
|
||||
* `parse5` source code location info, with start & end tags.
|
||||
*
|
||||
* Available if parsing with parse5 and location info is enabled.
|
||||
*/
|
||||
sourceCodeLocation?: TagSourceCodeLocation | null;
|
||||
/**
|
||||
* 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 CDATA;
|
||||
/**
|
||||
* @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 Comment;
|
||||
/**
|
||||
* @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 has children, `false` otherwise.
|
||||
*/
|
||||
export declare function hasChildren(node: Node): node is ParentNode;
|
||||
/**
|
||||
* 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
|
||||
+338
@@ -0,0 +1,338 @@
|
||||
import { ElementType, isTag as isTagRaw } from "domelementtype";
|
||||
/**
|
||||
* This object will be used as the prototype for Nodes when creating a
|
||||
* DOM-Level-1-compliant structure.
|
||||
*/
|
||||
export class Node {
|
||||
constructor() {
|
||||
/** 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;
|
||||
}
|
||||
// Read-write aliases for properties
|
||||
/**
|
||||
* Same as {@link parent}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get parentNode() {
|
||||
return this.parent;
|
||||
}
|
||||
set parentNode(parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
/**
|
||||
* Same as {@link prev}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get previousSibling() {
|
||||
return this.prev;
|
||||
}
|
||||
set previousSibling(prev) {
|
||||
this.prev = prev;
|
||||
}
|
||||
/**
|
||||
* Same as {@link next}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get nextSibling() {
|
||||
return this.next;
|
||||
}
|
||||
set nextSibling(next) {
|
||||
this.next = next;
|
||||
}
|
||||
/**
|
||||
* Clone this node, and optionally its children.
|
||||
*
|
||||
* @param recursive Clone child nodes as well.
|
||||
* @returns A clone of the node.
|
||||
*/
|
||||
cloneNode(recursive = false) {
|
||||
return cloneNode(this, recursive);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A node that contains some data.
|
||||
*/
|
||||
export class DataNode extends Node {
|
||||
/**
|
||||
* @param data The content of the data node
|
||||
*/
|
||||
constructor(data) {
|
||||
super();
|
||||
this.data = data;
|
||||
}
|
||||
/**
|
||||
* Same as {@link data}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get nodeValue() {
|
||||
return this.data;
|
||||
}
|
||||
set nodeValue(data) {
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Text within the document.
|
||||
*/
|
||||
export class Text extends DataNode {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = ElementType.Text;
|
||||
}
|
||||
get nodeType() {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Comments within the document.
|
||||
*/
|
||||
export class Comment extends DataNode {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = ElementType.Comment;
|
||||
}
|
||||
get nodeType() {
|
||||
return 8;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Processing instructions, including doc types.
|
||||
*/
|
||||
export class ProcessingInstruction extends DataNode {
|
||||
constructor(name, data) {
|
||||
super(data);
|
||||
this.name = name;
|
||||
this.type = ElementType.Directive;
|
||||
}
|
||||
get nodeType() {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* A `Node` that can have children.
|
||||
*/
|
||||
export class NodeWithChildren extends Node {
|
||||
/**
|
||||
* @param children Children of the node. Only certain node types can have children.
|
||||
*/
|
||||
constructor(children) {
|
||||
super();
|
||||
this.children = children;
|
||||
}
|
||||
// Aliases
|
||||
/** First child of the node. */
|
||||
get firstChild() {
|
||||
var _a;
|
||||
return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null;
|
||||
}
|
||||
/** Last child of the node. */
|
||||
get lastChild() {
|
||||
return this.children.length > 0
|
||||
? this.children[this.children.length - 1]
|
||||
: null;
|
||||
}
|
||||
/**
|
||||
* Same as {@link children}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get childNodes() {
|
||||
return this.children;
|
||||
}
|
||||
set childNodes(children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
export class CDATA extends NodeWithChildren {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = ElementType.CDATA;
|
||||
}
|
||||
get nodeType() {
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The root node of the document.
|
||||
*/
|
||||
export class Document extends NodeWithChildren {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.type = ElementType.Root;
|
||||
}
|
||||
get nodeType() {
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* An element within the DOM.
|
||||
*/
|
||||
export class Element extends NodeWithChildren {
|
||||
/**
|
||||
* @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, attribs, children = [], type = name === "script"
|
||||
? ElementType.Script
|
||||
: name === "style"
|
||||
? ElementType.Style
|
||||
: ElementType.Tag) {
|
||||
super(children);
|
||||
this.name = name;
|
||||
this.attribs = attribs;
|
||||
this.type = type;
|
||||
}
|
||||
get nodeType() {
|
||||
return 1;
|
||||
}
|
||||
// DOM Level 1 aliases
|
||||
/**
|
||||
* Same as {@link name}.
|
||||
* [DOM spec](https://dom.spec.whatwg.org)-compatible alias.
|
||||
*/
|
||||
get tagName() {
|
||||
return this.name;
|
||||
}
|
||||
set tagName(name) {
|
||||
this.name = name;
|
||||
}
|
||||
get attributes() {
|
||||
return Object.keys(this.attribs).map((name) => {
|
||||
var _a, _b;
|
||||
return ({
|
||||
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],
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node is a `Element`, `false` otherwise.
|
||||
*/
|
||||
export function isTag(node) {
|
||||
return isTagRaw(node);
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has the type `CDATA`, `false` otherwise.
|
||||
*/
|
||||
export function isCDATA(node) {
|
||||
return node.type === ElementType.CDATA;
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has the type `Text`, `false` otherwise.
|
||||
*/
|
||||
export function isText(node) {
|
||||
return node.type === ElementType.Text;
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has the type `Comment`, `false` otherwise.
|
||||
*/
|
||||
export function isComment(node) {
|
||||
return node.type === ElementType.Comment;
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
|
||||
*/
|
||||
export function isDirective(node) {
|
||||
return node.type === ElementType.Directive;
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has the type `ProcessingInstruction`, `false` otherwise.
|
||||
*/
|
||||
export function isDocument(node) {
|
||||
return node.type === ElementType.Root;
|
||||
}
|
||||
/**
|
||||
* @param node Node to check.
|
||||
* @returns `true` if the node has children, `false` otherwise.
|
||||
*/
|
||||
export function hasChildren(node) {
|
||||
return Object.prototype.hasOwnProperty.call(node, "children");
|
||||
}
|
||||
/**
|
||||
* Clone a node, and optionally its children.
|
||||
*
|
||||
* @param recursive Clone child nodes as well.
|
||||
* @returns A clone of the node.
|
||||
*/
|
||||
export function cloneNode(node, recursive = false) {
|
||||
let result;
|
||||
if (isText(node)) {
|
||||
result = new Text(node.data);
|
||||
}
|
||||
else if (isComment(node)) {
|
||||
result = new Comment(node.data);
|
||||
}
|
||||
else if (isTag(node)) {
|
||||
const children = recursive ? cloneChildren(node.children) : [];
|
||||
const clone = new Element(node.name, { ...node.attribs }, children);
|
||||
children.forEach((child) => (child.parent = clone));
|
||||
if (node.namespace != null) {
|
||||
clone.namespace = node.namespace;
|
||||
}
|
||||
if (node["x-attribsNamespace"]) {
|
||||
clone["x-attribsNamespace"] = { ...node["x-attribsNamespace"] };
|
||||
}
|
||||
if (node["x-attribsPrefix"]) {
|
||||
clone["x-attribsPrefix"] = { ...node["x-attribsPrefix"] };
|
||||
}
|
||||
result = clone;
|
||||
}
|
||||
else if (isCDATA(node)) {
|
||||
const children = recursive ? cloneChildren(node.children) : [];
|
||||
const clone = new CDATA(children);
|
||||
children.forEach((child) => (child.parent = clone));
|
||||
result = clone;
|
||||
}
|
||||
else if (isDocument(node)) {
|
||||
const children = recursive ? cloneChildren(node.children) : [];
|
||||
const clone = new Document(children);
|
||||
children.forEach((child) => (child.parent = clone));
|
||||
if (node["x-mode"]) {
|
||||
clone["x-mode"] = node["x-mode"];
|
||||
}
|
||||
result = clone;
|
||||
}
|
||||
else if (isDirective(node)) {
|
||||
const 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: ${node.type}`);
|
||||
}
|
||||
result.startIndex = node.startIndex;
|
||||
result.endIndex = node.endIndex;
|
||||
if (node.sourceCodeLocation != null) {
|
||||
result.sourceCodeLocation = node.sourceCodeLocation;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
function cloneChildren(childs) {
|
||||
const children = childs.map((child) => cloneNode(child, true));
|
||||
for (let i = 1; i < children.length; i++) {
|
||||
children[i].prev = children[i - 1];
|
||||
children[i - 1].next = children[i];
|
||||
}
|
||||
return children;
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"type":"module"}
|
||||
Reference in New Issue
Block a user