@node-red/editor-client 4.1.1 → 4.1.3
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 +54 -0
- package/public/red/red.js +291 -226
- package/public/red/red.min.js +3 -3
- package/public/red/style.min.css +1 -1
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() {
|
|
@@ -10039,7 +10047,13 @@ RED.utils = (function() {
|
|
|
10039
10047
|
var copyPayload = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-clipboard"></i></button>').appendTo(copyTools).on("click", function(e) {
|
|
10040
10048
|
e.preventDefault();
|
|
10041
10049
|
e.stopPropagation();
|
|
10042
|
-
|
|
10050
|
+
var payloadToCopy;
|
|
10051
|
+
if (typeof msg === "number") {
|
|
10052
|
+
payloadToCopy = obj.find(".red-ui-debug-msg-type-number").first().text();
|
|
10053
|
+
} else {
|
|
10054
|
+
payloadToCopy = msg;
|
|
10055
|
+
}
|
|
10056
|
+
RED.clipboard.copyText(payloadToCopy, copyPayload, "clipboard.copyMessageValue");
|
|
10043
10057
|
})
|
|
10044
10058
|
RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload"));
|
|
10045
10059
|
if (enablePinning && strippedKey !== undefined && strippedKey !== '') {
|
|
@@ -10367,7 +10381,7 @@ RED.utils = (function() {
|
|
|
10367
10381
|
var sr = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(stringRow);
|
|
10368
10382
|
var stringEncoding = "";
|
|
10369
10383
|
try {
|
|
10370
|
-
stringEncoding =
|
|
10384
|
+
stringEncoding = new TextDecoder().decode(new Uint8Array(data));
|
|
10371
10385
|
} catch(err) {
|
|
10372
10386
|
console.log(err);
|
|
10373
10387
|
}
|
|
@@ -11660,8 +11674,10 @@ RED.utils = (function() {
|
|
|
11660
11674
|
var deleteButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(li);
|
|
11661
11675
|
$('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton);
|
|
11662
11676
|
li.addClass("red-ui-editableList-item-removable");
|
|
11677
|
+
var removeTip = RED.popover.tooltip(deleteButton, RED._("common.label.delete"));
|
|
11663
11678
|
deleteButton.on("click", function(evt) {
|
|
11664
11679
|
evt.preventDefault();
|
|
11680
|
+
removeTip.close();
|
|
11665
11681
|
var data = row.data('data');
|
|
11666
11682
|
li.addClass("red-ui-editableList-item-deleting")
|
|
11667
11683
|
li.fadeOut(300, function() {
|
|
@@ -11969,7 +11985,10 @@ RED.utils = (function() {
|
|
|
11969
11985
|
} else {
|
|
11970
11986
|
that._topList.find(".focus").removeClass("focus")
|
|
11971
11987
|
}
|
|
11972
|
-
target.treeList.label
|
|
11988
|
+
if (target.treeList.label) {
|
|
11989
|
+
target.treeList.label.addClass('focus')
|
|
11990
|
+
}
|
|
11991
|
+
that.reveal(target);
|
|
11973
11992
|
}
|
|
11974
11993
|
});
|
|
11975
11994
|
this._data = [];
|
|
@@ -12660,6 +12679,10 @@ RED.utils = (function() {
|
|
|
12660
12679
|
}
|
|
12661
12680
|
|
|
12662
12681
|
that._topList.find(".focus").removeClass("focus");
|
|
12682
|
+
|
|
12683
|
+
if (item.treeList.label) {
|
|
12684
|
+
item.treeList.label.addClass("focus");
|
|
12685
|
+
}
|
|
12663
12686
|
|
|
12664
12687
|
if (triggerEvent !== false) {
|
|
12665
12688
|
this._trigger("select",null,item)
|
|
@@ -14759,12 +14782,18 @@ RED.tabs = (function() {
|
|
|
14759
14782
|
}
|
|
14760
14783
|
function activatePreviousTab() {
|
|
14761
14784
|
var previous = findPreviousVisibleTab();
|
|
14785
|
+
if (previous.length === 0) {
|
|
14786
|
+
previous = ul.find("li.red-ui-tab:not(.hide-tab)").last();
|
|
14787
|
+
}
|
|
14762
14788
|
if (previous.length > 0) {
|
|
14763
14789
|
activateTab(previous.find("a"));
|
|
14764
14790
|
}
|
|
14765
14791
|
}
|
|
14766
14792
|
function activateNextTab() {
|
|
14767
14793
|
var next = findNextVisibleTab();
|
|
14794
|
+
if (next.length === 0) {
|
|
14795
|
+
next = ul.find("li.red-ui-tab:not(.hide-tab)").first();
|
|
14796
|
+
}
|
|
14768
14797
|
if (next.length > 0) {
|
|
14769
14798
|
activateTab(next.find("a"));
|
|
14770
14799
|
}
|
|
@@ -17791,7 +17820,7 @@ RED.deploy = (function() {
|
|
|
17791
17820
|
}
|
|
17792
17821
|
|
|
17793
17822
|
function updateLockedState() {
|
|
17794
|
-
if (RED.
|
|
17823
|
+
if (!RED.user.hasPermission('flows.write')) {
|
|
17795
17824
|
$(".red-ui-deploy-button-group").addClass("readOnly");
|
|
17796
17825
|
$("#red-ui-header-button-deploy").addClass("disabled");
|
|
17797
17826
|
} else {
|
|
@@ -22742,6 +22771,7 @@ RED.view = (function() {
|
|
|
22742
22771
|
let suggestedLinks = [];
|
|
22743
22772
|
let suggestedJunctions = [];
|
|
22744
22773
|
|
|
22774
|
+
let forceFullRedraw = false
|
|
22745
22775
|
// Note: these are the permitted status colour aliases. The actual RGB values
|
|
22746
22776
|
// are set in the CSS - flow.scss/colors.scss
|
|
22747
22777
|
const status_colours = {
|
|
@@ -24014,6 +24044,13 @@ RED.view = (function() {
|
|
|
24014
24044
|
quickAddLink.virtualLink = true;
|
|
24015
24045
|
}
|
|
24016
24046
|
hideDragLines();
|
|
24047
|
+
} else if (quickAddLink) {
|
|
24048
|
+
// continuing an existing quick add - set the filter accordingly
|
|
24049
|
+
if (quickAddLink.portType === PORT_TYPE_OUTPUT) {
|
|
24050
|
+
filter = {input:true}
|
|
24051
|
+
} else {
|
|
24052
|
+
filter = {output:true}
|
|
24053
|
+
}
|
|
24017
24054
|
}
|
|
24018
24055
|
if (linkToSplice || spliceMultipleLinks) {
|
|
24019
24056
|
filter = {
|
|
@@ -25852,6 +25889,7 @@ RED.view = (function() {
|
|
|
25852
25889
|
|
|
25853
25890
|
function portMouseDown(d,portType,portIndex, evt) {
|
|
25854
25891
|
if (RED.view.DEBUG) { console.warn("portMouseDown", mouse_mode,d,portType,portIndex); }
|
|
25892
|
+
clearSuggestedFlow();
|
|
25855
25893
|
RED.contextMenu.hide();
|
|
25856
25894
|
evt = evt || d3.event;
|
|
25857
25895
|
if (evt === 1) {
|
|
@@ -26275,9 +26313,9 @@ RED.view = (function() {
|
|
|
26275
26313
|
return tooltip;
|
|
26276
26314
|
}
|
|
26277
26315
|
|
|
26278
|
-
function portMouseOver(port,d,portType,portIndex) {
|
|
26316
|
+
function portMouseOver(port,d,portType,portIndex, event) {
|
|
26279
26317
|
if (mouse_mode === RED.state.SELECTING_NODE) {
|
|
26280
|
-
d3.event.stopPropagation();
|
|
26318
|
+
(d3.event || event).stopPropagation();
|
|
26281
26319
|
return;
|
|
26282
26320
|
}
|
|
26283
26321
|
clearTimeout(portLabelHoverTimeout);
|
|
@@ -26316,9 +26354,9 @@ RED.view = (function() {
|
|
|
26316
26354
|
}
|
|
26317
26355
|
port.classed("red-ui-flow-port-hovered",active);
|
|
26318
26356
|
}
|
|
26319
|
-
function portMouseOut(port,d,portType,portIndex) {
|
|
26357
|
+
function portMouseOut(port,d,portType,portIndex, event) {
|
|
26320
26358
|
if (mouse_mode === RED.state.SELECTING_NODE) {
|
|
26321
|
-
d3.event.stopPropagation();
|
|
26359
|
+
(d3.event || event).stopPropagation();
|
|
26322
26360
|
return;
|
|
26323
26361
|
}
|
|
26324
26362
|
clearTimeout(portLabelHoverTimeout);
|
|
@@ -26436,6 +26474,7 @@ RED.view = (function() {
|
|
|
26436
26474
|
}
|
|
26437
26475
|
function nodeMouseDown(d) {
|
|
26438
26476
|
if (RED.view.DEBUG) { console.warn("nodeMouseDown", mouse_mode,d); }
|
|
26477
|
+
clearSuggestedFlow()
|
|
26439
26478
|
focusView();
|
|
26440
26479
|
RED.contextMenu.hide();
|
|
26441
26480
|
if (d3.event.button === 1) {
|
|
@@ -27061,130 +27100,211 @@ RED.view = (function() {
|
|
|
27061
27100
|
}
|
|
27062
27101
|
}
|
|
27063
27102
|
|
|
27103
|
+
function buildSubflowPort (d) {
|
|
27104
|
+
const NODE_TYPE = d.direction === "in" ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT;
|
|
27105
|
+
// PORT_TYPE is the 'opposite' of NODE_TYPE
|
|
27106
|
+
const PORT_TYPE = NODE_TYPE === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT;
|
|
27107
|
+
var node = d3.select(this);
|
|
27108
|
+
var nodeContents = document.createDocumentFragment();
|
|
27109
|
+
|
|
27110
|
+
d.h = 40;
|
|
27111
|
+
d.resize = true;
|
|
27112
|
+
d.dirty = true;
|
|
27113
|
+
|
|
27114
|
+
var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27115
|
+
mainRect.__data__ = d;
|
|
27116
|
+
mainRect.setAttribute("class", "red-ui-flow-subflow-port");
|
|
27117
|
+
mainRect.setAttribute("rx", 8);
|
|
27118
|
+
mainRect.setAttribute("ry", 8);
|
|
27119
|
+
mainRect.setAttribute("width", 40);
|
|
27120
|
+
mainRect.setAttribute("height", 40);
|
|
27121
|
+
node[0][0].__mainRect__ = mainRect;
|
|
27122
|
+
d3.select(mainRect)
|
|
27123
|
+
.on("mouseup",nodeMouseUp)
|
|
27124
|
+
.on("mousedown",nodeMouseDown)
|
|
27125
|
+
.on("touchstart",nodeTouchStart)
|
|
27126
|
+
.on("touchend",nodeTouchEnd)
|
|
27127
|
+
nodeContents.appendChild(mainRect);
|
|
27128
|
+
|
|
27129
|
+
const port_label_group = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27130
|
+
port_label_group.setAttribute("x",0);
|
|
27131
|
+
port_label_group.setAttribute("y",0);
|
|
27132
|
+
node[0][0].__portLabelGroup__ = port_label_group;
|
|
27133
|
+
|
|
27134
|
+
const port_label = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27135
|
+
port_label.setAttribute("class","red-ui-flow-port-label");
|
|
27136
|
+
port_label.style["font-size"] = "10px";
|
|
27137
|
+
port_label.textContent = NODE_TYPE === PORT_TYPE_INPUT? "input" : "output";
|
|
27138
|
+
port_label_group.appendChild(port_label);
|
|
27139
|
+
node[0][0].__portLabel__ = port_label;
|
|
27140
|
+
|
|
27141
|
+
if (NODE_TYPE === PORT_TYPE_OUTPUT) {
|
|
27142
|
+
const port_number = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27143
|
+
port_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
|
|
27144
|
+
port_number.setAttribute("x",0);
|
|
27145
|
+
port_number.setAttribute("y",0);
|
|
27146
|
+
port_number.textContent = d.i+1;
|
|
27147
|
+
port_label_group.appendChild(port_number);
|
|
27148
|
+
node[0][0].__portNumber__ = port_number;
|
|
27149
|
+
}
|
|
27150
|
+
|
|
27151
|
+
const port_border = document.createElementNS("http://www.w3.org/2000/svg","path");
|
|
27152
|
+
port_border.setAttribute("d","M 40 1 l 0 38")
|
|
27153
|
+
port_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
|
|
27154
|
+
port_label_group.appendChild(port_border);
|
|
27155
|
+
node[0][0].__portBorder__ = port_border;
|
|
27156
|
+
|
|
27157
|
+
nodeContents.appendChild(port_label_group);
|
|
27158
|
+
|
|
27159
|
+
var text = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27160
|
+
text.setAttribute("class","red-ui-flow-port-label");
|
|
27161
|
+
text.setAttribute("transform","translate(38,0)");
|
|
27162
|
+
text.setAttribute('style', 'fill : #888'); // hard coded here!
|
|
27163
|
+
node[0][0].__textGroup__ = text;
|
|
27164
|
+
nodeContents.append(text);
|
|
27165
|
+
|
|
27166
|
+
var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
|
|
27167
|
+
portEl.setAttribute('transform','translate(-5,15)')
|
|
27168
|
+
|
|
27169
|
+
var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
|
27170
|
+
port.setAttribute("class","red-ui-flow-port");
|
|
27171
|
+
port.setAttribute("rx",3);
|
|
27172
|
+
port.setAttribute("ry",3);
|
|
27173
|
+
port.setAttribute("width",10);
|
|
27174
|
+
port.setAttribute("height",10);
|
|
27175
|
+
portEl.appendChild(port);
|
|
27176
|
+
port.__data__ = d;
|
|
27177
|
+
|
|
27178
|
+
d3.select(port)
|
|
27179
|
+
.on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE,0);} )
|
|
27180
|
+
.on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE,0);d3.event.preventDefault();} )
|
|
27181
|
+
.on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE,0);})
|
|
27182
|
+
.on("touchend",function(d,i){portMouseUp(d,PORT_TYPE,0);d3.event.preventDefault();} )
|
|
27183
|
+
.on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE,0);})
|
|
27184
|
+
.on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE,0);});
|
|
27185
|
+
|
|
27186
|
+
node[0][0].__port__ = portEl
|
|
27187
|
+
nodeContents.appendChild(portEl);
|
|
27188
|
+
node[0][0].appendChild(nodeContents);
|
|
27189
|
+
}
|
|
27190
|
+
function updateSubflowPort (d) {
|
|
27191
|
+
if (d.dirty) {
|
|
27192
|
+
const port_height = 40;
|
|
27193
|
+
const NODE_TYPE = d.direction === "in" ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT;
|
|
27194
|
+
// PORT_TYPE is the 'opposite' of NODE_TYPE
|
|
27195
|
+
const PORT_TYPE = NODE_TYPE === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT;
|
|
27196
|
+
|
|
27197
|
+
var label = getPortLabel(activeSubflow, NODE_TYPE, d.i) || "";
|
|
27198
|
+
var hideLabel = (label.length < 1)
|
|
27199
|
+
var labelParts;
|
|
27200
|
+
if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label) {
|
|
27201
|
+
labelParts = getLabelParts(label, "red-ui-flow-node-label");
|
|
27202
|
+
if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
|
|
27203
|
+
d.resize = true;
|
|
27204
|
+
}
|
|
27205
|
+
this.__label__ = label;
|
|
27206
|
+
this.__labelLineCount__ = labelParts.lines.length;
|
|
27207
|
+
|
|
27208
|
+
if (hideLabel) {
|
|
27209
|
+
d.h = Math.max(port_height,(d.outputs || 0) * 15);
|
|
27210
|
+
} else {
|
|
27211
|
+
d.h = Math.max(6+24*labelParts.lines.length,(d.outputs || 0) * 15, port_height);
|
|
27212
|
+
}
|
|
27213
|
+
this.__hideLabel__ = hideLabel;
|
|
27214
|
+
}
|
|
27215
|
+
|
|
27216
|
+
if (d.resize) {
|
|
27217
|
+
var ow = d.w;
|
|
27218
|
+
if (hideLabel) {
|
|
27219
|
+
d.w = port_height;
|
|
27220
|
+
} else {
|
|
27221
|
+
d.w = Math.max(port_height,20*(Math.ceil((labelParts.width+50+7)/20)) );
|
|
27222
|
+
}
|
|
27223
|
+
if (ow !== undefined) {
|
|
27224
|
+
d.x += (d.w-ow)/2;
|
|
27225
|
+
}
|
|
27226
|
+
d.resize = false;
|
|
27227
|
+
}
|
|
27228
|
+
|
|
27229
|
+
this.setAttribute("transform", "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")");
|
|
27230
|
+
// This might be the first redraw after a node has been click-dragged to start a move.
|
|
27231
|
+
// So its selected state might have changed since the last redraw.
|
|
27232
|
+
this.classList.toggle("red-ui-flow-node-selected", !!d.selected )
|
|
27233
|
+
if (mouse_mode != RED.state.MOVING_ACTIVE) {
|
|
27234
|
+
this.classList.toggle("red-ui-flow-node-disabled", d.d === true);
|
|
27235
|
+
this.__mainRect__.setAttribute("width", d.w)
|
|
27236
|
+
this.__mainRect__.setAttribute("height", d.h)
|
|
27237
|
+
this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
|
|
27238
|
+
|
|
27239
|
+
if (labelParts) {
|
|
27240
|
+
// The label has changed
|
|
27241
|
+
var sa = labelParts.lines;
|
|
27242
|
+
var sn = labelParts.lines.length;
|
|
27243
|
+
var textLines = this.__textGroup__.childNodes;
|
|
27244
|
+
while(textLines.length > sn) {
|
|
27245
|
+
textLines[textLines.length-1].remove();
|
|
27246
|
+
}
|
|
27247
|
+
for (var i=0; i<sn; i++) {
|
|
27248
|
+
if (i===textLines.length) {
|
|
27249
|
+
var line = document.createElementNS("http://www.w3.org/2000/svg","text");
|
|
27250
|
+
line.setAttribute("class","red-ui-flow-node-label-text");
|
|
27251
|
+
line.setAttribute("x",0);
|
|
27252
|
+
line.setAttribute("y",i*24);
|
|
27253
|
+
this.__textGroup__.appendChild(line);
|
|
27254
|
+
}
|
|
27255
|
+
textLines[i].textContent = sa[i];
|
|
27256
|
+
}
|
|
27257
|
+
}
|
|
27258
|
+
|
|
27259
|
+
var textClass = "red-ui-flow-node-label"+(hideLabel?" hide":"");
|
|
27260
|
+
this.__textGroup__.setAttribute("class", textClass);
|
|
27261
|
+
var yp = d.h / 2 - (this.__labelLineCount__ / 2) * 24 + 13;
|
|
27262
|
+
|
|
27263
|
+
// this.__textGroup__.classList.remove("red-ui-flow-node-label-right");
|
|
27264
|
+
this.__textGroup__.setAttribute("transform", "translate(48,"+yp+")");
|
|
27265
|
+
|
|
27266
|
+
this.__portBorder__.setAttribute("d","M 40 1 l 0 "+(hideLabel?0:(d.h - 2)));
|
|
27267
|
+
const portX = PORT_TYPE === PORT_TYPE_OUTPUT ? d.w - 5 : -5
|
|
27268
|
+
this.__port__.setAttribute("transform","translate("+portX+","+((d.h/2)-5)+")");
|
|
27269
|
+
if (NODE_TYPE === PORT_TYPE_OUTPUT) {
|
|
27270
|
+
this.__portLabel__.setAttribute("transform","translate(20,"+((d.h/2)-8)+")");
|
|
27271
|
+
this.__portNumber__.setAttribute("transform","translate(20,"+((d.h/2)+7)+")");
|
|
27272
|
+
this.__portNumber__.textContent = d.i+1;
|
|
27273
|
+
} else {
|
|
27274
|
+
this.__portLabel__.setAttribute("transform","translate(20,"+(d.h/2)+")");
|
|
27275
|
+
}
|
|
27276
|
+
}
|
|
27277
|
+
d.dirty = false;
|
|
27278
|
+
return true
|
|
27279
|
+
}
|
|
27280
|
+
return false
|
|
27281
|
+
}
|
|
27282
|
+
|
|
27064
27283
|
function _redraw() {
|
|
27065
27284
|
eventLayer.attr("transform","scale("+scaleFactor+")");
|
|
27066
27285
|
outer.attr("width", space_width*scaleFactor).attr("height", space_height*scaleFactor);
|
|
27067
27286
|
|
|
27068
27287
|
// Don't bother redrawing nodes if we're drawing links
|
|
27069
|
-
if (showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {
|
|
27070
|
-
|
|
27288
|
+
if (forceFullRedraw || showAllLinkPorts !== -1 || mouse_mode != RED.state.JOINING) {
|
|
27289
|
+
forceFullRedraw = false
|
|
27071
27290
|
var dirtyNodes = {};
|
|
27072
27291
|
|
|
27073
27292
|
if (activeSubflow) {
|
|
27074
27293
|
var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;});
|
|
27075
27294
|
subflowOutputs.exit().remove();
|
|
27076
27295
|
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
|
-
});
|
|
27296
|
+
outGroup.each(buildSubflowPort);
|
|
27159
27297
|
|
|
27160
27298
|
var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;});
|
|
27161
27299
|
subflowInputs.exit().remove();
|
|
27162
27300
|
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");
|
|
27301
|
+
inGroup.each(buildSubflowPort);
|
|
27183
27302
|
|
|
27184
27303
|
var subflowStatus = nodeLayer.selectAll(".red-ui-flow-subflow-port-status").data(activeSubflow.status?[activeSubflow.status]:[],function(d,i){ return d.id;});
|
|
27185
27304
|
subflowStatus.exit().remove();
|
|
27186
27305
|
|
|
27187
27306
|
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)+")"});
|
|
27307
|
+
// TODO: use buildSubflowPort/updateSubflowPort for status port
|
|
27188
27308
|
statusGroup.each(function(d,i) {
|
|
27189
27309
|
d.w=40;
|
|
27190
27310
|
d.h=40;
|
|
@@ -27206,104 +27326,16 @@ RED.view = (function() {
|
|
|
27206
27326
|
|
|
27207
27327
|
statusGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",22).attr("y",20).style("font-size","10px").text("status");
|
|
27208
27328
|
|
|
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
|
-
|
|
27329
|
+
subflowOutputs.each(function (d,i) {
|
|
27330
|
+
if (updateSubflowPort.call(this, d)) {
|
|
27217
27331
|
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
27332
|
}
|
|
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) + ")"; });
|
|
27333
|
+
})
|
|
27334
|
+
subflowInputs.each(function (d,i) {
|
|
27335
|
+
if (updateSubflowPort.call(this, d)) {
|
|
27303
27336
|
dirtyNodes[d.id] = d;
|
|
27304
|
-
d.dirty = false;
|
|
27305
27337
|
}
|
|
27306
|
-
})
|
|
27338
|
+
})
|
|
27307
27339
|
subflowStatus.each(function(d,i) {
|
|
27308
27340
|
if (d.dirty) {
|
|
27309
27341
|
var output = d3.select(this);
|
|
@@ -29186,6 +29218,9 @@ RED.view = (function() {
|
|
|
29186
29218
|
suggestedNodes = [suggestedNodes]
|
|
29187
29219
|
}
|
|
29188
29220
|
suggestedNodes = suggestedNodes.filter(n => {
|
|
29221
|
+
if (n.type === 'junction') {
|
|
29222
|
+
return true
|
|
29223
|
+
}
|
|
29189
29224
|
const def = RED.nodes.getType(n.type)
|
|
29190
29225
|
if (def?.set && def.set.enabled === false) {
|
|
29191
29226
|
// Exclude disabled node set
|
|
@@ -29357,7 +29392,6 @@ RED.view = (function() {
|
|
|
29357
29392
|
refreshSuggestedFlow();
|
|
29358
29393
|
} else { // Anything else; clear the suggestion
|
|
29359
29394
|
clearSuggestedFlow();
|
|
29360
|
-
RED.view.redraw(true);
|
|
29361
29395
|
// manually push the event to the keyboard handler
|
|
29362
29396
|
RED.keyboard.handle(evt)
|
|
29363
29397
|
}
|
|
@@ -29366,7 +29400,6 @@ RED.view = (function() {
|
|
|
29366
29400
|
if (suggestion.clickToApply) {
|
|
29367
29401
|
$(window).on('mousedown.suggestedFlow', function (evnt) {
|
|
29368
29402
|
clearSuggestedFlow();
|
|
29369
|
-
RED.view.redraw(true);
|
|
29370
29403
|
})
|
|
29371
29404
|
}
|
|
29372
29405
|
}
|
|
@@ -29387,12 +29420,16 @@ RED.view = (function() {
|
|
|
29387
29420
|
}
|
|
29388
29421
|
|
|
29389
29422
|
function clearSuggestedFlow () {
|
|
29390
|
-
|
|
29391
|
-
|
|
29392
|
-
|
|
29393
|
-
|
|
29394
|
-
|
|
29395
|
-
|
|
29423
|
+
if (currentSuggestion) {
|
|
29424
|
+
$(window).off('mousedown.suggestedFlow');
|
|
29425
|
+
$(window).off('keydown.suggestedFlow')
|
|
29426
|
+
RED.keyboard.enable()
|
|
29427
|
+
currentSuggestion = null
|
|
29428
|
+
suggestedNodes = []
|
|
29429
|
+
suggestedLinks = []
|
|
29430
|
+
forceFullRedraw = true
|
|
29431
|
+
RED.view.redraw(true);
|
|
29432
|
+
}
|
|
29396
29433
|
}
|
|
29397
29434
|
|
|
29398
29435
|
function applySuggestedFlow () {
|
|
@@ -40019,6 +40056,9 @@ RED.editor = (function() {
|
|
|
40019
40056
|
changes.inputLabels = node.inputLabels;
|
|
40020
40057
|
node.inputLabels = newValue;
|
|
40021
40058
|
changed = true;
|
|
40059
|
+
if (node.type === "subflow") {
|
|
40060
|
+
node.in[0].dirty = true
|
|
40061
|
+
}
|
|
40022
40062
|
}
|
|
40023
40063
|
hasNonBlankLabel = false;
|
|
40024
40064
|
newValue = new Array(node.outputs);
|
|
@@ -47495,7 +47535,7 @@ RED.library = (function() {
|
|
|
47495
47535
|
icon: 'fa fa-cube',
|
|
47496
47536
|
label: options.type,
|
|
47497
47537
|
path: "",
|
|
47498
|
-
expanded:
|
|
47538
|
+
expanded: true,
|
|
47499
47539
|
children: function(done, item) {
|
|
47500
47540
|
loadLibraryFolder(lib.id, options.url, "", function(children) {
|
|
47501
47541
|
item.children = children;
|
|
@@ -48438,9 +48478,13 @@ RED.search = (function() {
|
|
|
48438
48478
|
function indexNode(n) {
|
|
48439
48479
|
var l = RED.utils.getNodeLabel(n);
|
|
48440
48480
|
if (l) {
|
|
48441
|
-
|
|
48442
|
-
|
|
48443
|
-
index[
|
|
48481
|
+
const originalLabel = "" + l;
|
|
48482
|
+
const indexLabel = originalLabel.toLowerCase();
|
|
48483
|
+
index[indexLabel] = index[indexLabel] || {};
|
|
48484
|
+
index[indexLabel][n.id] = {
|
|
48485
|
+
node: n,
|
|
48486
|
+
label: originalLabel
|
|
48487
|
+
};
|
|
48444
48488
|
}
|
|
48445
48489
|
l = l||n.label||n.name||n.id||"";
|
|
48446
48490
|
|
|
@@ -48829,6 +48873,12 @@ RED.search = (function() {
|
|
|
48829
48873
|
$('<div>',{class:"red-ui-search-result-node-type"}).text(node.type).appendTo(contentDiv);
|
|
48830
48874
|
$('<div>',{class:"red-ui-search-result-node-id"}).text(node.id).appendTo(contentDiv);
|
|
48831
48875
|
|
|
48876
|
+
div.on("mouseover", function(evt) {
|
|
48877
|
+
if ( node.z == RED.workspaces.active() ) {
|
|
48878
|
+
RED.view.reveal(node.id)
|
|
48879
|
+
}
|
|
48880
|
+
});
|
|
48881
|
+
|
|
48832
48882
|
div.on("click", function(evt) {
|
|
48833
48883
|
evt.preventDefault();
|
|
48834
48884
|
currentIndex = i;
|
|
@@ -49066,10 +49116,20 @@ RED.search = (function() {
|
|
|
49066
49116
|
show: show,
|
|
49067
49117
|
hide: hide,
|
|
49068
49118
|
search: search,
|
|
49069
|
-
getSearchOptions: getSearchOptions
|
|
49119
|
+
getSearchOptions: getSearchOptions,
|
|
49120
|
+
// Expose internals for testing
|
|
49121
|
+
_indexNode: indexNode,
|
|
49122
|
+
get _index() { return index; },
|
|
49123
|
+
set _index(val) { index = val; }
|
|
49070
49124
|
};
|
|
49071
49125
|
|
|
49072
49126
|
})();
|
|
49127
|
+
|
|
49128
|
+
|
|
49129
|
+
// Allow CommonJS import for testing
|
|
49130
|
+
if (typeof module !== "undefined" && module.exports) {
|
|
49131
|
+
module.exports = RED.search;
|
|
49132
|
+
}
|
|
49073
49133
|
;RED.contextMenu = (function () {
|
|
49074
49134
|
|
|
49075
49135
|
let menu;
|
|
@@ -49295,6 +49355,11 @@ RED.search = (function() {
|
|
|
49295
49355
|
{ onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }
|
|
49296
49356
|
)
|
|
49297
49357
|
}
|
|
49358
|
+
if (hasSelection && canEdit) {
|
|
49359
|
+
menuItems.push(
|
|
49360
|
+
{ onselect: 'core:convert-to-subflow', label: RED._("menu.label.selectionToSubflow") }
|
|
49361
|
+
)
|
|
49362
|
+
}
|
|
49298
49363
|
menuItems.push(
|
|
49299
49364
|
{ onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") }
|
|
49300
49365
|
)
|
|
@@ -53373,7 +53438,7 @@ RED.projects = (function() {
|
|
|
53373
53438
|
var validateForm = function() {
|
|
53374
53439
|
var valid = true;
|
|
53375
53440
|
var flowFile = projectFlowFileInput.val();
|
|
53376
|
-
if (flowFile === "" ||
|
|
53441
|
+
if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) {
|
|
53377
53442
|
valid = false;
|
|
53378
53443
|
if (!projectFlowFileInput.hasClass("input-error")) {
|
|
53379
53444
|
projectFlowFileInput.addClass("input-error");
|
|
@@ -53795,7 +53860,7 @@ RED.projects = (function() {
|
|
|
53795
53860
|
|
|
53796
53861
|
} else if (projectType === 'empty') {
|
|
53797
53862
|
var flowFile = projectFlowFileInput.val();
|
|
53798
|
-
if (flowFile === "" ||
|
|
53863
|
+
if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) {
|
|
53799
53864
|
valid = false;
|
|
53800
53865
|
if (!projectFlowFileInput.hasClass("input-error")) {
|
|
53801
53866
|
projectFlowFileInput.addClass("input-error");
|