UNPKG

zent

Version:

一套前端设计语言和基于React的实现

224 lines (223 loc) 6.7 kB
import { __assign } from "tslib"; import { isPathEqual } from './path-fns'; import { getNodeDepth } from './node-fns'; export function clone(from, cloneNode) { var stack = from.map(function (n) { return ({ node: cloneNode(n, null), children: n.children, }); }); var trees = stack.map(function (n) { return n.node; }); var _loop_1 = function () { var state = stack.pop(); if (!state) { return "continue"; } var node = state.node, children = state.children; children === null || children === void 0 ? void 0 : children.forEach(function (n) { var m = cloneNode(n, node); stack.push({ node: m, children: n.children }); node.children.push(m); }); }; while (stack.length > 0) { _loop_1(); } return trees; } export function insertPath(trees, path, createNode) { path = path.slice(); var stack = [ { parent: null, children: trees, node: path.shift(), }, ]; var _loop_2 = function () { var frame = stack.pop(); if (!frame) { return "continue"; } var children = frame.children, node = frame.node; if (!node) { return "break"; } var nval = node.value; var matchedNode = children.find(function (n) { return n.value === nval; }); if (!matchedNode) { matchedNode = createNode(node, frame.parent); children.push(matchedNode); } stack.push({ parent: matchedNode, children: matchedNode.children, node: path.shift(), }); }; while (stack.length > 0) { var state_1 = _loop_2(); if (state_1 === "break") break; } return trees; } var Forest = (function () { function Forest(from) { this.trees = this.build(from); } Forest.prototype.build = function (from) { return clone(from, createNode); }; Forest.prototype.reducePath = function (callback, initialValue) { var stack = reverse(this.trees); var path = []; var acc = initialValue; var earlyExit = false; var terminate = function () { earlyExit = true; }; while (stack.length > 0) { var node = stack.pop(); if (!node) { continue; } var depth = getNodeDepth(node); while (depth <= path.length) { path.pop(); } path.push(node); if (node.children.length > 0) { reversePush(stack, node.children); } else { acc = callback(acc, path.slice(), terminate); if (earlyExit) { break; } } } return acc; }; Forest.prototype.reduceNode = function (callback, initialValue) { var stack = reverse(this.trees); var acc = initialValue; var earlyExit = false; var terminate = function () { earlyExit = true; }; while (stack.length > 0) { var node = stack.pop(); if (!node) { continue; } acc = callback(acc, node, terminate); if (earlyExit) { break; } if (node.children.length > 0) { reversePush(stack, node.children); } } return acc; }; Forest.prototype.reduceNodeDfs = function (callback, initialValue) { var stack = this.trees.map(function (n) { return ({ node: n, phase: 'recurse', }); }); var acc = initialValue; var earlyExit = false; var terminate = function () { earlyExit = true; }; while (stack.length > 0) { var frame = stack.pop(); if (!frame) { continue; } var node = frame.node, phase = frame.phase; if (phase === 'recurse') { stack.push({ node: node, phase: 'visit', }); node.children.forEach(function (node) { stack.push({ node: node, phase: 'recurse', }); }); } else if (phase === 'visit') { acc = callback(acc, node, terminate); if (earlyExit) { break; } } } return acc; }; Forest.prototype.sort = function (paths) { return this.reducePath(function (acc, path) { if (paths.some(function (x) { return isPathEqual(x, path); })) { acc.push(path); } return acc; }, []); }; Forest.prototype.clone = function () { return new Forest(this.trees); }; Forest.prototype.insertPath = function (path) { insertPath(this.trees, path, createNode); return this; }; Forest.prototype.getTrees = function () { return this.trees; }; Forest.prototype.getPathByValue = function (values) { return this.reducePath(function (found, path, terminate) { if (values.length > path.length || values.length === 0) { return found; } var size = values.length; var i; for (i = 0; i < size; i++) { if (path[i].value !== values[i]) { return found; } } terminate(); return i === path.length ? path : path.slice(0, size); }, []); }; Forest.prototype.getPaths = function (startNode, predicate) { var depth = getNodeDepth(startNode); var idx = depth - 1; var value = startNode.value; return this.reducePath(function (acc, path) { if (path.length > idx && path[idx].value === value && (!predicate || predicate(path))) { acc.push(path); } return acc; }, []); }; return Forest; }()); export { Forest }; function reverse(arr) { var ret = arr.slice(); ret.reverse(); return ret; } function reversePush(arr, from) { for (var i = from.length - 1; i >= 0; i--) { arr.push(from[i]); } return arr; } function createNode(node, parent) { return __assign(__assign({}, node), { parent: parent, children: [] }); }