copy-tree.js 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. 'use strict';
  2. function copyNode(node) {
  3. var newNode = {};
  4. Object.keys(node).forEach(function(key) {
  5. newNode[key] = node[key];
  6. });
  7. return newNode;
  8. }
  9. var defaultNodeFactory = {
  10. topNode: copyNode,
  11. taskNode: copyNode,
  12. childNode: copyNode,
  13. };
  14. function copyTree(tree, opts, nodeFactory) {
  15. opts = opts || {};
  16. var depth = opts.tasksDepth;
  17. depth = typeof depth === 'number' ? ((depth < 1) ? 1 : depth) : null;
  18. nodeFactory = nodeFactory || defaultNodeFactory;
  19. var newTree = nodeFactory.topNode(tree);
  20. newTree.nodes = [];
  21. if (Array.isArray(tree.nodes)) {
  22. tree.nodes.forEach(visit);
  23. }
  24. function visit(node) {
  25. var newNode = nodeFactory.taskNode(node);
  26. newNode.nodes = [];
  27. newTree.nodes.push(newNode);
  28. if (opts.compactTasks) {
  29. forEach(node.nodes, copyNotRecursively, newNode);
  30. } else if (!depth || depth > 1) {
  31. forEach(node.nodes, copyRecursively, depth, 2, newNode);
  32. }
  33. }
  34. function copyNotRecursively(child, newParent) {
  35. var newChild = nodeFactory.childNode(child);
  36. newChild.nodes = [];
  37. newParent.nodes.push(newChild);
  38. if (child.branch) {
  39. forEach(child.nodes, copyNotRecursively, newChild);
  40. }
  41. }
  42. function copyRecursively(child, maxDepth, nowDepth, newParent) {
  43. var newChild = nodeFactory.childNode(child);
  44. newChild.nodes = [];
  45. newParent.nodes.push(newChild);
  46. if (!maxDepth || maxDepth > nowDepth) {
  47. forEach(child.nodes, copyRecursively, maxDepth, nowDepth + 1, newChild);
  48. }
  49. }
  50. return newTree;
  51. }
  52. function forEach(nodes, fn) {
  53. if (!Array.isArray(nodes)) {
  54. return;
  55. }
  56. var args = Array.prototype.slice.call(arguments, 2);
  57. for (var i = 0, n = nodes.length; i < n; i++) {
  58. fn.apply(nodes[i], [nodes[i]].concat(args));
  59. }
  60. }
  61. module.exports = copyTree;