mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Handle config nodes appearing out of order in flow
The editor ensures config nodes appear first in the flow file. The code in the runtime and editor assumes this to be the case, so that when a node is instantiated that requires a config node, it can assume the config node already exists. This change allows a config node to appear in the flow file after a node that wants to use it. In both the editor and runtime, the code now scans for config nodes and handles them first.
This commit is contained in:
parent
049a5f1be6
commit
d148a23ed6
@ -608,6 +608,21 @@ RED.nodes = (function() {
|
|||||||
});
|
});
|
||||||
new_subflows.push(n);
|
new_subflows.push(n);
|
||||||
addSubflow(n);
|
addSubflow(n);
|
||||||
|
} else {
|
||||||
|
var 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (defaultWorkspace == null) {
|
if (defaultWorkspace == null) {
|
||||||
@ -627,19 +642,7 @@ RED.nodes = (function() {
|
|||||||
// 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") {
|
||||||
var def = registry.getNodeType(n.type);
|
var def = registry.getNodeType(n.type);
|
||||||
if (def && def.category == "config") {
|
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);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
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]) {
|
||||||
|
@ -228,11 +228,14 @@ Flow.prototype.parseConfig = function(config) {
|
|||||||
this.nodes = {};
|
this.nodes = {};
|
||||||
this.subflows = {};
|
this.subflows = {};
|
||||||
|
|
||||||
|
this.configNodes = {};
|
||||||
|
|
||||||
var unknownTypes = {};
|
var unknownTypes = {};
|
||||||
|
|
||||||
for (i=0;i<this.config.length;i++) {
|
for (i=0;i<this.config.length;i++) {
|
||||||
nodeConfig = this.config[i];
|
nodeConfig = this.config[i];
|
||||||
nodeType = nodeConfig.type;
|
nodeType = nodeConfig.type;
|
||||||
|
this.allNodes[nodeConfig.id] = nodeConfig;
|
||||||
if (nodeType == "subflow") {
|
if (nodeType == "subflow") {
|
||||||
this.subflows[nodeConfig.id] = {
|
this.subflows[nodeConfig.id] = {
|
||||||
type: "subflow",
|
type: "subflow",
|
||||||
@ -243,11 +246,9 @@ Flow.prototype.parseConfig = function(config) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
//console.log("Known subflows:",Object.keys(this.subflows));
|
//console.log("Known subflows:",Object.keys(this.subflows));
|
||||||
|
|
||||||
for (i=0;i<this.config.length;i++) {
|
for (i=0;i<this.config.length;i++) {
|
||||||
nodeConfig = this.config[i];
|
nodeConfig = this.config[i];
|
||||||
|
|
||||||
this.allNodes[nodeConfig.id] = nodeConfig;
|
|
||||||
|
|
||||||
nodeType = nodeConfig.type;
|
nodeType = nodeConfig.type;
|
||||||
|
|
||||||
@ -273,6 +274,15 @@ Flow.prototype.parseConfig = function(config) {
|
|||||||
} else {
|
} else {
|
||||||
this.nodes[nodeConfig.id] = nodeInfo;
|
this.nodes[nodeConfig.id] = nodeInfo;
|
||||||
}
|
}
|
||||||
|
for (var prop in nodeConfig) {
|
||||||
|
if (nodeConfig.hasOwnProperty(prop) &&
|
||||||
|
prop != "id" &&
|
||||||
|
prop != "z" &&
|
||||||
|
prop != "wires" &&
|
||||||
|
this.allNodes[nodeConfig[prop]]) {
|
||||||
|
this.configNodes[nodeConfig[prop]] = this.allNodes[nodeConfig[prop]];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -303,9 +313,21 @@ Flow.prototype.start = function() {
|
|||||||
}
|
}
|
||||||
events.emit("nodes-starting");
|
events.emit("nodes-starting");
|
||||||
|
|
||||||
for (var id in this.nodes) {
|
var id;
|
||||||
|
var node;
|
||||||
|
|
||||||
|
for (id in this.configNodes) {
|
||||||
|
if (this.configNodes.hasOwnProperty(id)) {
|
||||||
|
node = this.configNodes[id];
|
||||||
|
if (!this.activeNodes[id]) {
|
||||||
|
this.activeNodes[id] = createNode(node.type,node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (id in this.nodes) {
|
||||||
if (this.nodes.hasOwnProperty(id)) {
|
if (this.nodes.hasOwnProperty(id)) {
|
||||||
var node = this.nodes[id];
|
node = this.nodes[id];
|
||||||
if (!node.subflow) {
|
if (!node.subflow) {
|
||||||
if (!this.activeNodes[id]) {
|
if (!this.activeNodes[id]) {
|
||||||
this.activeNodes[id] = createNode(node.type,node.config);
|
this.activeNodes[id] = createNode(node.type,node.config);
|
||||||
@ -460,7 +482,7 @@ Flow.prototype.applyConfig = function(config,type) {
|
|||||||
|
|
||||||
Flow.prototype.diffFlow = function(config) {
|
Flow.prototype.diffFlow = function(config) {
|
||||||
var flow = this;
|
var flow = this;
|
||||||
var configNodes = {};
|
var flowNodes = {};
|
||||||
var changedNodes = {};
|
var changedNodes = {};
|
||||||
var deletedNodes = {};
|
var deletedNodes = {};
|
||||||
var linkChangedNodes = {};
|
var linkChangedNodes = {};
|
||||||
@ -489,7 +511,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.forEach(function(node) {
|
config.forEach(function(node) {
|
||||||
configNodes[node.id] = node;
|
flowNodes[node.id] = node;
|
||||||
});
|
});
|
||||||
|
|
||||||
config.forEach(function(node) {
|
config.forEach(function(node) {
|
||||||
@ -500,7 +522,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
} else {
|
} else {
|
||||||
changed = diffNodeConfigs(flow.allNodes[node.id],node);
|
changed = diffNodeConfigs(flow.allNodes[node.id],node);
|
||||||
if (!changed) {
|
if (!changed) {
|
||||||
if (configNodes[node.z] && configNodes[node.z].type == "subflow") {
|
if (flowNodes[node.z] && flowNodes[node.z].type == "subflow") {
|
||||||
var originalNode = flow.allNodes[node.id];
|
var originalNode = flow.allNodes[node.id];
|
||||||
if (originalNode && !redUtil.compareObjects(originalNode.wires,node.wires)) {
|
if (originalNode && !redUtil.compareObjects(originalNode.wires,node.wires)) {
|
||||||
// This is a node in a subflow whose wiring has changed. Mark subflow as changed
|
// This is a node in a subflow whose wiring has changed. Mark subflow as changed
|
||||||
@ -515,7 +537,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.config.forEach(function(node) {
|
this.config.forEach(function(node) {
|
||||||
if (!configNodes[node.id] && node.type != "tab") {
|
if (!flowNodes[node.id] && node.type != "tab") {
|
||||||
deletedNodes[node.id] = node;
|
deletedNodes[node.id] = node;
|
||||||
}
|
}
|
||||||
buildNodeLinks(activeLinks,node,flow.allNodes);
|
buildNodeLinks(activeLinks,node,flow.allNodes);
|
||||||
@ -550,7 +572,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.keys(changedNodes).forEach(function(n) { checkSubflowMembership(configNodes,n)});
|
Object.keys(changedNodes).forEach(function(n) { checkSubflowMembership(flowNodes,n)});
|
||||||
Object.keys(deletedNodes).forEach(function(n) { checkSubflowMembership(flow.allNodes,n)});
|
Object.keys(deletedNodes).forEach(function(n) { checkSubflowMembership(flow.allNodes,n)});
|
||||||
|
|
||||||
while (changedSubflowStack.length > 0) {
|
while (changedSubflowStack.length > 0) {
|
||||||
@ -560,7 +582,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
if (node.type == "subflow:"+subflowId) {
|
if (node.type == "subflow:"+subflowId) {
|
||||||
if (!changedNodes[node.id]) {
|
if (!changedNodes[node.id]) {
|
||||||
changedNodes[node.id] = node;
|
changedNodes[node.id] = node;
|
||||||
checkSubflowMembership(configNodes,node.id);
|
checkSubflowMembership(flowNodes,node.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -568,7 +590,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.forEach(function(node) {
|
config.forEach(function(node) {
|
||||||
buildNodeLinks(newLinks,node,configNodes);
|
buildNodeLinks(newLinks,node,flowNodes);
|
||||||
});
|
});
|
||||||
|
|
||||||
var markLinkedNodes = function(linkChanged,otherChangedNodes,linkMap,allNodes) {
|
var markLinkedNodes = function(linkChanged,otherChangedNodes,linkMap,allNodes) {
|
||||||
@ -591,7 +613,7 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
markLinkedNodes(linkChangedNodes,{},newLinks,configNodes);
|
markLinkedNodes(linkChangedNodes,{},newLinks,flowNodes);
|
||||||
markLinkedNodes(linkChangedNodes,{},activeLinks,flow.allNodes);
|
markLinkedNodes(linkChangedNodes,{},activeLinks,flow.allNodes);
|
||||||
|
|
||||||
var modifiedLinkNodes = {};
|
var modifiedLinkNodes = {};
|
||||||
@ -613,8 +635,8 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
modifiedLinkNodes[node.id] = node;
|
modifiedLinkNodes[node.id] = node;
|
||||||
linkChangedNodes[node.id] = node;
|
linkChangedNodes[node.id] = node;
|
||||||
if (!changedNodes[link] && !deletedNodes[link]) {
|
if (!changedNodes[link] && !deletedNodes[link]) {
|
||||||
modifiedLinkNodes[link] = configNodes[link];
|
modifiedLinkNodes[link] = flowNodes[link];
|
||||||
linkChangedNodes[link] = configNodes[link];
|
linkChangedNodes[link] = flowNodes[link];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -623,15 +645,15 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
modifiedLinkNodes[node.id] = node;
|
modifiedLinkNodes[node.id] = node;
|
||||||
linkChangedNodes[node.id] = node;
|
linkChangedNodes[node.id] = node;
|
||||||
if (!changedNodes[link] && !deletedNodes[link]) {
|
if (!changedNodes[link] && !deletedNodes[link]) {
|
||||||
modifiedLinkNodes[link] = configNodes[link];
|
modifiedLinkNodes[link] = flowNodes[link];
|
||||||
linkChangedNodes[link] = configNodes[link];
|
linkChangedNodes[link] = flowNodes[link];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
markLinkedNodes(linkChangedNodes,modifiedLinkNodes,newLinks,configNodes);
|
markLinkedNodes(linkChangedNodes,modifiedLinkNodes,newLinks,flowNodes);
|
||||||
|
|
||||||
//config.forEach(function(n) {
|
//config.forEach(function(n) {
|
||||||
// console.log((changedNodes[n.id]!=null)?"[C]":"[ ]",(linkChangedNodes[n.id]!=null)?"[L]":"[ ]","[ ]",n.id,n.type,n.name);
|
// console.log((changedNodes[n.id]!=null)?"[C]":"[ ]",(linkChangedNodes[n.id]!=null)?"[L]":"[ ]","[ ]",n.id,n.type,n.name);
|
||||||
@ -643,14 +665,14 @@ Flow.prototype.diffFlow = function(config) {
|
|||||||
//});
|
//});
|
||||||
|
|
||||||
var diff = {
|
var diff = {
|
||||||
deleted: Object.keys(deletedNodes).filter(function(id) { return deletedNodes[id].type != "subflow" && (!deletedNodes[id].z || configNodes[deletedNodes[id].z].type != "subflow")}),
|
deleted: Object.keys(deletedNodes).filter(function(id) { return deletedNodes[id].type != "subflow" && (!deletedNodes[id].z || flowNodes[deletedNodes[id].z].type != "subflow")}),
|
||||||
changed: Object.keys(changedNodes).filter(function(id) { return changedNodes[id].type != "subflow" && (!changedNodes[id].z || configNodes[changedNodes[id].z].type != "subflow")}),
|
changed: Object.keys(changedNodes).filter(function(id) { return changedNodes[id].type != "subflow" && (!changedNodes[id].z || flowNodes[changedNodes[id].z].type != "subflow")}),
|
||||||
linked: Object.keys(linkChangedNodes).filter(function(id) { return linkChangedNodes[id].type != "subflow" && (!linkChangedNodes[id].z || configNodes[linkChangedNodes[id].z].type != "subflow")}),
|
linked: Object.keys(linkChangedNodes).filter(function(id) { return linkChangedNodes[id].type != "subflow" && (!linkChangedNodes[id].z || flowNodes[linkChangedNodes[id].z].type != "subflow")}),
|
||||||
wiringChanged: []
|
wiringChanged: []
|
||||||
}
|
}
|
||||||
|
|
||||||
config.forEach(function(n) {
|
config.forEach(function(n) {
|
||||||
if (!configNodes[n.z] || configNodes[n.z].type != "subflow") {
|
if (!flowNodes[n.z] || flowNodes[n.z].type != "subflow") {
|
||||||
var originalNode = flow.allNodes[n.id];
|
var originalNode = flow.allNodes[n.id];
|
||||||
if (originalNode && !redUtil.compareObjects(originalNode.wires,n.wires)) {
|
if (originalNode && !redUtil.compareObjects(originalNode.wires,n.wires)) {
|
||||||
diff.wiringChanged.push(n.id);
|
diff.wiringChanged.push(n.id);
|
||||||
|
Loading…
Reference in New Issue
Block a user