@node-red/editor-client 2.1.0-beta.1 → 2.1.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/public/red/red.js CHANGED
@@ -292,6 +292,7 @@ var RED = (function() {
292
292
  RED.projects.refresh(function(activeProject) {
293
293
  loadFlows(function() {
294
294
  RED.sidebar.info.refresh()
295
+ var showProjectWelcome = false;
295
296
  if (!activeProject) {
296
297
  // Projects enabled but no active project
297
298
  RED.menu.setDisabled('menu-item-projects-open',true);
@@ -299,10 +300,10 @@ var RED = (function() {
299
300
  if (activeProject === false) {
300
301
  // User previously decline the migration to projects.
301
302
  } else { // null/undefined
302
- RED.projects.showStartup();
303
+ showProjectWelcome = true;
303
304
  }
304
305
  }
305
- completeLoad();
306
+ completeLoad(showProjectWelcome);
306
307
  });
307
308
  });
308
309
  } else {
@@ -342,6 +343,9 @@ var RED = (function() {
342
343
  if (/^#flow\/.+$/.test(currentHash)) {
343
344
  RED.workspaces.show(currentHash.substring(6),true);
344
345
  }
346
+ if (RED.workspaces.active() === 0 && RED.workspaces.count() > 0) {
347
+ RED.workspaces.show(RED.nodes.getWorkspaceOrder()[0])
348
+ }
345
349
  } catch(err) {
346
350
  console.warn(err);
347
351
  RED.notify(
@@ -358,7 +362,7 @@ var RED = (function() {
358
362
  });
359
363
  }
360
364
 
361
- function completeLoad() {
365
+ function completeLoad(showProjectWelcome) {
362
366
  var persistentNotifications = {};
363
367
  RED.comms.subscribe("notification/#",function(topic,msg) {
364
368
  var parts = topic.split("/");
@@ -568,8 +572,17 @@ var RED = (function() {
568
572
  RED.nodes.addNodeSet(m);
569
573
  addedTypes = addedTypes.concat(m.types);
570
574
  RED.i18n.loadNodeCatalog(id, function() {
571
- $.get('nodes/'+id, function(data) {
572
- appendNodeConfig(data);
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
+ }
573
586
  });
574
587
  });
575
588
  });
@@ -596,10 +609,19 @@ var RED = (function() {
596
609
  typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
597
610
  RED.notify(RED._("palette.event.nodeEnabled", {count:msg.types.length})+typeList,"success");
598
611
  } else {
599
- $.get('nodes/'+msg.id, function(data) {
600
- appendNodeConfig(data);
601
- typeList = "<ul><li>"+msg.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
602
- RED.notify(RED._("palette.event.nodeAdded", {count:msg.types.length})+typeList,"success");
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
+ }
603
625
  });
604
626
  }
605
627
  }
@@ -626,18 +648,24 @@ var RED = (function() {
626
648
 
627
649
  setTimeout(function() {
628
650
  loader.end();
629
- checkFirstRun();
651
+ checkFirstRun(function() {
652
+ if (showProjectWelcome) {
653
+ RED.projects.showStartup();
654
+ }
655
+ });
630
656
  },100);
631
657
  }
632
658
 
633
- function checkFirstRun() {
659
+ function checkFirstRun(done) {
634
660
  if (RED.settings.theme("tours") === false) {
661
+ done();
635
662
  return;
636
663
  }
637
664
  if (!RED.settings.get("editor.view.view-show-welcome-tours", true)) {
665
+ done();
638
666
  return;
639
667
  }
640
- RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome"));
668
+ RED.actions.invoke("core:show-welcome-tour", RED.settings.get("editor.tours.welcome"), done);
641
669
  }
642
670
 
643
671
  function buildMainMenu() {
@@ -3813,8 +3841,8 @@ RED.nodes = (function() {
3813
3841
  },
3814
3842
  moveNode: function(n, newZ) {
3815
3843
  api.removeNode(n);
3816
- tabMap[newZ] = tabMap[newZ] || [];
3817
- tabMap[newZ].push(n);
3844
+ n.z = newZ;
3845
+ api.addNode(n)
3818
3846
  },
3819
3847
  moveNodesForwards: function(nodes) {
3820
3848
  var result = [];
@@ -4266,29 +4294,29 @@ RED.nodes = (function() {
4266
4294
  moveGroupToTab(node,z);
4267
4295
  return;
4268
4296
  }
4297
+ var oldZ = node.z;
4269
4298
  allNodes.moveNode(node,z);
4270
4299
  var nl = nodeLinks[node.id];
4271
4300
  if (nl) {
4272
4301
  nl.in.forEach(function(l) {
4273
- var idx = linkTabMap[node.z].indexOf(l);
4302
+ var idx = linkTabMap[oldZ].indexOf(l);
4274
4303
  if (idx != -1) {
4275
- linkTabMap[node.z].splice(idx, 1);
4304
+ linkTabMap[oldZ].splice(idx, 1);
4276
4305
  }
4277
4306
  if ((l.source.z === z) && linkTabMap[z]) {
4278
4307
  linkTabMap[z].push(l);
4279
4308
  }
4280
4309
  });
4281
4310
  nl.out.forEach(function(l) {
4282
- var idx = linkTabMap[node.z].indexOf(l);
4311
+ var idx = linkTabMap[oldZ].indexOf(l);
4283
4312
  if (idx != -1) {
4284
- linkTabMap[node.z].splice(idx, 1);
4313
+ linkTabMap[oldZ].splice(idx, 1);
4285
4314
  }
4286
4315
  if ((l.target.z === z) && linkTabMap[z]) {
4287
4316
  linkTabMap[z].push(l);
4288
4317
  }
4289
4318
  });
4290
4319
  }
4291
- node.z = z;
4292
4320
  RED.events.emit("nodes:change",node);
4293
4321
  }
4294
4322
  function moveGroupToTab(group, z) {
@@ -5931,7 +5959,6 @@ RED.nodes = (function() {
5931
5959
  }
5932
5960
 
5933
5961
  function clear() {
5934
- allNodes.clear();
5935
5962
  links = [];
5936
5963
  linkTabMap = {};
5937
5964
  nodeLinks = {};
@@ -5952,6 +5979,8 @@ RED.nodes = (function() {
5952
5979
  initialLoad = null;
5953
5980
  workspaces = {};
5954
5981
 
5982
+ allNodes.clear();
5983
+
5955
5984
  RED.nodes.dirty(false);
5956
5985
  RED.view.redraw(true, true);
5957
5986
  RED.palette.refresh();
@@ -7782,12 +7811,12 @@ RED.utils = (function() {
7782
7811
  type: 'descriptionList', // Should match "name" above
7783
7812
  raw: match[0], // Text to consume from the source
7784
7813
  text: match[0].trim(), // Additional custom properties
7785
- tokens: this.inlineTokens(match[0].trim()) // inlineTokens to process **bold**, *italics*, etc.
7814
+ tokens: this.lexer.inlineTokens(match[0].trim()) // inlineTokens to process **bold**, *italics*, etc.
7786
7815
  };
7787
7816
  }
7788
7817
  },
7789
7818
  renderer(token) {
7790
- return `<dl class="message-properties">${this.parseInline(token.tokens)}\n</dl>`; // parseInline to turn child tokens into HTML
7819
+ return `<dl class="message-properties">${this.parser.parseInline(token.tokens)}\n</dl>`; // parseInline to turn child tokens into HTML
7791
7820
  }
7792
7821
  };
7793
7822
 
@@ -7807,14 +7836,14 @@ RED.utils = (function() {
7807
7836
  return { // Token to generate
7808
7837
  type: 'description', // Should match "name" above
7809
7838
  raw: match[0], // Text to consume from the source
7810
- dt: this.inlineTokens(match[1].trim()), // Additional custom properties
7811
- types: this.inlineTokens(match[2].trim()),
7812
- dd: this.inlineTokens(match[3].trim()),
7839
+ dt: this.lexer.inlineTokens(match[1].trim()), // Additional custom properties
7840
+ types: this.lexer.inlineTokens(match[2].trim()),
7841
+ dd: this.lexer.inlineTokens(match[3].trim()),
7813
7842
  };
7814
7843
  }
7815
7844
  },
7816
7845
  renderer(token) {
7817
- return `\n<dt>${this.parseInline(token.dt)}<span class="property-type">${this.parseInline(token.types)}</span></dt><dd>${this.parseInline(token.dd)}</dd>`;
7846
+ return `\n<dt>${this.parser.parseInline(token.dt)}<span class="property-type">${this.parser.parseInline(token.types)}</span></dt><dd>${this.parser.parseInline(token.dd)}</dd>`;
7818
7847
  },
7819
7848
  childTokens: ['dt', 'dd'], // Any child tokens to be visited by walkTokens
7820
7849
  walkTokens(token) { // Post-processing on the completed token tree
@@ -8306,7 +8335,8 @@ RED.utils = (function() {
8306
8335
  expandPaths: expandPaths,
8307
8336
  ontoggle: ontoggle,
8308
8337
  exposeApi: exposeApi,
8309
- tools: tools
8338
+ // tools: tools // Do not pass tools down as we
8339
+ // keep them attached to the top-level header
8310
8340
  }
8311
8341
  ).appendTo(row);
8312
8342
  }
@@ -8335,7 +8365,8 @@ RED.utils = (function() {
8335
8365
  expandPaths: expandPaths,
8336
8366
  ontoggle: ontoggle,
8337
8367
  exposeApi: exposeApi,
8338
- tools: tools
8368
+ // tools: tools // Do not pass tools down as we
8369
+ // keep them attached to the top-level header
8339
8370
  }
8340
8371
  ).appendTo(row);
8341
8372
  }
@@ -8390,7 +8421,8 @@ RED.utils = (function() {
8390
8421
  expandPaths: expandPaths,
8391
8422
  ontoggle: ontoggle,
8392
8423
  exposeApi: exposeApi,
8393
- tools: tools
8424
+ // tools: tools // Do not pass tools down as we
8425
+ // keep them attached to the top-level header
8394
8426
  }
8395
8427
  ).appendTo(row);
8396
8428
  }
@@ -9577,6 +9609,9 @@ RED.utils = (function() {
9577
9609
  * - rootSortable: boolean - if 'sortable' is set, then setting this to
9578
9610
  * false, prevents items being sorted to the
9579
9611
  * top level of the tree
9612
+ * - autoSelect: boolean - default true - triggers item selection when navigating
9613
+ * list by keyboard. If the list has checkboxed items
9614
+ * you probably want to set this to false
9580
9615
  *
9581
9616
  * methods:
9582
9617
  * - data(items) - clears existing items and replaces with new data
@@ -9603,6 +9638,7 @@ RED.utils = (function() {
9603
9638
  * deferBuild: true/false, // don't build any ui elements for the item's children
9604
9639
  * until it is expanded by the user.
9605
9640
  * element: // custom dom element to use for the item - ignored if `label` is set
9641
+ * collapsible: true/false, // prevent a parent item from being collapsed. default true.
9606
9642
  * }
9607
9643
  * ]
9608
9644
  *
@@ -9643,77 +9679,96 @@ RED.utils = (function() {
9643
9679
  $.widget( "nodered.treeList", {
9644
9680
  _create: function() {
9645
9681
  var that = this;
9646
-
9682
+ var autoSelect = true;
9683
+ if (that.options.autoSelect === false) {
9684
+ autoSelect = false;
9685
+ }
9647
9686
  this.element.addClass('red-ui-treeList');
9648
9687
  this.element.attr("tabIndex",0);
9649
9688
  var wrapper = $('<div>',{class:'red-ui-treeList-container'}).appendTo(this.element);
9650
9689
  this.element.on('keydown', function(evt) {
9651
- var selected = that._topList.find(".selected").parent().data('data');
9652
- if (!selected && (evt.keyCode === 40 || evt.keyCode === 38)) {
9653
- that.select(that._data[0]);
9690
+ var focussed = that._topList.find(".focus").parent().data('data');
9691
+ if (!focussed && (evt.keyCode === 40 || evt.keyCode === 38)) {
9692
+ if (that._data[0]) {
9693
+ if (autoSelect) {
9694
+ that.select(that._data[0]);
9695
+ } else {
9696
+ that._topList.find(".focus").removeClass("focus")
9697
+ }
9698
+ that._data[0].treeList.label.addClass('focus')
9699
+ }
9654
9700
  return;
9655
9701
  }
9656
9702
  var target;
9657
9703
  switch(evt.keyCode) {
9704
+ case 32: // SPACE
9658
9705
  case 13: // ENTER
9659
9706
  evt.preventDefault();
9660
9707
  evt.stopPropagation();
9661
- if (selected.children) {
9662
- if (selected.treeList.container.hasClass("expanded")) {
9663
- selected.treeList.collapse()
9708
+ if (focussed.checkbox) {
9709
+ focussed.treeList.checkbox.trigger("click");
9710
+ } else if (focussed.radio) {
9711
+ focussed.treeList.radio.trigger("click");
9712
+ } else if (focussed.children) {
9713
+ if (focussed.treeList.container.hasClass("expanded")) {
9714
+ focussed.treeList.collapse()
9664
9715
  } else {
9665
- selected.treeList.expand()
9716
+ focussed.treeList.expand()
9666
9717
  }
9667
9718
  } else {
9668
- that._trigger("confirm",null,selected)
9719
+ that._trigger("confirm",null,focussed)
9669
9720
  }
9670
-
9671
9721
  break;
9672
9722
  case 37: // LEFT
9673
9723
  evt.preventDefault();
9674
9724
  evt.stopPropagation();
9675
- if (selected.children&& selected.treeList.container.hasClass("expanded")) {
9676
- selected.treeList.collapse()
9677
- } else if (selected.parent) {
9678
- target = selected.parent;
9725
+ if (focussed.children&& focussed.treeList.container.hasClass("expanded")) {
9726
+ focussed.treeList.collapse()
9727
+ } else if (focussed.parent) {
9728
+ target = focussed.parent;
9679
9729
  }
9680
9730
  break;
9681
9731
  case 38: // UP
9682
9732
  evt.preventDefault();
9683
9733
  evt.stopPropagation();
9684
- target = that._getPreviousSibling(selected);
9734
+ target = that._getPreviousSibling(focussed);
9685
9735
  if (target) {
9686
9736
  target = that._getLastDescendant(target);
9687
9737
  }
9688
- if (!target && selected.parent) {
9689
- target = selected.parent;
9738
+ if (!target && focussed.parent) {
9739
+ target = focussed.parent;
9690
9740
  }
9691
9741
  break;
9692
9742
  case 39: // RIGHT
9693
9743
  evt.preventDefault();
9694
9744
  evt.stopPropagation();
9695
- if (selected.children) {
9696
- if (!selected.treeList.container.hasClass("expanded")) {
9697
- selected.treeList.expand()
9745
+ if (focussed.children) {
9746
+ if (!focussed.treeList.container.hasClass("expanded")) {
9747
+ focussed.treeList.expand()
9698
9748
  }
9699
9749
  }
9700
9750
  break
9701
9751
  case 40: //DOWN
9702
9752
  evt.preventDefault();
9703
9753
  evt.stopPropagation();
9704
- if (selected.children && Array.isArray(selected.children) && selected.children.length > 0 && selected.treeList.container.hasClass("expanded")) {
9705
- target = selected.children[0];
9754
+ if (focussed.children && Array.isArray(focussed.children) && focussed.children.length > 0 && focussed.treeList.container.hasClass("expanded")) {
9755
+ target = focussed.children[0];
9706
9756
  } else {
9707
- target = that._getNextSibling(selected);
9708
- while (!target && selected.parent) {
9709
- selected = selected.parent;
9710
- target = that._getNextSibling(selected);
9757
+ target = that._getNextSibling(focussed);
9758
+ while (!target && focussed.parent) {
9759
+ focussed = focussed.parent;
9760
+ target = that._getNextSibling(focussed);
9711
9761
  }
9712
9762
  }
9713
9763
  break
9714
9764
  }
9715
9765
  if (target) {
9716
- that.select(target);
9766
+ if (autoSelect) {
9767
+ that.select(target);
9768
+ } else {
9769
+ that._topList.find(".focus").removeClass("focus")
9770
+ }
9771
+ target.treeList.label.addClass('focus')
9717
9772
  }
9718
9773
  });
9719
9774
  this._data = [];
@@ -10016,6 +10071,9 @@ RED.utils = (function() {
10016
10071
  container.addClass("expanded");
10017
10072
  }
10018
10073
  item.treeList.collapse = function() {
10074
+ if (item.collapsible === false) {
10075
+ return
10076
+ }
10019
10077
  if (!item.children) {
10020
10078
  return;
10021
10079
  }
@@ -10090,6 +10148,7 @@ RED.utils = (function() {
10090
10148
  var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (depth * 20)
10091
10149
  item.treeList.labelPadding = $('<span>').css({
10092
10150
  display: "inline-block",
10151
+ "flex-shrink": 0,
10093
10152
  width: labelPaddingWidth+'px'
10094
10153
  }).appendTo(label);
10095
10154
 
@@ -10135,7 +10194,7 @@ RED.utils = (function() {
10135
10194
  // Already a parent because we've got the angle-right icon
10136
10195
  return;
10137
10196
  }
10138
- $('<i class="fa fa-angle-right" />').appendTo(treeListIcon);
10197
+ $('<i class="fa fa-angle-right" />').toggleClass("hide",item.collapsible === false).appendTo(treeListIcon);
10139
10198
  treeListIcon.on("click.red-ui-treeList-expand", function(e) {
10140
10199
  e.stopPropagation();
10141
10200
  e.preventDefault();
@@ -10186,6 +10245,8 @@ RED.utils = (function() {
10186
10245
  label.on("click", function(e) {
10187
10246
  e.stopPropagation();
10188
10247
  cb.trigger("click");
10248
+ that._topList.find(".focus").removeClass("focus")
10249
+ label.addClass('focus')
10189
10250
  })
10190
10251
  }
10191
10252
  item.treeList.select = function(v) {
@@ -10193,6 +10254,7 @@ RED.utils = (function() {
10193
10254
  cb.trigger("click");
10194
10255
  }
10195
10256
  }
10257
+ item.treeList.checkbox = cb;
10196
10258
  selectWrapper.appendTo(label)
10197
10259
  } else if (item.radio) {
10198
10260
  var selectWrapper = $('<span class="red-ui-treeList-icon"></span>');
@@ -10221,6 +10283,8 @@ RED.utils = (function() {
10221
10283
  label.on("click", function(e) {
10222
10284
  e.stopPropagation();
10223
10285
  cb.trigger("click");
10286
+ that._topList.find(".focus").removeClass("focus")
10287
+ label.addClass('focus')
10224
10288
  })
10225
10289
  }
10226
10290
  item.treeList.select = function(v) {
@@ -10229,6 +10293,7 @@ RED.utils = (function() {
10229
10293
  }
10230
10294
  }
10231
10295
  selectWrapper.appendTo(label)
10296
+ item.treeList.radio = cb;
10232
10297
  } else {
10233
10298
  label.on("click", function(e) {
10234
10299
  if (!that.options.multi) {
@@ -10236,10 +10301,14 @@ RED.utils = (function() {
10236
10301
  }
10237
10302
  label.addClass("selected");
10238
10303
  that._selected.add(item);
10304
+ that._topList.find(".focus").removeClass("focus")
10305
+ label.addClass('focus')
10239
10306
 
10240
10307
  that._trigger("select",e,item)
10241
10308
  })
10242
10309
  label.on("dblclick", function(e) {
10310
+ that._topList.find(".focus").removeClass("focus")
10311
+ label.addClass('focus')
10243
10312
  if (!item.children) {
10244
10313
  that._trigger("confirm",e,item);
10245
10314
  }
@@ -10387,6 +10456,9 @@ RED.utils = (function() {
10387
10456
  if (item.treeList.label) {
10388
10457
  item.treeList.label.addClass("selected");
10389
10458
  }
10459
+
10460
+ that._topList.find(".focus").removeClass("focus");
10461
+
10390
10462
  if (triggerEvent !== false) {
10391
10463
  this._trigger("select",null,item)
10392
10464
  }
@@ -10394,6 +10466,9 @@ RED.utils = (function() {
10394
10466
  clearSelection: function() {
10395
10467
  this._selected.forEach(function(item) {
10396
10468
  item.selected = false;
10469
+ if (item.treeList.checkbox) {
10470
+ item.treeList.checkbox.prop('checked',false)
10471
+ }
10397
10472
  if (item.treeList.label) {
10398
10473
  item.treeList.label.removeClass("selected")
10399
10474
  }
@@ -11475,18 +11550,17 @@ RED.popover = (function() {
11475
11550
  return {
11476
11551
  create: createPopover,
11477
11552
  tooltip: function(target,content, action) {
11478
- var label = content;
11479
- if (action) {
11480
- label = function() {
11481
- var label = content;
11553
+ var label = function() {
11554
+ var label = content;
11555
+ if (action) {
11482
11556
  var shortcut = RED.keyboard.getShortcut(action);
11483
11557
  if (shortcut && shortcut.key) {
11484
11558
  label = $('<span>'+content+' <span class="red-ui-popover-key">'+RED.keyboard.formatKey(shortcut.key, true)+'</span></span>');
11485
11559
  }
11486
- return label;
11487
11560
  }
11561
+ return label;
11488
11562
  }
11489
- return RED.popover.create({
11563
+ var popover = RED.popover.create({
11490
11564
  tooltip: true,
11491
11565
  target:target,
11492
11566
  trigger: "hover",
@@ -11495,6 +11569,14 @@ RED.popover = (function() {
11495
11569
  content: label,
11496
11570
  delay: { show: 750, hide: 50 }
11497
11571
  });
11572
+ popover.setContent = function(newContent) {
11573
+ content = newContent;
11574
+ }
11575
+ popover.setAction = function(newAction) {
11576
+ action = newAction;
11577
+ }
11578
+ return popover;
11579
+
11498
11580
  },
11499
11581
  menu: function(options) {
11500
11582
  var list = $('<ul class="red-ui-menu"></ul>');
@@ -12034,9 +12116,9 @@ RED.tabs = (function() {
12034
12116
  }
12035
12117
  })
12036
12118
  scrollLeft = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-left"><a href="#" style="display:none;"><i class="fa fa-caret-left"></i></a></div>').appendTo(wrapper).find("a");
12037
- scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();});
12119
+ scrollLeft.on('mousedown',function(evt) {scrollEventHandler(evt, evt.shiftKey?('-='+scrollContainer.scrollLeft()):'-=150') }).on('click',function(evt){ evt.preventDefault();});
12038
12120
  scrollRight = $('<div class="red-ui-tab-button red-ui-tab-scroll red-ui-tab-scroll-right"><a href="#" style="display:none;"><i class="fa fa-caret-right"></i></a></div>').appendTo(wrapper).find("a");
12039
- scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,'+=150') }).on('click',function(evt){ evt.preventDefault();});
12121
+ scrollRight.on('mousedown',function(evt) { scrollEventHandler(evt,evt.shiftKey?('+='+(scrollContainer[0].scrollWidth - scrollContainer.width()-scrollContainer.scrollLeft())):'+=150') }).on('click',function(evt){ evt.preventDefault();});
12040
12122
  }
12041
12123
 
12042
12124
  if (options.collapsible) {
@@ -17511,7 +17593,13 @@ RED.keyboard = (function() {
17511
17593
 
17512
17594
  function resolveKeyEvent(evt) {
17513
17595
  var slot = partialState||handlers;
17514
- if (evt.ctrlKey || evt.metaKey) {
17596
+ // We cheat with MacOS CMD key and consider it the same as Ctrl.
17597
+ // That means we don't have to have separate keymaps for different OS.
17598
+ // It mostly works.
17599
+ // One exception is shortcuts that include both Cmd and Ctrl. We don't
17600
+ // support them - but we need to make sure we don't block browser-specific
17601
+ // shortcuts (such as Cmd-Ctrl-F for fullscreen).
17602
+ if ((evt.ctrlKey || evt.metaKey) && (evt.ctrlKey !== evt.metaKey)) {
17515
17603
  slot = slot.ctrl;
17516
17604
  }
17517
17605
  if (slot && evt.shiftKey) {
@@ -18408,7 +18496,7 @@ RED.workspaces = (function() {
18408
18496
  var changes = { disabled: workspace.disabled };
18409
18497
  workspace.disabled = disabled;
18410
18498
  $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
18411
- if (id === activeWorkspace) {
18499
+ if (id || activeWorkspace) {
18412
18500
  $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
18413
18501
  }
18414
18502
  var historyEvent = {
@@ -22597,10 +22685,10 @@ RED.view = (function() {
22597
22685
  var labelParts;
22598
22686
  if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label || this.__outputs__.length !== d.outputs) {
22599
22687
  labelParts = getLabelParts(label, "red-ui-flow-node-label");
22600
- this.__label__ = label;
22601
- if (labelParts.lines.length !== this.__labelLineCount__) {
22688
+ if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
22602
22689
  d.resize = true;
22603
22690
  }
22691
+ this.__label__ = label;
22604
22692
  this.__labelLineCount__ = labelParts.lines.length;
22605
22693
 
22606
22694
  if (hideLabel) {
@@ -26894,11 +26982,11 @@ RED.sidebar.info = (function() {
26894
26982
  var node = RED.nodes.node(item.id) || RED.nodes.group(item.id);
26895
26983
  if (node) {
26896
26984
  if (node.type === 'group' || node._def.category !== "config") {
26897
- RED.view.select({nodes:[node]})
26985
+ // RED.view.select({nodes:[node]})
26898
26986
  } else if (node._def.category === "config") {
26899
26987
  RED.sidebar.info.refresh(node);
26900
26988
  } else {
26901
- RED.view.select({nodes:[]})
26989
+ // RED.view.select({nodes:[]})
26902
26990
  }
26903
26991
  }
26904
26992
  })
@@ -27685,10 +27773,12 @@ RED.sidebar.help = (function() {
27685
27773
  treeList.treeList("select","changelog");
27686
27774
  show();
27687
27775
  }
27688
- function showWelcomeTour(lastSeenVersion) {
27776
+ function showWelcomeTour(lastSeenVersion, done) {
27777
+ done = done || function() {};
27689
27778
  RED.tourGuide.load("./tours/welcome.js", function(err, tour) {
27690
27779
  if (err) {
27691
27780
  console.warn("Failed to load welcome tour",err);
27781
+ done()
27692
27782
  return;
27693
27783
  }
27694
27784
  var currentVersionParts = RED.settings.version.split(".");
@@ -27697,6 +27787,7 @@ RED.sidebar.help = (function() {
27697
27787
  // Only display the tour if its MAJ.MIN versions the current version
27698
27788
  // This means if we update MAJ/MIN without updating the tour, the old tour won't get shown
27699
27789
  if (tourVersionParts[0] !== currentVersionParts[0] || tourVersionParts[1] !== currentVersionParts[1]) {
27790
+ done()
27700
27791
  return;
27701
27792
  }
27702
27793
 
@@ -27704,26 +27795,31 @@ RED.sidebar.help = (function() {
27704
27795
  // Previously displayed a welcome tour.
27705
27796
  if (lastSeenVersion === RED.settings.version) {
27706
27797
  // Exact match - don't show the tour
27798
+ done()
27707
27799
  return;
27708
27800
  }
27709
27801
  var lastSeenParts = lastSeenVersion.split(".");
27710
27802
  if (currentVersionParts[0] < lastSeenParts[0] || (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] < lastSeenParts[1])) {
27711
27803
  // Running an *older* version than last displayed tour.
27804
+ done()
27712
27805
  return;
27713
27806
  }
27714
27807
  if (currentVersionParts[0] === lastSeenParts[0] && currentVersionParts[1] === lastSeenParts[1]) {
27715
27808
  if (lastSeenParts.length === 3 && currentVersionParts.length === 3) {
27716
27809
  // Matching non-beta MAJ.MIN - don't repeat tour
27810
+ done()
27717
27811
  return;
27718
27812
  }
27719
27813
  if (currentVersionParts.length === 4 && (lastSeenParts.length === 3 || currentVersionParts[3] < lastSeenParts[3])) {
27720
27814
  // Running an *older* beta than last displayed tour.
27815
+ done()
27721
27816
  return
27722
27817
  }
27723
27818
  }
27724
27819
  }
27725
27820
  RED.tourGuide.run("./tours/welcome.js", function(err) {
27726
27821
  RED.settings.set("editor.tours.welcome", RED.settings.version)
27822
+ done()
27727
27823
  })
27728
27824
  })
27729
27825
 
@@ -31455,8 +31551,12 @@ RED.editor = (function() {
31455
31551
  editState.changes.disabled = workspace.disabled;
31456
31552
  editState.changed = true;
31457
31553
  workspace.disabled = disabled;
31458
- }
31459
31554
 
31555
+ $("#red-ui-tab-"+(workspace.id.replace(".","-"))).toggleClass('red-ui-workspace-disabled',!!workspace.disabled);
31556
+ if (workspace.id === RED.workspaces.active()) {
31557
+ $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled",!!workspace.disabled);
31558
+ }
31559
+ }
31460
31560
 
31461
31561
  if (editState.changed) {
31462
31562
  var historyEvent = {
@@ -45669,6 +45769,7 @@ RED.projects = (function() {
45669
45769
  return {
45670
45770
  init: init,
45671
45771
  showStartup: function() {
45772
+ console.warn("showStartup")
45672
45773
  if (!RED.user.hasPermission("projects.write")) {
45673
45774
  RED.notify(RED._("user.errors.notAuthorized"),"error");
45674
45775
  return;