mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Move external drag/drop to clipboard module
This commit is contained in:
		@@ -499,282 +499,277 @@ RED.nodes = (function() {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function importNodes(newNodesObj,createNewIds) {
 | 
					    function importNodes(newNodesObj,createNewIds) {
 | 
				
			||||||
        try {
 | 
					        var i;
 | 
				
			||||||
            var i;
 | 
					        var n;
 | 
				
			||||||
            var n;
 | 
					        var newNodes;
 | 
				
			||||||
            var newNodes;
 | 
					        if (typeof newNodesObj === "string") {
 | 
				
			||||||
            if (typeof newNodesObj === "string") {
 | 
					            if (newNodesObj === "") {
 | 
				
			||||||
                if (newNodesObj === "") {
 | 
					                return;
 | 
				
			||||||
                    return;
 | 
					            }
 | 
				
			||||||
                }
 | 
					            try {
 | 
				
			||||||
                newNodes = JSON.parse(newNodesObj);
 | 
					                newNodes = JSON.parse(newNodesObj);
 | 
				
			||||||
            } else {
 | 
					            } catch(err) {
 | 
				
			||||||
                newNodes = newNodesObj;
 | 
					                var e = new Error("Invalid flow: "+err.message);
 | 
				
			||||||
 | 
					                e.code = "NODE_RED";
 | 
				
			||||||
 | 
					                throw e;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            newNodes = newNodesObj;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (!$.isArray(newNodes)) {
 | 
					        if (!$.isArray(newNodes)) {
 | 
				
			||||||
                newNodes = [newNodes];
 | 
					            newNodes = [newNodes];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        var unknownTypes = [];
 | 
				
			||||||
 | 
					        for (i=0;i<newNodes.length;i++) {
 | 
				
			||||||
 | 
					            n = newNodes[i];
 | 
				
			||||||
 | 
					            // TODO: remove workspace in next release+1
 | 
				
			||||||
 | 
					            if (n.type != "workspace" && 
 | 
				
			||||||
 | 
					                n.type != "tab" && 
 | 
				
			||||||
 | 
					                n.type != "subflow" &&
 | 
				
			||||||
 | 
					                !registry.getNodeType(n.type) &&
 | 
				
			||||||
 | 
					                n.type.substring(0,8) != "subflow:") {
 | 
				
			||||||
 | 
					                // TODO: get this UI thing out of here! (see below as well)
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (unknownTypes.indexOf(n.type)==-1) {
 | 
				
			||||||
 | 
					                    unknownTypes.push(n.type);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                //if (n.x == null && n.y == null) {
 | 
				
			||||||
 | 
					                //    // config node - remove it
 | 
				
			||||||
 | 
					                //    newNodes.splice(i,1);
 | 
				
			||||||
 | 
					                //    i--;
 | 
				
			||||||
 | 
					                //}
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            var unknownTypes = [];
 | 
					        }
 | 
				
			||||||
 | 
					        if (unknownTypes.length > 0) {
 | 
				
			||||||
 | 
					            var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>";
 | 
				
			||||||
 | 
					            var type = "type"+(unknownTypes.length > 1?"s":"");
 | 
				
			||||||
 | 
					            RED.notify("<strong>Imported unrecognised "+type+":</strong>"+typeList,"error",false,10000);
 | 
				
			||||||
 | 
					            //"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        var activeWorkspace = RED.workspaces.active();
 | 
				
			||||||
 | 
					        var activeSubflow = getSubflow(activeWorkspace);
 | 
				
			||||||
 | 
					        if (activeSubflow) {
 | 
				
			||||||
            for (i=0;i<newNodes.length;i++) {
 | 
					            for (i=0;i<newNodes.length;i++) {
 | 
				
			||||||
                n = newNodes[i];
 | 
					                var m = /^subflow:(.+)$/.exec(newNodes[i].type);
 | 
				
			||||||
                // TODO: remove workspace in next release+1
 | 
					                if (m) {
 | 
				
			||||||
                if (n.type != "workspace" && 
 | 
					                    var subflowId = m[1];
 | 
				
			||||||
                    n.type != "tab" && 
 | 
					                    var err;
 | 
				
			||||||
                    n.type != "subflow" &&
 | 
					                    if (subflowId === activeSubflow.id) {
 | 
				
			||||||
                    !registry.getNodeType(n.type) &&
 | 
					                        err = new Error("Cannot add subflow to itself");
 | 
				
			||||||
                    n.type.substring(0,8) != "subflow:") {
 | 
					                    }
 | 
				
			||||||
                    // TODO: get this UI thing out of here! (see below as well)
 | 
					                    if (subflowContains(m[1],activeSubflow.id)) {
 | 
				
			||||||
 | 
					                        err = new Error("Cannot add subflow - circular reference detected");
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (err) {
 | 
				
			||||||
 | 
					                        // TODO: standardise error codes
 | 
				
			||||||
 | 
					                        err.code = "NODE_RED";
 | 
				
			||||||
 | 
					                        throw err;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    if (unknownTypes.indexOf(n.type)==-1) {
 | 
					 | 
				
			||||||
                        unknownTypes.push(n.type);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    //if (n.x == null && n.y == null) {
 | 
					 | 
				
			||||||
                    //    // config node - remove it
 | 
					 | 
				
			||||||
                    //    newNodes.splice(i,1);
 | 
					 | 
				
			||||||
                    //    i--;
 | 
					 | 
				
			||||||
                    //}
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (unknownTypes.length > 0) {
 | 
					        }
 | 
				
			||||||
                var typeList = "<ul><li>"+unknownTypes.join("</li><li>")+"</li></ul>";
 | 
					        
 | 
				
			||||||
                var type = "type"+(unknownTypes.length > 1?"s":"");
 | 
					        var new_workspaces = [];
 | 
				
			||||||
                RED.notify("<strong>Imported unrecognised "+type+":</strong>"+typeList,"error",false,10000);
 | 
					        var workspace_map = {};
 | 
				
			||||||
                //"DO NOT DEPLOY while in this state.<br/>Either, add missing types to Node-RED, restart and then reload page,<br/>or delete unknown "+n.name+", rewire as required, and then deploy.","error");
 | 
					        var new_subflows = [];
 | 
				
			||||||
            }
 | 
					        var subflow_map = {};
 | 
				
			||||||
 | 
					        var nid;
 | 
				
			||||||
            var activeWorkspace = RED.workspaces.active();
 | 
					        var def;
 | 
				
			||||||
            var activeSubflow = getSubflow(activeWorkspace);
 | 
					        for (i=0;i<newNodes.length;i++) {
 | 
				
			||||||
            if (activeSubflow) {
 | 
					            n = newNodes[i];
 | 
				
			||||||
                for (i=0;i<newNodes.length;i++) {
 | 
					            // TODO: remove workspace in next release+1
 | 
				
			||||||
                    var m = /^subflow:(.+)$/.exec(newNodes[i].type);
 | 
					            if (n.type === "workspace" || n.type === "tab") {
 | 
				
			||||||
                    if (m) {
 | 
					                if (n.type === "workspace") {
 | 
				
			||||||
                        var subflowId = m[1];
 | 
					                    n.type = "tab";
 | 
				
			||||||
                        var err;
 | 
					 | 
				
			||||||
                        if (subflowId === activeSubflow.id) {
 | 
					 | 
				
			||||||
                            err = new Error("Cannot add subflow to itself");
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        if (subflowContains(m[1],activeSubflow.id)) {
 | 
					 | 
				
			||||||
                            err = new Error("Cannot add subflow - circular reference detected");
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        if (err) {
 | 
					 | 
				
			||||||
                            // TODO: standardise error codes
 | 
					 | 
				
			||||||
                            err.code = "NODE_RED";
 | 
					 | 
				
			||||||
                            throw err;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					                if (defaultWorkspace == null) {
 | 
				
			||||||
            
 | 
					                    defaultWorkspace = n;
 | 
				
			||||||
            var new_workspaces = [];
 | 
					                }
 | 
				
			||||||
            var workspace_map = {};
 | 
					                if (createNewIds) {
 | 
				
			||||||
            var new_subflows = [];
 | 
					                    nid = getID();
 | 
				
			||||||
            var subflow_map = {};
 | 
					                    workspace_map[n.id] = nid;
 | 
				
			||||||
            var nid;
 | 
					                    n.id = nid;
 | 
				
			||||||
            var def;
 | 
					                }
 | 
				
			||||||
            for (i=0;i<newNodes.length;i++) {
 | 
					                addWorkspace(n);
 | 
				
			||||||
                n = newNodes[i];
 | 
					                RED.workspaces.add(n);
 | 
				
			||||||
                // TODO: remove workspace in next release+1
 | 
					                new_workspaces.push(n);
 | 
				
			||||||
                if (n.type === "workspace" || n.type === "tab") {
 | 
					            } else if (n.type === "subflow") {
 | 
				
			||||||
                    if (n.type === "workspace") {
 | 
					                subflow_map[n.id] = n;
 | 
				
			||||||
                        n.type = "tab";
 | 
					                if (createNewIds) {
 | 
				
			||||||
                    }
 | 
					                    nid = getID();
 | 
				
			||||||
                    if (defaultWorkspace == null) {
 | 
					                    n.id = nid;
 | 
				
			||||||
                        defaultWorkspace = n;
 | 
					                }
 | 
				
			||||||
                    }
 | 
					                // TODO: handle createNewIds - map old to new subflow ids
 | 
				
			||||||
                    if (createNewIds) {
 | 
					                n.in.forEach(function(input,i) {
 | 
				
			||||||
                        nid = getID();
 | 
					                    input.type = "subflow";
 | 
				
			||||||
                        workspace_map[n.id] = nid;
 | 
					                    input.direction = "in";
 | 
				
			||||||
                        n.id = nid;
 | 
					                    input.z = n.id;
 | 
				
			||||||
                    }
 | 
					                    input.i = i;
 | 
				
			||||||
                    addWorkspace(n);
 | 
					                    input.id = getID();
 | 
				
			||||||
                    RED.workspaces.add(n);
 | 
					                });
 | 
				
			||||||
                    new_workspaces.push(n);
 | 
					                n.out.forEach(function(output,i) {
 | 
				
			||||||
                } else if (n.type === "subflow") {
 | 
					                    output.type = "subflow";
 | 
				
			||||||
                    subflow_map[n.id] = n;
 | 
					                    output.direction = "out";
 | 
				
			||||||
                    if (createNewIds) {
 | 
					                    output.z = n.id;
 | 
				
			||||||
                        nid = getID();
 | 
					                    output.i = i;
 | 
				
			||||||
                        n.id = nid;
 | 
					                    output.id = getID();
 | 
				
			||||||
                    }
 | 
					                });
 | 
				
			||||||
                    // TODO: handle createNewIds - map old to new subflow ids
 | 
					                new_subflows.push(n);
 | 
				
			||||||
                    n.in.forEach(function(input,i) {
 | 
					                addSubflow(n);
 | 
				
			||||||
                        input.type = "subflow";
 | 
					            } else {
 | 
				
			||||||
                        input.direction = "in";
 | 
					                def = registry.getNodeType(n.type);
 | 
				
			||||||
                        input.z = n.id;
 | 
					                if (def && def.category == "config") {
 | 
				
			||||||
                        input.i = i;
 | 
					                    if (!RED.nodes.node(n.id)) {
 | 
				
			||||||
                        input.id = getID();
 | 
					                        var configNode = {id:n.id,type:n.type,users:[]};
 | 
				
			||||||
                    });
 | 
					                        for (var d in def.defaults) {
 | 
				
			||||||
                    n.out.forEach(function(output,i) {
 | 
					                            if (def.defaults.hasOwnProperty(d)) {
 | 
				
			||||||
                        output.type = "subflow";
 | 
					                                configNode[d] = n[d];
 | 
				
			||||||
                        output.direction = "out";
 | 
					 | 
				
			||||||
                        output.z = n.id;
 | 
					 | 
				
			||||||
                        output.i = i;
 | 
					 | 
				
			||||||
                        output.id = getID();
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    new_subflows.push(n);
 | 
					 | 
				
			||||||
                    addSubflow(n);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    def = registry.getNodeType(n.type);
 | 
					 | 
				
			||||||
                    if (def && def.category == "config") {
 | 
					 | 
				
			||||||
                        if (!RED.nodes.node(n.id)) {
 | 
					 | 
				
			||||||
                            var configNode = {id:n.id,type:n.type,users:[]};
 | 
					 | 
				
			||||||
                            for (var d in def.defaults) {
 | 
					 | 
				
			||||||
                                if (def.defaults.hasOwnProperty(d)) {
 | 
					 | 
				
			||||||
                                    configNode[d] = n[d];
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            configNode.label = def.label;
 | 
					 | 
				
			||||||
                            configNode._def = def;
 | 
					 | 
				
			||||||
                            RED.nodes.add(configNode);
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 | 
					                        configNode.label = def.label;
 | 
				
			||||||
 | 
					                        configNode._def = def;
 | 
				
			||||||
 | 
					                        RED.nodes.add(configNode);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (defaultWorkspace == null) {
 | 
					        }
 | 
				
			||||||
                defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" };
 | 
					        if (defaultWorkspace == null) {
 | 
				
			||||||
                addWorkspace(defaultWorkspace);
 | 
					            defaultWorkspace = { type:"tab", id:getID(), label:"Sheet 1" };
 | 
				
			||||||
                RED.workspaces.add(defaultWorkspace);
 | 
					            addWorkspace(defaultWorkspace);
 | 
				
			||||||
                new_workspaces.push(defaultWorkspace);
 | 
					            RED.workspaces.add(defaultWorkspace);
 | 
				
			||||||
                activeWorkspace = RED.workspaces.active();
 | 
					            new_workspaces.push(defaultWorkspace);
 | 
				
			||||||
            }
 | 
					            activeWorkspace = RED.workspaces.active();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            var node_map = {};
 | 
					        var node_map = {};
 | 
				
			||||||
            var new_nodes = [];
 | 
					        var new_nodes = [];
 | 
				
			||||||
            var new_links = [];
 | 
					        var new_links = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for (i=0;i<newNodes.length;i++) {
 | 
					        for (i=0;i<newNodes.length;i++) {
 | 
				
			||||||
                n = newNodes[i];
 | 
					            n = newNodes[i];
 | 
				
			||||||
                // TODO: remove workspace in next release+1
 | 
					            // TODO: remove workspace in next release+1
 | 
				
			||||||
                if (n.type !== "workspace" && n.type !== "tab" && n.type !== "subflow") {
 | 
					            if (n.type !== "workspace" && n.type !== "tab" && n.type !== "subflow") {
 | 
				
			||||||
                    def = registry.getNodeType(n.type);
 | 
					                def = registry.getNodeType(n.type);
 | 
				
			||||||
                    if (!def || def.category != "config") {
 | 
					                if (!def || def.category != "config") {
 | 
				
			||||||
                        var node = {x:n.x,y:n.y,z:n.z,type:0,wires:n.wires,changed:false};
 | 
					                    var node = {x:n.x,y:n.y,z:n.z,type:0,wires:n.wires,changed:false};
 | 
				
			||||||
                        if (createNewIds) {
 | 
					                    if (createNewIds) {
 | 
				
			||||||
                            if (subflow_map[node.z]) {
 | 
					                        if (subflow_map[node.z]) {
 | 
				
			||||||
                                node.z = subflow_map[node.z].id;
 | 
					                            node.z = subflow_map[node.z].id;
 | 
				
			||||||
                            } else {
 | 
					 | 
				
			||||||
                                node.z = workspace_map[node.z];
 | 
					 | 
				
			||||||
                                if (!workspaces[node.z]) {
 | 
					 | 
				
			||||||
                                    node.z = activeWorkspace;
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            node.id = getID();
 | 
					 | 
				
			||||||
                        } else {
 | 
					                        } else {
 | 
				
			||||||
                            node.id = n.id;
 | 
					                            node.z = workspace_map[node.z];
 | 
				
			||||||
                            if (node.z == null || (!workspaces[node.z] && !subflow_map[node.z])) {
 | 
					                            if (!workspaces[node.z]) {
 | 
				
			||||||
                                node.z = activeWorkspace;
 | 
					                                node.z = activeWorkspace;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        node.type = n.type;
 | 
					                        node.id = getID();
 | 
				
			||||||
                        node._def = def;
 | 
					                    } else {
 | 
				
			||||||
                        if (n.type.substring(0,7) === "subflow") {
 | 
					                        node.id = n.id;
 | 
				
			||||||
                            var parentId = n.type.split(":")[1];
 | 
					                        if (node.z == null || (!workspaces[node.z] && !subflow_map[node.z])) {
 | 
				
			||||||
                            var subflow = subflow_map[parentId]||getSubflow(parentId);
 | 
					                            node.z = activeWorkspace;
 | 
				
			||||||
                            if (createNewIds) {
 | 
					                        }
 | 
				
			||||||
                                parentId = subflow.id;
 | 
					                    }
 | 
				
			||||||
                                node.type = "subflow:"+parentId;
 | 
					                    node.type = n.type;
 | 
				
			||||||
                                node._def = registry.getNodeType(node.type);
 | 
					                    node._def = def;
 | 
				
			||||||
                                delete node.i;
 | 
					                    if (n.type.substring(0,7) === "subflow") {
 | 
				
			||||||
                            }
 | 
					                        var parentId = n.type.split(":")[1];
 | 
				
			||||||
                            node.name = n.name;
 | 
					                        var subflow = subflow_map[parentId]||getSubflow(parentId);
 | 
				
			||||||
                            node.outputs = subflow.out.length;
 | 
					                        if (createNewIds) {
 | 
				
			||||||
                            node.inputs = subflow.in.length;
 | 
					                            parentId = subflow.id;
 | 
				
			||||||
                        } else {
 | 
					                            node.type = "subflow:"+parentId;
 | 
				
			||||||
                            if (!node._def) {
 | 
					                            node._def = registry.getNodeType(node.type);
 | 
				
			||||||
                                if (node.x && node.y) {
 | 
					                            delete node.i;
 | 
				
			||||||
                                    node._def = {
 | 
					                        }
 | 
				
			||||||
                                        color:"#fee",
 | 
					                        node.name = n.name;
 | 
				
			||||||
                                        defaults: {},
 | 
					                        node.outputs = subflow.out.length;
 | 
				
			||||||
                                        label: "unknown: "+n.type,
 | 
					                        node.inputs = subflow.in.length;
 | 
				
			||||||
                                        labelStyle: "node_label_italic",
 | 
					                    } else {
 | 
				
			||||||
                                        outputs: n.outputs||n.wires.length
 | 
					                        if (!node._def) {
 | 
				
			||||||
                                    }
 | 
					                            if (node.x && node.y) {
 | 
				
			||||||
                                } else {
 | 
					                                node._def = {
 | 
				
			||||||
                                    node._def = {
 | 
					                                    color:"#fee",
 | 
				
			||||||
                                        category:"config"
 | 
					                                    defaults: {},
 | 
				
			||||||
                                    };
 | 
					                                    label: "unknown: "+n.type,
 | 
				
			||||||
                                    node.users = [];
 | 
					                                    labelStyle: "node_label_italic",
 | 
				
			||||||
                                }
 | 
					                                    outputs: n.outputs||n.wires.length
 | 
				
			||||||
                                var orig = {};
 | 
					                                }
 | 
				
			||||||
                                for (var p in n) {
 | 
					                            } else {
 | 
				
			||||||
                                    if (n.hasOwnProperty(p) && p!="x" && p!="y" && p!="z" && p!="id" && p!="wires") {
 | 
					                                node._def = {
 | 
				
			||||||
                                        orig[p] = n[p];
 | 
					                                    category:"config"
 | 
				
			||||||
                                    }
 | 
					                                };
 | 
				
			||||||
                                }
 | 
					                                node.users = [];
 | 
				
			||||||
                                node._orig = orig;
 | 
					                            }
 | 
				
			||||||
                                node.name = n.type;
 | 
					                            var orig = {};
 | 
				
			||||||
                                node.type = "unknown";
 | 
					                            for (var p in n) {
 | 
				
			||||||
                            }
 | 
					                                if (n.hasOwnProperty(p) && p!="x" && p!="y" && p!="z" && p!="id" && p!="wires") {
 | 
				
			||||||
                            if (node._def.category != "config") {
 | 
					                                    orig[p] = n[p];
 | 
				
			||||||
                                node.inputs = n.inputs||node._def.inputs;
 | 
					                                }
 | 
				
			||||||
                                node.outputs = n.outputs||node._def.outputs;
 | 
					                            }
 | 
				
			||||||
                                for (var d2 in node._def.defaults) {
 | 
					                            node._orig = orig;
 | 
				
			||||||
                                    if (node._def.defaults.hasOwnProperty(d2)) {
 | 
					                            node.name = n.type;
 | 
				
			||||||
                                        node[d2] = n[d2];
 | 
					                            node.type = "unknown";
 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        addNode(node);
 | 
					 | 
				
			||||||
                        RED.editor.validateNode(node);
 | 
					 | 
				
			||||||
                        node_map[n.id] = node;
 | 
					 | 
				
			||||||
                        if (node._def.category != "config") {
 | 
					                        if (node._def.category != "config") {
 | 
				
			||||||
                            new_nodes.push(node);
 | 
					                            node.inputs = n.inputs||node._def.inputs;
 | 
				
			||||||
 | 
					                            node.outputs = n.outputs||node._def.outputs;
 | 
				
			||||||
 | 
					                            for (var d2 in node._def.defaults) {
 | 
				
			||||||
 | 
					                                if (node._def.defaults.hasOwnProperty(d2)) {
 | 
				
			||||||
 | 
					                                    node[d2] = n[d2];
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    addNode(node);
 | 
				
			||||||
 | 
					                    RED.editor.validateNode(node);
 | 
				
			||||||
 | 
					                    node_map[n.id] = node;
 | 
				
			||||||
 | 
					                    if (node._def.category != "config") {
 | 
				
			||||||
 | 
					                        new_nodes.push(node);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            for (i=0;i<new_nodes.length;i++) {
 | 
					 | 
				
			||||||
                n = new_nodes[i];
 | 
					 | 
				
			||||||
                for (var w1=0;w1<n.wires.length;w1++) {
 | 
					 | 
				
			||||||
                    var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
 | 
					 | 
				
			||||||
                    for (var w2=0;w2<wires.length;w2++) {
 | 
					 | 
				
			||||||
                        if (wires[w2] in node_map) {
 | 
					 | 
				
			||||||
                            var link = {source:n,sourcePort:w1,target:node_map[wires[w2]]};
 | 
					 | 
				
			||||||
                            addLink(link);
 | 
					 | 
				
			||||||
                            new_links.push(link);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                delete n.wires;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            for (i=0;i<new_subflows.length;i++) {
 | 
					 | 
				
			||||||
                n = new_subflows[i];
 | 
					 | 
				
			||||||
                n.in.forEach(function(input) {
 | 
					 | 
				
			||||||
                    input.wires.forEach(function(wire) {
 | 
					 | 
				
			||||||
                        var link = {source:input, sourcePort:0, target:node_map[wire.id]};
 | 
					 | 
				
			||||||
                        addLink(link);
 | 
					 | 
				
			||||||
                        new_links.push(link);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    delete input.wires;
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
                n.out.forEach(function(output) {
 | 
					 | 
				
			||||||
                    output.wires.forEach(function(wire) {
 | 
					 | 
				
			||||||
                        var link;
 | 
					 | 
				
			||||||
                        if (wire.id == n.id) {
 | 
					 | 
				
			||||||
                            link = {source:n.in[wire.port], sourcePort:wire.port,target:output};
 | 
					 | 
				
			||||||
                        } else {
 | 
					 | 
				
			||||||
                            link = {source:node_map[wire.id], sourcePort:wire.port,target:output};
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        addLink(link);
 | 
					 | 
				
			||||||
                        new_links.push(link);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    delete output.wires;
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            return [new_nodes,new_links,new_workspaces,new_subflows];
 | 
					 | 
				
			||||||
        } catch(error) {
 | 
					 | 
				
			||||||
            if (error.code != "NODE_RED") {
 | 
					 | 
				
			||||||
                console.log(error.stack);
 | 
					 | 
				
			||||||
                RED.notify("<strong>Error</strong>: "+error,"error");
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                RED.notify("<strong>Error</strong>: "+error.message,"error");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return null;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        for (i=0;i<new_nodes.length;i++) {
 | 
				
			||||||
 | 
					            n = new_nodes[i];
 | 
				
			||||||
 | 
					            for (var w1=0;w1<n.wires.length;w1++) {
 | 
				
			||||||
 | 
					                var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
 | 
				
			||||||
 | 
					                for (var w2=0;w2<wires.length;w2++) {
 | 
				
			||||||
 | 
					                    if (wires[w2] in node_map) {
 | 
				
			||||||
 | 
					                        var link = {source:n,sourcePort:w1,target:node_map[wires[w2]]};
 | 
				
			||||||
 | 
					                        addLink(link);
 | 
				
			||||||
 | 
					                        new_links.push(link);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            delete n.wires;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        for (i=0;i<new_subflows.length;i++) {
 | 
				
			||||||
 | 
					            n = new_subflows[i];
 | 
				
			||||||
 | 
					            n.in.forEach(function(input) {
 | 
				
			||||||
 | 
					                input.wires.forEach(function(wire) {
 | 
				
			||||||
 | 
					                    var link = {source:input, sourcePort:0, target:node_map[wire.id]};
 | 
				
			||||||
 | 
					                    addLink(link);
 | 
				
			||||||
 | 
					                    new_links.push(link);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                delete input.wires;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            n.out.forEach(function(output) {
 | 
				
			||||||
 | 
					                output.wires.forEach(function(wire) {
 | 
				
			||||||
 | 
					                    var link;
 | 
				
			||||||
 | 
					                    if (wire.id == n.id) {
 | 
				
			||||||
 | 
					                        link = {source:n.in[wire.port], sourcePort:wire.port,target:output};
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        link = {source:node_map[wire.id], sourcePort:wire.port,target:output};
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    addLink(link);
 | 
				
			||||||
 | 
					                    new_links.push(link);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					                delete output.wires;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        return [new_nodes,new_links,new_workspaces,new_subflows];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -119,6 +119,11 @@ RED.clipboard = (function() {
 | 
				
			|||||||
            dialog.dialog("option","title","Export nodes to clipboard").dialog( "open" );
 | 
					            dialog.dialog("option","title","Export nodes to clipboard").dialog( "open" );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    function hideDropTarget() {
 | 
				
			||||||
 | 
					        $("#dropTarget").hide();
 | 
				
			||||||
 | 
					        RED.keyboard.remove(/* ESCAPE */ 27);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
        init: function() {
 | 
					        init: function() {
 | 
				
			||||||
@@ -135,6 +140,32 @@ RED.clipboard = (function() {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
            RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
 | 
					            RED.keyboard.add(/* e */ 69,{ctrl:true},function(){exportNodes();d3.event.preventDefault();});
 | 
				
			||||||
            RED.keyboard.add(/* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();});
 | 
					            RED.keyboard.add(/* i */ 73,{ctrl:true},function(){importNodes();d3.event.preventDefault();});
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $('#chart').on("dragenter",function(event) {
 | 
				
			||||||
 | 
					                if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
 | 
				
			||||||
 | 
					                    $("#dropTarget").css({display:'table'});
 | 
				
			||||||
 | 
					                    RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            $('#dropTarget').on("dragover",function(event) {
 | 
				
			||||||
 | 
					                if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
 | 
				
			||||||
 | 
					                    event.preventDefault();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .on("dragleave",function(event) {
 | 
				
			||||||
 | 
					                hideDropTarget();
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					            .on("drop",function(event) {
 | 
				
			||||||
 | 
					                var data = event.originalEvent.dataTransfer.getData("text/plain");
 | 
				
			||||||
 | 
					                hideDropTarget();
 | 
				
			||||||
 | 
					                RED.view.importNodes(data);
 | 
				
			||||||
 | 
					                event.preventDefault();
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        import: importNodes,
 | 
					        import: importNodes,
 | 
				
			||||||
        export: exportNodes
 | 
					        export: exportNodes
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -282,8 +282,100 @@ RED.view = (function() {
 | 
				
			|||||||
            updateSelection();
 | 
					            updateSelection();
 | 
				
			||||||
            updateActiveNodes();
 | 
					            updateActiveNodes();
 | 
				
			||||||
            redraw();
 | 
					            redraw();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        $('#btn-zoom-out').click(function() {zoomOut();});
 | 
				
			||||||
 | 
					        $('#btn-zoom-zero').click(function() {zoomZero();});
 | 
				
			||||||
 | 
					        $('#btn-zoom-in').click(function() {zoomIn();});
 | 
				
			||||||
 | 
					        $("#chart").on('DOMMouseScroll mousewheel', function (evt) {
 | 
				
			||||||
 | 
					            if ( evt.altKey ) {
 | 
				
			||||||
 | 
					                evt.preventDefault();
 | 
				
			||||||
 | 
					                evt.stopPropagation();
 | 
				
			||||||
 | 
					                var move = -(evt.originalEvent.detail) || evt.originalEvent.wheelDelta;
 | 
				
			||||||
 | 
					                if (move <= 0) { zoomOut(); }
 | 
				
			||||||
 | 
					                else { zoomIn(); }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Handle nodes dragged from the palette
 | 
				
			||||||
 | 
					        $("#chart").droppable({
 | 
				
			||||||
 | 
					            accept:".palette_node",
 | 
				
			||||||
 | 
					            drop: function( event, ui ) {
 | 
				
			||||||
 | 
					                d3.event = event;
 | 
				
			||||||
 | 
					                var selected_tool = ui.draggable[0].type;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                var m = /^subflow:(.+)$/.exec(selected_tool);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (activeSubflow && m) {
 | 
				
			||||||
 | 
					                    var subflowId = m[1];
 | 
				
			||||||
 | 
					                    if (subflowId === activeSubflow.id) {
 | 
				
			||||||
 | 
					                        RED.notify("<strong>Error</strong>: Cannot add subflow to itself","error");
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (RED.nodes.subflowContains(m[1],activeSubflow.id)) {
 | 
				
			||||||
 | 
					                        RED.notify("<strong>Error</strong>: Cannot add subflow - circular reference detected","error");
 | 
				
			||||||
 | 
					                        return;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                var mousePos = d3.touches(this)[0]||d3.mouse(this);
 | 
				
			||||||
 | 
					                mousePos[1] += this.scrollTop;
 | 
				
			||||||
 | 
					                mousePos[0] += this.scrollLeft;
 | 
				
			||||||
 | 
					                mousePos[1] /= scaleFactor;
 | 
				
			||||||
 | 
					                mousePos[0] /= scaleFactor;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                var nn = { id:(1+Math.random()*4294967295).toString(16),x: mousePos[0],y:mousePos[1],w:node_width,z:RED.workspaces.active()};
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                nn.type = selected_tool;
 | 
				
			||||||
 | 
					                nn._def = RED.nodes.getType(nn.type);
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (!m) {
 | 
				
			||||||
 | 
					                    nn.inputs = nn._def.inputs || 0;
 | 
				
			||||||
 | 
					                    nn.outputs = nn._def.outputs;
 | 
				
			||||||
 | 
					                    nn.changed = true;
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    for (var d in nn._def.defaults) {
 | 
				
			||||||
 | 
					                        if (nn._def.defaults.hasOwnProperty(d)) {
 | 
				
			||||||
 | 
					                            nn[d] = nn._def.defaults[d].value;
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    if (nn._def.onadd) {
 | 
				
			||||||
 | 
					                        nn._def.onadd.call(nn);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    var subflow = RED.nodes.subflow(m[1]);
 | 
				
			||||||
 | 
					                    nn.inputs = subflow.in.length;
 | 
				
			||||||
 | 
					                    nn.outputs = subflow.out.length;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                nn.h = Math.max(node_height,(nn.outputs||0) * 15);
 | 
				
			||||||
 | 
					                RED.history.push({t:'add',nodes:[nn.id],dirty:dirty});
 | 
				
			||||||
 | 
					                RED.nodes.add(nn);
 | 
				
			||||||
 | 
					                RED.editor.validateNode(nn);
 | 
				
			||||||
 | 
					                setDirty(true);
 | 
				
			||||||
 | 
					                // auto select dropped node - so info shows (if visible)
 | 
				
			||||||
 | 
					                clearSelection();
 | 
				
			||||||
 | 
					                nn.selected = true;
 | 
				
			||||||
 | 
					                moving_set.push({n:nn});
 | 
				
			||||||
 | 
					                updateActiveNodes();
 | 
				
			||||||
 | 
					                updateSelection();
 | 
				
			||||||
 | 
					                redraw();
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                if (nn._def.autoedit) {
 | 
				
			||||||
 | 
					                    RED.editor.edit(nn);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* z */ 90,{ctrl:true},function(){RED.history.pop();});
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();});
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();});
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();});
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();});
 | 
				
			||||||
 | 
					        RED.keyboard.add(/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function canvasMouseDown() {
 | 
					    function canvasMouseDown() {
 | 
				
			||||||
@@ -517,90 +609,6 @@ RED.view = (function() {
 | 
				
			|||||||
        redraw();
 | 
					        redraw();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $('#btn-zoom-out').click(function() {zoomOut();});
 | 
					 | 
				
			||||||
    $('#btn-zoom-zero').click(function() {zoomZero();});
 | 
					 | 
				
			||||||
    $('#btn-zoom-in').click(function() {zoomIn();});
 | 
					 | 
				
			||||||
    $("#chart").on('DOMMouseScroll mousewheel', function (evt) {
 | 
					 | 
				
			||||||
        if ( evt.altKey ) {
 | 
					 | 
				
			||||||
            evt.preventDefault();
 | 
					 | 
				
			||||||
            evt.stopPropagation();
 | 
					 | 
				
			||||||
            var move = -(evt.originalEvent.detail) || evt.originalEvent.wheelDelta;
 | 
					 | 
				
			||||||
            if (move <= 0) { zoomOut(); }
 | 
					 | 
				
			||||||
            else { zoomIn(); }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    $("#chart").droppable({
 | 
					 | 
				
			||||||
            accept:".palette_node",
 | 
					 | 
				
			||||||
            drop: function( event, ui ) {
 | 
					 | 
				
			||||||
                d3.event = event;
 | 
					 | 
				
			||||||
                var selected_tool = ui.draggable[0].type;
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                var m = /^subflow:(.+)$/.exec(selected_tool);
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                if (activeSubflow && m) {
 | 
					 | 
				
			||||||
                    var subflowId = m[1];
 | 
					 | 
				
			||||||
                    if (subflowId === activeSubflow.id) {
 | 
					 | 
				
			||||||
                        RED.notify("<strong>Error</strong>: Cannot add subflow to itself","error");
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if (RED.nodes.subflowContains(m[1],activeSubflow.id)) {
 | 
					 | 
				
			||||||
                        RED.notify("<strong>Error</strong>: Cannot add subflow - circular reference detected","error");
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                var mousePos = d3.touches(this)[0]||d3.mouse(this);
 | 
					 | 
				
			||||||
                mousePos[1] += this.scrollTop;
 | 
					 | 
				
			||||||
                mousePos[0] += this.scrollLeft;
 | 
					 | 
				
			||||||
                mousePos[1] /= scaleFactor;
 | 
					 | 
				
			||||||
                mousePos[0] /= scaleFactor;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                var nn = { id:(1+Math.random()*4294967295).toString(16),x: mousePos[0],y:mousePos[1],w:node_width,z:RED.workspaces.active()};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                nn.type = selected_tool;
 | 
					 | 
				
			||||||
                nn._def = RED.nodes.getType(nn.type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (!m) {
 | 
					 | 
				
			||||||
                    nn.inputs = nn._def.inputs || 0;
 | 
					 | 
				
			||||||
                    nn.outputs = nn._def.outputs;
 | 
					 | 
				
			||||||
                    nn.changed = true;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
                    for (var d in nn._def.defaults) {
 | 
					 | 
				
			||||||
                        if (nn._def.defaults.hasOwnProperty(d)) {
 | 
					 | 
				
			||||||
                            nn[d] = nn._def.defaults[d].value;
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
                    if (nn._def.onadd) {
 | 
					 | 
				
			||||||
                        nn._def.onadd.call(nn);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    var subflow = RED.nodes.subflow(m[1]);
 | 
					 | 
				
			||||||
                    nn.inputs = subflow.in.length;
 | 
					 | 
				
			||||||
                    nn.outputs = subflow.out.length;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                nn.h = Math.max(node_height,(nn.outputs||0) * 15);
 | 
					 | 
				
			||||||
                RED.history.push({t:'add',nodes:[nn.id],dirty:dirty});
 | 
					 | 
				
			||||||
                RED.nodes.add(nn);
 | 
					 | 
				
			||||||
                RED.editor.validateNode(nn);
 | 
					 | 
				
			||||||
                setDirty(true);
 | 
					 | 
				
			||||||
                // auto select dropped node - so info shows (if visible)
 | 
					 | 
				
			||||||
                clearSelection();
 | 
					 | 
				
			||||||
                nn.selected = true;
 | 
					 | 
				
			||||||
                moving_set.push({n:nn});
 | 
					 | 
				
			||||||
                updateActiveNodes();
 | 
					 | 
				
			||||||
                updateSelection();
 | 
					 | 
				
			||||||
                redraw();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (nn._def.autoedit) {
 | 
					 | 
				
			||||||
                    RED.editor.edit(nn);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    function zoomIn() {
 | 
					    function zoomIn() {
 | 
				
			||||||
        if (scaleFactor < 2) {
 | 
					        if (scaleFactor < 2) {
 | 
				
			||||||
            scaleFactor += 0.1;
 | 
					            scaleFactor += 0.1;
 | 
				
			||||||
@@ -1638,13 +1646,6 @@ RED.view = (function() {
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RED.keyboard.add(/* z */ 90,{ctrl:true},function(){RED.history.pop();});
 | 
					 | 
				
			||||||
    RED.keyboard.add(/* a */ 65,{ctrl:true},function(){selectAll();d3.event.preventDefault();});
 | 
					 | 
				
			||||||
    RED.keyboard.add(/* = */ 187,{ctrl:true},function(){zoomIn();d3.event.preventDefault();});
 | 
					 | 
				
			||||||
    RED.keyboard.add(/* - */ 189,{ctrl:true},function(){zoomOut();d3.event.preventDefault();});
 | 
					 | 
				
			||||||
    RED.keyboard.add(/* 0 */ 48,{ctrl:true},function(){zoomZero();d3.event.preventDefault();});
 | 
					 | 
				
			||||||
    RED.keyboard.add(/* v */ 86,{ctrl:true},function(){importNodes(clipboard);d3.event.preventDefault();});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    // TODO: 'dirty' should be a property of RED.nodes - with an event callback for ui hooks
 | 
					    // TODO: 'dirty' should be a property of RED.nodes - with an event callback for ui hooks
 | 
				
			||||||
    function setDirty(d) {
 | 
					    function setDirty(d) {
 | 
				
			||||||
        dirty = d;
 | 
					        dirty = d;
 | 
				
			||||||
@@ -1746,34 +1747,6 @@ RED.view = (function() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    function hideDropTarget() {
 | 
					 | 
				
			||||||
        $("#dropTarget").hide();
 | 
					 | 
				
			||||||
        RED.keyboard.remove(/* ESCAPE */ 27);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    $('#chart').on("dragenter",function(event) {
 | 
					 | 
				
			||||||
        if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
 | 
					 | 
				
			||||||
            $("#dropTarget").css({display:'table'});
 | 
					 | 
				
			||||||
            RED.keyboard.add(/* ESCAPE */ 27,hideDropTarget);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $('#dropTarget').on("dragover",function(event) {
 | 
					 | 
				
			||||||
        if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) {
 | 
					 | 
				
			||||||
            event.preventDefault();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .on("dragleave",function(event) {
 | 
					 | 
				
			||||||
        hideDropTarget();
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
    .on("drop",function(event) {
 | 
					 | 
				
			||||||
        var data = event.originalEvent.dataTransfer.getData("text/plain");
 | 
					 | 
				
			||||||
        hideDropTarget();
 | 
					 | 
				
			||||||
        RED.view.importNodes(data);
 | 
					 | 
				
			||||||
        event.preventDefault();
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // TODO: DRY
 | 
					    // TODO: DRY
 | 
				
			||||||
    var eventHandler = (function() {
 | 
					    var eventHandler = (function() {
 | 
				
			||||||
        var handlers = {};
 | 
					        var handlers = {};
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user