in packages/core/src/models/TreeNode.ts [791:845]
static clone(nodes: TreeNode[] = []) {
const groups: { [parentId: string]: TreeNode[] } = {}
const lastGroupNode: { [parentId: string]: TreeNode } = {}
const filterNestedNode = TreeNode.sort(nodes).filter((node) => {
return !nodes.some((parent) => {
return node.isMyParents(parent)
})
})
each(filterNestedNode, (node) => {
if (node === node.root) return
if (!node.allowClone()) return
if (!node?.operation) return
groups[node?.parent?.id] = groups[node?.parent?.id] || []
groups[node?.parent?.id].push(node)
if (lastGroupNode[node?.parent?.id]) {
if (node.index > lastGroupNode[node?.parent?.id].index) {
lastGroupNode[node?.parent?.id] = node
}
} else {
lastGroupNode[node?.parent?.id] = node
}
})
const parents = new Map<TreeNode, TreeNode[]>()
each(groups, (nodes, parentId) => {
const lastNode = lastGroupNode[parentId]
let insertPoint = lastNode
each(nodes, (node) => {
const cloned = node.clone()
if (!cloned) return
if (
node.operation?.selection.has(node) &&
insertPoint.parent.allowAppend([cloned])
) {
insertPoint.insertAfter(cloned)
insertPoint = insertPoint.next
} else if (node.operation.selection.length === 1) {
const targetNode = node.operation?.tree.findById(
node.operation.selection.first
)
let cloneNodes = parents.get(targetNode)
if (!cloneNodes) {
cloneNodes = []
parents.set(targetNode, cloneNodes)
}
if (targetNode && targetNode.allowAppend([cloned])) {
cloneNodes.push(cloned)
}
}
})
})
parents.forEach((nodes, target) => {
if (!nodes.length) return
target.append(...nodes)
})
}