Files
railwaysystem/RuoYi-Vue/ruoyi-ui/node_modules2/handsontable/utils/dataStructures/tree.js
T

217 lines
6.8 KiB
JavaScript
Raw Normal View History

2026-09-10 15:40:10 +08:00
"use strict";
exports.__esModule = true;
exports.depthFirstPreOrder = depthFirstPreOrder;
require("core-js/modules/es.array.push.js");
require("core-js/modules/es.error.cause.js");
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
/**
* Depth-first pre-order strategy (https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_(NLR)).
*
* @type {string}
*/
const TRAVERSAL_DF_PRE = 'DF-pre-order';
/**
* @param {Function} callback A callback which will be called on each visited node.
* @param {*} context A context to pass through.
* @returns {boolean}
*/
exports.TRAVERSAL_DF_PRE = TRAVERSAL_DF_PRE;
function depthFirstPreOrder(callback, context) {
let continueTraverse = callback.call(context, this);
for (let i = 0; i < this.childs.length; i++) {
if (continueTraverse === false) {
return false;
}
continueTraverse = depthFirstPreOrder.call(this.childs[i], callback, context);
}
return continueTraverse;
}
/**
* Depth-first post-order strategy (https://en.wikipedia.org/wiki/Tree_traversal#Post-order_(NLR)).
*
* @type {string}
*/
const TRAVERSAL_DF_POST = 'DF-post-order';
/**
* @param {Function} callback A callback which will be called on each visited node.
* @param {*} context A context to pass through.
* @returns {boolean}
*/
exports.TRAVERSAL_DF_POST = TRAVERSAL_DF_POST;
function depthFirstPostOrder(callback, context) {
for (let i = 0; i < this.childs.length; i++) {
const continueTraverse = depthFirstPostOrder.call(this.childs[i], callback, context);
if (continueTraverse === false) {
return false;
}
}
return callback.call(context, this);
}
/**
* Breadth-first traversal strategy (https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search_/_level_order).
*
* @type {string}
*/
const TRAVERSAL_BF = 'BF';
/**
* @param {Function} callback A callback which will be called on each visited node.
* @param {*} context A context to pass through.
*/
exports.TRAVERSAL_BF = TRAVERSAL_BF;
function breadthFirst(callback, context) {
const queue = [this];
/**
* Internal processor.
*/
function process() {
if (queue.length === 0) {
return;
}
const node = queue.shift();
queue.push(...node.childs);
if (callback.call(context, node) !== false) {
process();
}
}
process();
}
/**
* Default strategy for tree traversal.
*
* @type {string}
*/
const DEFAULT_TRAVERSAL_STRATEGY = TRAVERSAL_BF;
/**
* Collection of all available tree traversal strategies.
*
* @type {Map<string, Function>}
*/
const TRAVERSAL_STRATEGIES = new Map([[TRAVERSAL_DF_PRE, depthFirstPreOrder], [TRAVERSAL_DF_POST, depthFirstPostOrder], [TRAVERSAL_BF, breadthFirst]]);
/**
*
*/
class TreeNode {
constructor(data) {
/**
* A tree data.
*
* @type {object}
*/
_defineProperty(this, "data", {});
/**
* A parent node.
*
* @type {TreeNode}
*/
_defineProperty(this, "parent", null);
/**
* A tree leaves.
*
* @type {TreeNode[]}
*/
_defineProperty(this, "childs", []);
this.data = data;
}
/**
* Adds a node to tree leaves. Added node is linked with the parent node through "parent" property.
*
* @param {TreeNode} node A TreeNode to add.
*/
addChild(node) {
node.parent = this;
this.childs.push(node);
}
/* eslint-disable jsdoc/require-description-complete-sentence */
/**
* @memberof TreeNode#
* @function cloneTree
*
* Clones a tree structure deeply.
*
* For example, for giving a tree structure:
* .--(B1)--.
* .-(C1) .-(C2)-.----.
* (D1) (D2) (D3) (D4)
*
* Cloning a tree starting from C2 node creates a mirrored tree structure.
* .-(C2')-.-----.
* (D2') (D3') (D4')
*
* The cloned tree can be safely modified without affecting the original structure.
* After modification, the clone can be merged with a tree using the "replaceTreeWith" method.
*
* @param {TreeNode} [nodeTree=this] A TreeNode to clone.
* @returns {TreeNode}
*/
/* eslint-enable jsdoc/require-description-complete-sentence */
cloneTree() {
let nodeTree = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this;
const clonedNode = new TreeNode({
...nodeTree.data
});
for (let i = 0; i < nodeTree.childs.length; i++) {
clonedNode.addChild(this.cloneTree(nodeTree.childs[i]));
}
return clonedNode;
}
/**
* Replaces the current node with a passed tree structure.
*
* @param {TreeNode} nodeTree A TreeNode to replace with.
*/
replaceTreeWith(nodeTree) {
this.data = {
...nodeTree.data
};
this.childs = [];
for (let i = 0; i < nodeTree.childs.length; i++) {
this.addChild(nodeTree.childs[i]);
}
}
/**
* Traverses the tree structure through node childs. The walk down traversing supports
* a three different strategies.
* - Depth-first pre-order strategy (https://en.wikipedia.org/wiki/Tree_traversal#Pre-order_(NLR));
* - Depth-first post-order strategy (https://en.wikipedia.org/wiki/Tree_traversal#Post-order_(NLR));
* - Breadth-first traversal strategy (https://en.wikipedia.org/wiki/Tree_traversal#Breadth-first_search_/_level_order).
*
* @param {Function} callback The callback function which will be called for each node.
* @param {string} [traversalStrategy=DEFAULT_TRAVERSAL_STRATEGY] Traversing strategy.
*/
walkDown(callback) {
let traversalStrategy = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_TRAVERSAL_STRATEGY;
if (!TRAVERSAL_STRATEGIES.has(traversalStrategy)) {
throw new Error(`Traversal strategy "${traversalStrategy}" does not exist`);
}
TRAVERSAL_STRATEGIES.get(traversalStrategy).call(this, callback, this);
}
/**
* Traverses the tree structure through node parents.
*
* @param {Function} callback The callback function which will be called for each node.
*/
walkUp(callback) {
const context = this;
const process = node => {
const continueTraverse = callback.call(context, node);
if (continueTraverse !== false && node.parent !== null) {
process(node.parent);
}
};
process(this);
}
}
exports.default = TreeNode;