function newNodeCloning () { const MODULE_NAME = 'Node Cloning' const ERROR_LOG = true const logger = newWebDebugLog() logger.fileName = MODULE_NAME thisObject = { getNodeClone: getNodeClone } return thisObject function getNodeClone (node) { let idConversionMap = new Map() let inmatureClone = cloneNode(node) let matureClone = redirectReferenceParents(inmatureClone) return matureClone function cloneNode (node) { if (node === undefined) { return } let nodeDefinition = APP_SCHEMA_MAP.get(node.type) if (nodeDefinition !== undefined) { let object = { type: node.type, subType: node.subType, name: node.name, code: node.code } /* Children Nodes */ if (nodeDefinition.properties !== undefined) { for (let i = 0; i < nodeDefinition.properties.length; i++) { let property = nodeDefinition.properties[i] switch (property.type) { case 'node': { if (node[property.name] !== undefined) { object[property.name] = cloneNode(node[property.name]) } break } case 'array': { if (node[property.name] !== undefined) { let nodePropertyArray = node[property.name] object[property.name] = [] for (let m = 0; m < nodePropertyArray.length; m++) { let protocolNode = cloneNode(nodePropertyArray[m]) if (protocolNode !== undefined) { object[property.name].push(protocolNode) } } } break } } } } object.id = newUniqueId() idConversionMap.set(node.id, object.id) object.savedPayload = getSavedPayload(node) return object } } function redirectReferenceParents (node) { if (node === undefined) { return } let nodeDefinition = APP_SCHEMA_MAP.get(node.type) if (nodeDefinition !== undefined) { let object = { type: node.type, subType: node.subType, name: node.name, code: node.code } /* Children Nodes */ if (nodeDefinition.properties !== undefined) { for (let i = 0; i < nodeDefinition.properties.length; i++) { let property = nodeDefinition.properties[i] switch (property.type) { case 'node': { if (node[property.name] !== undefined) { object[property.name] = redirectReferenceParents(node[property.name]) } break } case 'array': { if (node[property.name] !== undefined) { let nodePropertyArray = node[property.name] object[property.name] = [] for (let m = 0; m < nodePropertyArray.length; m++) { let protocolNode = redirectReferenceParents(nodePropertyArray[m]) if (protocolNode !== undefined) { object[property.name].push(protocolNode) } } } break } } } } object.id = node.id object.savedPayload = node.savedPayload if (object.savedPayload !== undefined) { if (object.savedPayload.referenceParent !== undefined) { let newId = idConversionMap.get(object.savedPayload.referenceParent.id) if (newId !== undefined) { object.savedPayload.referenceParent.id = newId } } } return object } } } function getSavedPayload (node) { if (node.payload === undefined) { return } let savedPayload = { position: { x: node.payload.position.x, y: node.payload.position.y }, targetPosition: { x: node.payload.targetPosition.x, y: node.payload.targetPosition.y }, floatingObject: { isPinned: node.payload.floatingObject.isPinned, isFrozen: (node.payload.floatingObject.isFrozen && node.payload.floatingObject.frozenManually), isCollapsed: (node.payload.floatingObject.isCollapsed && node.payload.floatingObject.collapsedManually), isTensed: (node.payload.floatingObject.isTensed && node.payload.floatingObject.tensedManually) }, uiObject: { isRunning: node.payload.uiObject.isRunning, shortcutKey: node.payload.uiObject.shortcutKey } } /* Next for the ones that have a reference parent, we include it */ if (node.payload.referenceParent !== undefined) { savedPayload.referenceParent = { type: node.payload.referenceParent.type, subType: node.payload.referenceParent.subType, name: node.payload.referenceParent.name, id: node.payload.referenceParent.id } } else { /* The referenceParent property can be inherited from the previous saved payload. */ if (node.savedPayload !== undefined) { savedPayload.referenceParent = node.savedPayload.referenceParent } } return savedPayload } }