"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 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 get: function () { return this.parent; }, set: function (parent) { this.parent = parent; }, enumerable: false, configurable: true }); Object.defineProperty(Node.prototype, "previousSibling", { get: function () { return this.prev; }, set: function (prev) { this.prev = prev; }, enumerable: false, configurable: true }); Object.defineProperty(Node.prototype, "nextSibling", { 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; 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", { get: function () { return this.data; }, set: function (data) { this.data = data; }, enumerable: false, configurable: true }); return DataNode; }(Node)); exports.DataNode = DataNode; 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; 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; 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 get: function () { var _a; return (_a = this.children[0]) !== null && _a !== void 0 ? _a : null; }, enumerable: false, configurable: true }); Object.defineProperty(NodeWithChildren.prototype, "lastChild", { get: function () { return this.children.length > 0 ? this.children[this.children.length - 1] : null; }, enumerable: false, configurable: true }); Object.defineProperty(NodeWithChildren.prototype, "childNodes", { get: function () { return this.children; }, set: function (children) { this.children = children; }, enumerable: false, configurable: true }); return NodeWithChildren; }(Node)); exports.NodeWithChildren = NodeWithChildren; 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; 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 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 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["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: " + node.type); } result.startIndex = node.startIndex; result.endIndex = node.endIndex; 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; }