@node-red/editor-client 4.1.1 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/public/red/about +21 -0
- package/public/red/red.js +230 -216
- package/public/red/red.min.js +3 -3
package/package.json
CHANGED
package/public/red/about
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
+
#### 4.1.2: Maintenance Release
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
Editor
|
|
5
|
+
|
|
6
|
+
- Fix invalid `dirty` state during redo after deployment (#5352) @GogoVega
|
|
7
|
+
- Fix up port event cancelling on node-select (#5338) @knolleary
|
|
8
|
+
- Add selection-to-subflow context menu item (#5337) @knolleary
|
|
9
|
+
- Show subflow input label on virtual port (#5325) @knolleary
|
|
10
|
+
- Clear suggestions on node/port mouse down (#5323) @knolleary
|
|
11
|
+
- Fix lock icon for read-only user (#5336) @knolleary
|
|
12
|
+
- Fix `RED.comms.subscribe` callback on error (#5313) @GogoVega
|
|
13
|
+
|
|
14
|
+
Runtime
|
|
15
|
+
|
|
16
|
+
- ci: add files generated by npm test to .gitignore (#5230) @bryopsida
|
|
17
|
+
- Handle plugin name in `plugins.getConfig` (#5276) @GogoVega
|
|
18
|
+
- Update express version to 4.22.1 (#5365) @hardillb
|
|
19
|
+
- Improved readme (#5340) @dimitrieh
|
|
20
|
+
- Fix race condition in projects initialization by returning gitTools.init() promise (#5315) @stoprocent
|
|
21
|
+
|
|
1
22
|
#### 4.1.1: Maintenance Release
|
|
2
23
|
|
|
3
24
|
Editor
|
package/public/red/red.js
CHANGED
|
@@ -2139,8 +2139,8 @@ RED.comms = (function() {
|
|
|
2139
2139
|
subscribers[i](msg.topic,msg.data);
|
|
2140
2140
|
} catch (error) {
|
|
2141
2141
|
// need to decide what to do with this uncaught error
|
|
2142
|
-
console.warn('Uncaught error from RED.comms.subscribe: ' +
|
|
2143
|
-
console.warn(
|
|
2142
|
+
console.warn('Uncaught error from RED.comms.subscribe: ' + error.toString())
|
|
2143
|
+
console.warn(error)
|
|
2144
2144
|
}
|
|
2145
2145
|
}
|
|
2146
2146
|
}
|
|
@@ -9321,7 +9321,15 @@ RED.history = (function() {
|
|
|
9321
9321
|
}
|
|
9322
9322
|
}
|
|
9323
9323
|
}
|
|
9324
|
-
|
|
9324
|
+
if (ev.node.type === 'subflow') {
|
|
9325
|
+
// Ensure ports get a refresh in case of a label change
|
|
9326
|
+
if (ev.changes.inputLabels) {
|
|
9327
|
+
ev.node.in.forEach(function(input) { input.dirty = true; });
|
|
9328
|
+
}
|
|
9329
|
+
if (ev.changes.outputLabels) {
|
|
9330
|
+
ev.node.out.forEach(function(output) { output.dirty = true; });
|
|
9331
|
+
}
|
|
9332
|
+
}
|
|
9325
9333
|
ev.node.dirty = true;
|
|
9326
9334
|
ev.node.changed = ev.changed;
|
|
9327
9335
|
|
|
@@ -9632,8 +9640,8 @@ RED.history = (function() {
|
|
|
9632
9640
|
return {
|
|
9633
9641
|
//TODO: this function is a placeholder until there is a 'save' event that can be listened to
|
|
9634
9642
|
markAllDirty: function() {
|
|
9635
|
-
for (
|
|
9636
|
-
|
|
9643
|
+
for (const event of [...undoHistory, ...redoHistory]) {
|
|
9644
|
+
event.dirty = true;
|
|
9637
9645
|
}
|
|
9638
9646
|
},
|
|
9639
9647
|
list: function() {
|
|
@@ -17791,7 +17799,7 @@ RED.deploy = (function() {
|
|
|
17791
17799
|
}
|
|
17792
17800
|
|
|
17793
17801
|
function updateLockedState() {
|
|
17794
|
-
if (RED.
|
|
17802
|
+
if (!RED.user.hasPermission('flows.write')) {
|
|
17795
17803
|
$(".red-ui-deploy-button-group").addClass("readOnly");
|
|
17796
17804
|
$("#red-ui-header-button-deploy").addClass("disabled");
|
|
17797
17805
|
} else {
|
|
@@ -22742,6 +22750,7 @@ RED.view = (function() {
|
|
|
22742
22750
|
let suggestedLinks = [];
|
|
22743
22751
|
let suggestedJunctions = [];
|
|
22744
22752
|
|
|
22753
|
+
let forceFullRedraw = false
|
|
22745
22754
|
// Note: these are the permitted status colour aliases. The actual RGB values
|
|
22746
22755
|
// are set in the CSS - flow.scss/colors.scss
|
|
22747
22756
|
const status_colours = {
|
|
@@ -25852,6 +25861,7 @@ RED.view = (function() {
|
|
|
25852
25861
|
|
|
25853
25862
|
function portMouseDown(d,portType,portIndex, evt) {
|
|
25854
25863
|
if (RED.view.DEBUG) { console.warn("portMouseDown", mouse_mode,d,portType,portIndex); }
|
|
25864
|
+
clearSuggestedFlow();
|
|
25855
25865
|
RED.contextMenu.hide();
|
|
25856
25866
|
evt = evt || d3.event;
|
|
25857
25867
|
if (evt === 1) {
|
|
@@ -26275,9 +26285,9 @@ RED.view = (function() {
|
|
|
26275
26285
|
return tooltip;
|
|
26276
26286
|
}
|
|
26277
26287
|
|
|
26278
|
-
function portMouseOver(port,d,portType,portIndex) {
|
|
26288
|
+
function portMouseOver(port,d,portType,portIndex, event) {
|
|
26279
26289
|
if (mouse_mode === RED.state.SELECTING_NODE) {
|
|
26280
|
-
d3.event.stopPropagation();
|
|
26290
|
+
(d3.event || event).stopPropagation();
|
|
26281
26291
|
return;
|
|
26282
26292
|
}
|
|
26283
26293
|
clearTimeout(portLabelHoverTimeout);
|
|
@@ -26316,9 +26326,9 @@ RED.view = (function() {
|
|
|
26316
26326
|
}
|
|
26317
26327
|
port.classed("red-ui-flow-port-hovered",active);
|
|
26318
26328
|
}
|
|
26319
|
-
function portMouseOut(port,d,portType,portIndex) {
|
|
26329
|
+
function portMouseOut(port,d,portType,portIndex, event) {
|
|
26320
26330
|
if (mouse_mode === RED.state.SELECTING_NODE) {
|
|
26321
|
-
d3.event.stopPropagation();
|
|
26331
|
+
(d3.event || event).stopPropagation();
|
|
26322
26332
|
return;
|
|
26323
26333
|
}
|
|
26324
26334
|
clearTimeout(portLabelHoverTimeout);
|
|
@@ -26436,6 +26446,7 @@ RED.view = (function() {
|
|
|
26436
26446
|
}
|
|
26437
26447
|
function nodeMouseDown(d) {
|
|
26438
26448
|
if (RED.view.DEBUG) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|
26449
|
+
clearSuggestedFlow()
|
|
26439
26450
|
focusView();
|
|
26440
26451
|
RED.contextMenu.hide();
|
|
26441
26452
|
if (d3.event.button === 1) {
|
|
@@ -27061,130 +27072,211 @@ RED.view = (function() {
|
|
|
27061
27072
|
}
|
|
27062
27073
|
}
|
|
27063
27074
|
|
|
27075
|
+
function buildSubflowPort (d) {
|
|
27076
|
+
const NODE_TYPE = d.direction === "in" ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT;
|
|
27077
|
+
// PORT_TYPE is the 'opposite' of NODE_TYPE
|
|
27078
|
+
const PORT_TYPE = NODE_TYPE === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT;
|
|
27079
|
+
var node = d3.select(this);
|
|
27080
|
+
var nodeContents = document.createDocumentFragment();
|
|
27081
|
+
|
|
27082
|
+
d.h = 40;
|
|
27083
|
+
d.resize = true;
|
|
27084
|
+
d.dirty = true;
|
|
27085
|
+
|
|
27086
|
+
var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27087
|
+
mainRect.__data__ = d;
|
|
27088
|
+
mainRect.setAttribute("class", "red-ui-flow-subflow-port");
|
|
27089
|
+
mainRect.setAttribute("rx", 8);
|
|
27090
|
+
mainRect.setAttribute("ry", 8);
|
|
27091
|
+
mainRect.setAttribute("width", 40);
|
|
27092
|
+
mainRect.setAttribute("height", 40);
|
|
27093
|
+
node[0][0].__mainRect__ = mainRect;
|
|
27094
|
+
d3.select(mainRect)
|
|
27095
|
+
.on("mouseup",nodeMouseUp)
|
|
27096
|
+
.on("mousedown",nodeMouseDown)
|
|
27097
|
+
.on("touchstart",nodeTouchStart)
|
|
27098
|
+
.on("touchend",nodeTouchEnd)
|
|
27099
|
+
nodeContents.appendChild(mainRect);
|
|
27100
|
+
|
|
27101
|
+
const port_label_group = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27102
|
+
port_label_group.setAttribute("x",0);
|
|
27103
|
+
port_label_group.setAttribute("y",0);
|
|
27104
|
+
node[0][0].__portLabelGroup__ = port_label_group;
|
|
27105
|
+
|
|
27106
|
+
const port_label = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27107
|
+
port_label.setAttribute("class","red-ui-flow-port-label");
|
|
27108
|
+
port_label.style["font-size"] = "10px";
|
|
27109
|
+
port_label.textContent = NODE_TYPE === PORT_TYPE_INPUT? "input" : "output";
|
|
27110
|
+
port_label_group.appendChild(port_label);
|
|
27111
|
+
node[0][0].__portLabel__ = port_label;
|
|
27112
|
+
|
|
27113
|
+
if (NODE_TYPE === PORT_TYPE_OUTPUT) {
|
|
27114
|
+
const port_number = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27115
|
+
port_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
|
|
27116
|
+
port_number.setAttribute("x",0);
|
|
27117
|
+
port_number.setAttribute("y",0);
|
|
27118
|
+
port_number.textContent = d.i+1;
|
|
27119
|
+
port_label_group.appendChild(port_number);
|
|
27120
|
+
node[0][0].__portNumber__ = port_number;
|
|
27121
|
+
}
|
|
27122
|
+
|
|
27123
|
+
const port_border = document.createElementNS("http://www.w3.org/2000/svg","path");
|
|
27124
|
+
port_border.setAttribute("d","M 40 1 l 0 38")
|
|
27125
|
+
port_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
|
|
27126
|
+
port_label_group.appendChild(port_border);
|
|
27127
|
+
node[0][0].__portBorder__ = port_border;
|
|
27128
|
+
|
|
27129
|
+
nodeContents.appendChild(port_label_group);
|
|
27130
|
+
|
|
27131
|
+
var text = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27132
|
+
text.setAttribute("class","red-ui-flow-port-label");
|
|
27133
|
+
text.setAttribute("transform","translate(38,0)");
|
|
27134
|
+
text.setAttribute('style', 'fill : #888'); // hard coded here!
|
|
27135
|
+
node[0][0].__textGroup__ = text;
|
|
27136
|
+
nodeContents.append(text);
|
|
27137
|
+
|
|
27138
|
+
var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27139
|
+
portEl.setAttribute('transform','translate(-5,15)')
|
|
27140
|
+
|
|
27141
|
+
var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27142
|
+
port.setAttribute("class","red-ui-flow-port");
|
|
27143
|
+
port.setAttribute("rx",3);
|
|
27144
|
+
port.setAttribute("ry",3);
|
|
27145
|
+
port.setAttribute("width",10);
|
|
27146
|
+
port.setAttribute("height",10);
|
|
27147
|
+
portEl.appendChild(port);
|
|
27148
|
+
port.__data__ = d;
|
|
27149
|
+
|
|
27150
|
+
d3.select(port)
|
|
27151
|
+
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE,0);} )
|
|
27152
|
+
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE,0);d3.event.preventDefault();} )
|
|
27153
|
+
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE,0);})
|
|
27154
|
+
.on("touchend",function(d,i){portMouseUp(d,PORT_TYPE,0);d3.event.preventDefault();} )
|
|
27155
|
+
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE,0);})
|
|
27156
|
+
.on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE,0);});
|
|
27157
|
+
|
|
27158
|
+
node[0][0].__port__ = portEl
|
|
27159
|
+
nodeContents.appendChild(portEl);
|
|
27160
|
+
node[0][0].appendChild(nodeContents);
|
|
27161
|
+
}
|
|
27162
|
+
function updateSubflowPort (d) {
|
|
27163
|
+
if (d.dirty) {
|
|
27164
|
+
const port_height = 40;
|
|
27165
|
+
const NODE_TYPE = d.direction === "in" ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT;
|
|
27166
|
+
// PORT_TYPE is the 'opposite' of NODE_TYPE
|
|
27167
|
+
const PORT_TYPE = NODE_TYPE === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT;
|
|
27168
|
+
|
|
27169
|
+
var label = getPortLabel(activeSubflow, NODE_TYPE, d.i) || "";
|
|
27170
|
+
var hideLabel = (label.length < 1)
|
|
27171
|
+
var labelParts;
|
|
27172
|
+
if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label) {
|
|
27173
|
+
labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
|
27174
|
+
if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
|
|
27175
|
+
d.resize = true;
|
|
27176
|
+
}
|
|
27177
|
+
this.__label__ = label;
|
|
27178
|
+
this.__labelLineCount__ = labelParts.lines.length;
|
|
27179
|
+
|
|
27180
|
+
if (hideLabel) {
|
|
27181
|
+
d.h = Math.max(port_height,(d.outputs || 0) * 15);
|
|
27182
|
+
} else {
|
|
27183
|
+
d.h = Math.max(6+24*labelParts.lines.length,(d.outputs || 0) * 15, port_height);
|
|
27184
|
+
}
|
|
27185
|
+
this.__hideLabel__ = hideLabel;
|
|
27186
|
+
}
|
|
27187
|
+
|
|
27188
|
+
if (d.resize) {
|
|
27189
|
+
var ow = d.w;
|
|
27190
|
+
if (hideLabel) {
|
|
27191
|
+
d.w = port_height;
|
|
27192
|
+
} else {
|
|
27193
|
+
d.w = Math.max(port_height,20*(Math.ceil((labelParts.width+50+7)/20)) );
|
|
27194
|
+
}
|
|
27195
|
+
if (ow !== undefined) {
|
|
27196
|
+
d.x += (d.w-ow)/2;
|
|
27197
|
+
}
|
|
27198
|
+
d.resize = false;
|
|
27199
|
+
}
|
|
27200
|
+
|
|
27201
|
+
this.setAttribute("transform", "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")");
|
|
27202
|
+
// This might be the first redraw after a node has been click-dragged to start a move.
|
|
27203
|
+
// So its selected state might have changed since the last redraw.
|
|
27204
|
+
this.classList.toggle("red-ui-flow-node-selected", !!d.selected )
|
|
27205
|
+
if (mouse_mode != RED.state.MOVING_ACTIVE) {
|
|
27206
|
+
this.classList.toggle("red-ui-flow-node-disabled", d.d === true);
|
|
27207
|
+
this.__mainRect__.setAttribute("width", d.w)
|
|
27208
|
+
this.__mainRect__.setAttribute("height", d.h)
|
|
27209
|
+
this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
|
|
27210
|
+
|
|
27211
|
+
if (labelParts) {
|
|
27212
|
+
// The label has changed
|
|
27213
|
+
var sa = labelParts.lines;
|
|
27214
|
+
var sn = labelParts.lines.length;
|
|
27215
|
+
var textLines = this.__textGroup__.childNodes;
|
|
27216
|
+
while(textLines.length > sn) {
|
|
27217
|
+
textLines[textLines.length-1].remove();
|
|
27218
|
+
}
|
|
27219
|
+
for (var i=0; i<sn; i++) {
|
|
27220
|
+
if (i===textLines.length) {
|
|
27221
|
+
var line = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27222
|
+
line.setAttribute("class","red-ui-flow-node-label-text");
|
|
27223
|
+
line.setAttribute("x",0);
|
|
27224
|
+
line.setAttribute("y",i*24);
|
|
27225
|
+
this.__textGroup__.appendChild(line);
|
|
27226
|
+
}
|
|
27227
|
+
textLines[i].textContent = sa[i];
|
|
27228
|
+
}
|
|
27229
|
+
}
|
|
27230
|
+
|
|
27231
|
+
var textClass = "red-ui-flow-node-label"+(hideLabel?" hide":"");
|
|
27232
|
+
this.__textGroup__.setAttribute("class", textClass);
|
|
27233
|
+
var yp = d.h / 2 - (this.__labelLineCount__ / 2) * 24 + 13;
|
|
27234
|
+
|
|
27235
|
+
// this.__textGroup__.classList.remove("red-ui-flow-node-label-right");
|
|
27236
|
+
this.__textGroup__.setAttribute("transform", "translate(48,"+yp+")");
|
|
27237
|
+
|
|
27238
|
+
this.__portBorder__.setAttribute("d","M 40 1 l 0 "+(hideLabel?0:(d.h - 2)));
|
|
27239
|
+
const portX = PORT_TYPE === PORT_TYPE_OUTPUT ? d.w - 5 : -5
|
|
27240
|
+
this.__port__.setAttribute("transform","translate("+portX+","+((d.h/2)-5)+")");
|
|
27241
|
+
if (NODE_TYPE === PORT_TYPE_OUTPUT) {
|
|
27242
|
+
this.__portLabel__.setAttribute("transform","translate(20,"+((d.h/2)-8)+")");
|
|
27243
|
+
this.__portNumber__.setAttribute("transform","translate(20,"+((d.h/2)+7)+")");
|
|
27244
|
+
this.__portNumber__.textContent = d.i+1;
|
|
27245
|
+
} else {
|
|
27246
|
+
this.__portLabel__.setAttribute("transform","translate(20,"+(d.h/2)+")");
|
|
27247
|
+
}
|
|
27248
|
+
}
|
|
27249
|
+
d.dirty = false;
|
|
27250
|
+
return true
|
|
27251
|
+
}
|
|
27252
|
+
return false
|
|
27253
|
+
}
|
|
27254
|
+
|
|
27064
27255
|
function _redraw() {
|
|
27065
27256
|
eventLayer.attr("transform","scale("+scaleFactor+")");
|
|
27066
27257
|
outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor);
|
|
27067
27258
|
|
|
27068
27259
|
// Don't bother redrawing nodes if we're drawing links
|
|
27069
|
-
if (showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {
|
|
27070
|
-
|
|
27260
|
+
if (forceFullRedraw || showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {
|
|
27261
|
+
forceFullRedraw = false
|
|
27071
27262
|
var dirtyNodes = {};
|
|
27072
27263
|
|
|
27073
27264
|
if (activeSubflow) {
|
|
27074
27265
|
var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;});
|
|
27075
27266
|
subflowOutputs.exit().remove();
|
|
27076
27267
|
var outGroup = subflowOutputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-output")
|
|
27077
|
-
outGroup.each(
|
|
27078
|
-
var node = d3.select(this);
|
|
27079
|
-
var nodeContents = document.createDocumentFragment();
|
|
27080
|
-
|
|
27081
|
-
d.h = 40;
|
|
27082
|
-
d.resize = true;
|
|
27083
|
-
d.dirty = true;
|
|
27084
|
-
|
|
27085
|
-
var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27086
|
-
mainRect.__data__ = d;
|
|
27087
|
-
mainRect.setAttribute("class", "red-ui-flow-subflow-port");
|
|
27088
|
-
mainRect.setAttribute("rx", 8);
|
|
27089
|
-
mainRect.setAttribute("ry", 8);
|
|
27090
|
-
mainRect.setAttribute("width", 40);
|
|
27091
|
-
mainRect.setAttribute("height", 40);
|
|
27092
|
-
node[0][0].__mainRect__ = mainRect;
|
|
27093
|
-
d3.select(mainRect)
|
|
27094
|
-
.on("mouseup",nodeMouseUp)
|
|
27095
|
-
.on("mousedown",nodeMouseDown)
|
|
27096
|
-
.on("touchstart",nodeTouchStart)
|
|
27097
|
-
.on("touchend",nodeTouchEnd)
|
|
27098
|
-
nodeContents.appendChild(mainRect);
|
|
27099
|
-
|
|
27100
|
-
var output_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27101
|
-
output_groupEl.setAttribute("x",0);
|
|
27102
|
-
output_groupEl.setAttribute("y",0);
|
|
27103
|
-
node[0][0].__outputLabelGroup__ = output_groupEl;
|
|
27104
|
-
|
|
27105
|
-
var output_output = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27106
|
-
output_output.setAttribute("class","red-ui-flow-port-label");
|
|
27107
|
-
output_output.style["font-size"] = "10px";
|
|
27108
|
-
output_output.textContent = "output";
|
|
27109
|
-
output_groupEl.appendChild(output_output);
|
|
27110
|
-
node[0][0].__outputOutput__ = output_output;
|
|
27111
|
-
|
|
27112
|
-
var output_number = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27113
|
-
output_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
|
|
27114
|
-
output_number.setAttribute("x",0);
|
|
27115
|
-
output_number.setAttribute("y",0);
|
|
27116
|
-
output_number.textContent = d.i+1;
|
|
27117
|
-
output_groupEl.appendChild(output_number);
|
|
27118
|
-
node[0][0].__outputNumber__ = output_number;
|
|
27119
|
-
|
|
27120
|
-
var output_border = document.createElementNS("http://www.w3.org/2000/svg","path");
|
|
27121
|
-
output_border.setAttribute("d","M 40 1 l 0 38")
|
|
27122
|
-
output_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
|
|
27123
|
-
output_groupEl.appendChild(output_border);
|
|
27124
|
-
node[0][0].__outputBorder__ = output_border;
|
|
27125
|
-
|
|
27126
|
-
nodeContents.appendChild(output_groupEl);
|
|
27127
|
-
|
|
27128
|
-
var text = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27129
|
-
text.setAttribute("class","red-ui-flow-port-label");
|
|
27130
|
-
text.setAttribute("transform","translate(38,0)");
|
|
27131
|
-
text.setAttribute('style', 'fill : #888'); // hard coded here!
|
|
27132
|
-
node[0][0].__textGroup__ = text;
|
|
27133
|
-
nodeContents.append(text);
|
|
27134
|
-
|
|
27135
|
-
var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27136
|
-
portEl.setAttribute('transform','translate(-5,15)')
|
|
27137
|
-
|
|
27138
|
-
var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27139
|
-
port.setAttribute("class","red-ui-flow-port");
|
|
27140
|
-
port.setAttribute("rx",3);
|
|
27141
|
-
port.setAttribute("ry",3);
|
|
27142
|
-
port.setAttribute("width",10);
|
|
27143
|
-
port.setAttribute("height",10);
|
|
27144
|
-
portEl.appendChild(port);
|
|
27145
|
-
port.__data__ = d;
|
|
27146
|
-
|
|
27147
|
-
d3.select(port)
|
|
27148
|
-
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
|
|
27149
|
-
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
|
|
27150
|
-
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
|
|
27151
|
-
.on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
|
|
27152
|
-
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
|
|
27153
|
-
.on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
|
|
27154
|
-
|
|
27155
|
-
node[0][0].__port__ = portEl
|
|
27156
|
-
nodeContents.appendChild(portEl);
|
|
27157
|
-
node[0][0].appendChild(nodeContents);
|
|
27158
|
-
});
|
|
27268
|
+
outGroup.each(buildSubflowPort);
|
|
27159
27269
|
|
|
27160
27270
|
var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;});
|
|
27161
27271
|
subflowInputs.exit().remove();
|
|
27162
27272
|
var inGroup = subflowInputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-input").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
|
|
27163
|
-
inGroup.each(
|
|
27164
|
-
d.w=40;
|
|
27165
|
-
d.h=40;
|
|
27166
|
-
});
|
|
27167
|
-
inGroup.append("rect").attr("class","red-ui-flow-subflow-port").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40)
|
|
27168
|
-
// TODO: This is exactly the same set of handlers used for regular nodes - DRY
|
|
27169
|
-
.on("mouseup",nodeMouseUp)
|
|
27170
|
-
.on("mousedown",nodeMouseDown)
|
|
27171
|
-
.on("touchstart",nodeTouchStart)
|
|
27172
|
-
.on("touchend", nodeTouchEnd);
|
|
27173
|
-
|
|
27174
|
-
inGroup.append("g").attr('transform','translate(35,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
|
|
27175
|
-
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);} )
|
|
27176
|
-
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_OUTPUT,i);d3.event.preventDefault();} )
|
|
27177
|
-
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_OUTPUT,i);})
|
|
27178
|
-
.on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_OUTPUT,i);d3.event.preventDefault();} )
|
|
27179
|
-
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_OUTPUT,0);})
|
|
27180
|
-
.on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_OUTPUT,0);});
|
|
27181
|
-
|
|
27182
|
-
inGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",18).attr("y",20).style("font-size","10px").text("input");
|
|
27273
|
+
inGroup.each(buildSubflowPort);
|
|
27183
27274
|
|
|
27184
27275
|
var subflowStatus = nodeLayer.selectAll(".red-ui-flow-subflow-port-status").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;});
|
|
27185
27276
|
subflowStatus.exit().remove();
|
|
27186
27277
|
|
|
27187
27278
|
var statusGroup = subflowStatus.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-status").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
|
|
27279
|
+
// TODO: use buildSubflowPort/updateSubflowPort for status port
|
|
27188
27280
|
statusGroup.each(function(d,i) {
|
|
27189
27281
|
d.w=40;
|
|
27190
27282
|
d.h=40;
|
|
@@ -27206,104 +27298,16 @@ RED.view = (function() {
|
|
|
27206
27298
|
|
|
27207
27299
|
statusGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",22).attr("y",20).style("font-size","10px").text("status");
|
|
27208
27300
|
|
|
27209
|
-
subflowOutputs.each(function(d,i) {
|
|
27210
|
-
if (d
|
|
27211
|
-
|
|
27212
|
-
var port_height = 40;
|
|
27213
|
-
|
|
27214
|
-
var self = this;
|
|
27215
|
-
var thisNode = d3.select(this);
|
|
27216
|
-
|
|
27301
|
+
subflowOutputs.each(function (d,i) {
|
|
27302
|
+
if (updateSubflowPort.call(this, d)) {
|
|
27217
27303
|
dirtyNodes[d.id] = d;
|
|
27218
|
-
|
|
27219
|
-
var label = getPortLabel(activeSubflow, PORT_TYPE_OUTPUT, d.i) || "";
|
|
27220
|
-
var hideLabel = (label.length < 1)
|
|
27221
|
-
|
|
27222
|
-
var labelParts;
|
|
27223
|
-
if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label) {
|
|
27224
|
-
labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
|
27225
|
-
if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
|
|
27226
|
-
d.resize = true;
|
|
27227
|
-
}
|
|
27228
|
-
this.__label__ = label;
|
|
27229
|
-
this.__labelLineCount__ = labelParts.lines.length;
|
|
27230
|
-
|
|
27231
|
-
if (hideLabel) {
|
|
27232
|
-
d.h = Math.max(port_height,(d.outputs || 0) * 15);
|
|
27233
|
-
} else {
|
|
27234
|
-
d.h = Math.max(6+24*labelParts.lines.length,(d.outputs || 0) * 15, port_height);
|
|
27235
|
-
}
|
|
27236
|
-
this.__hideLabel__ = hideLabel;
|
|
27237
|
-
}
|
|
27238
|
-
|
|
27239
|
-
if (d.resize) {
|
|
27240
|
-
var ow = d.w;
|
|
27241
|
-
if (hideLabel) {
|
|
27242
|
-
d.w = port_height;
|
|
27243
|
-
} else {
|
|
27244
|
-
d.w = Math.max(port_height,20*(Math.ceil((labelParts.width+50+7)/20)) );
|
|
27245
|
-
}
|
|
27246
|
-
if (ow !== undefined) {
|
|
27247
|
-
d.x += (d.w-ow)/2;
|
|
27248
|
-
}
|
|
27249
|
-
d.resize = false;
|
|
27250
|
-
}
|
|
27251
|
-
|
|
27252
|
-
this.setAttribute("transform", "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")");
|
|
27253
|
-
// This might be the first redraw after a node has been click-dragged to start a move.
|
|
27254
|
-
// So its selected state might have changed since the last redraw.
|
|
27255
|
-
this.classList.toggle("red-ui-flow-node-selected", !!d.selected )
|
|
27256
|
-
if (mouse_mode != RED.state.MOVING_ACTIVE) {
|
|
27257
|
-
this.classList.toggle("red-ui-flow-node-disabled", d.d === true);
|
|
27258
|
-
this.__mainRect__.setAttribute("width", d.w)
|
|
27259
|
-
this.__mainRect__.setAttribute("height", d.h)
|
|
27260
|
-
this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
|
|
27261
|
-
|
|
27262
|
-
if (labelParts) {
|
|
27263
|
-
// The label has changed
|
|
27264
|
-
var sa = labelParts.lines;
|
|
27265
|
-
var sn = labelParts.lines.length;
|
|
27266
|
-
var textLines = this.__textGroup__.childNodes;
|
|
27267
|
-
while(textLines.length > sn) {
|
|
27268
|
-
textLines[textLines.length-1].remove();
|
|
27269
|
-
}
|
|
27270
|
-
for (var i=0; i<sn; i++) {
|
|
27271
|
-
if (i===textLines.length) {
|
|
27272
|
-
var line = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27273
|
-
line.setAttribute("class","red-ui-flow-node-label-text");
|
|
27274
|
-
line.setAttribute("x",0);
|
|
27275
|
-
line.setAttribute("y",i*24);
|
|
27276
|
-
this.__textGroup__.appendChild(line);
|
|
27277
|
-
}
|
|
27278
|
-
textLines[i].textContent = sa[i];
|
|
27279
|
-
}
|
|
27280
|
-
}
|
|
27281
|
-
|
|
27282
|
-
var textClass = "red-ui-flow-node-label"+(hideLabel?" hide":"");
|
|
27283
|
-
this.__textGroup__.setAttribute("class", textClass);
|
|
27284
|
-
var yp = d.h / 2 - (this.__labelLineCount__ / 2) * 24 + 13;
|
|
27285
|
-
|
|
27286
|
-
// this.__textGroup__.classList.remove("red-ui-flow-node-label-right");
|
|
27287
|
-
this.__textGroup__.setAttribute("transform", "translate(48,"+yp+")");
|
|
27288
|
-
|
|
27289
|
-
this.__outputBorder__.setAttribute("d","M 40 1 l 0 "+(hideLabel?0:(d.h - 2)));
|
|
27290
|
-
this.__port__.setAttribute("transform","translate(-5,"+((d.h/2)-5)+")");
|
|
27291
|
-
this.__outputOutput__.setAttribute("transform","translate(20,"+((d.h/2)-8)+")");
|
|
27292
|
-
this.__outputNumber__.setAttribute("transform","translate(20,"+((d.h/2)+7)+")");
|
|
27293
|
-
this.__outputNumber__.textContent = d.i+1;
|
|
27294
|
-
}
|
|
27295
|
-
d.dirty = false;
|
|
27296
27304
|
}
|
|
27297
|
-
})
|
|
27298
|
-
subflowInputs.each(function(d,i) {
|
|
27299
|
-
if (d
|
|
27300
|
-
var input = d3.select(this);
|
|
27301
|
-
input.classed("red-ui-flow-node-selected",function(d) { return d.selected; })
|
|
27302
|
-
input.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; });
|
|
27305
|
+
})
|
|
27306
|
+
subflowInputs.each(function (d,i) {
|
|
27307
|
+
if (updateSubflowPort.call(this, d)) {
|
|
27303
27308
|
dirtyNodes[d.id] = d;
|
|
27304
|
-
d.dirty = false;
|
|
27305
27309
|
}
|
|
27306
|
-
})
|
|
27310
|
+
})
|
|
27307
27311
|
subflowStatus.each(function(d,i) {
|
|
27308
27312
|
if (d.dirty) {
|
|
27309
27313
|
var output = d3.select(this);
|
|
@@ -29357,7 +29361,6 @@ RED.view = (function() {
|
|
|
29357
29361
|
refreshSuggestedFlow();
|
|
29358
29362
|
} else { // Anything else; clear the suggestion
|
|
29359
29363
|
clearSuggestedFlow();
|
|
29360
|
-
RED.view.redraw(true);
|
|
29361
29364
|
// manually push the event to the keyboard handler
|
|
29362
29365
|
RED.keyboard.handle(evt)
|
|
29363
29366
|
}
|
|
@@ -29366,7 +29369,6 @@ RED.view = (function() {
|
|
|
29366
29369
|
if (suggestion.clickToApply) {
|
|
29367
29370
|
$(window).on('mousedown.suggestedFlow', function (evnt) {
|
|
29368
29371
|
clearSuggestedFlow();
|
|
29369
|
-
RED.view.redraw(true);
|
|
29370
29372
|
})
|
|
29371
29373
|
}
|
|
29372
29374
|
}
|
|
@@ -29387,12 +29389,16 @@ RED.view = (function() {
|
|
|
29387
29389
|
}
|
|
29388
29390
|
|
|
29389
29391
|
function clearSuggestedFlow () {
|
|
29390
|
-
|
|
29391
|
-
|
|
29392
|
-
|
|
29393
|
-
|
|
29394
|
-
|
|
29395
|
-
|
|
29392
|
+
if (currentSuggestion) {
|
|
29393
|
+
$(window).off('mousedown.suggestedFlow');
|
|
29394
|
+
$(window).off('keydown.suggestedFlow')
|
|
29395
|
+
RED.keyboard.enable()
|
|
29396
|
+
currentSuggestion = null
|
|
29397
|
+
suggestedNodes = []
|
|
29398
|
+
suggestedLinks = []
|
|
29399
|
+
forceFullRedraw = true
|
|
29400
|
+
RED.view.redraw(true);
|
|
29401
|
+
}
|
|
29396
29402
|
}
|
|
29397
29403
|
|
|
29398
29404
|
function applySuggestedFlow () {
|
|
@@ -40019,6 +40025,9 @@ RED.editor = (function() {
|
|
|
40019
40025
|
changes.inputLabels = node.inputLabels;
|
|
40020
40026
|
node.inputLabels = newValue;
|
|
40021
40027
|
changed = true;
|
|
40028
|
+
if (node.type === "subflow") {
|
|
40029
|
+
node.in[0].dirty = true
|
|
40030
|
+
}
|
|
40022
40031
|
}
|
|
40023
40032
|
hasNonBlankLabel = false;
|
|
40024
40033
|
newValue = new Array(node.outputs);
|
|
@@ -49295,6 +49304,11 @@ RED.search = (function() {
|
|
|
49295
49304
|
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }
|
|
49296
49305
|
)
|
|
49297
49306
|
}
|
|
49307
|
+
if (hasSelection && canEdit) {
|
|
49308
|
+
menuItems.push(
|
|
49309
|
+
{ onselect: 'core:convert-to-subflow', label: RED._("menu.label.selectionToSubflow") }
|
|
49310
|
+
)
|
|
49311
|
+
}
|
|
49298
49312
|
menuItems.push(
|
|
49299
49313
|
{ onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") }
|
|
49300
49314
|
)
|