@node-red/editor-client 5.0.0-beta.1 → 5.0.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
@@ -945,7 +945,6 @@ var RED = (function() {
945
945
  '<div id="red-ui-workspace"></div>'+
946
946
  '<div id="red-ui-sidebar"></div>'+
947
947
  '<div id="red-ui-editor-stack" tabindex="-1"></div>'+
948
- // '<div id="red-ui-palette"></div>'+
949
948
  '</div>').appendTo(options.target);
950
949
 
951
950
  // Don't use the `hide` class on this container, as the show reverts it to block rather
@@ -955,6 +954,7 @@ var RED = (function() {
955
954
  $('<div id="red-ui-editor-plugin-configs"></div>').appendTo(options.target);
956
955
  $('<div id="red-ui-editor-node-configs"></div>').appendTo(options.target);
957
956
  $('<div id="red-ui-full-shade" class="hide"></div>').appendTo(options.target);
957
+ $('<div id="red-ui-global-dialog-container"></div>').appendTo(options.target);
958
958
 
959
959
  loader.init().appendTo("#red-ui-main-container");
960
960
  loader.start("...",0);
@@ -10063,7 +10063,13 @@ RED.utils = (function() {
10063
10063
  var copyPayload = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-clipboard"></i></button>').appendTo(copyTools).on("click", function(e) {
10064
10064
  e.preventDefault();
10065
10065
  e.stopPropagation();
10066
- RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue");
10066
+ var payloadToCopy;
10067
+ if (typeof msg === "number") {
10068
+ payloadToCopy = obj.find(".red-ui-debug-msg-type-number").first().text();
10069
+ } else {
10070
+ payloadToCopy = msg;
10071
+ }
10072
+ RED.clipboard.copyText(payloadToCopy, copyPayload, "clipboard.copyMessageValue");
10067
10073
  })
10068
10074
  RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload"));
10069
10075
  if (enablePinning && strippedKey !== undefined && strippedKey !== '') {
@@ -10391,7 +10397,7 @@ RED.utils = (function() {
10391
10397
  var sr = $('<div class="red-ui-debug-msg-object-entry collapsed"></div>').appendTo(stringRow);
10392
10398
  var stringEncoding = "";
10393
10399
  try {
10394
- stringEncoding = String.fromCharCode.apply(null, new Uint16Array(data))
10400
+ stringEncoding = new TextDecoder().decode(new Uint8Array(data));
10395
10401
  } catch(err) {
10396
10402
  console.log(err);
10397
10403
  }
@@ -11684,8 +11690,10 @@ RED.utils = (function() {
11684
11690
  var deleteButton = $('<a/>',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(li);
11685
11691
  $('<i/>',{class:"fa fa-remove"}).appendTo(deleteButton);
11686
11692
  li.addClass("red-ui-editableList-item-removable");
11693
+ var removeTip = RED.popover.tooltip(deleteButton, RED._("common.label.delete"));
11687
11694
  deleteButton.on("click", function(evt) {
11688
11695
  evt.preventDefault();
11696
+ removeTip.close();
11689
11697
  var data = row.data('data');
11690
11698
  li.addClass("red-ui-editableList-item-deleting")
11691
11699
  li.fadeOut(300, function() {
@@ -11833,6 +11841,7 @@ RED.utils = (function() {
11833
11841
  * - autoSelect: boolean - default true - triggers item selection when navigating
11834
11842
  * list by keyboard. If the list has checkboxed items
11835
11843
  * you probably want to set this to false
11844
+ * - expandOnLabel: boolean - default true - items expand when their label is clicked
11836
11845
  *
11837
11846
  * methods:
11838
11847
  * - data(items) - clears existing items and replaces with new data
@@ -11896,6 +11905,7 @@ RED.utils = (function() {
11896
11905
  *
11897
11906
  *
11898
11907
  */
11908
+ const paddingPerDepth = 5;
11899
11909
 
11900
11910
  $.widget( "nodered.treeList", {
11901
11911
  _create: function() {
@@ -11993,7 +12003,10 @@ RED.utils = (function() {
11993
12003
  } else {
11994
12004
  that._topList.find(".focus").removeClass("focus")
11995
12005
  }
11996
- target.treeList.label.addClass('focus')
12006
+ if (target.treeList.label) {
12007
+ target.treeList.label.addClass('focus')
12008
+ }
12009
+ that.reveal(target);
11997
12010
  }
11998
12011
  });
11999
12012
  this._data = [];
@@ -12147,11 +12160,11 @@ RED.utils = (function() {
12147
12160
  if (child.depth !== parent.depth+1) {
12148
12161
  child.depth = parent.depth+1;
12149
12162
  // var labelPaddingWidth = ((child.gutter ? child.gutter[0].offsetWidth + 2 : 0) + (child.depth * 20));
12150
- var labelPaddingWidth = (((child.gutter&&!child.gutter.hasClass("red-ui-treeList-gutter-float"))?child.gutter.width()+2:0)+(child.depth*20));
12163
+ var labelPaddingWidth = (((child.gutter&&!child.gutter.hasClass("red-ui-treeList-gutter-float"))?child.gutter.width()+2:0)+(child.depth*paddingPerDepth));
12151
12164
  child.treeList.labelPadding.width(labelPaddingWidth+'px');
12152
12165
  if (child.element) {
12153
12166
  $(child.element).css({
12154
- width: "calc(100% - "+(labelPaddingWidth+20+(child.icon?20:0))+"px)"
12167
+ width: "calc(100% - "+(labelPaddingWidth+paddingPerDepth+(child.icon?paddingPerDepth:0))+"px)"
12155
12168
  })
12156
12169
  }
12157
12170
  // This corrects all child item depths
@@ -12280,7 +12293,7 @@ RED.utils = (function() {
12280
12293
  if (!childrenAdded) {
12281
12294
  startTime = Date.now();
12282
12295
  spinner = $('<div class="red-ui-treeList-spinner">').css({
12283
- "background-position": (35+depth*20)+'px 50%'
12296
+ "background-position": (35+depth*paddingPerDepth)+'px 50%'
12284
12297
  }).appendTo(container);
12285
12298
  }
12286
12299
 
@@ -12332,10 +12345,10 @@ RED.utils = (function() {
12332
12345
  $(element).appendTo(item.treeList.label);
12333
12346
  // using the JQuery Object, the gutter width will
12334
12347
  // be wrong when the element is reattached the second time
12335
- var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (item.depth * 20);
12348
+ var labelPaddingWidth = (item.gutter ? item.gutter[0].offsetWidth + 2 : 0) + (item.depth * paddingPerDepth);
12336
12349
 
12337
12350
  $(element).css({
12338
- width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)"
12351
+ width: "calc(100% - "+(labelPaddingWidth+paddingPerDepth+(item.icon?paddingPerDepth:0))+"px)"
12339
12352
  })
12340
12353
  }
12341
12354
  item.element = element;
@@ -12370,7 +12383,7 @@ RED.utils = (function() {
12370
12383
 
12371
12384
  }
12372
12385
 
12373
- var labelPaddingWidth = ((item.gutter&&!item.gutter.hasClass("red-ui-treeList-gutter-float"))?item.gutter.width()+2:0)+(depth*20);
12386
+ var labelPaddingWidth = ((item.gutter&&!item.gutter.hasClass("red-ui-treeList-gutter-float"))?item.gutter.width()+2:0)+(depth*paddingPerDepth);
12374
12387
 
12375
12388
  item.treeList.labelPadding = $('<span>').css({
12376
12389
  display: "inline-block",
@@ -12432,12 +12445,14 @@ RED.utils = (function() {
12432
12445
  });
12433
12446
  // $('<span class="red-ui-treeList-icon"><i class="fa fa-folder-o" /></span>').appendTo(label);
12434
12447
  label.on("click.red-ui-treeList-expand", function(e) {
12435
- if (container.hasClass("expanded")) {
12436
- if (item.hasOwnProperty('selected') || label.hasClass("selected")) {
12437
- item.treeList.collapse();
12448
+ if (that.options.expandOnLabel !== false || item.expandOnLabel === true) {
12449
+ if (container.hasClass("expanded")) {
12450
+ if (item.hasOwnProperty('selected') || label.hasClass("selected")) {
12451
+ item.treeList.collapse();
12452
+ }
12453
+ } else {
12454
+ item.treeList.expand();
12438
12455
  }
12439
- } else {
12440
- item.treeList.expand();
12441
12456
  }
12442
12457
  })
12443
12458
  if (!item.children) {
@@ -12575,7 +12590,7 @@ RED.utils = (function() {
12575
12590
  } else if (item.element) {
12576
12591
  $(item.element).appendTo(label);
12577
12592
  $(item.element).css({
12578
- width: "calc(100% - "+(labelPaddingWidth+20+(item.icon?20:0))+"px)"
12593
+ width: "calc(100% - "+(labelPaddingWidth+paddingPerDepth+(item.icon?paddingPerDepth:0))+"px)"
12579
12594
  })
12580
12595
  }
12581
12596
  if (item.children) {
@@ -12684,6 +12699,10 @@ RED.utils = (function() {
12684
12699
  }
12685
12700
 
12686
12701
  that._topList.find(".focus").removeClass("focus");
12702
+
12703
+ if (item.treeList.label) {
12704
+ item.treeList.label.addClass("focus");
12705
+ }
12687
12706
 
12688
12707
  if (triggerEvent !== false) {
12689
12708
  this._trigger("select",null,item)
@@ -14790,12 +14809,18 @@ RED.tabs = (function() {
14790
14809
  }
14791
14810
  function activatePreviousTab() {
14792
14811
  var previous = findPreviousVisibleTab();
14812
+ if (previous.length === 0) {
14813
+ previous = ul.find("li.red-ui-tab:not(.hide-tab)").last();
14814
+ }
14793
14815
  if (previous.length > 0) {
14794
14816
  activateTab(previous.find("a"));
14795
14817
  }
14796
14818
  }
14797
14819
  function activateNextTab() {
14798
14820
  var next = findNextVisibleTab();
14821
+ if (next.length === 0) {
14822
+ next = ul.find("li.red-ui-tab:not(.hide-tab)").first();
14823
+ }
14799
14824
  if (next.length > 0) {
14800
14825
  activateTab(next.find("a"));
14801
14826
  }
@@ -17952,16 +17977,10 @@ RED.deploy = (function() {
17952
17977
  }
17953
17978
 
17954
17979
  function shadeShow() {
17955
- $("#red-ui-header-shade").show();
17956
- $("#red-ui-editor-shade").show();
17957
- $("#red-ui-palette-shade").show();
17958
- $(".red-ui-sidebar-shade").show();
17980
+ RED.notifications.shade.show();
17959
17981
  }
17960
17982
  function shadeHide() {
17961
- $("#red-ui-header-shade").hide();
17962
- $("#red-ui-editor-shade").hide();
17963
- $("#red-ui-palette-shade").hide();
17964
- $(".red-ui-sidebar-shade").hide();
17983
+ RED.notifications.shade.hide();
17965
17984
  }
17966
17985
  function deployButtonSetBusy(){
17967
17986
  $(".red-ui-deploy-button-content").css('opacity',0);
@@ -23639,8 +23658,8 @@ RED.view = (function() {
23639
23658
  element: $('<span class="button-group">'+
23640
23659
  '<button class="red-ui-footer-button" id="red-ui-view-searchtools-search"><i class="fa fa-search"></i></button>' +
23641
23660
  '</span>' +
23642
- '<span class="button-group search-counter">' +
23643
- '<span class="red-ui-footer-button" id="red-ui-view-searchtools-counter">? of ?</span>' +
23661
+ '<span class="button-group red-ui-view-searchtools-counter">' +
23662
+ '<span class="red-ui-footer-button" id="red-ui-view-searchtools-counter-label">? of ?</span>' +
23644
23663
  '</span>' +
23645
23664
  '<span class="button-group">' +
23646
23665
  '<button class="red-ui-footer-button" id="red-ui-view-searchtools-prev"><i class="fa fa-chevron-left"></i></button>' +
@@ -24414,6 +24433,13 @@ RED.view = (function() {
24414
24433
  quickAddLink.virtualLink = true;
24415
24434
  }
24416
24435
  hideDragLines();
24436
+ } else if (quickAddLink) {
24437
+ // continuing an existing quick add - set the filter accordingly
24438
+ if (quickAddLink.portType === PORT_TYPE_OUTPUT) {
24439
+ filter = {input:true}
24440
+ } else {
24441
+ filter = {output:true}
24442
+ }
24417
24443
  }
24418
24444
  if (linkToSplice || spliceMultipleLinks) {
24419
24445
  filter = {
@@ -30040,6 +30066,9 @@ RED.view = (function() {
30040
30066
  suggestedNodes = [suggestedNodes]
30041
30067
  }
30042
30068
  suggestedNodes = suggestedNodes.filter(n => {
30069
+ if (n.type === 'junction') {
30070
+ return true
30071
+ }
30043
30072
  const def = RED.nodes.getType(n.type)
30044
30073
  if (def?.set && def.set.enabled === false) {
30045
30074
  // Exclude disabled node set
@@ -30465,7 +30494,6 @@ RED.view = (function() {
30465
30494
  },
30466
30495
  selectNodes: function(options) {
30467
30496
  $("#red-ui-workspace-tabs-shade").show();
30468
- $("#red-ui-palette-shade").show();
30469
30497
  $(".red-ui-sidebar-shade").show();
30470
30498
  $("#red-ui-header-shade").show();
30471
30499
  $("#red-ui-workspace").addClass("red-ui-workspace-select-mode");
@@ -30487,7 +30515,6 @@ RED.view = (function() {
30487
30515
  var closeNotification = function() {
30488
30516
  clearSelection();
30489
30517
  $("#red-ui-workspace-tabs-shade").hide();
30490
- $("#red-ui-palette-shade").hide();
30491
30518
  $(".red-ui-sidebar-shade").hide();
30492
30519
  $("#red-ui-header-shade").hide();
30493
30520
  $("#red-ui-workspace").removeClass("red-ui-workspace-select-mode");
@@ -31149,8 +31176,8 @@ RED.view.navigator = (function() {
31149
31176
  RED.actions.add("core:toggle-navigator",toggle);
31150
31177
  navContainer = $('<div>').css({
31151
31178
  "position":"absolute",
31152
- "bottom":$("#red-ui-workspace-footer").height() + 2,
31153
- "right": 4,
31179
+ "bottom":$("#red-ui-workspace-footer").height() + 12,
31180
+ "right": 16,
31154
31181
  zIndex: 1
31155
31182
  }).addClass('red-ui-navigator-container').appendTo("#red-ui-workspace").hide();
31156
31183
  navBox = d3.select(navContainer[0])
@@ -32699,6 +32726,7 @@ RED.view.tools = (function() {
32699
32726
  * limitations under the License.
32700
32727
  **/
32701
32728
  RED.sidebar = (function() {
32729
+ const sidebarLayoutVersion = 1
32702
32730
  const sidebars = {
32703
32731
  primary: {
32704
32732
  id: 'primary',
@@ -32717,12 +32745,12 @@ RED.sidebar = (function() {
32717
32745
  maximumWidth: 800,
32718
32746
  // Make LH side slightly narrower by default as its the palette that doesn't require a lot of width
32719
32747
  defaultWidth: 210,
32720
- defaultTopHeight: 1
32748
+ defaultTopHeight: 0.5
32721
32749
  }
32722
32750
  }
32723
32751
  const defaultSidebarConfiguration = {
32724
32752
  primary: [ ['info','help','config','context'], ['debug'] ],
32725
- secondary: [ ['explorer','palette'], [] ]
32753
+ secondary: [ ['explorer'], ['palette'] ]
32726
32754
  }
32727
32755
 
32728
32756
  const knownTabs = {};
@@ -32730,7 +32758,8 @@ RED.sidebar = (function() {
32730
32758
  function exportSidebarState () {
32731
32759
  const state = {
32732
32760
  primary: [[], []],
32733
- secondary: [[], []]
32761
+ secondary: [[], []],
32762
+ v: sidebarLayoutVersion
32734
32763
  }
32735
32764
  function getTabButtons(tabBar) {
32736
32765
  const result = []
@@ -32779,8 +32808,8 @@ RED.sidebar = (function() {
32779
32808
 
32780
32809
  // Check the saved sidebar state to see if this tab should be added to the primary or secondary sidebar
32781
32810
  let savedState = RED.settings.get('editor.sidebar.state', defaultSidebarConfiguration)
32782
- if (true || typeof savedState.primary[0] === 'string' || typeof savedState.secondary[0] === 'string') {
32783
- // This is a beta.0 format. Reset it for beta.1
32811
+ if (typeof savedState.primary[0] === 'string' || typeof savedState.secondary[0] === 'string' || savedState.v === undefined) {
32812
+ // This is a beta.0/1 format. Reset it for beta.2
32784
32813
  savedState = defaultSidebarConfiguration
32785
32814
  RED.settings.set('editor.sidebar.state', savedState)
32786
32815
  }
@@ -32874,6 +32903,11 @@ RED.sidebar = (function() {
32874
32903
  const targetSidebar = options.target === 'secondary' ? sidebars.secondary : sidebars.primary;
32875
32904
  //
32876
32905
  if (targetSidebar.tabBars[options.targetSection].active === options.id && RED.menu.isSelected(targetSidebar.menuToggle)) {
32906
+ // if (!targetSidebar.sections[options.targetSection].hidden) {
32907
+ // targetSidebar.hideSection(options.targetSection)
32908
+ // } else {
32909
+ // targetSidebar.showSection(options.targetSection)
32910
+ // }
32877
32911
  RED.menu.setSelected(targetSidebar.menuToggle, false);
32878
32912
  } else {
32879
32913
  RED.sidebar.show(options.id)
@@ -32949,23 +32983,30 @@ RED.sidebar = (function() {
32949
32983
  sidebar.tabBars.bottom.resizeSidebarTabBar();
32950
32984
  }
32951
32985
  sidebar.hideSection = function (position) {
32952
- sidebar.sections.bottom.container.hide()
32953
- sidebar.sections.bottom.hidden = true
32954
- sidebar.sections.top.container.css('flex-grow', '1')
32955
- sidebar.tabBars.top.container.css('flex-grow', '1')
32956
- sidebar.tabBars.bottom.container.css('flex-grow', '0')
32957
- sidebar.tabBars.bottom.container.css('height', '60px')
32986
+ sidebar.sections[position].container.hide()
32987
+ sidebar.sections[position].hidden = true
32988
+
32989
+ const otherPosition = position === 'top' ? 'bottom' : 'top'
32990
+ sidebar.sections[otherPosition].container.css('flex-grow', '1')
32991
+
32992
+ sidebar.tabBars[position].clearSelected()
32993
+ // sidebar.tabBars.top.container.css('flex-grow', '1')
32994
+ // sidebar.tabBars[position].container.css('flex-grow', '0')
32995
+ // sidebar.tabBars[position].container.css('height', '60px')
32958
32996
 
32959
32997
  sidebar.resizeSidebar()
32960
32998
  }
32961
32999
  sidebar.showSection = function (position) {
32962
- sidebar.sections.bottom.container.show()
32963
- sidebar.sections.bottom.hidden = false
32964
- sidebar.sections.top.container.css('flex-grow', '0')
32965
- sidebar.sections.top.container.css('height', '70%')
32966
- sidebar.tabBars.top.container.css('flex-grow', '')
32967
- sidebar.tabBars.bottom.container.css('flex-grow', '')
32968
- sidebar.tabBars.bottom.container.css('height', '')
33000
+ sidebar.sections[position].container.show()
33001
+ sidebar.sections[position].hidden = false
33002
+ const otherPosition = position === 'top' ? 'bottom' : 'top'
33003
+ sidebar.sections[otherPosition].container.css('flex-grow', '0')
33004
+ sidebar.sections[otherPosition].container.css('height', '70%')
33005
+ // sidebar.tabBars.top.container.css('flex-grow', '')
33006
+ // sidebar.tabBars[position].container.css('flex-grow', '')
33007
+ // sidebar.tabBars[position].container.css('height', '')
33008
+ // sidebar.tabBars[position].active
33009
+ sidebar.tabBars[position].container.find('button[data-tab-id="'+sidebar.tabBars[position].active+'"]').addClass('selected')
32969
33010
 
32970
33011
  sidebar.resizeSidebar()
32971
33012
  }
@@ -33003,7 +33044,7 @@ RED.sidebar = (function() {
33003
33044
  var elementPos = tabOverflowButton.offset();
33004
33045
  menu.css({
33005
33046
  top: (elementPos.top+tabOverflowButton.height()- menu.height() - 10)+"px",
33006
- left: (elementPos.left - menu.width() - 3)+"px"
33047
+ left: sidebar.direction === 'left' ? ((elementPos.left + tabOverflowButton.width() + 3)+"px") : ((elementPos.left - menu.width() - 3)+"px")
33007
33048
  })
33008
33049
  $(".red-ui-menu.red-ui-menu-dropdown").hide();
33009
33050
  setTimeout(() => {
@@ -33027,6 +33068,14 @@ RED.sidebar = (function() {
33027
33068
  connectWith: ".red-ui-sidebar-tab-bar-buttons",
33028
33069
  start: function(event, ui) {
33029
33070
  const tabId = ui.item.attr('data-tab-id');
33071
+ const tabCount = tabBarButtonsContainer.children('button:not(.red-ui-sidebar-tab-bar-overflow-button):not(.red-ui-sidebar-tab-bar-button-placeholder)').length
33072
+ if (position === 'top' && tabCount === 1) {
33073
+ // Call in a timeout to allow the stortable start event to complete
33074
+ // processing - otherwise errors are thrown
33075
+ setTimeout(function () {
33076
+ tabBarButtonsContainer.sortable('cancel');
33077
+ }, 0);
33078
+ }
33030
33079
  const options = knownTabs[tabId];
33031
33080
  options.tabButtonTooltip.delete()
33032
33081
  draggingTabButton = true
@@ -33075,7 +33124,7 @@ RED.sidebar = (function() {
33075
33124
  // Nothing visible - bail out
33076
33125
  return
33077
33126
  }
33078
- if (tabBarButtonsBottom < bottomButton.position().top + buttonHeight * 1.5) {
33127
+ if (tabBarButtonsBottom < bottomButton.position().top + buttonHeight) {
33079
33128
  tabOverflowButton.show()
33080
33129
  let tabOverflowButtonBottom = tabOverflowButton.position().top + buttonHeight * 1.5;
33081
33130
  while (tabBarButtonsBottom < tabOverflowButtonBottom) {
@@ -33236,11 +33285,13 @@ RED.sidebar = (function() {
33236
33285
  // Show the last selected tab for each sidebar
33237
33286
  Object.keys(sidebars).forEach(function(sidebarKey) {
33238
33287
  const sidebar = sidebars[sidebarKey];
33239
- let lastTabId = lastSessionSelectedTabs[sidebarKey];
33240
- if (!lastTabId) {
33241
- lastTabId = sidebar.tabBars.top.container.children('button').first().attr('data-tab-id');
33242
- }
33243
- showSidebar(lastTabId, true)
33288
+ ['top','bottom'].forEach(function(position) {
33289
+ let lastTabId = lastSessionSelectedTabs[sidebarKey + '-' + position];
33290
+ if (!lastTabId) {
33291
+ lastTabId = sidebar.tabBars[position].container.children('button').first().attr('data-tab-id');
33292
+ }
33293
+ showSidebar(lastTabId, true)
33294
+ })
33244
33295
  })
33245
33296
  return
33246
33297
  }
@@ -33257,16 +33308,21 @@ RED.sidebar = (function() {
33257
33308
  $(tabOptions.wrapper).show();
33258
33309
  if (tabOptions.toolbar) {
33259
33310
  $(tabOptions.toolbar).show();
33311
+ targetSidebar.sections[targetSection].footer.show();
33312
+ } else {
33313
+ targetSidebar.sections[targetSection].footer.hide();
33260
33314
  }
33261
- RED.settings.setLocal("last-sidebar-tab-" + targetSidebar.id, tabOptions.id)
33315
+ RED.settings.setLocal("last-sidebar-tab-" + targetSidebar.id+'-'+targetSection, tabOptions.id)
33262
33316
  // TODO: find which tabBar the button is in
33263
33317
  targetSidebar.tabBars[targetSection].clearSelected()
33264
33318
  targetSidebar.tabBars[targetSection].container.find('button[data-tab-id="'+id+'"]').addClass('selected')
33265
33319
  targetSidebar.tabBars[targetSection].active = id
33266
-
33267
33320
  if (!skipShowSidebar && !RED.menu.isSelected(targetSidebar.menuToggle)) {
33268
33321
  RED.menu.setSelected(targetSidebar.menuToggle,true);
33269
33322
  }
33323
+ if (targetSidebar.sections[targetSection].hidden) {
33324
+ targetSidebar.showSection(targetSection)
33325
+ }
33270
33326
  }
33271
33327
  }
33272
33328
  }
@@ -33287,11 +33343,13 @@ RED.sidebar = (function() {
33287
33343
  sidebar.sections = {};
33288
33344
  sidebar.sections.top = {}
33289
33345
  sidebar.sections.top.container = $('<div class="red-ui-sidebar-section red-ui-sidebar-section-top"></div>').appendTo(sidebar.container);
33346
+ // sidebar.sections.top.banner = $('<div class="red-ui-sidebar-banner">Head</div>').appendTo(sidebar.sections.top.container);
33290
33347
  sidebar.sections.top.content = $('<div class="red-ui-sidebar-content"></div>').appendTo(sidebar.sections.top.container);
33291
33348
  sidebar.sections.top.footer = $('<div class="red-ui-sidebar-footer"></div>').appendTo(sidebar.sections.top.container);
33292
33349
  sidebar.sectionsSeparator = $('<div class="red-ui-sidebar-tab-bar-separator"><div class="red-ui-sidebar-separator-handle"></div></div>').appendTo(sidebar.container);
33293
33350
  sidebar.sections.bottom = {}
33294
33351
  sidebar.sections.bottom.container = $('<div class="red-ui-sidebar-section red-ui-sidebar-section-bottom"></div>').appendTo(sidebar.container);
33352
+ // sidebar.sections.bottom.banner = $('<div class="red-ui-sidebar-banner">Head</div>').appendTo(sidebar.sections.bottom.container);
33295
33353
  sidebar.sections.bottom.content = $('<div class="red-ui-sidebar-content"></div>').appendTo(sidebar.sections.bottom.container);
33296
33354
  sidebar.sections.bottom.footer = $('<div class="red-ui-sidebar-footer"></div>').appendTo(sidebar.sections.bottom.container);
33297
33355
 
@@ -33299,12 +33357,14 @@ RED.sidebar = (function() {
33299
33357
  let startTopSectionHeight
33300
33358
  let startTopTabSectionHeight
33301
33359
  let startSidebarHeight
33360
+ let lastSeparatorPosition
33302
33361
  sidebar.sectionsSeparator.draggable({
33303
33362
  axis: "y",
33304
33363
  containment: sidebar.container,
33305
33364
  scroll: false,
33306
33365
  start:function(event,ui) {
33307
33366
  startPosition = ui.position.top
33367
+ lastSeparatorPosition = ui.position.top
33308
33368
  startTopSectionHeight = sidebar.sections.top.container.outerHeight()
33309
33369
  startTopTabSectionHeight = sidebar.tabBars.top.container.outerHeight()
33310
33370
  startSidebarHeight = sidebar.container.height()
@@ -33314,12 +33374,13 @@ RED.sidebar = (function() {
33314
33374
  const newTopHeight = startTopSectionHeight + delta
33315
33375
  const newBottomHeight = startSidebarHeight - newTopHeight
33316
33376
  if (newTopHeight < 100 || newBottomHeight < 100) {
33317
- ui.position.top += delta
33377
+ ui.position.top = lastSeparatorPosition
33318
33378
  return
33319
33379
  }
33320
33380
  sidebar.sections.top.container.outerHeight(startTopSectionHeight + delta)
33321
33381
  sidebar.tabBars.top.container.outerHeight(startTopTabSectionHeight + delta)
33322
33382
  ui.position.top -= delta
33383
+ lastSeparatorPosition = ui.position.top
33323
33384
  sidebar.resizeSidebar()
33324
33385
  },
33325
33386
  stop:function(event,ui) {
@@ -33384,7 +33445,8 @@ RED.sidebar = (function() {
33384
33445
  // Remember the last selected tab for each sidebar before
33385
33446
  // the tabs are readded causing the state to get updated
33386
33447
  Object.keys(sidebars).forEach(function(sidebarKey) {
33387
- lastSessionSelectedTabs[sidebarKey] = RED.settings.getLocal("last-sidebar-tab-" + sidebarKey)
33448
+ lastSessionSelectedTabs[sidebarKey + '-top'] = RED.settings.getLocal("last-sidebar-tab-" + sidebarKey + '-top');
33449
+ lastSessionSelectedTabs[sidebarKey + '-bottom'] = RED.settings.getLocal("last-sidebar-tab-" + sidebarKey + '-bottom');
33388
33450
  })
33389
33451
  }
33390
33452
 
@@ -34030,7 +34092,6 @@ RED.palette = (function() {
34030
34092
  $('<img src="red/images/spin.svg" class="red-ui-palette-spinner hide"/>').appendTo("#red-ui-palette");
34031
34093
  $('<div id="red-ui-palette-search" class="red-ui-palette-search hide"><input type="text" data-i18n="[placeholder]palette.filter"></input></div>').appendTo("#red-ui-palette");
34032
34094
  $('<div id="red-ui-palette-container" class="red-ui-palette-scroll hide"></div>').appendTo("#red-ui-palette");
34033
- // $('<div id="red-ui-palette-shade" class="hide"></div>').appendTo("#red-ui-palette");
34034
34095
 
34035
34096
  $("#red-ui-palette > .red-ui-palette-spinner").show();
34036
34097
 
@@ -34804,11 +34865,13 @@ RED.sidebar.info = (function() {
34804
34865
  {
34805
34866
  label: RED._("menu.label.flows"),
34806
34867
  expanded: true,
34868
+ expandOnLabel: true,
34807
34869
  children: []
34808
34870
  },
34809
34871
  {
34810
34872
  id: "__subflow__",
34811
34873
  label: RED._("menu.label.subflows"),
34874
+ expandOnLabel: true,
34812
34875
  children: [
34813
34876
  getEmptyItem("__subflow__")
34814
34877
  ]
@@ -34817,6 +34880,7 @@ RED.sidebar.info = (function() {
34817
34880
  id: "__global__",
34818
34881
  flow: "__global__",
34819
34882
  label: RED._("sidebar.info.globalConfig"),
34883
+ expandOnLabel: true,
34820
34884
  types: {},
34821
34885
  children: [
34822
34886
  getEmptyItem("__global__")
@@ -34828,7 +34892,6 @@ RED.sidebar.info = (function() {
34828
34892
  subflowList = flowData[1];
34829
34893
  globalConfigNodes = flowData[2];
34830
34894
  configNodeTypes = { __global__: globalConfigNodes};
34831
-
34832
34895
  return flowData;
34833
34896
  }
34834
34897
 
@@ -35007,8 +35070,6 @@ RED.sidebar.info = (function() {
35007
35070
  }
35008
35071
  return RED._("common.label."+(((n.type==='tab' && n.disabled) || (n.type!=='tab' && n.d))?"enable":"disable"));
35009
35072
  });
35010
- } else {
35011
- $('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
35012
35073
  }
35013
35074
  if (n.type === 'tab') {
35014
35075
  var lockToggleButton = $('<button type="button" class="red-ui-info-outline-item-control-lock red-ui-button red-ui-button-small"><i class="fa fa-unlock-alt"></i><i class="fa fa-lock"></i></button>').appendTo(controls).on("click",function(evt) {
@@ -35023,7 +35084,7 @@ RED.sidebar.info = (function() {
35023
35084
  RED.popover.tooltip(lockToggleButton,function() {
35024
35085
  return RED._("common.label."+(n.locked?"unlock":"lock"));
35025
35086
  });
35026
- } else {
35087
+ } else if (n.type !== 'subflow') {
35027
35088
  $('<div class="red-ui-info-outline-item-control-spacer">').appendTo(controls)
35028
35089
  }
35029
35090
  controls.find("button").on("dblclick", function(evt) {
@@ -35082,12 +35143,18 @@ RED.sidebar.info = (function() {
35082
35143
  // <div class="red-ui-info-outline-item red-ui-info-outline-item-flow" style=";"><div class="red-ui-search-result-description red-ui-info-outline-item-label">Space Monkey</div><div class="red-ui-info-outline-item-controls"><button class="red-ui-button red-ui-button-small" style="position:absolute;right:5px;"><i class="fa fa-ellipsis-h"></i></button></div></div></div>').appendTo(container)
35083
35144
 
35084
35145
  treeList = $("<div>").css({width: "100%"}).appendTo(container).treeList({
35085
- data:getFlowData()
35146
+ data:getFlowData(),
35147
+ expandOnLabel: false
35086
35148
  })
35087
35149
  treeList.on('treelistselect', function(e,item) {
35088
35150
  var node = RED.nodes.node(item.id) || RED.nodes.group(item.id) || RED.nodes.workspace(item.id) || RED.nodes.subflow(item.id);
35089
35151
  if (node) {
35090
- RED.sidebar.info.refresh(node);
35152
+ if (node.type === 'tab' || node.type === 'subflow') {
35153
+ RED.workspaces.show(node.id)
35154
+ } else {
35155
+ RED.view.reveal(node.id);
35156
+ }
35157
+ // RED.sidebar.info.refresh(node);
35091
35158
  // if (node.type === 'group' || node._def.category !== "config") {
35092
35159
  // // RED.view.select({nodes:[node]})
35093
35160
  // } else if (node._def.category === "config") {
@@ -35371,14 +35438,15 @@ RED.sidebar.info = (function() {
35371
35438
  }
35372
35439
  }
35373
35440
  function getGutter(n) {
35374
- var span = $("<span>",{class:"red-ui-info-outline-gutter red-ui-treeList-gutter-float"});
35375
- 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) {
35376
- evt.preventDefault();
35377
- evt.stopPropagation();
35378
- RED.view.reveal(n.id);
35379
- })
35380
- RED.popover.tooltip(revealButton,RED._("sidebar.info.find"));
35381
- return span;
35441
+ // var span = $("<span>",{class:"red-ui-info-outline-gutter red-ui-treeList-gutter-float"});
35442
+ // 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) {
35443
+ // evt.preventDefault();
35444
+ // evt.stopPropagation();
35445
+ // RED.view.reveal(n.id);
35446
+ // })
35447
+ // RED.popover.tooltip(revealButton,RED._("sidebar.info.find"));
35448
+ // return span;
35449
+ return null;
35382
35450
  }
35383
35451
 
35384
35452
  function createFlowConfigNode(parent,type) {
@@ -35659,6 +35727,7 @@ RED.sidebar.help = (function() {
35659
35727
 
35660
35728
  $(window).on("resize", resizeStack);
35661
35729
  $(window).on("focus", resizeStack);
35730
+ RED.events.on("sidebar:resize", resizeStack);
35662
35731
 
35663
35732
  RED.events.on('registry:node-type-added', queueRefresh);
35664
35733
  RED.events.on('registry:node-type-removed', queueRefresh);
@@ -47230,7 +47299,6 @@ RED.eventLog = (function() {
47230
47299
  function finishBuild() {
47231
47300
  $("#red-ui-header-shade").show();
47232
47301
  $("#red-ui-editor-shade").show();
47233
- $("#red-ui-palette-shade").show();
47234
47302
  $(".red-ui-sidebar-shade").show();
47235
47303
  tray.preferredWidth = Math.max(el.width(),500);
47236
47304
  if (!options.maximized) {
@@ -47350,7 +47418,6 @@ RED.eventLog = (function() {
47350
47418
  tray.tray.css({right:0});
47351
47419
  $("#red-ui-header-shade").show();
47352
47420
  $("#red-ui-editor-shade").show();
47353
- $("#red-ui-palette-shade").show();
47354
47421
  $(".red-ui-sidebar-shade").show();
47355
47422
  stackHidden = false;
47356
47423
  }
@@ -47387,7 +47454,6 @@ RED.eventLog = (function() {
47387
47454
  });
47388
47455
  $("#red-ui-header-shade").hide();
47389
47456
  $("#red-ui-editor-shade").hide();
47390
- $("#red-ui-palette-shade").hide();
47391
47457
  $(".red-ui-sidebar-shade").hide();
47392
47458
  stackHidden = true;
47393
47459
  }
@@ -47431,7 +47497,6 @@ RED.eventLog = (function() {
47431
47497
  if (stack.length === 0) {
47432
47498
  $("#red-ui-header-shade").hide();
47433
47499
  $("#red-ui-editor-shade").hide();
47434
- $("#red-ui-palette-shade").hide();
47435
47500
  $(".red-ui-sidebar-shade").hide();
47436
47501
  RED.events.emit("editor:close");
47437
47502
  RED.view.focus();
@@ -49132,7 +49197,7 @@ RED.library = (function() {
49132
49197
  icon: 'fa fa-cube',
49133
49198
  label: options.type,
49134
49199
  path: "",
49135
- expanded: false,
49200
+ expanded: true,
49136
49201
  children: function(done, item) {
49137
49202
  loadLibraryFolder(lib.id, options.url, "", function(children) {
49138
49203
  item.children = children;
@@ -49740,10 +49805,10 @@ RED.notifications = (function() {
49740
49805
  });
49741
49806
  */
49742
49807
 
49743
- var persistentNotifications = {};
49808
+ const persistentNotifications = {};
49744
49809
 
49745
- var shade = (function() {
49746
- var shadeUsers = 0;
49810
+ const shade = (function() {
49811
+ let shadeUsers = 0;
49747
49812
  return {
49748
49813
  show: function() {
49749
49814
  shadeUsers++;
@@ -50021,7 +50086,8 @@ RED.notifications = (function() {
50021
50086
  showPersistent();
50022
50087
  })
50023
50088
  },
50024
- notify: notify
50089
+ notify: notify,
50090
+ shade: shade
50025
50091
  }
50026
50092
  })();
50027
50093
  ;/**
@@ -50075,9 +50141,13 @@ RED.search = (function() {
50075
50141
  function indexNode(n) {
50076
50142
  var l = RED.utils.getNodeLabel(n);
50077
50143
  if (l) {
50078
- l = (""+l).toLowerCase();
50079
- index[l] = index[l] || {};
50080
- index[l][n.id] = {node:n,label:l}
50144
+ const originalLabel = "" + l;
50145
+ const indexLabel = originalLabel.toLowerCase();
50146
+ index[indexLabel] = index[indexLabel] || {};
50147
+ index[indexLabel][n.id] = {
50148
+ node: n,
50149
+ label: originalLabel
50150
+ };
50081
50151
  }
50082
50152
  l = l||n.label||n.name||n.id||"";
50083
50153
 
@@ -50293,7 +50363,7 @@ RED.search = (function() {
50293
50363
 
50294
50364
  }
50295
50365
  function createDialog() {
50296
- dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#red-ui-main-container");
50366
+ dialog = $("<div>",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#red-ui-global-dialog-container");
50297
50367
  var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
50298
50368
  searchInput = $('<input type="text" data-i18n="[placeholder]menu.label.searchInput">').appendTo(searchDiv).searchBox({
50299
50369
  delay: 200,
@@ -50547,10 +50617,8 @@ RED.search = (function() {
50547
50617
  }
50548
50618
  if (!visible) {
50549
50619
  previousActiveElement = document.activeElement;
50550
- $("#red-ui-header-shade").show();
50551
- $("#red-ui-editor-shade").show();
50552
- $("#red-ui-palette-shade").show();
50553
- $(".red-ui-sidebar-shade").show();
50620
+ RED.notifications.shade.show();
50621
+ $("#red-ui-full-shade").one('mousedown.red-ui-actionList', hide)
50554
50622
 
50555
50623
  if (dialog === null) {
50556
50624
  createDialog();
@@ -50571,10 +50639,8 @@ RED.search = (function() {
50571
50639
  function hide(el, keepSearchToolbar) {
50572
50640
  if (visible) {
50573
50641
  visible = false;
50574
- $("#red-ui-header-shade").hide();
50575
- $("#red-ui-editor-shade").hide();
50576
- $("#red-ui-palette-shade").hide();
50577
- $(".red-ui-sidebar-shade").hide();
50642
+ RED.notifications.shade.hide();
50643
+ $("#red-ui-full-shade").off('mousedown.red-ui-actionList')
50578
50644
  if (dialog !== null) {
50579
50645
  dialog.slideUp(200,function() {
50580
50646
  searchInput.searchBox('value','');
@@ -50605,7 +50671,7 @@ RED.search = (function() {
50605
50671
  result: (currentIndex + 1),
50606
50672
  count: activeResults.length
50607
50673
  }
50608
- $("#red-ui-view-searchtools-counter").text(RED._('actions.search-counter', i18nSearchCounterData));
50674
+ $("#red-ui-view-searchtools-counter-label").text(RED._('actions.search-counter', i18nSearchCounterData));
50609
50675
  $("#view-search-tools > :not(:first-child)").show(); //show other tools
50610
50676
  } else {
50611
50677
  clearActiveSearch();
@@ -50671,11 +50737,6 @@ RED.search = (function() {
50671
50737
  updateSearchToolbar();
50672
50738
  });
50673
50739
 
50674
- $("#red-ui-header-shade").on('mousedown',hide);
50675
- $("#red-ui-editor-shade").on('mousedown',hide);
50676
- $("#red-ui-palette-shade").on('mousedown',hide);
50677
- $(".red-ui-sidebar-shade").on('mousedown',hide);
50678
-
50679
50740
  $("#red-ui-view-searchtools-close").on("click", function close() {
50680
50741
  clearActiveSearch();
50681
50742
  updateSearchToolbar();
@@ -50707,10 +50768,20 @@ RED.search = (function() {
50707
50768
  show: show,
50708
50769
  hide: hide,
50709
50770
  search: search,
50710
- getSearchOptions: getSearchOptions
50771
+ getSearchOptions: getSearchOptions,
50772
+ // Expose internals for testing
50773
+ _indexNode: indexNode,
50774
+ get _index() { return index; },
50775
+ set _index(val) { index = val; }
50711
50776
  };
50712
50777
 
50713
50778
  })();
50779
+
50780
+
50781
+ // Allow CommonJS import for testing
50782
+ if (typeof module !== "undefined" && module.exports) {
50783
+ module.exports = RED.search;
50784
+ }
50714
50785
  ;RED.contextMenu = (function () {
50715
50786
 
50716
50787
  let menu;
@@ -51054,7 +51125,7 @@ RED.actionList = (function() {
51054
51125
  }
51055
51126
 
51056
51127
  function createDialog() {
51057
- dialog = $("<div>",{id:"red-ui-actionList",class:"red-ui-search"}).appendTo("#red-ui-main-container");
51128
+ dialog = $("<div>",{id:"red-ui-actionList",class:"red-ui-search"}).appendTo("#red-ui-global-dialog-container");
51058
51129
  var searchDiv = $("<div>",{class:"red-ui-search-container"}).appendTo(dialog);
51059
51130
  searchInput = $('<input type="text" data-i18n="[placeholder]keyboard.filterActions">').appendTo(searchDiv).searchBox({
51060
51131
  change: function() {
@@ -51162,10 +51233,8 @@ RED.actionList = (function() {
51162
51233
  }
51163
51234
  if (!visible) {
51164
51235
  previousActiveElement = document.activeElement;
51165
- $("#red-ui-header-shade").show();
51166
- $("#red-ui-editor-shade").show();
51167
- $("#red-ui-palette-shade").show();
51168
- $(".red-ui-sidebar-shade").show();
51236
+ RED.notifications.shade.show();
51237
+ $("#red-ui-full-shade").one('mousedown.red-ui-actionList', hide)
51169
51238
  if (dialog === null) {
51170
51239
  createDialog();
51171
51240
  }
@@ -51196,10 +51265,9 @@ RED.actionList = (function() {
51196
51265
  function hide() {
51197
51266
  if (visible) {
51198
51267
  visible = false;
51199
- $("#red-ui-header-shade").hide();
51200
- $("#red-ui-editor-shade").hide();
51201
- $("#red-ui-palette-shade").hide();
51202
- $(".red-ui-sidebar-shade").hide();
51268
+ RED.notifications.shade.hide();
51269
+ $("#red-ui-full-shade").off('mousedown.red-ui-actionList')
51270
+
51203
51271
  if (dialog !== null) {
51204
51272
  dialog.slideUp(200,function() {
51205
51273
  searchInput.searchBox('value','');
@@ -51226,12 +51294,6 @@ RED.actionList = (function() {
51226
51294
  RED.events.on("type-search:close",function() { disabled = false; });
51227
51295
 
51228
51296
  RED.keyboard.add("red-ui-actionList","escape",function(){hide()});
51229
-
51230
-
51231
- $("#red-ui-header-shade").on('mousedown',hide);
51232
- $("#red-ui-editor-shade").on('mousedown',hide);
51233
- $("#red-ui-palette-shade").on('mousedown',hide);
51234
- $(".red-ui-sidebar-shade").on('mousedown',hide);
51235
51297
  }
51236
51298
 
51237
51299
  return {
@@ -55017,7 +55079,7 @@ RED.projects = (function() {
55017
55079
  var validateForm = function() {
55018
55080
  var valid = true;
55019
55081
  var flowFile = projectFlowFileInput.val();
55020
- if (flowFile === "" || !/\.json$/.test(flowFile)) {
55082
+ if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) {
55021
55083
  valid = false;
55022
55084
  if (!projectFlowFileInput.hasClass("input-error")) {
55023
55085
  projectFlowFileInput.addClass("input-error");
@@ -55439,7 +55501,7 @@ RED.projects = (function() {
55439
55501
 
55440
55502
  } else if (projectType === 'empty') {
55441
55503
  var flowFile = projectFlowFileInput.val();
55442
- if (flowFile === "" || !/\.json$/.test(flowFile)) {
55504
+ if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) {
55443
55505
  valid = false;
55444
55506
  if (!projectFlowFileInput.hasClass("input-error")) {
55445
55507
  projectFlowFileInput.addClass("input-error");