@stackend/api
Version:
JS bindings to api.stackend.com
365 lines • 9.61 kB
JavaScript
"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