1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Allow a node to reorder its outputs and maintain links

Fixes #1031
This commit is contained in:
Nick O'Leary 2016-11-08 17:00:47 +00:00
parent 8a5db8ce4b
commit 6042395b81
3 changed files with 60 additions and 8 deletions

View File

@ -236,7 +236,16 @@ RED.history = (function() {
RED.editor.updateNodeProperties(n); RED.editor.updateNodeProperties(n);
}); });
} else { } else {
RED.editor.updateNodeProperties(ev.node); var outputMap;
if (ev.outputMap) {
outputMap = {};
for (var port in ev.outputMap) {
if (ev.outputMap.hasOwnProperty(port) && ev.outputMap[port] !== -1) {
outputMap[ev.outputMap[port]] = port;
}
}
}
RED.editor.updateNodeProperties(ev.node,outputMap);
RED.editor.validateNode(ev.node); RED.editor.validateNode(ev.node);
} }
if (ev.links) { if (ev.links) {

View File

@ -180,19 +180,31 @@ RED.editor = (function() {
* Marks the node as dirty and needing a size check. * Marks the node as dirty and needing a size check.
* Removes any links to non-existant outputs. * Removes any links to non-existant outputs.
* @param node - the node that has been updated * @param node - the node that has been updated
* @param outputMap - (optional) a map of old->new port numbers if wires should be moved
* @returns {array} the links that were removed due to this update * @returns {array} the links that were removed due to this update
*/ */
function updateNodeProperties(node) { function updateNodeProperties(node, outputMap) {
node.resize = true; node.resize = true;
node.dirty = true; node.dirty = true;
var removedLinks = []; var removedLinks = [];
if (node.ports) { if (node.ports) {
if (outputMap) {
RED.nodes.eachLink(function(l) {
if (l.source === node && outputMap.hasOwnProperty(l.sourcePort)) {
if (outputMap[l.sourcePort] === -1) {
removedLinks.push(l);
} else {
l.sourcePort = outputMap[l.sourcePort];
}
}
});
}
if (node.outputs < node.ports.length) { if (node.outputs < node.ports.length) {
while (node.outputs < node.ports.length) { while (node.outputs < node.ports.length) {
node.ports.pop(); node.ports.pop();
} }
RED.nodes.eachLink(function(l) { RED.nodes.eachLink(function(l) {
if (l.source === node && l.sourcePort >= node.outputs) { if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) {
removedLinks.push(l); removedLinks.push(l);
} }
}); });
@ -597,6 +609,7 @@ RED.editor = (function() {
var changed = false; var changed = false;
var wasDirty = RED.nodes.dirty(); var wasDirty = RED.nodes.dirty();
var d; var d;
var outputMap;
if (editing_node._def.oneditsave) { if (editing_node._def.oneditsave) {
var oldValues = {}; var oldValues = {};
@ -681,8 +694,14 @@ RED.editor = (function() {
var credsChanged = updateNodeCredentials(editing_node,credDefinition,prefix); var credsChanged = updateNodeCredentials(editing_node,credDefinition,prefix);
changed = changed || credsChanged; changed = changed || credsChanged;
} }
if (editing_node.hasOwnProperty("_outputs")) {
var removedLinks = updateNodeProperties(editing_node); outputMap = editing_node._outputs;
delete editing_node._outputs;
if (Object.keys(outputMap).length > 0) {
changed = true;
}
}
var removedLinks = updateNodeProperties(editing_node,outputMap);
if (changed) { if (changed) {
var wasChanged = editing_node.changed; var wasChanged = editing_node.changed;
editing_node.changed = true; editing_node.changed = true;
@ -712,6 +731,9 @@ RED.editor = (function() {
dirty:wasDirty, dirty:wasDirty,
changed:wasChanged changed:wasChanged
}; };
if (outputMap) {
historyEvent.outputMap = outputMap;
}
if (subflowInstances) { if (subflowInstances) {
historyEvent.subflow = { historyEvent.subflow = {
instances:subflowInstances instances:subflowInstances

View File

@ -115,7 +115,10 @@
$("#node-input-rule-container").css('min-height','250px').css('min-width','450px').editableList({ $("#node-input-rule-container").css('min-height','250px').css('min-width','450px').editableList({
addItem: function(container,i,opt) { addItem: function(container,i,opt) {
var rule = opt; if (!opt.hasOwnProperty('r')) {
opt.r = {};
}
var rule = opt.r;
if (!rule.hasOwnProperty('t')) { if (!rule.hasOwnProperty('t')) {
rule.t = 'eq'; rule.t = 'eq';
} }
@ -177,6 +180,12 @@
selectField.change(); selectField.change();
}, },
removeItem: function(opt) { removeItem: function(opt) {
if (opt.hasOwnProperty('i')) {
var removedList = $("#node-input-rule-container").data('removedList')||[];
removedList.push(opt.i);
$("#node-input-rule-container").data('removedList',removedList);
}
var rules = $("#node-input-rule-container").editableList('items'); var rules = $("#node-input-rule-container").editableList('items');
rules.each(function(i) { $(this).find(".node-input-rule-index").html(i+1); }); rules.each(function(i) { $(this).find(".node-input-rule-index").html(i+1); });
}, },
@ -191,15 +200,21 @@
for (var i=0;i<this.rules.length;i++) { for (var i=0;i<this.rules.length;i++) {
var rule = this.rules[i]; var rule = this.rules[i];
$("#node-input-rule-container").editableList('addItem',rule); $("#node-input-rule-container").editableList('addItem',{r:rule,i:i});
} }
}, },
oneditsave: function() { oneditsave: function() {
var rules = $("#node-input-rule-container").editableList('items'); var rules = $("#node-input-rule-container").editableList('items');
var ruleset; var ruleset;
var node = this; var node = this;
node.rules= []; node.rules = [];
var changedOutputs = {};
var removedList = $("#node-input-rule-container").data('removedList')||[];
removedList.forEach(function(i) {
changedOutputs[i] = -1;
});
rules.each(function(i) { rules.each(function(i) {
var ruleData = $(this).data('data');
var rule = $(this); var rule = $(this);
var type = rule.find("select").val(); var type = rule.find("select").val();
var r = {t:type}; var r = {t:type};
@ -217,8 +232,14 @@
r.case = rule.find(".node-input-rule-case").prop("checked"); r.case = rule.find(".node-input-rule-case").prop("checked");
} }
} }
if (ruleData.hasOwnProperty('i')) {
if (ruleData.i !== i) {
changedOutputs[ruleData.i] = i;
}
}
node.rules.push(r); node.rules.push(r);
}); });
this._outputs = changedOutputs;
this.outputs = node.rules.length; this.outputs = node.rules.length;
this.propertyType = $("#node-input-property").typedInput('type'); this.propertyType = $("#node-input-property").typedInput('type');
}, },