@node-red/editor-client 2.1.0 → 2.1.4

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;
@@ -7799,7 +7818,7 @@ RED.utils = (function() {
7799
7818
  level: 'block', // Is this a block-level or inline-level tokenizer?
7800
7819
  start(src) {
7801
7820
  if (!src) { return null; }
7802
- let m = src.match(/:[^:\n]/);
7821
+ let m = src.match(/:[^:\n]/g);
7803
7822
  return m && m.index; // Hint to Marked.js to stop and check for a match
7804
7823
  },
7805
7824
  tokenizer(src, tokens) {
@@ -7825,7 +7844,7 @@ RED.utils = (function() {
7825
7844
  level: 'inline', // Is this a block-level or inline-level tokenizer?
7826
7845
  start(src) {
7827
7846
  if (!src) { return null; }
7828
- let m = src.match(/:/);
7847
+ let m = src.match(/:/g);
7829
7848
  return m && m.index; // Hint to Marked.js to stop and check for a match
7830
7849
  },
7831
7850
  tokenizer(src, tokens) {
@@ -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");
@@ -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
  },
@@ -13567,7 +13596,8 @@ RED.stack = (function() {
13567
13596
  }
13568
13597
  nlsd = true;
13569
13598
  var that = this;
13570
-
13599
+ this.identifier = this.element.attr('id') || "TypedInput-"+Math.floor(Math.random()*100);
13600
+ if (this.options.debug) { console.log(this.identifier,"Create",{defaultType:this.options.default, value:this.element.val()}) }
13571
13601
  this.disarmClick = false;
13572
13602
  this.input = $('<input class="red-ui-typedInput-input" type="text"></input>');
13573
13603
  this.input.insertAfter(this.element);
@@ -13681,9 +13711,9 @@ RED.stack = (function() {
13681
13711
  // explicitly set optionSelectTrigger display to inline-block otherwise jQ sets it to 'inline'
13682
13712
  this.optionSelectTrigger = $('<button tabindex="0" class="red-ui-typedInput-option-trigger" style="display:inline-block"><span class="red-ui-typedInput-option-caret"><i class="red-ui-typedInput-icon fa fa-caret-down"></i></span></button>').appendTo(this.uiSelect);
13683
13713
  this.optionSelectLabel = $('<span class="red-ui-typedInput-option-label"></span>').prependTo(this.optionSelectTrigger);
13684
- RED.popover.tooltip(this.optionSelectLabel,function() {
13685
- return that.optionValue;
13686
- });
13714
+ // RED.popover.tooltip(this.optionSelectLabel,function() {
13715
+ // return that.optionValue;
13716
+ // });
13687
13717
  this.optionSelectTrigger.on("click", function(event) {
13688
13718
  event.preventDefault();
13689
13719
  event.stopPropagation();
@@ -13703,7 +13733,8 @@ RED.stack = (function() {
13703
13733
  this.optionExpandButton = $('<button tabindex="0" class="red-ui-typedInput-option-expand" style="display:inline-block"></button>').appendTo(this.uiSelect);
13704
13734
  this.optionExpandButtonIcon = $('<i class="red-ui-typedInput-icon fa fa-ellipsis-h"></i>').appendTo(this.optionExpandButton);
13705
13735
 
13706
- this.type(this.options.default||this.typeList[0].value);
13736
+ this.type(this.typeField.val() || this.options.default||this.typeList[0].value);
13737
+ this.typeChanged = !!this.options.default;
13707
13738
  }catch(err) {
13708
13739
  console.log(err.stack);
13709
13740
  }
@@ -13951,6 +13982,7 @@ RED.stack = (function() {
13951
13982
  var that = this;
13952
13983
  var currentType = this.type();
13953
13984
  this.typeMap = {};
13985
+ var firstCall = (this.typeList === undefined);
13954
13986
  this.typeList = types.map(function(opt) {
13955
13987
  var result;
13956
13988
  if (typeof opt === 'string') {
@@ -13975,10 +14007,14 @@ RED.stack = (function() {
13975
14007
  }
13976
14008
  this.menu = this._createMenu(this.typeList,{},function(v) { that.type(v) });
13977
14009
  if (currentType && !this.typeMap.hasOwnProperty(currentType)) {
13978
- this.type(this.typeList[0].value);
14010
+ if (!firstCall) {
14011
+ this.type(this.typeList[0].value);
14012
+ }
13979
14013
  } else {
13980
14014
  this.propertyType = null;
13981
- this.type(currentType);
14015
+ if (!firstCall) {
14016
+ this.type(currentType);
14017
+ }
13982
14018
  }
13983
14019
  if (this.typeList.length === 1 && !this.typeList[0].icon && (!this.typeList[0].label || this.typeList[0].showLabel === false)) {
13984
14020
  this.selectTrigger.hide()
@@ -13994,7 +14030,10 @@ RED.stack = (function() {
13994
14030
  },
13995
14031
  value: function(value) {
13996
14032
  var that = this;
13997
- var opt = this.typeMap[this.propertyType];
14033
+ // If the default type has been set to an invalid type, then on first
14034
+ // creation, the current propertyType will not exist. Default to an
14035
+ // empty object on the assumption the corrent type will be set shortly
14036
+ var opt = this.typeMap[this.propertyType] || {};
13998
14037
  if (!arguments.length) {
13999
14038
  var v = this.input.val();
14000
14039
  if (opt.export) {
@@ -14002,27 +14041,38 @@ RED.stack = (function() {
14002
14041
  }
14003
14042
  return v;
14004
14043
  } else {
14044
+ if (this.options.debug) { console.log(this.identifier,"----- SET VALUE ------",value) }
14005
14045
  var selectedOption = [];
14046
+ var valueToCheck = value;
14006
14047
  if (opt.options) {
14007
- var checkValues = [value];
14048
+ if (opt.hasValue && opt.parse) {
14049
+ var parts = opt.parse(value);
14050
+ if (this.options.debug) { console.log(this.identifier,"new parse",parts) }
14051
+ value = parts.value;
14052
+ valueToCheck = parts.option || parts.value;
14053
+ }
14054
+
14055
+ var checkValues = [valueToCheck];
14008
14056
  if (opt.multiple) {
14009
14057
  selectedOption = [];
14010
- checkValues = value.split(",");
14058
+ checkValues = valueToCheck.split(",");
14011
14059
  }
14012
- checkValues.forEach(function(value) {
14060
+ checkValues.forEach(function(valueToCheck) {
14013
14061
  for (var i=0;i<opt.options.length;i++) {
14014
14062
  var op = opt.options[i];
14015
14063
  if (typeof op === "string") {
14016
- if (op === value || op === ""+value) {
14064
+ if (op === valueToCheck || op === ""+valueToCheck) {
14017
14065
  selectedOption.push(that.activeOptions[op]);
14018
14066
  break;
14019
14067
  }
14020
- } else if (op.value === value) {
14068
+ } else if (op.value === valueToCheck) {
14021
14069
  selectedOption.push(op);
14022
14070
  break;
14023
14071
  }
14024
14072
  }
14025
14073
  })
14074
+ if (this.options.debug) { console.log(this.identifier,"set value to",value) }
14075
+
14026
14076
  this.input.val(value);
14027
14077
  if (!opt.multiple) {
14028
14078
  if (selectedOption.length === 0) {
@@ -14047,15 +14097,16 @@ RED.stack = (function() {
14047
14097
  return this.propertyType;
14048
14098
  } else {
14049
14099
  var that = this;
14100
+ if (this.options.debug) { console.log(this.identifier,"----- SET TYPE -----",type) }
14050
14101
  var previousValue = null;
14051
14102
  var opt = this.typeMap[type];
14052
14103
  if (opt && this.propertyType !== type) {
14053
14104
  // If previousType is !null, then this is a change of the type, rather than the initialisation
14054
14105
  var previousType = this.typeMap[this.propertyType];
14055
- var typeChanged = !!previousType;
14056
14106
  previousValue = this.input.val();
14057
14107
 
14058
- if (typeChanged) {
14108
+ if (previousType && this.typeChanged) {
14109
+ if (this.options.debug) { console.log(this.identifier,"typeChanged",{previousType,previousValue}) }
14059
14110
  if (previousType.options && opt.hasValue !== true) {
14060
14111
  this.oldValues[previousType.value] = previousValue;
14061
14112
  } else if (previousType.hasValue === false) {
@@ -14065,27 +14116,37 @@ RED.stack = (function() {
14065
14116
  }
14066
14117
  if ((opt.options && opt.hasValue !== true) || opt.hasValue === false) {
14067
14118
  if (this.oldValues.hasOwnProperty(opt.value)) {
14119
+ if (this.options.debug) { console.log(this.identifier,"restored previous (1)",this.oldValues[opt.value]) }
14068
14120
  this.input.val(this.oldValues[opt.value]);
14069
- } else {
14121
+ } else if (opt.options) {
14070
14122
  // No old value for the option type.
14071
14123
  // It is possible code has called 'value' then 'type'
14072
14124
  // to set the selected option. This is what the Inject/Switch/Change
14073
14125
  // nodes did before 2.1.
14074
14126
  // So we need to be careful to not reset the value if it is a valid option.
14075
14127
  var validOptions = isOptionValueValid(opt,previousValue);
14076
- if (previousValue && validOptions) {
14128
+ if (this.options.debug) { console.log(this.identifier,{previousValue,opt,validOptions}) }
14129
+ if ((previousValue || previousValue === '') && validOptions) {
14130
+ if (this.options.debug) { console.log(this.identifier,"restored previous (2)") }
14077
14131
  this.input.val(previousValue);
14078
14132
  } else {
14079
14133
  if (typeof opt.default === "string") {
14134
+ if (this.options.debug) { console.log(this.identifier,"restored previous (3)",opt.default) }
14080
14135
  this.input.val(opt.default);
14081
14136
  } else if (Array.isArray(opt.default)) {
14137
+ if (this.options.debug) { console.log(this.identifier,"restored previous (4)",opt.default.join(",")) }
14082
14138
  this.input.val(opt.default.join(","))
14083
14139
  } else {
14140
+ if (this.options.debug) { console.log(this.identifier,"restored previous (5)") }
14084
14141
  this.input.val("");
14085
14142
  }
14086
14143
  }
14144
+ } else {
14145
+ if (this.options.debug) { console.log(this.identifier,"restored default/blank",opt.default||"") }
14146
+ this.input.val(opt.default||"")
14087
14147
  }
14088
14148
  } else {
14149
+ if (this.options.debug) { console.log(this.identifier,"restored old/default/blank") }
14089
14150
  this.input.val(this.oldValues.hasOwnProperty("_")?this.oldValues["_"]:(opt.default||""))
14090
14151
  }
14091
14152
  if (previousType.autoComplete) {
@@ -14093,6 +14154,7 @@ RED.stack = (function() {
14093
14154
  }
14094
14155
  }
14095
14156
  this.propertyType = type;
14157
+ this.typeChanged = true;
14096
14158
  if (this.typeField) {
14097
14159
  this.typeField.val(type);
14098
14160
  }
@@ -14188,7 +14250,8 @@ RED.stack = (function() {
14188
14250
  } else {
14189
14251
  var selectedOption = this.optionValue||opt.options[0];
14190
14252
  if (opt.parse) {
14191
- var parts = opt.parse(this.input.val(),selectedOption);
14253
+ var selectedOptionObj = typeof selectedOption === "string"?{value:selectedOption}:selectedOption
14254
+ var parts = opt.parse(this.input.val(),selectedOptionObj);
14192
14255
  if (parts.option) {
14193
14256
  selectedOption = parts.option;
14194
14257
  if (!this.activeOptions.hasOwnProperty(selectedOption)) {
@@ -14212,6 +14275,7 @@ RED.stack = (function() {
14212
14275
  this._updateOptionSelectLabel(this.activeOptions[selectedOption]);
14213
14276
  }
14214
14277
  } else if (selectedOption) {
14278
+ if (this.options.debug) { console.log(this.identifier,"HERE",{optionValue:selectedOption.value}) }
14215
14279
  this.optionValue = selectedOption.value;
14216
14280
  this._updateOptionSelectLabel(selectedOption);
14217
14281
  } else {
@@ -14502,7 +14566,7 @@ RED.stack = (function() {
14502
14566
  * value: String : the value to insert if selected
14503
14567
  * label: String|DOM Element : the label to display in the dropdown.
14504
14568
  * }
14505
- *
14569
+ *
14506
14570
  */
14507
14571
 
14508
14572
  $.widget( "nodered.autoComplete", {
@@ -14543,7 +14607,7 @@ RED.stack = (function() {
14543
14607
  maxHeight: 200,
14544
14608
  class: "red-ui-autoComplete-container",
14545
14609
  options: completions,
14546
- 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") },
14547
14611
  onclose: () => { this.completionMenuShown = false; delete this.menu; this.element.focus()}
14548
14612
  });
14549
14613
  this.menu.show({
@@ -15720,6 +15784,8 @@ RED.deploy = (function() {
15720
15784
  color: "#DDAA99",
15721
15785
  defaults:{name:{value:""}}
15722
15786
  }
15787
+ } else if (node.type === "group") {
15788
+ def = RED.group.def;
15723
15789
  } else {
15724
15790
  def = {};
15725
15791
  }
@@ -15929,16 +15995,15 @@ RED.deploy = (function() {
15929
15995
  }
15930
15996
  }
15931
15997
 
15932
-
15933
15998
  if (node.hasOwnProperty('x')) {
15934
15999
  if (localNode) {
15935
- 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 ) {
15936
16001
  localChanged = true;
15937
16002
  localChanges++;
15938
16003
  }
15939
16004
  }
15940
16005
  if (remoteNode) {
15941
- 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) {
15942
16007
  remoteChanged = true;
15943
16008
  remoteChanges++;
15944
16009
  }
@@ -15956,7 +16021,12 @@ RED.deploy = (function() {
15956
16021
  localCell.addClass("red-ui-diff-status-"+(localChanged?"changed":"unchanged"));
15957
16022
  $('<span class="red-ui-diff-status">'+(localChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(localCell);
15958
16023
  element = $('<span class="red-ui-diff-list-element"></span>').appendTo(localCell);
15959
- 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,
15960
16030
  {
15961
16031
  path: "position",
15962
16032
  exposeApi: true,
@@ -15977,7 +16047,12 @@ RED.deploy = (function() {
15977
16047
  if (remoteNode) {
15978
16048
  $('<span class="red-ui-diff-status">'+(remoteChanged?'<i class="fa fa-square"></i>':'')+'</span>').appendTo(remoteCell);
15979
16049
  element = $('<span class="red-ui-diff-list-element"></span>').appendTo(remoteCell);
15980
- 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,
15981
16056
  {
15982
16057
  path: "position",
15983
16058
  exposeApi: true,
@@ -16049,11 +16124,11 @@ RED.deploy = (function() {
16049
16124
  }
16050
16125
  }
16051
16126
  }
16052
- 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))});
16053
16128
  if (def.defaults) {
16054
16129
  properties = properties.concat(Object.keys(def.defaults));
16055
16130
  }
16056
- if (node.type !== 'tab') {
16131
+ if (node.type !== 'tab' && node.type !== "group") {
16057
16132
  properties = properties.concat(['inputLabels','outputLabels']);
16058
16133
  }
16059
16134
  if ( ((localNode && localNode.hasOwnProperty('icon')) || (remoteNode && remoteNode.hasOwnProperty('icon'))) &&
@@ -18306,55 +18381,64 @@ RED.workspaces = (function() {
18306
18381
  scrollable: true,
18307
18382
  addButton: "core:add-flow",
18308
18383
  addButtonCaption: RED._("workspace.addFlow"),
18309
- menu: [
18310
- {
18311
- id:"red-ui-tabs-menu-option-search-flows",
18312
- label: RED._("workspace.listFlows"),
18313
- onselect: "core:list-flows"
18314
- },
18315
- {
18316
- id:"red-ui-tabs-menu-option-search-subflows",
18317
- label: RED._("workspace.listSubflows"),
18318
- onselect: "core:list-subflows"
18319
- },
18320
- null,
18321
- {
18322
- id:"red-ui-tabs-menu-option-add-flow",
18323
- label: RED._("workspace.addFlow"),
18324
- onselect: "core:add-flow"
18325
- },
18326
- {
18327
- id:"red-ui-tabs-menu-option-add-flow-right",
18328
- label: RED._("workspace.addFlowToRight"),
18329
- onselect: "core:add-flow-to-right"
18330
- },
18331
- null,
18332
- {
18333
- id:"red-ui-tabs-menu-option-add-hide-flows",
18334
- label: RED._("workspace.hideFlow"),
18335
- onselect: "core:hide-flow"
18336
- },
18337
- {
18338
- id:"red-ui-tabs-menu-option-add-hide-other-flows",
18339
- label: RED._("workspace.hideOtherFlows"),
18340
- onselect: "core:hide-other-flows"
18341
- },
18342
- {
18343
- id:"red-ui-tabs-menu-option-add-show-all-flows",
18344
- label: RED._("workspace.showAllFlows"),
18345
- onselect: "core:show-all-flows"
18346
- },
18347
- {
18348
- id:"red-ui-tabs-menu-option-add-hide-all-flows",
18349
- label: RED._("workspace.hideAllFlows"),
18350
- onselect: "core:hide-all-flows"
18351
- },
18352
- {
18353
- id:"red-ui-tabs-menu-option-add-show-last-flow",
18354
- label: RED._("workspace.showLastHiddenFlow"),
18355
- onselect: "core:show-last-hidden-flow"
18384
+ menu: function() {
18385
+ var menuItems = [
18386
+ {
18387
+ id:"red-ui-tabs-menu-option-search-flows",
18388
+ label: RED._("workspace.listFlows"),
18389
+ onselect: "core:list-flows"
18390
+ },
18391
+ {
18392
+ id:"red-ui-tabs-menu-option-search-subflows",
18393
+ label: RED._("workspace.listSubflows"),
18394
+ onselect: "core:list-subflows"
18395
+ },
18396
+ null,
18397
+ {
18398
+ id:"red-ui-tabs-menu-option-add-flow",
18399
+ label: RED._("workspace.addFlow"),
18400
+ onselect: "core:add-flow"
18401
+ },
18402
+ {
18403
+ id:"red-ui-tabs-menu-option-add-flow-right",
18404
+ label: RED._("workspace.addFlowToRight"),
18405
+ onselect: "core:add-flow-to-right"
18406
+ },
18407
+ null,
18408
+ {
18409
+ id:"red-ui-tabs-menu-option-add-hide-flows",
18410
+ label: RED._("workspace.hideFlow"),
18411
+ onselect: "core:hide-flow"
18412
+ },
18413
+ {
18414
+ id:"red-ui-tabs-menu-option-add-hide-other-flows",
18415
+ label: RED._("workspace.hideOtherFlows"),
18416
+ onselect: "core:hide-other-flows"
18417
+ },
18418
+ {
18419
+ id:"red-ui-tabs-menu-option-add-show-all-flows",
18420
+ label: RED._("workspace.showAllFlows"),
18421
+ onselect: "core:show-all-flows"
18422
+ },
18423
+ {
18424
+ id:"red-ui-tabs-menu-option-add-hide-all-flows",
18425
+ label: RED._("workspace.hideAllFlows"),
18426
+ onselect: "core:hide-all-flows"
18427
+ },
18428
+ {
18429
+ id:"red-ui-tabs-menu-option-add-show-last-flow",
18430
+ label: RED._("workspace.showLastHiddenFlow"),
18431
+ onselect: "core:show-last-hidden-flow"
18432
+ }
18433
+ ]
18434
+ if (hideStack.length > 0) {
18435
+ menuItems.unshift({
18436
+ label: RED._("workspace.hiddenFlows",{count: hideStack.length}),
18437
+ onselect: "core:list-hidden-flows"
18438
+ })
18356
18439
  }
18357
- ]
18440
+ return menuItems;
18441
+ }
18358
18442
  });
18359
18443
  workspaceTabCount = 0;
18360
18444
  }
@@ -18494,7 +18578,9 @@ RED.workspaces = (function() {
18494
18578
  }
18495
18579
  }
18496
18580
  })
18497
-
18581
+ RED.actions.add("core:list-hidden-flows",function() {
18582
+ RED.actions.invoke("core:search","is:hidden ");
18583
+ })
18498
18584
  RED.actions.add("core:list-flows",function() {
18499
18585
  RED.actions.invoke("core:search","type:tab ");
18500
18586
  })
@@ -18538,7 +18624,7 @@ RED.workspaces = (function() {
18538
18624
  var changes = { disabled: workspace.disabled };
18539
18625
  workspace.disabled = disabled;
18540
18626
  $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
18541
- if (id || activeWorkspace) {
18627
+ if (!id || (id === activeWorkspace)) {
18542
18628
  $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
18543
18629
  }
18544
18630
  var historyEvent = {
@@ -18624,6 +18710,9 @@ RED.workspaces = (function() {
18624
18710
  RED.settings.setLocal("hiddenTabs",JSON.stringify(hiddenTabs));
18625
18711
  }
18626
18712
  },
18713
+ isHidden: function(id) {
18714
+ return hideStack.includes(id)
18715
+ },
18627
18716
  show: function(id,skipStack,unhideOnly) {
18628
18717
  if (!workspace_tabs.contains(id)) {
18629
18718
  var sf = RED.nodes.subflow(id);
@@ -22396,7 +22485,11 @@ RED.view = (function() {
22396
22485
  nodeEl = document.getElementById(d.id);
22397
22486
  }
22398
22487
  if (nodeEl) {
22399
- if (!showStatus || !d.status) {
22488
+ // Do not show node status if:
22489
+ // - global flag set
22490
+ // - node has no status
22491
+ // - node is disabled
22492
+ if (!showStatus || !d.status || d.d === true) {
22400
22493
  nodeEl.__statusGroup__.style.display = "none";
22401
22494
  } else {
22402
22495
  nodeEl.__statusGroup__.style.display = "inline";
@@ -23142,6 +23235,9 @@ RED.view = (function() {
23142
23235
  n.selected = true;
23143
23236
  n.dirty = true;
23144
23237
  movingSet.add(n);
23238
+ if (targets.length === 1) {
23239
+ RED.view.reveal(n.id);
23240
+ }
23145
23241
  });
23146
23242
  updateSelection();
23147
23243
  redraw();
@@ -23678,7 +23774,7 @@ RED.view = (function() {
23678
23774
  counts.push(RED._("clipboard.group",{count:newGroupCount}));
23679
23775
  }
23680
23776
  if (newConfigNodeCount > 0) {
23681
- counts.push(RED._("clipboard.configNode",{count:newNodeCount}));
23777
+ counts.push(RED._("clipboard.configNode",{count:newConfigNodeCount}));
23682
23778
  }
23683
23779
  if (new_subflows.length > 0) {
23684
23780
  counts.push(RED._("clipboard.subflow",{count:new_subflows.length}));
@@ -23750,6 +23846,7 @@ RED.view = (function() {
23750
23846
  delete node.d;
23751
23847
  }
23752
23848
  node.dirty = true;
23849
+ node.dirtyStatus = true;
23753
23850
  node.changed = true;
23754
23851
  RED.events.emit("nodes:change",node);
23755
23852
  }
@@ -26912,6 +27009,7 @@ RED.sidebar.info = (function() {
26912
27009
  n.d = true;
26913
27010
  }
26914
27011
  n.dirty = true;
27012
+ n.dirtyStatus = true;
26915
27013
  n.changed = true;
26916
27014
  RED.events.emit("nodes:change",n);
26917
27015
  groupHistoryEvent.events.push(historyEvent);
@@ -26940,6 +27038,7 @@ RED.sidebar.info = (function() {
26940
27038
  n.d = true;
26941
27039
  }
26942
27040
  n.dirty = true;
27041
+ n.dirtyStatus = true;
26943
27042
  n.changed = true;
26944
27043
  RED.events.emit("nodes:change",n);
26945
27044
  RED.history.push(historyEvent);
@@ -27009,6 +27108,7 @@ RED.sidebar.info = (function() {
27009
27108
  {label:RED._("sidebar.info.search.invalidNodes"), value: "is:invalid"},
27010
27109
  {label:RED._("sidebar.info.search.uknownNodes"), value: "type:unknown"},
27011
27110
  {label:RED._("sidebar.info.search.unusedSubflows"), value:"is:subflow is:unused"},
27111
+ {label:RED._("sidebar.info.search.hiddenFlows"), value:"is:hidden"},
27012
27112
  ]
27013
27113
  });
27014
27114
 
@@ -27300,7 +27400,7 @@ RED.sidebar.info = (function() {
27300
27400
  }
27301
27401
  }
27302
27402
  function getGutter(n) {
27303
- var span = $("<span>",{class:"red-ui-info-outline-gutter"});
27403
+ var span = $("<span>",{class:"red-ui-info-outline-gutter red-ui-treeList-gutter-float"});
27304
27404
  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) {
27305
27405
  evt.preventDefault();
27306
27406
  evt.stopPropagation();
@@ -27801,7 +27901,7 @@ RED.sidebar.help = (function() {
27801
27901
  var currentVersionParts = RED.settings.version.split(".");
27802
27902
  var tourVersionParts = tour.version.split(".");
27803
27903
  if (tourVersionParts[0] === currentVersionParts[0] && tourVersionParts[1] === currentVersionParts[1]) {
27804
- tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">Take a tour</button></div>'
27904
+ tourHeader = '<div><button type="button" onclick="RED.actions.invoke(\'core:show-welcome-tour\')" class="red-ui-button">' + RED._("tourGuide.takeATour") + '</button></div>';
27805
27905
  }
27806
27906
  }
27807
27907
  var aboutHeader = '<div style="text-align:center;">'+tourHeader+'</div>'
@@ -30582,7 +30682,16 @@ RED.editor = (function() {
30582
30682
  delete cn.__label__;
30583
30683
  });
30584
30684
 
30585
- select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:type})+'</option>');
30685
+ var label = type;
30686
+ if (typeof node_def.paletteLabel !== "undefined") {
30687
+ try {
30688
+ label = RED.utils.sanitize((typeof node_def.paletteLabel === "function" ? node_def.paletteLabel.call(node_def) : node_def.paletteLabel)||type);
30689
+ } catch(err) {
30690
+ console.log("Definition error: "+type+".paletteLabel",err);
30691
+ }
30692
+ }
30693
+
30694
+ select.append('<option value="_ADD_"'+(value===""?" selected":"")+'>'+RED._("editor.addNewType", {type:label})+'</option>');
30586
30695
  window.setTimeout(function() { select.trigger("change");},50);
30587
30696
  }
30588
30697
  }
@@ -32421,8 +32530,12 @@ RED.editor = (function() {
32421
32530
  });
32422
32531
  }
32423
32532
  if (!isSameObj(old_env, new_env)) {
32424
- node.env = new_env;
32425
32533
  editState.changes.env = node.env;
32534
+ if (new_env.length === 0) {
32535
+ delete node.env;
32536
+ } else {
32537
+ node.env = new_env;
32538
+ }
32426
32539
  editState.changed = true;
32427
32540
  }
32428
32541
  }
@@ -32852,34 +32965,6 @@ RED.editor = (function() {
32852
32965
  }
32853
32966
 
32854
32967
  })();
32855
- ;;(function() {
32856
-
32857
- RED.editor.registerEditPane(
32858
- "editor-tab-testing",
32859
- function(node) {
32860
- return {
32861
- label: "Testing",
32862
- name: "Testing",
32863
- iconClass: "fa fa-paper-plane",
32864
- create: function(container) {
32865
- },
32866
- resize: function(size) {
32867
- },
32868
- close: function() {
32869
- },
32870
- show: function() {
32871
- },
32872
- apply: function(editState) {
32873
- }
32874
- }
32875
- },
32876
- function(node) {
32877
- if (node.type === "inject") {
32878
- return true;
32879
- }
32880
- }
32881
- );
32882
- })();
32883
32968
  ;/**
32884
32969
  * Copyright JS Foundation and other contributors, http://js.foundation
32885
32970
  *
@@ -40117,6 +40202,7 @@ RED.search = (function() {
40117
40202
  val = extractFlag(val,"unused",flags);
40118
40203
  val = extractFlag(val,"config",flags);
40119
40204
  val = extractFlag(val,"subflow",flags);
40205
+ val = extractFlag(val,"hidden",flags);
40120
40206
  // uses:<node-id>
40121
40207
  val = extractValue(val,"uses",flags);
40122
40208
 
@@ -40162,7 +40248,15 @@ RED.search = (function() {
40162
40248
  continue;
40163
40249
  }
40164
40250
  }
40165
-
40251
+ if (flags.hasOwnProperty("hidden")) {
40252
+ // Only tabs can be hidden
40253
+ if (node.node.type !== 'tab') {
40254
+ continue
40255
+ }
40256
+ if (!RED.workspaces.isHidden(node.node.id)) {
40257
+ continue
40258
+ }
40259
+ }
40166
40260
  if (flags.hasOwnProperty("unused")) {
40167
40261
  var isUnused = (node.node.type === 'subflow' && node.node.instances.length === 0) ||
40168
40262
  (isConfigNode && node.node.users.length === 0)
@@ -49910,7 +50004,12 @@ RED.touch.radialMenu = (function() {
49910
50004
  maxWidth: maxWidth+"px",
49911
50005
  direction: direction,
49912
50006
  })
49913
-
50007
+ setTimeout(function() {
50008
+ var pos = popover.element.position()
50009
+ if (pos.left < 0) {
50010
+ popover.element.css({left: 0});
50011
+ }
50012
+ },100);
49914
50013
  if (nextButton) {
49915
50014
  setTimeout(function() {
49916
50015
  nextButton.focus();
@@ -49921,6 +50020,8 @@ RED.touch.radialMenu = (function() {
49921
50020
  if (step.fallback) {
49922
50021
  focus.one("mouseenter", function(evt) {
49923
50022
  setTimeout(function() {
50023
+ var pos = targetElement[0].getBoundingClientRect();
50024
+ var dimension = Math.max(50, Math.max(pos.width,pos.height)*1.5);
49924
50025
  focus.css({
49925
50026
  width: (4*dimension)+"px",
49926
50027
  height: (4*dimension)+"px"