@node-red/editor-client 3.1.7 → 3.1.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/editor-client",
3
- "version": "3.1.7",
3
+ "version": "3.1.9",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
package/public/red/about CHANGED
@@ -1,3 +1,19 @@
1
+ #### 3.1.9: Maintenance Release
2
+
3
+ - Prevent subflow being added to itself (#4654) @knolleary
4
+ - Fix use of spawn on windows with cmd files (#4652) @knolleary
5
+ - Guard refresh of unknown subflow (#4640) @knolleary
6
+ - Fix subflow module sending messages to debug sidebar (#4642) @knolleary
7
+
8
+ #### 3.1.8: Maintenance Release
9
+
10
+ - Add validation and error handling on subflow instance properties (#4632) @knolleary
11
+ - Hide import/export context menu if disabled in theme (#4633) @knolleary
12
+ - Show change indicator on subflow tabs (#4631) @knolleary
13
+ - Bump dependencies (#4630) @knolleary
14
+ - Reset workspace index when clearing nodes (#4619) @knolleary
15
+ - Remove typo in global config (#4613) @kazuhitoyokoi
16
+
1
17
  #### 3.1.7: Maintenance Release
2
18
 
3
19
  - Add Japanese translation for v3.1.6 (#4603) @kazuhitoyokoi
package/public/red/red.js CHANGED
@@ -4264,12 +4264,16 @@ RED.nodes = (function() {
4264
4264
  * @param {String} z tab id
4265
4265
  */
4266
4266
  checkTabState: function (z) {
4267
- const ws = workspaces[z]
4267
+ const ws = workspaces[z] || subflows[z]
4268
4268
  if (ws) {
4269
4269
  const contentsChanged = tabDirtyMap[z].size > 0 || tabDeletedNodesMap[z].size > 0
4270
4270
  if (Boolean(ws.contentsChanged) !== contentsChanged) {
4271
4271
  ws.contentsChanged = contentsChanged
4272
- RED.events.emit("flows:change", ws);
4272
+ if (ws.type === 'tab') {
4273
+ RED.events.emit("flows:change", ws);
4274
+ } else {
4275
+ RED.events.emit("subflows:change", ws);
4276
+ }
4273
4277
  }
4274
4278
  }
4275
4279
  }
@@ -4742,7 +4746,22 @@ RED.nodes = (function() {
4742
4746
  RED.nodes.registerType("subflow:"+sf.id, {
4743
4747
  defaults:{
4744
4748
  name:{value:""},
4745
- env:{value:[]}
4749
+ env:{value:[], validate: function(value) {
4750
+ const errors = []
4751
+ if (value) {
4752
+ value.forEach(env => {
4753
+ const r = RED.utils.validateTypedProperty(env.value, env.type)
4754
+ if (r !== true) {
4755
+ errors.push(env.name+': '+r)
4756
+ }
4757
+ })
4758
+ }
4759
+ if (errors.length === 0) {
4760
+ return true
4761
+ } else {
4762
+ return errors
4763
+ }
4764
+ }}
4746
4765
  },
4747
4766
  icon: function() { return sf.icon||"subflow.svg" },
4748
4767
  category: sf.category || "subflows",
@@ -20068,6 +20087,11 @@ RED.workspaces = (function() {
20068
20087
  createWorkspaceTabs();
20069
20088
  RED.events.on("sidebar:resize",workspace_tabs.resize);
20070
20089
 
20090
+ RED.events.on("workspace:clear", () => {
20091
+ // Reset the index used to generate new flow names
20092
+ workspaceIndex = 0
20093
+ })
20094
+
20071
20095
  RED.actions.add("core:show-next-tab",function() {
20072
20096
  var oldActive = activeWorkspace;
20073
20097
  workspace_tabs.nextTab();
@@ -20234,6 +20258,9 @@ RED.workspaces = (function() {
20234
20258
  RED.events.on("flows:change", (ws) => {
20235
20259
  $("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
20236
20260
  })
20261
+ RED.events.on("subflows:change", (ws) => {
20262
+ $("#red-ui-tab-"+(ws.id.replace(".","-"))).toggleClass('red-ui-workspace-changed',!!(ws.contentsChanged || ws.changed || ws.added));
20263
+ })
20237
20264
 
20238
20265
  hideWorkspace();
20239
20266
  }
@@ -21185,120 +21212,128 @@ RED.view = (function() {
21185
21212
  }
21186
21213
  d3.event = event;
21187
21214
  var selected_tool = $(ui.draggable[0]).attr("data-palette-type");
21188
- var result = createNode(selected_tool);
21189
- if (!result) {
21190
- return;
21191
- }
21192
- var historyEvent = result.historyEvent;
21193
- var nn = RED.nodes.add(result.node);
21215
+ try {
21216
+ var result = createNode(selected_tool);
21217
+ if (!result) {
21218
+ return;
21219
+ }
21220
+ var historyEvent = result.historyEvent;
21221
+ var nn = RED.nodes.add(result.node);
21194
21222
 
21195
- var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
21196
- if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
21197
- nn.l = showLabel;
21198
- }
21223
+ var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label");
21224
+ if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) {
21225
+ nn.l = showLabel;
21226
+ }
21199
21227
 
21200
- var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0));
21201
- var helperWidth = ui.helper.width();
21202
- var helperHeight = ui.helper.height();
21203
- var mousePos = d3.touches(this)[0]||d3.mouse(this);
21228
+ var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0));
21229
+ var helperWidth = ui.helper.width();
21230
+ var helperHeight = ui.helper.height();
21231
+ var mousePos = d3.touches(this)[0]||d3.mouse(this);
21204
21232
 
21205
- try {
21206
- var isLink = (nn.type === "link in" || nn.type === "link out")
21207
- var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink;
21208
-
21209
- var label = RED.utils.getNodeLabel(nn, nn.type);
21210
- var labelParts = getLabelParts(label, "red-ui-flow-node-label");
21211
- if (hideLabel) {
21212
- nn.w = node_height;
21213
- nn.h = Math.max(node_height,(nn.outputs || 0) * 15);
21214
- } else {
21215
- nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) );
21216
- nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30);
21217
- }
21218
- } catch(err) {
21219
- }
21233
+ try {
21234
+ var isLink = (nn.type === "link in" || nn.type === "link out")
21235
+ var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink;
21220
21236
 
21221
- mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]);
21222
- mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]);
21223
- mousePos[1] /= scaleFactor;
21224
- mousePos[0] /= scaleFactor;
21237
+ var label = RED.utils.getNodeLabel(nn, nn.type);
21238
+ var labelParts = getLabelParts(label, "red-ui-flow-node-label");
21239
+ if (hideLabel) {
21240
+ nn.w = node_height;
21241
+ nn.h = Math.max(node_height,(nn.outputs || 0) * 15);
21242
+ } else {
21243
+ nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) );
21244
+ nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30);
21245
+ }
21246
+ } catch(err) {
21247
+ }
21225
21248
 
21226
- nn.x = mousePos[0];
21227
- nn.y = mousePos[1];
21249
+ mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]);
21250
+ mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]);
21251
+ mousePos[1] /= scaleFactor;
21252
+ mousePos[0] /= scaleFactor;
21228
21253
 
21229
- var minX = nn.w/2 -5;
21230
- if (nn.x < minX) {
21231
- nn.x = minX;
21232
- }
21233
- var minY = nn.h/2 -5;
21234
- if (nn.y < minY) {
21235
- nn.y = minY;
21236
- }
21237
- var maxX = space_width -nn.w/2 +5;
21238
- if (nn.x > maxX) {
21239
- nn.x = maxX;
21240
- }
21241
- var maxY = space_height -nn.h +5;
21242
- if (nn.y > maxY) {
21243
- nn.y = maxY;
21244
- }
21254
+ nn.x = mousePos[0];
21255
+ nn.y = mousePos[1];
21245
21256
 
21246
- if (snapGrid) {
21247
- var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
21248
- nn.x -= gridOffset.x;
21249
- nn.y -= gridOffset.y;
21250
- }
21257
+ var minX = nn.w/2 -5;
21258
+ if (nn.x < minX) {
21259
+ nn.x = minX;
21260
+ }
21261
+ var minY = nn.h/2 -5;
21262
+ if (nn.y < minY) {
21263
+ nn.y = minY;
21264
+ }
21265
+ var maxX = space_width -nn.w/2 +5;
21266
+ if (nn.x > maxX) {
21267
+ nn.x = maxX;
21268
+ }
21269
+ var maxY = space_height -nn.h +5;
21270
+ if (nn.y > maxY) {
21271
+ nn.y = maxY;
21272
+ }
21251
21273
 
21252
- var linkToSplice = $(ui.helper).data("splice");
21253
- if (linkToSplice) {
21254
- spliceLink(linkToSplice, nn, historyEvent)
21255
- }
21274
+ if (snapGrid) {
21275
+ var gridOffset = RED.view.tools.calculateGridSnapOffsets(nn);
21276
+ nn.x -= gridOffset.x;
21277
+ nn.y -= gridOffset.y;
21278
+ }
21256
21279
 
21257
- var group = $(ui.helper).data("group");
21258
- if (group) {
21259
- var oldX = group.x;
21260
- var oldY = group.y;
21261
- RED.group.addToGroup(group, nn);
21262
- var moveEvent = null;
21263
- if ((group.x !== oldX) ||
21264
- (group.y !== oldY)) {
21265
- moveEvent = {
21266
- t: "move",
21267
- nodes: [{n: group,
21268
- ox: oldX, oy: oldY,
21269
- dx: group.x -oldX,
21270
- dy: group.y -oldY}],
21271
- dirty: true
21272
- };
21280
+ var linkToSplice = $(ui.helper).data("splice");
21281
+ if (linkToSplice) {
21282
+ spliceLink(linkToSplice, nn, historyEvent)
21273
21283
  }
21274
- historyEvent = {
21275
- t: 'multi',
21276
- events: [historyEvent],
21277
21284
 
21278
- };
21279
- if (moveEvent) {
21280
- historyEvent.events.push(moveEvent)
21285
+ var group = $(ui.helper).data("group");
21286
+ if (group) {
21287
+ var oldX = group.x;
21288
+ var oldY = group.y;
21289
+ RED.group.addToGroup(group, nn);
21290
+ var moveEvent = null;
21291
+ if ((group.x !== oldX) ||
21292
+ (group.y !== oldY)) {
21293
+ moveEvent = {
21294
+ t: "move",
21295
+ nodes: [{n: group,
21296
+ ox: oldX, oy: oldY,
21297
+ dx: group.x -oldX,
21298
+ dy: group.y -oldY}],
21299
+ dirty: true
21300
+ };
21301
+ }
21302
+ historyEvent = {
21303
+ t: 'multi',
21304
+ events: [historyEvent],
21305
+
21306
+ };
21307
+ if (moveEvent) {
21308
+ historyEvent.events.push(moveEvent)
21309
+ }
21310
+ historyEvent.events.push({
21311
+ t: "addToGroup",
21312
+ group: group,
21313
+ nodes: nn
21314
+ })
21281
21315
  }
21282
- historyEvent.events.push({
21283
- t: "addToGroup",
21284
- group: group,
21285
- nodes: nn
21286
- })
21287
- }
21288
21316
 
21289
- RED.history.push(historyEvent);
21290
- RED.editor.validateNode(nn);
21291
- RED.nodes.dirty(true);
21292
- // auto select dropped node - so info shows (if visible)
21293
- clearSelection();
21294
- nn.selected = true;
21295
- movingSet.add(nn);
21296
- updateActiveNodes();
21297
- updateSelection();
21298
- redraw();
21317
+ RED.history.push(historyEvent);
21318
+ RED.editor.validateNode(nn);
21319
+ RED.nodes.dirty(true);
21320
+ // auto select dropped node - so info shows (if visible)
21321
+ clearSelection();
21322
+ nn.selected = true;
21323
+ movingSet.add(nn);
21324
+ updateActiveNodes();
21325
+ updateSelection();
21326
+ redraw();
21299
21327
 
21300
- if (nn._def.autoedit) {
21301
- RED.editor.edit(nn);
21328
+ if (nn._def.autoedit) {
21329
+ RED.editor.edit(nn);
21330
+ }
21331
+ } catch (error) {
21332
+ if (error.code != "NODE_RED") {
21333
+ RED.notify(RED._("notification.error",{message:error.toString()}),"error");
21334
+ } else {
21335
+ RED.notify(RED._("notification.error",{message:error.message}),"error");
21336
+ }
21302
21337
  }
21303
21338
  }
21304
21339
  });
@@ -26602,14 +26637,19 @@ RED.view = (function() {
26602
26637
  function createNode(type, x, y, z) {
26603
26638
  const wasDirty = RED.nodes.dirty()
26604
26639
  var m = /^subflow:(.+)$/.exec(type);
26605
- var activeSubflow = z ? RED.nodes.subflow(z) : null;
26640
+ var activeSubflow = (z || RED.workspaces.active()) ? RED.nodes.subflow(z || RED.workspaces.active()) : null;
26641
+
26606
26642
  if (activeSubflow && m) {
26607
26643
  var subflowId = m[1];
26644
+ let err
26608
26645
  if (subflowId === activeSubflow.id) {
26609
- throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddSubflowToItself") }))
26646
+ err = new Error(RED._("notification.errors.cannotAddSubflowToItself"))
26647
+ } else if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
26648
+ err = new Error(RED._("notification.errors.cannotAddCircularReference"))
26610
26649
  }
26611
- if (RED.nodes.subflowContains(m[1], activeSubflow.id)) {
26612
- throw new Error(RED._("notification.error", { message: RED._("notification.errors.cannotAddCircularReference") }))
26650
+ if (err) {
26651
+ err.code = 'NODE_RED'
26652
+ throw err
26613
26653
  }
26614
26654
  }
26615
26655
 
@@ -31187,8 +31227,10 @@ RED.sidebar.help = (function() {
31187
31227
 
31188
31228
  function refreshSubflow(sf) {
31189
31229
  var item = treeList.treeList('get',"node-type:subflow:"+sf.id);
31190
- item.subflowLabel = sf._def.label().toLowerCase();
31191
- item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
31230
+ if (item) {
31231
+ item.subflowLabel = sf._def.label().toLowerCase();
31232
+ item.treeList.replaceElement(getNodeLabel({_def:sf._def,type:sf._def.label()}));
31233
+ }
31192
31234
  }
31193
31235
 
31194
31236
  function hideTOC() {
@@ -45179,10 +45221,16 @@ RED.search = (function() {
45179
45221
  onselect: 'core:split-wire-with-link-nodes',
45180
45222
  disabled: !canEdit || !hasLinks
45181
45223
  },
45182
- null,
45183
- { onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
45184
- { onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
45224
+ null
45185
45225
  )
45226
+ if (RED.settings.theme("menu.menu-item-import-library", true)) {
45227
+ insertOptions.push(
45228
+ { onselect: 'core:show-import-dialog', label: RED._('common.label.import')},
45229
+ { onselect: 'core:show-examples-import-dialog', label: RED._('menu.label.importExample') }
45230
+ )
45231
+ }
45232
+
45233
+
45186
45234
  if (hasSelection && canEdit) {
45187
45235
  const nodeOptions = []
45188
45236
  if (!hasMultipleSelection && !isGroup) {
@@ -45255,8 +45303,14 @@ RED.search = (function() {
45255
45303
  { onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
45256
45304
  { onselect: 'core:delete-selection', label: RED._('keyboard.deleteSelected'), disabled: !canEdit || !canDelete },
45257
45305
  { onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
45258
- { onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
45259
- { onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") },
45306
+ )
45307
+ if (RED.settings.theme("menu.menu-item-export-library", true)) {
45308
+ menuItems.push(
45309
+ { onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }
45310
+ )
45311
+ }
45312
+ menuItems.push(
45313
+ { onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") }
45260
45314
  )
45261
45315
  }
45262
45316