UNPKG

@stackend/api

Version:

JS bindings to api.stackend.com

365 lines 9.61 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getTreePermalink = exports.isSubPath = exports.forEachNode = exports.getNode = exports.getNodePath = exports.findNode = exports.addNode = exports.moveTreeNode = exports.InsertionPoint = exports.removeTreeNodeByPermalink = exports.removeTreeNode = exports._findNodeByPermalink = exports.getTreeNodeByPermalink = exports.getTreePathMatch = exports.getTreePath = exports.getPermalink = exports.cloneTree = exports.cloneNode = exports.newTreeNode = exports.newTree = exports.TREE_CLASS = void 0; var permalink_1 = require("./permalink"); exports.TREE_CLASS = 'se.josh.xcap.tree.impl.TreeImpl'; /** * Create, but does not store a new tree */ function newTree(name) { var permalink = (0, permalink_1.generatePermalink)(name); if (!permalink) { throw Error('Could not generate permalink'); } return { __type: exports.TREE_CLASS, id: 0, permalink: permalink, name: name, description: '', ref: null, children: [], data: {}, totalChildNodes: 0, referenceId: 0 }; } exports.newTree = newTree; /** * Create, but does not store a new node */ function newTreeNode(name) { var permalink = (0, permalink_1.generatePermalink)(name); if (!permalink) { throw Error('Could not generate permalink'); } return { name: name, permalink: permalink, description: '', ref: null, children: [], data: {}, referenceId: 0 }; } exports.newTreeNode = newTreeNode; /** * Clone a node * @param node * @returns {Node|*} */ function cloneNode(node) { if (node == null) { return node; } var children = []; for (var i = 0; i < node.children.length; i++) { var c = node.children[i]; children.push(cloneNode(c)); } return Object.assign({}, node, { children: children }); } exports.cloneNode = cloneNode; /** * Clone a tree * @param tree * @returns {Node} */ function cloneTree(tree) { return cloneNode(tree); } exports.cloneTree = cloneTree; function _forEachNode(node, parents, apply) { parents.push(node); for (var i = 0; i < node.children.length; i++) { var n = node.children[i]; if (apply(n, node, parents, i)) { parents.push(n); return parents; } var r = _forEachNode(n, parents, apply); if (r) { return r; } } parents.pop(); return null; } /** * Get the permalink to a three path * @param treePath * @param node */ function getPermalink(treePath, node) { var s = ''; for (var i = 0; i < treePath.length; i++) { s += '/' + treePath[i].permalink; } if (node) { s += '/' + node.permalink; } return s; } exports.getPermalink = getPermalink; function makeNodePermalinksUnique(children) { var pls = new Set(); for (var i = 0; i < children.length; i++) { var n = children[i]; var pl = n.permalink || 'page'; var x = pl; var j = 0; while (true) { if (!pls.has(x)) { n.permalink = x; break; } j++; x = pl + '-' + j; } pls.add(n.permalink); makeNodePermalinksUnique(n.children); } } /** * Get an array with all parent nodes up to a specific node * @param tree * @param node */ function getTreePath(tree, node) { if (!tree || !node) { return null; } return _forEachNode(tree, [], function (n) { return node === n; }); } exports.getTreePath = getTreePath; function getTreePathMatch(tree, apply) { if (!tree) { return null; } return _forEachNode(tree, [], apply); } exports.getTreePathMatch = getTreePathMatch; /** * Get a tree node by its permalink * @param tree * @param permalink */ function getTreeNodeByPermalink(tree, permalink) { if (!tree || !permalink) { return null; } var p = permalink.replace(/^\//, '').replace(/\/$/, ''); if (!p) { return null; } return _findNodeByPermalink(tree, p); } exports.getTreeNodeByPermalink = getTreeNodeByPermalink; function _findNodeByPermalink(tree, permalink, accumulatedPermalink) { if (!tree) { return null; } for (var i = 0; i < tree.children.length; i++) { var n = tree.children[i]; var p = (accumulatedPermalink ? accumulatedPermalink + '/' : '') + n.permalink; if (permalink == p) { return n; } var f = _findNodeByPermalink(n, permalink, p); if (f) { return f; } } return null; } exports._findNodeByPermalink = _findNodeByPermalink; /** * Remove a tree node * @param tree * @param node * @returns {boolean} */ function removeTreeNode(tree, node) { if (tree == null || node == null) { return null; } var r = _forEachNode(tree, [], function (n, parent, parents, i) { if (n === node) { parent.children.splice(i, 1); return true; } return false; }); return r === null ? null : r[r.length - 1]; } exports.removeTreeNode = removeTreeNode; function removeTreeNodeByPermalink(tree, permalink) { if (tree == null || !permalink) { return null; } var r = _forEachNode(tree, [], function (n, parent, parents, i) { var pl = getPermalink(parents, n); if (pl === permalink) { parent.children.splice(i, 1); return true; } return false; }); return r == null ? null : r[r.length - 1]; } exports.removeTreeNodeByPermalink = removeTreeNodeByPermalink; var InsertionPoint; (function (InsertionPoint) { InsertionPoint["BEFORE"] = "BEFORE"; InsertionPoint["AFTER"] = "AFTER"; InsertionPoint["CHILD"] = "CHILD"; })(InsertionPoint = exports.InsertionPoint || (exports.InsertionPoint = {})); /** * Move a tree node * @param tree * @param node * @param insertionPoint * @param relativeTo */ function moveTreeNode(tree, node, insertionPoint, relativeTo) { console.assert(tree); console.assert(node); console.assert(insertionPoint); console.assert(relativeTo); removeTreeNode(tree, node); if (insertionPoint === InsertionPoint.CHILD) { relativeTo.children.push(node); makeNodePermalinksUnique(relativeTo.children); return true; } // Insertion before or after var parents = getTreePath(tree, relativeTo); if (!parents) { return false; // Should not happen } var insertionParent = parents[parents.length - 2]; var idx = insertionParent.children.findIndex(function (c) { return c === relativeTo; }); if (idx === -1) { return false; } var i = insertionPoint === InsertionPoint.BEFORE ? idx : idx + 1; insertionParent.children.splice(i, 0, node); makeNodePermalinksUnique(insertionParent.children); return true; } exports.moveTreeNode = moveTreeNode; /** * Add a node to the tree * @param tree * @param node */ function addNode(tree, node) { if (!tree || !node) { return null; } tree.children = tree.children.concat(node); makeNodePermalinksUnique(tree.children); return tree; } exports.addNode = addNode; /** * Find a node that matches the test * @param tree * @param test * @returns {Node|null|?Node} */ function findNode(tree, test) { if (!tree) { return null; } for (var i = 0; i < tree.children.length; i++) { var n = tree.children[i]; if (test(n)) { return n; } var f = findNode(n, test); if (f) { return f; } } return null; } exports.findNode = findNode; /** * Get the tree path to a node * @param tree * @param permalink * @returns {?Array<Node>} */ function getNodePath(tree, permalink) { return _forEachNode(tree, [], function (node, parent, parents) { return getPermalink(parents, node) === permalink; }); } exports.getNodePath = getNodePath; /** * Get a node by it's permalink * @param tree * @param permalink */ function getNode(tree, permalink) { var path = getNodePath(tree, permalink); if (!path) { return null; } return path[path.length - 1]; } exports.getNode = getNode; /** * Apply a function to each node * @param tree * @param apply A function to apply. Returning true will abort the processing * @return Path to the node where the iteration was aborted */ function forEachNode(tree, apply) { if (!tree) { return null; } return _forEachNode(tree, [], apply); } exports.forEachNode = forEachNode; /** * Check if the path is a sub path of ofPath * @param path * @param ofPath * @returns {boolean} */ function isSubPath(path, ofPath) { if (!path || !ofPath || path.length > ofPath.length) { return false; } for (var i = 0; i < path.length; i++) { if (ofPath[i].permalink !== path[i].permalink) { return false; } } return true; } exports.isSubPath = isSubPath; /** * Get the tree part of the permalink * @param permalink * @returns {string|null} */ function getTreePermalink(permalink) { if (!permalink) { return null; } var pl = permalink; if (pl.startsWith('/')) { pl = pl.substring(1); } var i = pl.indexOf('/'); if (i !== -1) { pl = pl.substring(0, i); } return pl; } exports.getTreePermalink = getTreePermalink; //# sourceMappingURL=tree.js.map