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.
 
 
 
 

88 lines
2.6 KiB

(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);