You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
89 lines
2.6 KiB
89 lines
2.6 KiB
|
3 days ago
|
(function (global) {
|
||
|
|
'use strict';
|
||
|
|
|
||
|
|
function nodeId(n) {
|
||
|
|
return String(n.uuid || n._id || n.name || '');
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 先序遍历;fn 返回 false 时提前停止。
|
||
|
|
* @param {*} node
|
||
|
|
* @param {function(*):boolean|void} fn
|
||
|
|
* @returns {boolean} false 表示被 fn 中止
|
||
|
|
*/
|
||
|
|
function walk(node, fn) {
|
||
|
|
if (!node) return true;
|
||
|
|
if (fn(node) === false) return false;
|
||
|
|
var ch = node.children;
|
||
|
|
if (!ch) return true;
|
||
|
|
for (var i = 0; i < ch.length; i++) {
|
||
|
|
if (walk(ch[i], fn) === false) return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
|
||
|
|
/** 按 uuid / _id / name 查找节点,命中即停。 */
|
||
|
|
function findNodeByUuid(root, uuid) {
|
||
|
|
if (!root || !uuid) return null;
|
||
|
|
var found = null;
|
||
|
|
walk(root, function (n) {
|
||
|
|
if (nodeId(n) === uuid) {
|
||
|
|
found = n;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
});
|
||
|
|
return found;
|
||
|
|
}
|
||
|
|
|
||
|
|
function serializeNode(node, depth, maxDepth) {
|
||
|
|
if (!node || depth > maxDepth) return null;
|
||
|
|
var children = [];
|
||
|
|
var ch = node.children || [];
|
||
|
|
for (var i = 0; i < ch.length; i++) {
|
||
|
|
var c = serializeNode(ch[i], depth + 1, maxDepth);
|
||
|
|
if (c) children.push(c);
|
||
|
|
}
|
||
|
|
var comps = [];
|
||
|
|
if (node.components) {
|
||
|
|
for (var j = 0; j < node.components.length; j++) {
|
||
|
|
var comp = node.components[j];
|
||
|
|
if (comp && comp.constructor) comps.push(comp.constructor.name || '');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return {
|
||
|
|
uuid: nodeId(node),
|
||
|
|
name: node.name || '(未命名)',
|
||
|
|
active: node.active !== false,
|
||
|
|
comps: comps,
|
||
|
|
children: children,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function copySeries(series) {
|
||
|
|
var out = {};
|
||
|
|
for (var k in series) {
|
||
|
|
if (Object.prototype.hasOwnProperty.call(series, k)) out[k] = series[k].slice();
|
||
|
|
}
|
||
|
|
return out;
|
||
|
|
}
|
||
|
|
|
||
|
|
function hierFingerprint(node) {
|
||
|
|
if (!node) return '';
|
||
|
|
var parts = [node.uuid, node.name, node.active ? 1 : 0, (node.comps || []).length];
|
||
|
|
var ch = node.children || [];
|
||
|
|
parts.push(ch.length);
|
||
|
|
for (var i = 0; i < ch.length; i++) parts.push(hierFingerprint(ch[i]));
|
||
|
|
return parts.join('/');
|
||
|
|
}
|
||
|
|
|
||
|
|
global.PWAgentUtil = {
|
||
|
|
nodeId: nodeId,
|
||
|
|
walk: walk,
|
||
|
|
findNodeByUuid: findNodeByUuid,
|
||
|
|
serializeNode: serializeNode,
|
||
|
|
copySeries: copySeries,
|
||
|
|
hierFingerprint: hierFingerprint,
|
||
|
|
};
|
||
|
|
})(window);
|