import * as plugins from './classes.plugins.js'; export class Tree { symbolTree: any; constructor() { this.symbolTree = new plugins.symbolTree(); } // ======================================= // Functions that map to the functionality of symbol-tree // ======================================= /** * * @param objectArg */ initialize(objectArg: T): T { return this.symbolTree.initialize(objectArg); } hasChildren(objectArg: T): boolean { return this.symbolTree.hasChildren(objectArg); } firstChild(objectArg: T): T { return this.symbolTree.firstChild(objectArg); } lastChild(objectArg: T): T { return this.symbolTree.lastChild(objectArg); } previousSibling(objectArg: T): T { return this.symbolTree.previousSibling(objectArg); } nextSibling(objectArg: T): T { return this.symbolTree.nextSibling(objectArg); } parent(objectArg: T): T { return this.symbolTree.parent(objectArg); } lastInclusiveDescendant(objectArg: T): T { return this.symbolTree.lastInclusiveDescendant(objectArg); } preceding(objectArg: T, optionsArg?: any): T { return this.symbolTree.preceding(objectArg, optionsArg); } following(object: T, optionsArg: any) { return this.symbolTree.following(object, optionsArg); } childrenToArray(parentArg: T, optionsArg: any): T[] { return this.symbolTree.childrenToArray(parentArg, optionsArg); } ancestorsToArray(objectArg: T, optionsArg: any): T[] { return this.symbolTree.ancestorsToArray(objectArg, optionsArg); } treeToArray(rootArg: T, optionsArg: any): T[] { return this.symbolTree.treeToArray(rootArg, optionsArg); } childrenIterator(parentArg: T, optionsArg: any): T { return this.symbolTree.childrenIterator(parentArg, optionsArg); } previousSiblingsIterator(objectArg: T): T { return this.symbolTree.previousSiblingsIterator(objectArg); } nextSiblingsIterator(objectArg: T) { return this.symbolTree.nextSiblingsIterator(objectArg); } ancestorsIterator(objectArg: T): Iterable { return this.symbolTree.ancestorsIterator(objectArg); } treeIterator(rootArg: T, optionsArg?: any): Iterable { return this.symbolTree.treeIterator(rootArg, optionsArg); } index(childArg: T): number { return this.symbolTree.index(childArg); } childrenCount(parentArg: T): number { return this.symbolTree.childrenCount(parentArg); } compareTreePosition(leftArg: T, rightArg: T): number { return this.symbolTree.compareTreePosition(leftArg, rightArg); } remove(removeObjectArg: T): T { return this.symbolTree.remove(removeObjectArg); } insertBefore(referenceObjectArg: T, newObjectArg: T): T { return this.symbolTree.insertBefore(referenceObjectArg, newObjectArg); } insertAfter(referenceObject: T, newObjectArg: T) { return this.symbolTree.insertAfter(referenceObject, newObjectArg); } prependChild(referenceObjectArg: T, newObjectArg: T): T { return this.symbolTree.prependChild(referenceObjectArg, newObjectArg); } appendChild(referenceObjectArg: T, newObjectArg: T) { return this.symbolTree.appendChild(referenceObjectArg, newObjectArg); } // =========================================== // Functionality that extends symbol-tree // =========================================== /** * returns a branch of the tree as a recursive JSON structure */ toJsonWithHierachy(rootElement: T): ITreeNode { const buildNode = (element: T): ITreeNode => { const children: ITreeNode[] = []; if (this.hasChildren(element)) { const childrenArray = this.childrenToArray(element, {}); for (const child of childrenArray) { children.push(buildNode(child)); } } return { data: element, children }; }; return buildNode(rootElement); } /** * builds a tree from a recursive JSON structure * @param jsonRoot the root node in ITreeNode format * @param reviver optional function to reconstruct T from serialized data */ fromJsonWithHierachy(jsonRoot: ITreeNode, reviver?: (data: any) => T): T { const buildTree = (node: ITreeNode, parentElement?: T): T => { const element = reviver ? reviver(node.data) : node.data; this.initialize(element); if (parentElement) { this.appendChild(parentElement, element); } for (const childNode of node.children) { buildTree(childNode, element); } return element; }; return buildTree(jsonRoot); } } export interface ITreeNode { data: T; children: ITreeNode[]; }