UNPKG

@openxmldev/linq-to-xml

Version:
107 lines 3.67 kB
/** * @author Thomas Barnekow * @license MIT */ import { Inserter, InvalidOperationException, LinqElements, XElement, XObject, } from './internal.js'; /** * Represents an XML node. */ export class XNode extends XObject { constructor() { super(); /** @internal */ this._next = null; } /** * Gets the next sibling node of this node. * * If this node does not have a parent, or if there is no next node, * then this property returns null. */ get nextNode() { return this._parent === null || this._parent._content === this ? null : this._next; } /** * Gets the previous sibling node of this node. * * If this property does not have a parent, or if there is no previous node, * then this property returns null. */ get previousNode() { if (this._parent === null) return null; // At this point, we know that the parent XContainer has XNode content. // We start with p being null and n being the first node. let previousNode = null; let nextNode = this._parent._content._next; while (nextNode !== this) { previousNode = nextNode; nextNode = nextNode._next; } return previousNode; } /** * Returns the collection of the ancestor elements for this node. * * @param name The optional name of the ancestor elements to find. * @returns The ancestor elements of this node. */ ancestors(name) { return name === null ? new LinqElements(XElement.emptySequence) : new LinqElements(getAncestors(this, name !== null && name !== void 0 ? name : null, false)); } /** @internal */ // eslint-disable-next-line @typescript-eslint/no-unused-vars appendText(_sb) { // No operation } /** * Removes this `XNode` from the underlying XML tree. */ remove() { this.getParentXContainerOrThrow().removeNode(this); } /** * Replaces this node with the specified content. * * @param content Content that replaces this node. */ replaceWith(...content) { const parent = this.getParentXContainerOrThrow(); // Get the previous sibling node as the anchor for inserting the replacement // content. That anchor will be null if the this node is the parent's only // child node. let previousNode = parent._content; while (previousNode._next !== this) previousNode = previousNode._next; if (previousNode === parent._content) previousNode = null; parent.removeNode(this); if (previousNode !== null && previousNode._parent !== parent) { throw new InvalidOperationException('This operation was corrupted by external code.'); } if (content.length > 0) { // Add the replacement content after the previous (anchor) node. new Inserter(parent, previousNode).add(content.length === 1 ? content[0] : content); } } getParentXContainerOrThrow() { if (this._parent === null) { throw new InvalidOperationException('The parent is missing.'); } return this._parent; } } /** @internal */ export function* getAncestors(node, name, self) { let e = (self ? node : node._parent); while (e !== null) { if (name === null || e._name === name) yield e; e = e._parent; } } //# sourceMappingURL=XNode.js.map