@node-red/editor-client 2.1.2 → 2.1.6

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/public/red/red.js CHANGED
@@ -566,31 +566,33 @@ var RED = (function() {
566
566
  var typeList;
567
567
  var info;
568
568
  if (topic == "notification/node/added") {
569
- var addedTypes = [];
570
- msg.forEach(function(m) {
571
- var id = m.id;
572
- RED.nodes.addNodeSet(m);
573
- addedTypes = addedTypes.concat(m.types);
574
- RED.i18n.loadNodeCatalog(id, function() {
575
- var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
576
- $.ajax({
577
- headers: {
578
- "Accept":"text/html",
579
- "Accept-Language": lang
580
- },
581
- cache: false,
582
- url: 'nodes/'+id,
583
- success: function(data) {
584
- appendNodeConfig(data);
585
- }
569
+ RED.settings.refreshSettings(function(err, data) {
570
+ var addedTypes = [];
571
+ msg.forEach(function(m) {
572
+ var id = m.id;
573
+ RED.nodes.addNodeSet(m);
574
+ addedTypes = addedTypes.concat(m.types);
575
+ RED.i18n.loadNodeCatalog(id, function() {
576
+ var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
577
+ $.ajax({
578
+ headers: {
579
+ "Accept":"text/html",
580
+ "Accept-Language": lang
581
+ },
582
+ cache: false,
583
+ url: 'nodes/'+id,
584
+ success: function(data) {
585
+ appendNodeConfig(data);
586
+ }
587
+ });
586
588
  });
587
589
  });
588
- });
589
- if (addedTypes.length) {
590
- typeList = "<ul><li>"+addedTypes.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
591
- RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
592
- }
593
- loadIconList();
590
+ if (addedTypes.length) {
591
+ typeList = "<ul><li>"+addedTypes.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
592
+ RED.notify(RED._("palette.event.nodeAdded", {count:addedTypes.length})+typeList,"success");
593
+ }
594
+ loadIconList();
595
+ })
594
596
  } else if (topic == "notification/node/removed") {
595
597
  for (i=0;i<msg.length;i++) {
596
598
  m = msg[i];
@@ -603,27 +605,29 @@ var RED = (function() {
603
605
  loadIconList();
604
606
  } else if (topic == "notification/node/enabled") {
605
607
  if (msg.types) {
606
- info = RED.nodes.getNodeSet(msg.id);
607
- if (info.added) {
608
- RED.nodes.enableNodeSet(msg.id);
609
- typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
610
- RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
611
- } else {
612
- var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
613
- $.ajax({
614
- headers: {
615
- "Accept":"text/html",
616
- "Accept-Language": lang
617
- },
618
- cache: false,
619
- url: 'nodes/'+msg.id,
620
- success: function(data) {
621
- appendNodeConfig(data);
622
- typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
623
- RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
624
- }
625
- });
626
- }
608
+ RED.settings.refreshSettings(function(err, data) {
609
+ info = RED.nodes.getNodeSet(msg.id);
610
+ if (info.added) {
611
+ RED.nodes.enableNodeSet(msg.id);
612
+ typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
613
+ RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
614
+ } else {
615
+ var lang = localStorage.getItem("editor-language")||RED.i18n.detectLanguage();
616
+ $.ajax({
617
+ headers: {
618
+ "Accept":"text/html",
619
+ "Accept-Language": lang
620
+ },
621
+ cache: false,
622
+ url: 'nodes/'+msg.id,
623
+ success: function(data) {
624
+ appendNodeConfig(data);
625
+ typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
626
+ RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
627
+ }
628
+ });
629
+ }
630
+ });
627
631
  }
628
632
  } else if (topic == "notification/node/disabled") {
629
633
  if (msg.types) {
@@ -677,7 +681,7 @@ var RED = (function() {
677
681
  {id:"menu-item-projects-settings",label:RED._("menu.label.projects-settings"),disabled:false,onselect:"core:show-project-settings"}
678
682
  ]});
679
683
  }
680
- menuOptions.push({id:"menu-item-edit-menu", label:"Edit", options: [
684
+ menuOptions.push({id:"menu-item-edit-menu", label:RED._("menu.label.edit"), options: [
681
685
  {id: "menu-item-edit-undo", label:RED._("keyboard.undoChange"), disabled: true, onselect: "core:undo"},
682
686
  {id: "menu-item-edit-redo", label:RED._("keyboard.redoChange"), disabled: true, onselect: "core:redo"},
683
687
  null,
@@ -1168,6 +1172,8 @@ RED.i18n = (function() {
1168
1172
  defaultNS: "editor",
1169
1173
  fallbackLng: ['en-US'],
1170
1174
  returnObjects: true,
1175
+ keySeparator: ".",
1176
+ nsSeparator: ":",
1171
1177
  interpolation: {
1172
1178
  unescapeSuffix: 'HTML',
1173
1179
  escapeValue: false,
@@ -1408,7 +1414,7 @@ RED.settings = (function () {
1408
1414
  load(done);
1409
1415
  }
1410
1416
 
1411
- var load = function(done) {
1417
+ var refreshSettings = function(done) {
1412
1418
  $.ajax({
1413
1419
  headers: {
1414
1420
  "Accept": "application/json"
@@ -1418,6 +1424,23 @@ RED.settings = (function () {
1418
1424
  url: 'settings',
1419
1425
  success: function (data) {
1420
1426
  setProperties(data);
1427
+ done(null, data);
1428
+ },
1429
+ error: function(jqXHR,textStatus,errorThrown) {
1430
+ if (jqXHR.status === 401) {
1431
+ if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
1432
+ window.location.search = "";
1433
+ }
1434
+ RED.user.login(function() { refreshSettings(done); });
1435
+ } else {
1436
+ console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
1437
+ }
1438
+ }
1439
+ });
1440
+ }
1441
+ var load = function(done) {
1442
+ refreshSettings(function(err, data) {
1443
+ if (!err) {
1421
1444
  if (!RED.settings.user || RED.settings.user.anonymous) {
1422
1445
  RED.settings.remove("auth-tokens");
1423
1446
  }
@@ -1430,18 +1453,8 @@ RED.settings = (function () {
1430
1453
  console.log("D3",d3.version);
1431
1454
  console.groupEnd();
1432
1455
  loadUserSettings(done);
1433
- },
1434
- error: function(jqXHR,textStatus,errorThrown) {
1435
- if (jqXHR.status === 401) {
1436
- if (/[?&]access_token=(.*?)(?:$|&)/.test(window.location.search)) {
1437
- window.location.search = "";
1438
- }
1439
- RED.user.login(function() { load(done); });
1440
- } else {
1441
- console.log("Unexpected error loading settings:",jqXHR.status,textStatus);
1442
- }
1443
1456
  }
1444
- });
1457
+ })
1445
1458
  };
1446
1459
 
1447
1460
  function loadUserSettings(done) {
@@ -1517,6 +1530,7 @@ RED.settings = (function () {
1517
1530
  init: init,
1518
1531
  load: load,
1519
1532
  loadUserSettings: loadUserSettings,
1533
+ refreshSettings: refreshSettings,
1520
1534
  set: set,
1521
1535
  get: get,
1522
1536
  remove: remove,
@@ -4380,7 +4394,6 @@ RED.nodes = (function() {
4380
4394
  var removedGroups = [];
4381
4395
  if (ws) {
4382
4396
  delete workspaces[id];
4383
- allNodes.removeTab(id);
4384
4397
  delete linkTabMap[id];
4385
4398
  workspacesOrder.splice(workspacesOrder.indexOf(id),1);
4386
4399
  var i;
@@ -4418,6 +4431,7 @@ RED.nodes = (function() {
4418
4431
  for (i=removedGroups.length-1; i>=0; i--) {
4419
4432
  removeGroup(removedGroups[i]);
4420
4433
  }
4434
+ allNodes.removeTab(id);
4421
4435
  RED.events.emit('flows:remove',ws);
4422
4436
  }
4423
4437
  return {nodes:removedNodes,links:removedLinks, groups: removedGroups};
@@ -4672,6 +4686,11 @@ RED.nodes = (function() {
4672
4686
  // Until we know how that can happen, add a filter here to remove them
4673
4687
  node.nodes = node.nodes.filter(function(n) { return !!n }).map(function(n) { return n.id });
4674
4688
  }
4689
+ if (n.type === "tab" || n.type === "group") {
4690
+ if (node.env && node.env.length === 0) {
4691
+ delete node.env;
4692
+ }
4693
+ }
4675
4694
  if (n._def.category != "config") {
4676
4695
  node.x = n.x;
4677
4696
  node.y = n.y;
@@ -7881,7 +7900,7 @@ RED.utils = (function() {
7881
7900
  window._marked.use({extensions: [descriptionList, description] } );
7882
7901
 
7883
7902
  function renderMarkdown(txt) {
7884
- var rendered = _marked(txt);
7903
+ var rendered = _marked.parse(txt);
7885
7904
  var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true})
7886
7905
  return cleaned;
7887
7906
  }
@@ -7914,6 +7933,8 @@ RED.utils = (function() {
7914
7933
  result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta"></span>').text('function');
7915
7934
  } else if (value.hasOwnProperty('type') && (value.type === 'number' || value.type === 'bigint')) {
7916
7935
  result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-number"></span>').text(value.data);
7936
+ } else if (value.hasOwnProperty('type') && value.type === 'regexp') {
7937
+ result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-string"></span>').text(value.data);
7917
7938
  } else {
7918
7939
  result = $('<span class="red-ui-debug-msg-object-value red-ui-debug-msg-type-meta">object</span>');
7919
7940
  }
@@ -8212,6 +8233,8 @@ RED.utils = (function() {
8212
8233
  $('<span class="red-ui-debug-msg-type-null">undefined</span>').appendTo(entryObj);
8213
8234
  } else if (obj.__enc__ && (obj.type === 'number' || obj.type === 'bigint')) {
8214
8235
  e = $('<span class="red-ui-debug-msg-type-number red-ui-debug-msg-object-header"></span>').text(obj.data).appendTo(entryObj);
8236
+ } else if (typeHint === "regexp" || (obj.__enc__ && obj.type === 'regexp')) {
8237
+ e = $('<span class="red-ui-debug-msg-type-string red-ui-debug-msg-object-header"></span>').text((typeof obj === "string")?obj:obj.data).appendTo(entryObj);
8215
8238
  } else if (typeHint === "function" || (obj.__enc__ && obj.type === 'function')) {
8216
8239
  e = $('<span class="red-ui-debug-msg-type-meta red-ui-debug-msg-object-header"></span>').text("function").appendTo(entryObj);
8217
8240
  } else if (typeHint === "internal" || (obj.__enc__ && obj.type === 'internal')) {
@@ -9925,7 +9948,7 @@ RED.utils = (function() {
9925
9948
  if (child.depth !== parent.depth+1) {
9926
9949
  child.depth = parent.depth+1;
9927
9950
  // var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
9928
- var labelPaddingWidth = ((child.gutter?child.gutter.width()+2:0)+(child.depth*20));
9951
+ var labelPaddingWidth = (((child.gutter&&!child.gutter.hasClass("red-ui-treeList-gutter-float"))?child.gutter.width()+2:0)+(child.depth*20));
9929
9952
  child.treeList.labelPadding.width(labelPaddingWidth+'px');
9930
9953
  if (child.element) {
9931
9954
  $(child.element).css({
@@ -10147,8 +10170,9 @@ RED.utils = (function() {
10147
10170
  }).appendTo(label)
10148
10171
 
10149
10172
  }
10150
- // var labelPaddingWidth = (item.gutter?item.gutter.width()+2:0)+(depth*20);
10151
- var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
10173
+
10174
+ var labelPaddingWidth = ((item.gutter&&!item.gutter.hasClass("red-ui-treeList-gutter-float"))?item.gutter.width()+2:0)+(depth*20);
10175
+
10152
10176
  item.treeList.labelPadding = $('<span>').css({
10153
10177
  display: "inline-block",
10154
10178
  "flex-shrink": 0,
@@ -12072,6 +12096,8 @@ RED.tabs = (function() {
12072
12096
  menuOptions = options.menu()
12073
12097
  } else if (Array.isArray(options.menu)) {
12074
12098
  menuOptions = options.menu;
12099
+ } else if (typeof options.menu === 'function') {
12100
+ menuOptions = options.menu();
12075
12101
  }
12076
12102
  menu = RED.menu.init({options: menuOptions});
12077
12103
  menu.attr("id",options.id+"-menu");
@@ -12531,7 +12557,7 @@ RED.tabs = (function() {
12531
12557
 
12532
12558
  function findPreviousVisibleTab(li) {
12533
12559
  if (!li) {
12534
- li = ul.find("li.active").parent();
12560
+ li = ul.find("li.active");
12535
12561
  }
12536
12562
  var previous = li.prev();
12537
12563
  while(previous.length > 0 && previous.hasClass("hide-tab")) {
@@ -12541,9 +12567,9 @@ RED.tabs = (function() {
12541
12567
  }
12542
12568
  function findNextVisibleTab(li) {
12543
12569
  if (!li) {
12544
- li = ul.find("li.active").parent();
12570
+ li = ul.find("li.active");
12545
12571
  }
12546
- var next = ul.find("li.active").next();
12572
+ var next = li.next();
12547
12573
  while(next.length > 0 && next.hasClass("hide-tab")) {
12548
12574
  next = next.next();
12549
12575
  }
@@ -12764,15 +12790,18 @@ RED.tabs = (function() {
12764
12790
  event.preventDefault();
12765
12791
  removeTab(tab.id);
12766
12792
  });
12793
+ RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
12767
12794
  }
12768
12795
  if (tab.hideable) {
12769
12796
  li.addClass("red-ui-tabs-closeable")
12770
- var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close"}).appendTo(li);
12771
- closeLink.append('<i class="fa fa-times" />');
12797
+ var closeLink = $("<a/>",{href:"#",class:"red-ui-tab-close red-ui-tab-hide"}).appendTo(li);
12798
+ closeLink.append('<i class="fa fa-eye" />');
12799
+ closeLink.append('<i class="fa fa-eye-slash" />');
12772
12800
  closeLink.on("click",function(event) {
12773
12801
  event.preventDefault();
12774
12802
  hideTab(tab.id);
12775
12803
  });
12804
+ RED.popover.tooltip(closeLink,RED._("workspace.hideFlow"));
12776
12805
  }
12777
12806
 
12778
12807
  var badges = $('<span class="red-ui-tabs-badges"></span>').appendTo(li);
@@ -12781,7 +12810,8 @@ RED.tabs = (function() {
12781
12810
  $('<i class="red-ui-tabs-badge-selected fa fa-check-circle"></i>').appendTo(badges);
12782
12811
  }
12783
12812
 
12784
- link.attr("title",tab.label);
12813
+ // link.attr("title",tab.label);
12814
+ RED.popover.tooltip(link,function() { return tab.label})
12785
12815
 
12786
12816
  if (options.onadd) {
12787
12817
  options.onadd(tab);
@@ -12900,7 +12930,6 @@ RED.tabs = (function() {
12900
12930
  renameTab: function(id,label) {
12901
12931
  tabs[id].label = label;
12902
12932
  var tab = ul.find("a[href='#"+id+"']");
12903
- tab.attr("title",label);
12904
12933
  tab.find("span.red-ui-text-bidi-aware").text(label).attr('dir', RED.text.bidi.resolveBaseTextDir(label));
12905
12934
  updateTabWidths();
12906
12935
  },
@@ -13704,7 +13733,7 @@ RED.stack = (function() {
13704
13733
  this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
13705
13734
  this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
13706
13735
 
13707
- this.type(this.options.default||this.typeList[0].value);
13736
+ this.type(this.typeField.val() || this.options.default||this.typeList[0].value);
13708
13737
  this.typeChanged = !!this.options.default;
13709
13738
  }catch(err) {
13710
13739
  console.log(err.stack);
@@ -13953,6 +13982,7 @@ RED.stack = (function() {
13953
13982
  var that = this;
13954
13983
  var currentType = this.type();
13955
13984
  this.typeMap = {};
13985
+ var firstCall = (this.typeList === undefined);
13956
13986
  this.typeList = types.map(function(opt) {
13957
13987
  var result;
13958
13988
  if (typeof opt === 'string') {
@@ -13977,10 +14007,14 @@ RED.stack = (function() {
13977
14007
  }
13978
14008
  this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) });
13979
14009
  if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
13980
- this.type(this.typeList[0].value);
14010
+ if (!firstCall) {
14011
+ this.type(this.typeList[0].value);
14012
+ }
13981
14013
  } else {
13982
14014
  this.propertyType = null;
13983
- this.type(currentType);
14015
+ if (!firstCall) {
14016
+ this.type(currentType);
14017
+ }
13984
14018
  }
13985
14019
  if (this.typeList.length === 1 && !this.typeList[0].icon && (!this.typeList[0].label || this.typeList[0].showLabel === false)) {
13986
14020
  this.selectTrigger.hide()
@@ -14071,7 +14105,7 @@ RED.stack = (function() {
14071
14105
  var previousType = this.typeMap[this.propertyType];
14072
14106
  previousValue = this.input.val();
14073
14107
 
14074
- if (this.typeChanged) {
14108
+ if (previousType && this.typeChanged) {
14075
14109
  if (this.options.debug) { console.log(this.identifier,"typeChanged",{previousType,previousValue}) }
14076
14110
  if (previousType.options && opt.hasValue !== true) {
14077
14111
  this.oldValues[previousType.value] = previousValue;
@@ -14532,7 +14566,7 @@ RED.stack = (function() {
14532
14566
  * value: String : the value to insert if selected
14533
14567
  * label: String|DOM Element : the label to display in the dropdown.
14534
14568
  * }
14535
- *
14569
+ *
14536
14570
  */
14537
14571
 
14538
14572
  $.widget( "nodered.autoComplete", {
@@ -14573,7 +14607,7 @@ RED.stack = (function() {
14573
14607
  maxHeight: 200,
14574
14608
  class: "red-ui-autoComplete-container",
14575
14609
  options: completions,
14576
- onselect: (opt) => { this.element.val(opt.value); this.element.focus() },
14610
+ onselect: (opt) => { this.element.val(opt.value); this.element.focus(); this.element.trigger("change") },
14577
14611
  onclose: () => { this.completionMenuShown = false; delete this.menu; this.element.focus()}
14578
14612
  });
14579
14613
  this.menu.show({
@@ -15750,6 +15784,8 @@ RED.deploy = (function() {
15750
15784
  color: "#DDAA99",
15751
15785
  defaults:{name:{value:""}}
15752
15786
  }
15787
+ } else if (node.type === "group") {
15788
+ def = RED.group.def;
15753
15789
  } else {
15754
15790
  def = {};
15755
15791
  }
@@ -15959,16 +15995,15 @@ RED.deploy = (function() {
15959
15995
  }
15960
15996
  }
15961
15997
 
15962
-
15963
15998
  if (node.hasOwnProperty('x')) {
15964
15999
  if (localNode) {
15965
- if (localNode.x !== node.x || localNode.y !== node.y) {
16000
+ if (localNode.x !== node.x || localNode.y !== node.y || localNode.w !== node.w || localNode.h !== node.h ) {
15966
16001
  localChanged = true;
15967
16002
  localChanges++;
15968
16003
  }
15969
16004
  }
15970
16005
  if (remoteNode) {
15971
- if (remoteNode.x !== node.x || remoteNode.y !== node.y) {
16006
+ if (remoteNode.x !== node.x || remoteNode.y !== node.y|| remoteNode.w !== node.w || remoteNode.h !== node.h) {
15972
16007
  remoteChanged = true;
15973
16008
  remoteChanges++;
15974
16009
  }
@@ -15986,7 +16021,12 @@ RED.deploy = (function() {
15986
16021
  localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged"));
15987
16022
  $('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
15988
16023
  element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
15989
- propertyElements['local.position'] = RED.utils.createObjectElement({x:localNode.x,y:localNode.y},
16024
+ var localPosition = {x:localNode.x,y:localNode.y};
16025
+ if (localNode.hasOwnProperty('w')) {
16026
+ localPosition.w = localNode.w;
16027
+ localPosition.h = localNode.h;
16028
+ }
16029
+ propertyElements['local.position'] = RED.utils.createObjectElement(localPosition,
15990
16030
  {
15991
16031
  path: "position",
15992
16032
  exposeApi: true,
@@ -16007,7 +16047,12 @@ RED.deploy = (function() {
16007
16047
  if (remoteNode) {
16008
16048
  $('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
16009
16049
  element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
16010
- propertyElements['remote.position'] = RED.utils.createObjectElement({x:remoteNode.x,y:remoteNode.y},
16050
+ var remotePosition = {x:remoteNode.x,y:remoteNode.y};
16051
+ if (remoteNode.hasOwnProperty('w')) {
16052
+ remotePosition.w = remoteNode.w;
16053
+ remotePosition.h = remoteNode.h;
16054
+ }
16055
+ propertyElements['remote.position'] = RED.utils.createObjectElement(remotePosition,
16011
16056
  {
16012
16057
  path: "position",
16013
16058
  exposeApi: true,
@@ -16079,11 +16124,11 @@ RED.deploy = (function() {
16079
16124
  }
16080
16125
  }
16081
16126
  }
16082
- var properties = Object.keys(node).filter(function(p) { return p!='inputLabels'&&p!='outputLabels'&&p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))});
16127
+ var properties = Object.keys(node).filter(function(p) { return p!='inputLabels'&&p!='outputLabels'&&p!='z'&&p!='wires'&&p!=='x'&&p!=='y'&&p!=='w'&&p!=='h'&&p!=='id'&&p!=='type'&&(!def.defaults||!def.defaults.hasOwnProperty(p))});
16083
16128
  if (def.defaults) {
16084
16129
  properties = properties.concat(Object.keys(def.defaults));
16085
16130
  }
16086
- if (node.type !== 'tab') {
16131
+ if (node.type !== 'tab' && node.type !== "group") {
16087
16132
  properties = properties.concat(['inputLabels','outputLabels']);
16088
16133
  }
16089
16134
  if ( ((localNode && localNode.hasOwnProperty('icon')) || (remoteNode && remoteNode.hasOwnProperty('icon'))) &&
@@ -18184,7 +18229,7 @@ RED.workspaces = (function() {
18184
18229
  var tabId = RED.nodes.id();
18185
18230
  do {
18186
18231
  workspaceIndex += 1;
18187
- } while ($("#red-ui-workspace-tabs a[title='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
18232
+ } while ($("#red-ui-workspace-tabs li[flowname='"+RED._('workspace.defaultName',{number:workspaceIndex})+"']").size() !== 0);
18188
18233
 
18189
18234
  ws = {
18190
18235
  type: "tab",
@@ -18197,12 +18242,15 @@ RED.workspaces = (function() {
18197
18242
  };
18198
18243
  RED.nodes.addWorkspace(ws,targetIndex);
18199
18244
  workspace_tabs.addTab(ws,targetIndex);
18245
+
18200
18246
  workspace_tabs.activateTab(tabId);
18201
18247
  if (!skipHistoryEntry) {
18202
18248
  RED.history.push({t:'add',workspaces:[ws],dirty:RED.nodes.dirty()});
18203
18249
  RED.nodes.dirty(true);
18204
18250
  }
18205
18251
  }
18252
+ $("#red-ui-tab-"+(ws.id.replace(".","-"))).attr("flowname",ws.label)
18253
+
18206
18254
  RED.view.focus();
18207
18255
  return ws;
18208
18256
  }
@@ -18326,65 +18374,84 @@ RED.workspaces = (function() {
18326
18374
  },
18327
18375
  onhide: function(tab) {
18328
18376
  hideStack.push(tab.id);
18377
+
18378
+ var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
18379
+ hiddenTabs[tab.id] = true;
18380
+ RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
18381
+
18329
18382
  RED.events.emit("workspace:hide",{workspace: tab.id})
18330
18383
  },
18331
18384
  onshow: function(tab) {
18332
18385
  removeFromHideStack(tab.id);
18386
+
18387
+ var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
18388
+ delete hiddenTabs[tab.id];
18389
+ RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
18390
+
18333
18391
  RED.events.emit("workspace:show",{workspace: tab.id})
18334
18392
  },
18335
18393
  minimumActiveTabWidth: 150,
18336
18394
  scrollable: true,
18337
18395
  addButton: "core:add-flow",
18338
18396
  addButtonCaption: RED._("workspace.addFlow"),
18339
- menu: [
18340
- {
18341
- id:"red-ui-tabs-menu-option-search-flows",
18342
- label: RED._("workspace.listFlows"),
18343
- onselect: "core:list-flows"
18344
- },
18345
- {
18346
- id:"red-ui-tabs-menu-option-search-subflows",
18347
- label: RED._("workspace.listSubflows"),
18348
- onselect: "core:list-subflows"
18349
- },
18350
- null,
18351
- {
18352
- id:"red-ui-tabs-menu-option-add-flow",
18353
- label: RED._("workspace.addFlow"),
18354
- onselect: "core:add-flow"
18355
- },
18356
- {
18357
- id:"red-ui-tabs-menu-option-add-flow-right",
18358
- label: RED._("workspace.addFlowToRight"),
18359
- onselect: "core:add-flow-to-right"
18360
- },
18361
- null,
18362
- {
18363
- id:"red-ui-tabs-menu-option-add-hide-flows",
18364
- label: RED._("workspace.hideFlow"),
18365
- onselect: "core:hide-flow"
18366
- },
18367
- {
18368
- id:"red-ui-tabs-menu-option-add-hide-other-flows",
18369
- label: RED._("workspace.hideOtherFlows"),
18370
- onselect: "core:hide-other-flows"
18371
- },
18372
- {
18373
- id:"red-ui-tabs-menu-option-add-show-all-flows",
18374
- label: RED._("workspace.showAllFlows"),
18375
- onselect: "core:show-all-flows"
18376
- },
18377
- {
18378
- id:"red-ui-tabs-menu-option-add-hide-all-flows",
18379
- label: RED._("workspace.hideAllFlows"),
18380
- onselect: "core:hide-all-flows"
18381
- },
18382
- {
18383
- id:"red-ui-tabs-menu-option-add-show-last-flow",
18384
- label: RED._("workspace.showLastHiddenFlow"),
18385
- onselect: "core:show-last-hidden-flow"
18397
+ menu: function() {
18398
+ var menuItems = [
18399
+ {
18400
+ id:"red-ui-tabs-menu-option-search-flows",
18401
+ label: RED._("workspace.listFlows"),
18402
+ onselect: "core:list-flows"
18403
+ },
18404
+ {
18405
+ id:"red-ui-tabs-menu-option-search-subflows",
18406
+ label: RED._("workspace.listSubflows"),
18407
+ onselect: "core:list-subflows"
18408
+ },
18409
+ null,
18410
+ {
18411
+ id:"red-ui-tabs-menu-option-add-flow",
18412
+ label: RED._("workspace.addFlow"),
18413
+ onselect: "core:add-flow"
18414
+ },
18415
+ {
18416
+ id:"red-ui-tabs-menu-option-add-flow-right",
18417
+ label: RED._("workspace.addFlowToRight"),
18418
+ onselect: "core:add-flow-to-right"
18419
+ },
18420
+ null,
18421
+ {
18422
+ id:"red-ui-tabs-menu-option-add-hide-flows",
18423
+ label: RED._("workspace.hideFlow"),
18424
+ onselect: "core:hide-flow"
18425
+ },
18426
+ {
18427
+ id:"red-ui-tabs-menu-option-add-hide-other-flows",
18428
+ label: RED._("workspace.hideOtherFlows"),
18429
+ onselect: "core:hide-other-flows"
18430
+ },
18431
+ {
18432
+ id:"red-ui-tabs-menu-option-add-show-all-flows",
18433
+ label: RED._("workspace.showAllFlows"),
18434
+ onselect: "core:show-all-flows"
18435
+ },
18436
+ {
18437
+ id:"red-ui-tabs-menu-option-add-hide-all-flows",
18438
+ label: RED._("workspace.hideAllFlows"),
18439
+ onselect: "core:hide-all-flows"
18440
+ },
18441
+ {
18442
+ id:"red-ui-tabs-menu-option-add-show-last-flow",
18443
+ label: RED._("workspace.showLastHiddenFlow"),
18444
+ onselect: "core:show-last-hidden-flow"
18445
+ }
18446
+ ]
18447
+ if (hideStack.length > 0) {
18448
+ menuItems.unshift({
18449
+ label: RED._("workspace.hiddenFlows",{count: hideStack.length}),
18450
+ onselect: "core:list-hidden-flows"
18451
+ })
18386
18452
  }
18387
- ]
18453
+ return menuItems;
18454
+ }
18388
18455
  });
18389
18456
  workspaceTabCount = 0;
18390
18457
  }
@@ -18524,7 +18591,9 @@ RED.workspaces = (function() {
18524
18591
  }
18525
18592
  }
18526
18593
  })
18527
-
18594
+ RED.actions.add("core:list-hidden-flows",function() {
18595
+ RED.actions.invoke("core:search","is:hidden ");
18596
+ })
18528
18597
  RED.actions.add("core:list-flows",function() {
18529
18598
  RED.actions.invoke("core:search","type:tab ");
18530
18599
  })
@@ -18568,7 +18637,7 @@ RED.workspaces = (function() {
18568
18637
  var changes = { disabled: workspace.disabled };
18569
18638
  workspace.disabled = disabled;
18570
18639
  $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
18571
- if (id || activeWorkspace) {
18640
+ if (!id || (id === activeWorkspace)) {
18572
18641
  $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
18573
18642
  }
18574
18643
  var historyEvent = {
@@ -18649,11 +18718,11 @@ RED.workspaces = (function() {
18649
18718
  }
18650
18719
  if (workspace_tabs.contains(id)) {
18651
18720
  workspace_tabs.hideTab(id);
18652
- var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
18653
- hiddenTabs[id] = true;
18654
- RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
18655
18721
  }
18656
18722
  },
18723
+ isHidden: function(id) {
18724
+ return hideStack.includes(id)
18725
+ },
18657
18726
  show: function(id,skipStack,unhideOnly) {
18658
18727
  if (!workspace_tabs.contains(id)) {
18659
18728
  var sf = RED.nodes.subflow(id);
@@ -18676,14 +18745,11 @@ RED.workspaces = (function() {
18676
18745
  }
18677
18746
  workspace_tabs.activateTab(id);
18678
18747
  }
18679
- var hiddenTabs = JSON.parse(RED.settings.getLocal("hiddenTabs")||"{}");
18680
- delete hiddenTabs[id];
18681
- RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
18682
18748
  },
18683
18749
  refresh: function() {
18684
18750
  RED.nodes.eachWorkspace(function(ws) {
18685
18751
  workspace_tabs.renameTab(ws.id,ws.label);
18686
-
18752
+ $("#red-ui-tab-"+(ws.id.replace(".","-"))).attr("flowname",ws.label)
18687
18753
  })
18688
18754
  RED.nodes.eachSubflow(function(sf) {
18689
18755
  if (workspace_tabs.contains(sf.id)) {
@@ -19347,7 +19413,7 @@ RED.view = (function() {
19347
19413
  },
19348
19414
  tooltip: function(d) {
19349
19415
  if (d.validationErrors && d.validationErrors.length > 0) {
19350
- return RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - ")
19416
+ return RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - ")
19351
19417
  }
19352
19418
  },
19353
19419
  show: function(n) { return !n.valid }
@@ -22426,7 +22492,11 @@ RED.view = (function() {
22426
22492
  nodeEl = document.getElementById(d.id);
22427
22493
  }
22428
22494
  if (nodeEl) {
22429
- if (!showStatus || !d.status) {
22495
+ // Do not show node status if:
22496
+ // - global flag set
22497
+ // - node has no status
22498
+ // - node is disabled
22499
+ if (!showStatus || !d.status || d.d === true) {
22430
22500
  nodeEl.__statusGroup__.style.display = "none";
22431
22501
  } else {
22432
22502
  nodeEl.__statusGroup__.style.display = "inline";
@@ -23172,6 +23242,9 @@ RED.view = (function() {
23172
23242
  n.selected = true;
23173
23243
  n.dirty = true;
23174
23244
  movingSet.add(n);
23245
+ if (targets.length === 1) {
23246
+ RED.view.reveal(n.id);
23247
+ }
23175
23248
  });
23176
23249
  updateSelection();
23177
23250
  redraw();
@@ -23708,7 +23781,7 @@ RED.view = (function() {
23708
23781
  counts.push(RED._("clipboard.group",{count:newGroupCount}));
23709
23782
  }
23710
23783
  if (newConfigNodeCount > 0) {
23711
- counts.push(RED._("clipboard.configNode",{count:newNodeCount}));
23784
+ counts.push(RED._("clipboard.configNode",{count:newConfigNodeCount}));
23712
23785
  }
23713
23786
  if (new_subflows.length > 0) {
23714
23787
  counts.push(RED._("clipboard.subflow",{count:new_subflows.length}));
@@ -23780,6 +23853,7 @@ RED.view = (function() {
23780
23853
  delete node.d;
23781
23854
  }
23782
23855
  node.dirty = true;
23856
+ node.dirtyStatus = true;
23783
23857
  node.changed = true;
23784
23858
  RED.events.emit("nodes:change",node);
23785
23859
  }
@@ -26942,6 +27016,7 @@ RED.sidebar.info = (function() {
26942
27016
  n.d = true;
26943
27017
  }
26944
27018
  n.dirty = true;
27019
+ n.dirtyStatus = true;
26945
27020
  n.changed = true;
26946
27021
  RED.events.emit("nodes:change",n);
26947
27022
  groupHistoryEvent.events.push(historyEvent);
@@ -26970,6 +27045,7 @@ RED.sidebar.info = (function() {
26970
27045
  n.d = true;
26971
27046
  }
26972
27047
  n.dirty = true;
27048
+ n.dirtyStatus = true;
26973
27049
  n.changed = true;
26974
27050
  RED.events.emit("nodes:change",n);
26975
27051
  RED.history.push(historyEvent);
@@ -27039,6 +27115,7 @@ RED.sidebar.info = (function() {
27039
27115
  {label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
27040
27116
  {label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
27041
27117
  {label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
27118
+ {label:RED._("sidebar.info.search.hiddenFlows"), value:"is:hidden"},
27042
27119
  ]
27043
27120
  });
27044
27121
 
@@ -27330,7 +27407,7 @@ RED.sidebar.info = (function() {
27330
27407
  }
27331
27408
  }
27332
27409
  function getGutter(n) {
27333
- var span = $("<span>",{class:"red-ui-info-outline-gutter"});
27410
+ var span = $("<span>",{class:"red-ui-info-outline-gutter red-ui-treeList-gutter-float"});
27334
27411
  var revealButton = $('<button type="button" class="red-ui-info-outline-item-control-reveal red-ui-button red-ui-button-small"><i class="fa fa-search"></i></button>').appendTo(span).on("click",function(evt) {
27335
27412
  evt.preventDefault();
27336
27413
  evt.stopPropagation();
@@ -27831,7 +27908,7 @@ RED.sidebar.help = (function() {
27831
27908
  var currentVersionParts = RED.settings.version.split(".");
27832
27909
  var tourVersionParts = tour.version.split(".");
27833
27910
  if (tourVersionParts[0] === currentVersionParts[0] && tourVersionParts[1] === currentVersionParts[1]) {
27834
- tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">Take a tour</button></div>'
27911
+ tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">' + RED._("tourGuide.takeATour") + '</button></div>';
27835
27912
  }
27836
27913
  }
27837
27914
  var aboutHeader = '<div style="text-align:center;">'+tourHeader+'</div>'
@@ -30612,7 +30689,16 @@ RED.editor = (function() {
30612
30689
  delete cn.__label__;
30613
30690
  });
30614
30691
 
30615
- select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:type})+'</option>');
30692
+ var label = type;
30693
+ if (typeof node_def.paletteLabel !== "undefined") {
30694
+ try {
30695
+ label = RED.utils.sanitize((typeof node_def.paletteLabel === "function" ? node_def.paletteLabel.call(node_def) : node_def.paletteLabel)||type);
30696
+ } catch(err) {
30697
+ console.log("Definition error: "+type+".paletteLabel",err);
30698
+ }
30699
+ }
30700
+
30701
+ select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:label})+'</option>');
30616
30702
  window.setTimeout(function() { select.trigger("change");},50);
30617
30703
  }
30618
30704
  }
@@ -32450,9 +32536,15 @@ RED.editor = (function() {
32450
32536
  }
32451
32537
  });
32452
32538
  }
32453
- if (!isSameObj(old_env, new_env)) {
32454
- node.env = new_env;
32539
+ if (!old_env && new_env.length === 0) {
32540
+ delete node.env;
32541
+ } else if (!isSameObj(old_env, new_env)) {
32455
32542
  editState.changes.env = node.env;
32543
+ if (new_env.length === 0) {
32544
+ delete node.env;
32545
+ } else {
32546
+ node.env = new_env;
32547
+ }
32456
32548
  editState.changed = true;
32457
32549
  }
32458
32550
  }
@@ -34271,7 +34363,7 @@ RED.editor = (function() {
34271
34363
  var currentExpression = expressionEditor.getValue();
34272
34364
  var expr;
34273
34365
  var usesContext = false;
34274
- var legacyMode = /(^|[^a-zA-Z0-9_'"])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression);
34366
+ var legacyMode = /(^|[^a-zA-Z0-9_'".])msg([^a-zA-Z0-9_'"]|$)/.test(currentExpression);
34275
34367
  $(".red-ui-editor-type-expression-legacy").toggle(legacyMode);
34276
34368
  try {
34277
34369
  expr = jsonata(currentExpression);
@@ -34560,7 +34652,8 @@ RED.editor = (function() {
34560
34652
  clearTimeout: true,
34561
34653
  setInterval: true,
34562
34654
  clearInterval: true
34563
- }
34655
+ },
34656
+ extraLibs: options.extraLibs
34564
34657
  });
34565
34658
  if (options.cursor) {
34566
34659
  expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
@@ -37579,6 +37672,7 @@ RED.clipboard = (function() {
37579
37672
  text: RED._("common.label.cancel"),
37580
37673
  click: function() {
37581
37674
  $( this ).dialog( "close" );
37675
+ RED.view.focus();
37582
37676
  }
37583
37677
  },
37584
37678
  { // red-ui-clipboard-dialog-download
@@ -37589,6 +37683,7 @@ RED.clipboard = (function() {
37589
37683
  var data = $("#red-ui-clipboard-dialog-export-text").val();
37590
37684
  downloadData("flows.json", data);
37591
37685
  $( this ).dialog( "close" );
37686
+ RED.view.focus();
37592
37687
  }
37593
37688
  },
37594
37689
  { // red-ui-clipboard-dialog-export
@@ -37603,6 +37698,7 @@ RED.clipboard = (function() {
37603
37698
  $( this ).dialog( "close" );
37604
37699
  copyText(flowData);
37605
37700
  RED.notify(RED._("clipboard.nodesExported"),{id:"clipboard"});
37701
+ RED.view.focus();
37606
37702
  } else {
37607
37703
  var flowToExport = $("#red-ui-clipboard-dialog-export-text").val();
37608
37704
  var selectedPath = activeLibraries[activeTab].getSelected();
@@ -37618,6 +37714,7 @@ RED.clipboard = (function() {
37618
37714
  contentType: "application/json; charset=utf-8"
37619
37715
  }).done(function() {
37620
37716
  $(dialog).dialog( "close" );
37717
+ RED.view.focus();
37621
37718
  RED.notify(RED._("library.exportedToLibrary"),"success");
37622
37719
  }).fail(function(xhr,textStatus,err) {
37623
37720
  if (xhr.status === 401) {
@@ -37679,6 +37776,7 @@ RED.clipboard = (function() {
37679
37776
  }
37680
37777
  }
37681
37778
  $( this ).dialog( "close" );
37779
+ RED.view.focus();
37682
37780
  }
37683
37781
  },
37684
37782
  { // red-ui-clipboard-dialog-import-conflict
@@ -37711,6 +37809,7 @@ RED.clipboard = (function() {
37711
37809
  // console.table(pendingImportConfig.importNodes.map(function(n) { return {id:n.id,type:n.type,result:importMap[n.id]}}))
37712
37810
  RED.view.importNodes(newNodes, pendingImportConfig.importOptions);
37713
37811
  $( this ).dialog( "close" );
37812
+ RED.view.focus();
37714
37813
  }
37715
37814
  }
37716
37815
  ],
@@ -38448,7 +38547,8 @@ RED.clipboard = (function() {
38448
38547
  if (truncated) {
38449
38548
  msg += "_truncated";
38450
38549
  }
38451
- $("#red-ui-clipboard-hidden").val(value).focus().select();
38550
+ var clipboardHidden = $('<textarea type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo(document.body);
38551
+ clipboardHidden.val(value).focus().select();
38452
38552
  var result = document.execCommand("copy");
38453
38553
  if (result && element) {
38454
38554
  var popover = RED.popover.create({
@@ -38462,14 +38562,13 @@ RED.clipboard = (function() {
38462
38562
  },1000);
38463
38563
  popover.open();
38464
38564
  }
38465
- $("#red-ui-clipboard-hidden").val("");
38565
+ clipboardHidden.remove();
38466
38566
  if (currentFocus) {
38467
38567
  $(currentFocus).focus();
38468
38568
  }
38469
38569
  return result;
38470
38570
  }
38471
38571
 
38472
-
38473
38572
  function importNodes(nodesStr,addFlow) {
38474
38573
  var newNodes = nodesStr;
38475
38574
  if (typeof nodesStr === 'string') {
@@ -38744,8 +38843,6 @@ RED.clipboard = (function() {
38744
38843
  init: function() {
38745
38844
  setupDialogs();
38746
38845
 
38747
- $('<textarea type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo("#red-ui-editor");
38748
-
38749
38846
  RED.actions.add("core:show-export-dialog",showExportNodes);
38750
38847
  RED.actions.add("core:show-import-dialog",showImportNodes);
38751
38848
 
@@ -40119,6 +40216,7 @@ RED.search = (function() {
40119
40216
  val = extractFlag(val,"unused",flags);
40120
40217
  val = extractFlag(val,"config",flags);
40121
40218
  val = extractFlag(val,"subflow",flags);
40219
+ val = extractFlag(val,"hidden",flags);
40122
40220
  // uses:<node-id>
40123
40221
  val = extractValue(val,"uses",flags);
40124
40222
 
@@ -40164,7 +40262,15 @@ RED.search = (function() {
40164
40262
  continue;
40165
40263
  }
40166
40264
  }
40167
-
40265
+ if (flags.hasOwnProperty("hidden")) {
40266
+ // Only tabs can be hidden
40267
+ if (node.node.type !== 'tab') {
40268
+ continue
40269
+ }
40270
+ if (!RED.workspaces.isHidden(node.node.id)) {
40271
+ continue
40272
+ }
40273
+ }
40168
40274
  if (flags.hasOwnProperty("unused")) {
40169
40275
  var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
40170
40276
  (isConfigNode && node.node.users.length === 0)
@@ -49928,6 +50034,8 @@ RED.touch.radialMenu = (function() {
49928
50034
  if (step.fallback) {
49929
50035
  focus.one("mouseenter", function(evt) {
49930
50036
  setTimeout(function() {
50037
+ var pos = targetElement[0].getBoundingClientRect();
50038
+ var dimension = Math.max(50, Math.max(pos.width,pos.height)*1.5);
49931
50039
  focus.css({
49932
50040
  width: (4*dimension)+"px",
49933
50041
  height: (4*dimension)+"px"