static clone()

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)
    })
  }