Merge branch 'dev' into pr_2042

This commit is contained in:
Nick O'Leary
2019-02-04 14:39:00 +00:00
29 changed files with 784 additions and 129 deletions

View File

@@ -273,6 +273,7 @@
"editSubflowProperties": "edit properties",
"input": "inputs:",
"output": "outputs:",
"status": "status node",
"deleteSubflow": "delete subflow",
"info": "Description",
"category": "Category",

View File

@@ -1,6 +1,6 @@
{
"name": "@node-red/editor-client",
"version": "0.20.0-beta.3",
"version": "0.20.0-beta.4",
"license": "Apache-2.0",
"repository": {
"type": "git",

View File

@@ -125,14 +125,20 @@ RED.history = (function() {
});
}
}
if (ev.subflow && ev.subflow.hasOwnProperty('instances')) {
ev.subflow.instances.forEach(function(n) {
var node = RED.nodes.node(n.id);
if (node) {
node.changed = n.changed;
node.dirty = true;
}
});
if (ev.subflow) {
if (ev.subflow.hasOwnProperty('instances')) {
ev.subflow.instances.forEach(function(n) {
var node = RED.nodes.node(n.id);
if (node) {
node.changed = n.changed;
node.dirty = true;
}
});
}
if (ev.subflow.hasOwnProperty('status')) {
subflow = RED.nodes.subflow(ev.subflow.id);
subflow.status = ev.subflow.status;
}
}
if (subflow) {
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
@@ -232,6 +238,11 @@ RED.history = (function() {
}
});
}
if (ev.subflow.hasOwnProperty('status')) {
if (ev.subflow.status) {
delete ev.node.status;
}
}
RED.editor.validateNode(ev.node);
RED.nodes.filterNodes({type:"subflow:"+ev.node.id}).forEach(function(n) {
n.inputs = ev.node.in.length;
@@ -262,6 +273,8 @@ RED.history = (function() {
} else if (ev.t == "createSubflow") {
if (ev.nodes) {
RED.nodes.filterNodes({z:ev.subflow.subflow.id}).forEach(function(n) {
n.x += ev.subflow.offsetX;
n.y += ev.subflow.offsetY;
n.z = ev.activeWorkspace;
n.dirty = true;
});
@@ -288,6 +301,7 @@ RED.history = (function() {
RED.workspaces.order(ev.order);
}
}
Object.keys(modifiedTabs).forEach(function(id) {
var subflow = RED.nodes.subflow(id);
if (subflow) {
@@ -301,6 +315,7 @@ RED.history = (function() {
RED.palette.refresh();
RED.workspaces.refresh();
RED.sidebar.config.refresh();
RED.subflow.refresh();
}
}

View File

@@ -575,6 +575,18 @@ RED.nodes = (function() {
node.icon = n.icon;
}
}
if (n.status) {
node.status = {x: n.status.x, y: n.status.y, wires:[]};
links.forEach(function(d) {
if (d.target === n.status) {
if (d.source.type != "subflow") {
node.status.wires.push({id:d.source.id, port:d.sourcePort})
} else {
node.status.wires.push({id:n.id, port:0})
}
}
});
}
return node;
}
@@ -855,6 +867,12 @@ RED.nodes = (function() {
output.i = i;
output.id = getID();
});
if (n.status) {
n.status.type = "subflow";
n.status.direction = "status";
n.status.z = n.id;
n.status.id = getID();
}
new_subflows.push(n);
addSubflow(n,createNewIds);
}
@@ -1194,6 +1212,19 @@ RED.nodes = (function() {
});
delete output.wires;
});
if (n.status) {
n.status.wires.forEach(function(wire) {
var link;
if (subflow_map[wire.id] && subflow_map[wire.id].id == n.id) {
link = {source:n.in[wire.port], sourcePort:wire.port,target:n.status};
} else {
link = {source:node_map[wire.id]||subflow_map[wire.id], sourcePort:wire.port,target:n.status};
}
addLink(link);
new_links.push(link);
});
delete n.status.wires;
}
}
RED.workspaces.refresh();

View File

@@ -687,7 +687,7 @@ RED.diff = (function() {
diff: remoteDiff
}
}
var selectState = "";
if (conflicted) {
@@ -1158,19 +1158,19 @@ RED.diff = (function() {
}
});
return {
var diff = {
currentConfig: currentConfig,
newConfig: newConfig,
added: added,
deleted: deleted,
changed: changed,
moved: moved
}
};
return diff;
}
function resolveDiffs(localDiff,remoteDiff) {
var conflicted = {};
var resolutions = {};
var diff = {
localDiff: localDiff,
remoteDiff: remoteDiff,
@@ -1348,7 +1348,7 @@ RED.diff = (function() {
if (node) {
nodeChangedStates[id] = node.changed;
}
localChangedStates[id] = true;
localChangedStates[id] = 1;
newConfig.push(remoteDiff.newConfig.all[id]);
}
} else {
@@ -1363,7 +1363,7 @@ RED.diff = (function() {
nodeChangedStates[id] = node.changed;
}
if (!localDiff.added.hasOwnProperty(id)) {
localChangedStates[id] = true;
localChangedStates[id] = 2;
newConfig.push(remoteDiff.newConfig.all[id]);
}
}
@@ -1376,24 +1376,42 @@ RED.diff = (function() {
}
function mergeDiff(diff) {
//console.log(diff);
var appliedDiff = applyDiff(diff);
var newConfig = appliedDiff.config;
var nodeChangedStates = appliedDiff.nodeChangedStates;
var localChangedStates = appliedDiff.localChangedStates;
var isDirty = RED.nodes.dirty();
var historyEvent = {
t:"replace",
config: RED.nodes.createCompleteNodeSet(),
changed: nodeChangedStates,
dirty: RED.nodes.dirty(),
dirty: isDirty,
rev: RED.nodes.version()
}
RED.history.push(historyEvent);
var originalFlow = RED.nodes.originalFlow();
// originalFlow is what the editor things it loaded
// - add any newly added nodes from remote diff as they are now part of the record
for (var id in diff.remoteDiff.added) {
if (diff.remoteDiff.added.hasOwnProperty(id)) {
if (diff.remoteDiff.newConfig.all.hasOwnProperty(id)) {
originalFlow.push(JSON.parse(JSON.stringify(diff.remoteDiff.newConfig.all[id])));
}
}
}
RED.nodes.clear();
var imported = RED.nodes.import(newConfig);
// Restore the original flow so subsequent merge resolutions can properly
// identify new-vs-old
RED.nodes.originalFlow(originalFlow);
imported[0].forEach(function(n) {
if (nodeChangedStates[n.id] || localChangedStates[n.id]) {
n.changed = true;
@@ -1402,11 +1420,16 @@ RED.diff = (function() {
RED.nodes.version(diff.remoteDiff.rev);
if (isDirty) {
RED.nodes.dirty(true);
}
RED.view.redraw(true);
RED.palette.refresh();
RED.workspaces.refresh();
RED.sidebar.config.refresh();
}
function showTestFlowDiff(index) {
if (index === 1) {
var localFlow = RED.nodes.createCompleteNodeSet();

View File

@@ -16,12 +16,12 @@
RED.subflow = (function() {
var _subflowEditTemplate = '<script type="text/x-red" data-template-name="subflow">'+
'<div class="form-row"><label for="node-input-name" data-i18n="[append]editor:common.label.name"><i class="fa fa-tag"></i> </label><input type="text" id="node-input-name"></div>'+
'<div class="form-row" style="margin-bottom: 0px;"><label style="width: auto;" data-i18n="[append]editor:editor-tab.env"><i class="fa fa-th-list"></i> </label></div>'+
'<div class="form-row node-input-env-container-row"><ol id="node-input-env-container"></ol></div>'+
'</script>';
var _subflowTemplateEditTemplate = '<script type="text/x-red" data-template-name="subflow-template">'+
'<div class="form-row"><i class="fa fa-tag"></i> <label for="subflow-input-name" data-i18n="common.label.name"></label><input type="text" id="subflow-input-name"></div>'+
'<div class="form-row"><i class="fa fa-folder-o"></i> <label for="subflow-input-category" data-i18n="editor:subflow.category"></label><select style="width: 250px;" id="subflow-input-category"></select><input style="display:none; margin-left: 10px; width:calc(100% - 250px)" type="text" id="subflow-input-custom-category"></div>'+
@@ -30,26 +30,22 @@ RED.subflow = (function() {
'<div class="form-row form-tips" id="subflow-dialog-user-count"></div>'+
'</script>';
function getSubflow() {
return RED.nodes.subflow(RED.workspaces.active());
}
function findAvailableSubflowIOPosition(subflow,isInput) {
var pos = {x:50,y:30};
if (!isInput) {
pos.x += 110;
}
for (var i=0;i<subflow.out.length+subflow.in.length;i++) {
var port;
if (i < subflow.out.length) {
port = subflow.out[i];
} else {
port = subflow.in[i-subflow.out.length];
}
var ports = [].concat(subflow.out).concat(subflow.in);
if (subflow.status) {
ports.push(subflow.status);
}
ports.sort(function(A,B) {
return A.x-B.x;
});
for (var i=0; i<ports.length; i++) {
var port = ports[i];
if (port.x == pos.x && port.y == pos.y) {
pos.x += 55;
i=0;
}
}
return pos;
@@ -197,6 +193,61 @@ RED.subflow = (function() {
return {subflowOutputs: removedSubflowOutputs, links: removedLinks}
}
function addSubflowStatus() {
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (subflow.status) {
return;
}
var position = findAvailableSubflowIOPosition(subflow,false);
var statusNode = {
type:"subflow",
direction:"status",
z:subflow.id,
x:position.x,
y:position.y,
id:RED.nodes.id()
};
subflow.status = statusNode;
subflow.dirty = true;
var wasDirty = RED.nodes.dirty();
var wasChanged = subflow.changed;
subflow.changed = true;
var result = refresh(true);
var historyEvent = {
t:'edit',
node:subflow,
dirty:wasDirty,
changed:wasChanged,
subflow: { status: true }
};
RED.history.push(historyEvent);
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw();
$("#workspace-subflow-status").prop("checked",!!subflow.status);
$("#workspace-subflow-status").parent().parent().toggleClass("active",!!subflow.status);
}
function removeSubflowStatus() {
var subflow = RED.nodes.subflow(RED.workspaces.active());
if (!subflow.status) {
return;
}
var subflowRemovedLinks = [];
RED.nodes.eachLink(function(l) {
if (l.target.type == "subflow" && l.target.z == subflow.id && l.target.direction == "status") {
subflowRemovedLinks.push(l);
}
});
subflowRemovedLinks.forEach(function(l) { RED.nodes.removeLink(l)});
delete subflow.status;
$("#workspace-subflow-status").prop("checked",!!subflow.status);
$("#workspace-subflow-status").parent().parent().toggleClass("active",!!subflow.status);
return { links: subflowRemovedLinks }
}
function refresh(markChange) {
var activeSubflow = RED.nodes.subflow(RED.workspaces.active());
refreshToolbar(activeSubflow);
@@ -225,12 +276,17 @@ RED.subflow = (function() {
}
}
}
function refreshToolbar(activeSubflow) {
if (activeSubflow) {
$("#workspace-subflow-input-add").toggleClass("active", activeSubflow.in.length !== 0);
$("#workspace-subflow-input-remove").toggleClass("active",activeSubflow.in.length === 0);
$("#workspace-subflow-output .spinner-value").text(activeSubflow.out.length);
$("#workspace-subflow-status").prop("checked",!!activeSubflow.status);
$("#workspace-subflow-status").parent().parent().toggleClass("active",!!activeSubflow.status);
}
}
@@ -238,22 +294,32 @@ RED.subflow = (function() {
var toolbar = $("#workspace-toolbar");
toolbar.empty();
// Edit properties
$('<a class="button" id="workspace-subflow-edit" href="#" data-i18n="[append]subflow.editSubflowProperties"><i class="fa fa-pencil"></i> </a>').appendTo(toolbar);
// Inputs
$('<span style="margin-left: 5px;" data-i18n="subflow.input"></span> '+
'<div style="display: inline-block;" class="button-group">'+
'<a id="workspace-subflow-input-remove" class="button active" href="#">0</a>'+
'<a id="workspace-subflow-input-add" class="button" href="#">1</a>'+
'</div>').appendTo(toolbar);
// Outputs
$('<span style="margin-left: 5px;" data-i18n="subflow.output"></span> <div id="workspace-subflow-output" style="display: inline-block;" class="button-group spinner-group">'+
'<a id="workspace-subflow-output-remove" class="button" href="#"><i class="fa fa-minus"></i></a>'+
'<div class="spinner-value">3</div>'+
'<a id="workspace-subflow-output-add" class="button" href="#"><i class="fa fa-plus"></i></a>'+
'</div>').appendTo(toolbar);
// Status
$('<span class="button-group"><span class="button" style="padding:0"><label for="workspace-subflow-status"><input id="workspace-subflow-status" type="checkbox"> <span data-i18n="subflow.status"></span></label></span></span>').appendTo(toolbar);
// $('<a class="button disabled" id="workspace-subflow-add-input" href="#" data-i18n="[append]subflow.input"><i class="fa fa-plus"></i> </a>').appendTo(toolbar);
// $('<a class="button" id="workspace-subflow-add-output" href="#" data-i18n="[append]subflow.output"><i class="fa fa-plus"></i> </a>').appendTo(toolbar);
// Delete
$('<a class="button" id="workspace-subflow-delete" href="#" data-i18n="[append]subflow.deleteSubflow"><i class="fa fa-trash"></i> </a>').appendTo(toolbar);
toolbar.i18n();
@@ -280,6 +346,7 @@ RED.subflow = (function() {
RED.view.redraw(true);
}
});
$("#workspace-subflow-output-add").click(function(event) {
event.preventDefault();
addSubflowOutput();
@@ -289,6 +356,7 @@ RED.subflow = (function() {
event.preventDefault();
addSubflowInput();
});
$("#workspace-subflow-input-remove").click(function(event) {
event.preventDefault();
var wasDirty = RED.nodes.dirty();
@@ -313,6 +381,33 @@ RED.subflow = (function() {
}
});
$("#workspace-subflow-status").change(function(evt) {
if (this.checked) {
addSubflowStatus();
} else {
var currentStatus = activeSubflow.status;
var wasChanged = activeSubflow.changed;
var result = removeSubflowStatus();
if (result) {
activeSubflow.changed = true;
var wasDirty = RED.nodes.dirty();
RED.history.push({
t:'delete',
links:result.links,
changed: wasChanged,
dirty:wasDirty,
subflow: {
id: activeSubflow.id,
status: currentStatus
}
});
RED.view.select();
RED.nodes.dirty(true);
RED.view.redraw();
}
}
})
$("#workspace-subflow-edit").click(function(event) {
RED.editor.editSubflow(RED.nodes.subflow(RED.workspaces.active()));
event.preventDefault();
@@ -334,6 +429,7 @@ RED.subflow = (function() {
$("#chart").css({"margin-top": "40px"});
$("#workspace-toolbar").show();
}
function hideWorkspaceToolbar() {
$("#workspace-toolbar").hide().empty();
$("#chart").css({"margin-top": "0"});
@@ -379,6 +475,7 @@ RED.subflow = (function() {
subflows: [activeSubflow]
}
}
function init() {
RED.events.on("workspace:change",function(event) {
var activeSubflow = RED.nodes.subflow(event.workspace);
@@ -436,6 +533,13 @@ RED.subflow = (function() {
RED.nodes.dirty(true);
}
function snapToGrid(x) {
if (RED.settings.get("editor").view['view-snap-grid']) {
x = Math.round(x / RED.view.gridSize()) * RED.view.gridSize();
}
return x;
}
function convertToSubflow() {
var selection = RED.view.selection();
if (!selection.nodes) {
@@ -451,7 +555,6 @@ RED.subflow = (function() {
var candidateOutputs = [];
var candidateInputNodes = {};
var boundingBox = [selection.nodes[0].x,
selection.nodes[0].y,
selection.nodes[0].x,
@@ -467,8 +570,14 @@ RED.subflow = (function() {
Math.max(boundingBox[3],n.y)
]
}
var offsetX = snapToGrid(boundingBox[0] - 200);
var offsetY = snapToGrid(boundingBox[1] - 80);
var center = [(boundingBox[2]+boundingBox[0]) / 2,(boundingBox[3]+boundingBox[1]) / 2];
var center = [
snapToGrid((boundingBox[2]+boundingBox[0]) / 2),
snapToGrid((boundingBox[3]+boundingBox[1]) / 2)
];
RED.nodes.eachLink(function(link) {
if (nodes[link.source.id] && nodes[link.target.id]) {
@@ -525,8 +634,8 @@ RED.subflow = (function() {
in: Object.keys(candidateInputNodes).map(function(v,i) { var index = i; return {
type:"subflow",
direction:"in",
x:candidateInputNodes[v].x-(candidateInputNodes[v].w/2)-80,
y:candidateInputNodes[v].y,
x:snapToGrid(candidateInputNodes[v].x-(candidateInputNodes[v].w/2)-80 - offsetX),
y:snapToGrid(candidateInputNodes[v].y - offsetY),
z:subflowId,
i:index,
id:RED.nodes.id(),
@@ -535,8 +644,8 @@ RED.subflow = (function() {
out: candidateOutputs.map(function(v,i) { var index = i; return {
type:"subflow",
direction:"in",
x:v.source.x+(v.source.w/2)+80,
y:v.source.y,
x:snapToGrid(v.source.x+(v.source.w/2)+80 - offsetX),
y:snapToGrid(v.source.y - offsetY),
z:subflowId,
i:index,
id:RED.nodes.id(),
@@ -611,6 +720,8 @@ RED.subflow = (function() {
return isLocalLink;
});
}
n.x -= offsetX;
n.y -= offsetY;
n.z = subflow.id;
}
@@ -619,7 +730,9 @@ RED.subflow = (function() {
nodes:[subflowInstance.id],
links:new_links,
subflow: {
subflow: subflow
subflow: subflow,
offsetX: offsetX,
offsetY: offsetY
},
activeWorkspace: RED.workspaces.active(),
@@ -633,8 +746,6 @@ RED.subflow = (function() {
RED.view.redraw(true);
}
return {
init: init,
createSubflow: createSubflow,
@@ -642,6 +753,7 @@ RED.subflow = (function() {
removeSubflow: removeSubflow,
refresh: refresh,
removeInput: removeSubflowInput,
removeOutput: removeSubflowOutput
removeOutput: removeSubflowOutput,
removeStatus: removeSubflowStatus
}
})();

View File

@@ -1261,6 +1261,13 @@ RED.view = (function() {
moving_set.push({n:n});
}
});
if (activeSubflow.status) {
activeSubflow.status.selected = (activeSubflow.status.x > x && activeSubflow.status.x < x2 && activeSubflow.status.y > y && activeSubflow.status.y < y2);
if (activeSubflow.status.selected) {
activeSubflow.status.dirty = true;
moving_set.push({n:activeSubflow.status});
}
}
}
updateSelection();
lasso.remove();
@@ -1367,6 +1374,13 @@ RED.view = (function() {
moving_set.push({n:n});
}
});
if (activeSubflow.status) {
if (!activeSubflow.status.selected) {
activeSubflow.status.selected = true;
activeSubflow.status.dirty = true;
moving_set.push({n:activeSubflow.status});
}
}
}
selected_link = null;
@@ -1552,6 +1566,7 @@ RED.view = (function() {
var removedLinks = [];
var removedSubflowOutputs = [];
var removedSubflowInputs = [];
var removedSubflowStatus = undefined;
var subflowInstances = [];
var startDirty = RED.nodes.dirty();
@@ -1573,6 +1588,8 @@ RED.view = (function() {
removedSubflowOutputs.push(node);
} else if (node.direction === "in") {
removedSubflowInputs.push(node);
} else if (node.direction === "status") {
removedSubflowStatus = node;
}
node.dirty = true;
}
@@ -1590,12 +1607,19 @@ RED.view = (function() {
removedLinks = removedLinks.concat(result.links);
}
}
if (removedSubflowStatus) {
result = RED.subflow.removeStatus();
if (result) {
removedLinks = removedLinks.concat(result.links);
}
}
var instances = RED.subflow.refresh(true);
if (instances) {
subflowInstances = instances.instances;
}
moving_set = [];
if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0) {
if (removedNodes.length > 0 || removedSubflowOutputs.length > 0 || removedSubflowInputs.length > 0 || removedSubflowStatus) {
RED.nodes.dirty(true);
}
}
@@ -1651,10 +1675,14 @@ RED.view = (function() {
subflowOutputs:removedSubflowOutputs,
subflowInputs:removedSubflowInputs,
subflow: {
id: activeSubflow?activeSubflow.id:undefined,
instances: subflowInstances
},
dirty:startDirty
};
if (removedSubflowStatus) {
historyEvent.subflow.status = removedSubflowStatus;
}
}
RED.history.push(historyEvent);
@@ -2420,6 +2448,49 @@ RED.view = (function() {
inGroup.append("svg:text").attr("class","port_label").attr("x",18).attr("y",20).style("font-size","10px").text("input");
var subflowStatus = nodeLayer.selectAll(".subflowstatus").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;});
subflowStatus.exit().remove();
var statusGroup = subflowStatus.enter().insert("svg:g").attr("class","node subflowstatus").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
statusGroup.each(function(d,i) {
d.w=40;
d.h=40;
});
statusGroup.append("rect").attr("class","subflowport").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40)
// TODO: This is exactly the same set of handlers used for regular nodes - DRY
.on("mouseup",nodeMouseUp)
.on("mousedown",nodeMouseDown)
.on("touchstart",function(d) {
var obj = d3.select(this);
var touch0 = d3.event.touches.item(0);
var pos = [touch0.pageX,touch0.pageY];
startTouchCenter = [touch0.pageX,touch0.pageY];
startTouchDistance = 0;
touchStartTime = setTimeout(function() {
showTouchMenu(obj,pos);
},touchLongPressTimeout);
nodeMouseDown.call(this,d)
})
.on("touchend", function(d) {
clearTimeout(touchStartTime);
touchStartTime = null;
if (RED.touch.radialMenu.active()) {
d3.event.stopPropagation();
return;
}
nodeMouseUp.call(this,d);
});
statusGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
.on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);} )
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
.on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
statusGroup.append("svg:text").attr("class","port_label").attr("x",22).attr("y",20).style("font-size","10px").text("status");
subflowOutputs.each(function(d,i) {
if (d.dirty) {
var output = d3.select(this);
@@ -2439,9 +2510,22 @@ RED.view = (function() {
d.dirty = false;
}
});
subflowStatus.each(function(d,i) {
if (d.dirty) {
var output = d3.select(this);
output.selectAll(".subflowport").classed("node_selected",function(d) { return d.selected; })
output.selectAll(".port_index").text(function(d){ return d.i+1});
output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; });
dirtyNodes[d.id] = d;
d.dirty = false;
}
});
} else {
nodeLayer.selectAll(".subflowoutput").remove();
nodeLayer.selectAll(".subflowinput").remove();
nodeLayer.selectAll(".subflowstatus").remove();
}
var node = nodeLayer.selectAll(".nodegroup").data(activeNodes,function(d){return d.id});
@@ -2703,6 +2787,8 @@ RED.view = (function() {
d.resize = false;
}
var thisNode = d3.select(this);
thisNode.classed("node_subflow",function(d) { return activeSubflow != null; })
//thisNode.selectAll(".centerDot").attr({"cx":function(d) { return d.w/2;},"cy":function(d){return d.h/2}});
thisNode.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; });
if (mouse_mode != RED.state.MOVING_ACTIVE) {
@@ -3004,6 +3090,9 @@ RED.view = (function() {
links.each(function(d) {
var link = d3.select(this);
if (d.added || d===selected_link || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) {
if (/link_line/.test(link.attr('class'))) {
link.classed("link_subflow", function(d) { return !d.link && activeSubflow });
}
link.attr("d",function(d){
var numOutputs = d.source.outputs || 1;
var sourcePort = d.sourcePort || 0;
@@ -3017,8 +3106,11 @@ RED.view = (function() {
// " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+
// (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+
// d.x2+" "+d.y2;
return generateLinkPath(d.x1,d.y1,d.x2,d.y2,1);
var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1);
if (/NaN/.test(path)) {
return ""
}
return path;
});
}
})

View File

@@ -33,6 +33,15 @@
transition: right 0.2s ease;
overflow: hidden;
label {
padding: 1px 8px;
margin: 0;
font-size: 12px;
}
input[type="checkbox"] {
margin: 0 3px 0 0 ;
padding: 0;
}
.button {
@include workspace-button;
margin-right: 10px;