@node-red/editor-client 2.2.0-beta.1 → 2.2.0

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
@@ -647,8 +647,7 @@ var RED = (function() {
647
647
 
648
648
  $(".red-ui-header-toolbar").show();
649
649
 
650
-
651
- RED.sidebar.show(":first");
650
+ RED.sidebar.show(":first", true);
652
651
 
653
652
  setTimeout(function() {
654
653
  loader.end();
@@ -8064,7 +8063,7 @@ RED.utils = (function() {
8064
8063
  window._marked.use({extensions: [descriptionList, description] } );
8065
8064
 
8066
8065
  function renderMarkdown(txt) {
8067
- var rendered = _marked(txt);
8066
+ var rendered = _marked.parse(txt);
8068
8067
  var cleaned = DOMPurify.sanitize(rendered, {SAFE_FOR_JQUERY: true})
8069
8068
  return cleaned;
8070
8069
  }
@@ -12700,23 +12699,19 @@ RED.tabs = (function() {
12700
12699
  }
12701
12700
  }
12702
12701
 
12703
- li.one("transitionend", function(evt) {
12704
- li.remove();
12705
- if (tabs[id].pinned) {
12706
- pinnedTabsCount--;
12707
- }
12708
- if (options.onremove) {
12709
- options.onremove(tabs[id]);
12710
- }
12711
- delete tabs[id];
12712
- updateTabWidths();
12713
- if (collapsibleMenu) {
12714
- collapsibleMenu.remove();
12715
- collapsibleMenu = null;
12716
- }
12717
- })
12718
- li.addClass("hide-tab");
12719
- li.width(0);
12702
+ li.remove();
12703
+ if (tabs[id].pinned) {
12704
+ pinnedTabsCount--;
12705
+ }
12706
+ if (options.onremove) {
12707
+ options.onremove(tabs[id]);
12708
+ }
12709
+ delete tabs[id];
12710
+ updateTabWidths();
12711
+ if (collapsibleMenu) {
12712
+ collapsibleMenu.remove();
12713
+ collapsibleMenu = null;
12714
+ }
12720
12715
  }
12721
12716
 
12722
12717
  function findPreviousVisibleTab(li) {
@@ -14825,33 +14820,39 @@ RED.stack = (function() {
14825
14820
  ;RED.actions = (function() {
14826
14821
  var actions = {
14827
14822
 
14828
- }
14823
+ };
14829
14824
 
14830
- function addAction(name,handler) {
14825
+ function addAction(name,handler,options) {
14831
14826
  if (typeof handler !== 'function') {
14832
14827
  throw new Error("Action handler not a function");
14833
14828
  }
14834
14829
  if (actions[name]) {
14835
14830
  throw new Error("Cannot override existing action");
14836
14831
  }
14837
- actions[name] = handler;
14832
+ actions[name] = {
14833
+ handler: handler,
14834
+ options: options,
14835
+ };
14838
14836
  }
14839
14837
  function removeAction(name) {
14840
14838
  delete actions[name];
14841
14839
  }
14842
14840
  function getAction(name) {
14843
- return actions[name];
14841
+ return actions[name].handler;
14844
14842
  }
14845
14843
  function invokeAction() {
14846
14844
  var args = Array.prototype.slice.call(arguments);
14847
14845
  var name = args.shift();
14848
14846
  if (actions.hasOwnProperty(name)) {
14849
- actions[name].apply(null, args);
14847
+ var handler = actions[name].handler;
14848
+ handler.apply(null, args);
14850
14849
  }
14851
14850
  }
14852
14851
  function listActions() {
14853
14852
  var result = [];
14853
+ var missing = [];
14854
14854
  Object.keys(actions).forEach(function(action) {
14855
+ var def = actions[action];
14855
14856
  var shortcut = RED.keyboard.getShortcut(action);
14856
14857
  var isUser = false;
14857
14858
  if (shortcut) {
@@ -14859,13 +14860,38 @@ RED.stack = (function() {
14859
14860
  } else {
14860
14861
  isUser = !!RED.keyboard.getUserShortcut(action);
14861
14862
  }
14863
+ if (!def.label) {
14864
+ var name = action;
14865
+ var options = def.options;
14866
+ var key = options ? options.label : undefined;
14867
+ if (!key) {
14868
+ key = "action-list." +name.replace(/^.*:/,"");
14869
+ }
14870
+ var label = RED._(key);
14871
+ if (label === key) {
14872
+ // no translation. convert `name` to description
14873
+ label = name.replace(/(^.+:([a-z]))|(-([a-z]))/g, function() {
14874
+ if (arguments[5] === 0) {
14875
+ return arguments[2].toUpperCase();
14876
+ } else {
14877
+ return " "+arguments[4].toUpperCase();
14878
+ }
14879
+ });
14880
+ missing.push(key);
14881
+ }
14882
+ def.label = label;
14883
+ }
14884
+ //console.log("; missing:", missing);
14885
+
14862
14886
  result.push({
14863
14887
  id:action,
14864
14888
  scope:shortcut?shortcut.scope:undefined,
14865
14889
  key:shortcut?shortcut.key:undefined,
14866
- user:isUser
14867
- })
14868
- })
14890
+ user:isUser,
14891
+ label: def.label,
14892
+ options: def.options,
14893
+ });
14894
+ });
14869
14895
  return result;
14870
14896
  }
14871
14897
  return {
@@ -17690,15 +17716,15 @@ RED.keyboard = (function() {
17690
17716
  "]": 221,
17691
17717
  "{": 219,// <- QWERTY specific
17692
17718
  "}": 221 // <- QWERTY specific
17693
- }
17719
+ };
17694
17720
  var metaKeyCodes = {
17695
17721
  16: true,
17696
17722
  17: true,
17697
17723
  18: true,
17698
17724
  91: true,
17699
17725
  93: true
17700
- }
17701
- var actionToKeyMap = {}
17726
+ };
17727
+ var actionToKeyMap = {};
17702
17728
  var defaultKeyMap = {};
17703
17729
 
17704
17730
  // FF generates some different keycodes because reasons.
@@ -17706,7 +17732,7 @@ RED.keyboard = (function() {
17706
17732
  59:186,
17707
17733
  61:187,
17708
17734
  173:189
17709
- }
17735
+ };
17710
17736
 
17711
17737
  function migrateOldKeymap() {
17712
17738
  // pre-0.18
@@ -17721,7 +17747,7 @@ RED.keyboard = (function() {
17721
17747
  }
17722
17748
 
17723
17749
  function getUserKey(action) {
17724
- return RED.settings.get('editor.keymap',{})[action]
17750
+ return RED.settings.get('editor.keymap',{})[action];
17725
17751
  }
17726
17752
 
17727
17753
  function mergeKeymaps(defaultKeymap, themeKeymap) {
@@ -17746,7 +17772,7 @@ RED.keyboard = (function() {
17746
17772
  scope:scope,
17747
17773
  key:key,
17748
17774
  user:false
17749
- })
17775
+ });
17750
17776
  }
17751
17777
  }
17752
17778
  }
@@ -17756,13 +17782,13 @@ RED.keyboard = (function() {
17756
17782
  if (themeKeymap.hasOwnProperty(action)) {
17757
17783
  if (!themeKeymap[action].key) {
17758
17784
  // No key for this action - default is no keybinding
17759
- delete mergedKeymap[action]
17785
+ delete mergedKeymap[action];
17760
17786
  } else {
17761
17787
  mergedKeymap[action] = [{
17762
17788
  scope: themeKeymap[action].scope || "*",
17763
17789
  key: themeKeymap[action].key,
17764
17790
  user: false
17765
- }]
17791
+ }];
17766
17792
  if (mergedKeymap[action][0].scope === "workspace") {
17767
17793
  mergedKeymap[action][0].scope = "red-ui-workspace";
17768
17794
  }
@@ -17820,7 +17846,7 @@ RED.keyboard = (function() {
17820
17846
  close: function() {
17821
17847
  RED.menu.refreshShortcuts();
17822
17848
  }
17823
- })
17849
+ });
17824
17850
  }
17825
17851
 
17826
17852
  function revertToDefault(action) {
@@ -17968,7 +17994,7 @@ RED.keyboard = (function() {
17968
17994
  scope:scope,
17969
17995
  key:key,
17970
17996
  user:false
17971
- }
17997
+ };
17972
17998
  }
17973
17999
  if (!ondown) {
17974
18000
  var userAction = getUserKey(cbdown);
@@ -17991,7 +18017,7 @@ RED.keyboard = (function() {
17991
18017
  }
17992
18018
  }
17993
18019
  } else {
17994
- keys.push([key,mod])
18020
+ keys.push([key,mod]);
17995
18021
  }
17996
18022
  var slot = handlers;
17997
18023
  for (i=0;i<keys.length;i++) {
@@ -18014,7 +18040,7 @@ RED.keyboard = (function() {
18014
18040
  //slot[key] = {scope: scope, ondown:cbdown};
18015
18041
  }
18016
18042
  slot.handlers = slot.handlers || [];
18017
- slot.handlers.push({scope:scope,ondown:cbdown})
18043
+ slot.handlers.push({scope:scope,ondown:cbdown});
18018
18044
  slot.scope = scope;
18019
18045
  slot.ondown = cbdown;
18020
18046
  }
@@ -18031,12 +18057,12 @@ RED.keyboard = (function() {
18031
18057
  if (parsedKey) {
18032
18058
  keys.push(parsedKey);
18033
18059
  } else {
18034
- console.log("Unrecognised key specifier:",key)
18060
+ console.log("Unrecognised key specifier:",key);
18035
18061
  return;
18036
18062
  }
18037
18063
  }
18038
18064
  } else {
18039
- keys.push([key,mod])
18065
+ keys.push([key,mod]);
18040
18066
  }
18041
18067
  var slot = handlers;
18042
18068
  for (i=0;i<keys.length;i++) {
@@ -18058,7 +18084,7 @@ RED.keyboard = (function() {
18058
18084
  }
18059
18085
  if (typeof slot.ondown === "string") {
18060
18086
  if (typeof modifiers === 'boolean' && modifiers) {
18061
- actionToKeyMap[slot.ondown] = {user: modifiers}
18087
+ actionToKeyMap[slot.ondown] = {user: modifiers};
18062
18088
  } else {
18063
18089
  delete actionToKeyMap[slot.ondown];
18064
18090
  }
@@ -18074,11 +18100,11 @@ RED.keyboard = (function() {
18074
18100
  function formatKey(key,plain) {
18075
18101
  var formattedKey = isMac?key.replace(/ctrl-?/,"&#8984;"):key;
18076
18102
  formattedKey = isMac?formattedKey.replace(/alt-?/,"&#8997;"):key;
18077
- formattedKey = formattedKey.replace(/shift-?/,"&#8679;")
18078
- formattedKey = formattedKey.replace(/left/,"&#x2190;")
18079
- formattedKey = formattedKey.replace(/up/,"&#x2191;")
18080
- formattedKey = formattedKey.replace(/right/,"&#x2192;")
18081
- formattedKey = formattedKey.replace(/down/,"&#x2193;")
18103
+ formattedKey = formattedKey.replace(/shift-?/,"&#8679;");
18104
+ formattedKey = formattedKey.replace(/left/,"&#x2190;");
18105
+ formattedKey = formattedKey.replace(/up/,"&#x2191;");
18106
+ formattedKey = formattedKey.replace(/right/,"&#x2192;");
18107
+ formattedKey = formattedKey.replace(/down/,"&#x2193;");
18082
18108
  if (plain) {
18083
18109
  return formattedKey;
18084
18110
  }
@@ -18102,7 +18128,6 @@ RED.keyboard = (function() {
18102
18128
  var container = $(this);
18103
18129
  var object = container.data('data');
18104
18130
 
18105
-
18106
18131
  if (!container.hasClass('keyboard-shortcut-entry-expanded')) {
18107
18132
  endEditShortcut();
18108
18133
 
@@ -18126,7 +18151,7 @@ RED.keyboard = (function() {
18126
18151
  }
18127
18152
  $(this).toggleClass("input-error",!valid);
18128
18153
  okButton.attr("disabled",!valid);
18129
- })
18154
+ });
18130
18155
 
18131
18156
  var scopeSelect = $('<select><option value="*" data-i18n="keyboard.global"></option><option value="red-ui-workspace" data-i18n="keyboard.workspace"></option></select>').appendTo(scope);
18132
18157
  scopeSelect.i18n();
@@ -18136,7 +18161,7 @@ RED.keyboard = (function() {
18136
18161
  scopeSelect.val(object.scope||'*');
18137
18162
  scopeSelect.on("change", function() {
18138
18163
  keyInput.trigger("change");
18139
- })
18164
+ });
18140
18165
 
18141
18166
  var div = $('<div class="keyboard-shortcut-edit button-group-vertical"></div>').appendTo(scope);
18142
18167
  var okButton = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-check"></i></button>').appendTo(div);
@@ -18162,10 +18187,13 @@ RED.keyboard = (function() {
18162
18187
  id:object.id,
18163
18188
  scope:shortcut?shortcut.scope:undefined,
18164
18189
  key:shortcut?shortcut.key:undefined,
18165
- user:shortcut?shortcut.user:undefined
18166
- }
18190
+ user:shortcut?shortcut.user:undefined,
18191
+
18192
+ label: object.label,
18193
+ options: object.options,
18194
+ };
18167
18195
  buildShortcutRow(container,obj);
18168
- })
18196
+ });
18169
18197
 
18170
18198
  keyInput.trigger("focus");
18171
18199
  }
@@ -18200,7 +18228,7 @@ RED.keyboard = (function() {
18200
18228
  delete object.scope;
18201
18229
  } else {
18202
18230
  keyDiv.parent().removeClass("keyboard-shortcut-entry-unassigned");
18203
- keyDiv.append(RED.keyboard.formatKey(key))
18231
+ keyDiv.append(RED.keyboard.formatKey(key));
18204
18232
  $("<span>").text(scope).appendTo(scopeDiv);
18205
18233
  object.key = key;
18206
18234
  object.scope = scope;
@@ -18213,7 +18241,7 @@ RED.keyboard = (function() {
18213
18241
  userKeymap[object.id] = {
18214
18242
  scope:shortcut.scope,
18215
18243
  key:shortcut.key
18216
- }
18244
+ };
18217
18245
  RED.settings.set('editor.keymap',userKeymap);
18218
18246
  }
18219
18247
  }
@@ -18229,13 +18257,7 @@ RED.keyboard = (function() {
18229
18257
  var item = $('<div class="keyboard-shortcut-entry">').appendTo(container);
18230
18258
  container.data('data',object);
18231
18259
 
18232
- var text = object.id.replace(/(^.+:([a-z]))|(-([a-z]))/g,function() {
18233
- if (arguments[5] === 0) {
18234
- return arguments[2].toUpperCase();
18235
- } else {
18236
- return " "+arguments[4].toUpperCase();
18237
- }
18238
- });
18260
+ var text = object.label;
18239
18261
  var label = $('<div>').addClass("keyboard-shortcut-entry-text").text(text).appendTo(item);
18240
18262
 
18241
18263
  var user = $('<i class="fa fa-user"></i>').prependTo(label);
@@ -18276,8 +18298,9 @@ RED.keyboard = (function() {
18276
18298
  } else {
18277
18299
  filterValue = filterValue.replace(/\s/g,"");
18278
18300
  shortcutList.editableList('filter', function(data) {
18279
- return data.id.toLowerCase().replace(/^.*:/,"").replace("-","").indexOf(filterValue) > -1;
18280
- })
18301
+ var label = data.label.toLowerCase();
18302
+ return label.indexOf(filterValue) > -1;
18303
+ });
18281
18304
  }
18282
18305
  }
18283
18306
  });
@@ -18298,9 +18321,9 @@ RED.keyboard = (function() {
18298
18321
  });
18299
18322
  var shortcuts = RED.actions.list();
18300
18323
  shortcuts.sort(function(A,B) {
18301
- var Aid = A.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase();
18302
- var Bid = B.id.replace(/^.*:/,"").replace(/[ -]/g,"").toLowerCase();
18303
- return Aid.localeCompare(Bid);
18324
+ var Akey = A.label;
18325
+ var Bkey = B.label;
18326
+ return Akey.localeCompare(Bkey);
18304
18327
  });
18305
18328
  knownShortcuts = new Set();
18306
18329
  shortcuts.forEach(function(s) {
@@ -19663,12 +19686,45 @@ RED.view = (function() {
19663
19686
  },
19664
19687
  tooltip: function(d) {
19665
19688
  if (d.validationErrors && d.validationErrors.length > 0) {
19666
- return RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - ")
19689
+ return RED._("editor.errors.invalidProperties")+"\n - "+d.validationErrors.join("\n - ")
19667
19690
  }
19668
19691
  },
19669
19692
  show: function(n) { return !n.valid }
19670
19693
  })
19671
19694
 
19695
+ if (RED.settings.get("editor.view.view-store-zoom")) {
19696
+ var userZoomLevel = parseFloat(RED.settings.getLocal('zoom-level'))
19697
+ if (!isNaN(userZoomLevel)) {
19698
+ scaleFactor = userZoomLevel
19699
+ }
19700
+ }
19701
+
19702
+ var onScrollTimer = null;
19703
+ function storeScrollPosition() {
19704
+ workspaceScrollPositions[RED.workspaces.active()] = {
19705
+ left:chart.scrollLeft(),
19706
+ top:chart.scrollTop()
19707
+ };
19708
+ RED.settings.setLocal('scroll-positions', JSON.stringify(workspaceScrollPositions) )
19709
+ }
19710
+ chart.on("scroll", function() {
19711
+ if (RED.settings.get("editor.view.view-store-position")) {
19712
+ if (onScrollTimer) {
19713
+ clearTimeout(onScrollTimer)
19714
+ }
19715
+ onScrollTimer = setTimeout(storeScrollPosition, 200);
19716
+ }
19717
+ })
19718
+
19719
+ if (RED.settings.get("editor.view.view-store-position")) {
19720
+ var scrollPositions = RED.settings.getLocal('scroll-positions')
19721
+ if (scrollPositions) {
19722
+ try {
19723
+ workspaceScrollPositions = JSON.parse(scrollPositions)
19724
+ } catch(err) {
19725
+ }
19726
+ }
19727
+ }
19672
19728
  }
19673
19729
 
19674
19730
 
@@ -20956,6 +21012,7 @@ RED.view = (function() {
20956
21012
  }
20957
21013
  function zoomZero() { zoomView(1); }
20958
21014
 
21015
+
20959
21016
  function zoomView(factor) {
20960
21017
  var screenSize = [chart.width(),chart.height()];
20961
21018
  var scrollPos = [chart.scrollLeft(),chart.scrollTop()];
@@ -20968,6 +21025,9 @@ RED.view = (function() {
20968
21025
 
20969
21026
  RED.view.navigator.resize();
20970
21027
  redraw();
21028
+ if (RED.settings.get("editor.view.view-store-zoom")) {
21029
+ RED.settings.setLocal('zoom-level', factor.toFixed(1))
21030
+ }
20971
21031
  }
20972
21032
 
20973
21033
  function selectNone() {
@@ -22946,28 +23006,89 @@ RED.view = (function() {
22946
23006
  if (activeSubflow) {
22947
23007
  var subflowOutputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-output").data(activeSubflow.out,function(d,i){ return d.id;});
22948
23008
  subflowOutputs.exit().remove();
22949
- var outGroup = subflowOutputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-output").attr("transform",function(d) { return "translate("+(d.x-20)+","+(d.y-20)+")"});
23009
+ var outGroup = subflowOutputs.enter().insert("svg:g").attr("class","red-ui-flow-node red-ui-flow-subflow-port-output")
22950
23010
  outGroup.each(function(d,i) {
22951
- d.w=40;
22952
- d.h=40;
23011
+ var node = d3.select(this);
23012
+ var nodeContents = document.createDocumentFragment();
23013
+
23014
+ d.h = 40;
23015
+ d.resize = true;
23016
+ d.dirty = true;
23017
+
23018
+ var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
23019
+ mainRect.__data__ = d;
23020
+ mainRect.setAttribute("class", "red-ui-flow-subflow-port");
23021
+ mainRect.setAttribute("rx", 8);
23022
+ mainRect.setAttribute("ry", 8);
23023
+ mainRect.setAttribute("width", 40);
23024
+ mainRect.setAttribute("height", 40);
23025
+ node[0][0].__mainRect__ = mainRect;
23026
+ d3.select(mainRect)
23027
+ .on("mouseup",nodeMouseUp)
23028
+ .on("mousedown",nodeMouseDown)
23029
+ .on("touchstart",nodeTouchStart)
23030
+ .on("touchend",nodeTouchEnd)
23031
+ nodeContents.appendChild(mainRect);
23032
+
23033
+ var output_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
23034
+ output_groupEl.setAttribute("x",0);
23035
+ output_groupEl.setAttribute("y",0);
23036
+ node[0][0].__outputLabelGroup__ = output_groupEl;
23037
+
23038
+ var output_output = document.createElementNS("http://www.w3.org/2000/svg","text");
23039
+ output_output.setAttribute("class","red-ui-flow-port-label");
23040
+ output_output.style["font-size"] = "10px";
23041
+ output_output.textContent = "output";
23042
+ output_groupEl.appendChild(output_output);
23043
+ node[0][0].__outputOutput__ = output_output;
23044
+
23045
+ var output_number = document.createElementNS("http://www.w3.org/2000/svg","text");
23046
+ output_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
23047
+ output_number.setAttribute("x",0);
23048
+ output_number.setAttribute("y",0);
23049
+ output_number.textContent = d.i+1;
23050
+ output_groupEl.appendChild(output_number);
23051
+ node[0][0].__outputNumber__ = output_number;
23052
+
23053
+ var output_border = document.createElementNS("http://www.w3.org/2000/svg","path");
23054
+ output_border.setAttribute("d","M 40 1 l 0 38")
23055
+ output_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
23056
+ output_groupEl.appendChild(output_border);
23057
+ node[0][0].__outputBorder__ = output_border;
23058
+
23059
+ nodeContents.appendChild(output_groupEl);
23060
+
23061
+ var text = document.createElementNS("http://www.w3.org/2000/svg","g");
23062
+ text.setAttribute("class","red-ui-flow-port-label");
23063
+ text.setAttribute("transform","translate(38,0)");
23064
+ text.setAttribute('style', 'fill : #888'); // hard coded here!
23065
+ node[0][0].__textGroup__ = text;
23066
+ nodeContents.append(text);
23067
+
23068
+ var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
23069
+ portEl.setAttribute('transform','translate(-5,15)')
23070
+
23071
+ var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
23072
+ port.setAttribute("class","red-ui-flow-port");
23073
+ port.setAttribute("rx",3);
23074
+ port.setAttribute("ry",3);
23075
+ port.setAttribute("width",10);
23076
+ port.setAttribute("height",10);
23077
+ portEl.appendChild(port);
23078
+ port.__data__ = d;
23079
+
23080
+ d3.select(port)
23081
+ .on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
23082
+ .on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
23083
+ .on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
23084
+ .on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
23085
+ .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
23086
+ .on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
23087
+
23088
+ node[0][0].__port__ = portEl
23089
+ nodeContents.appendChild(portEl);
23090
+ node[0][0].appendChild(nodeContents);
22953
23091
  });
22954
- outGroup.append("rect").attr("class","red-ui-flow-subflow-port").attr("rx",8).attr("ry",8).attr("width",40).attr("height",40)
22955
- // TODO: This is exactly the same set of handlers used for regular nodes - DRY
22956
- .on("mouseup",nodeMouseUp)
22957
- .on("mousedown",nodeMouseDown)
22958
- .on("touchstart",nodeTouchStart)
22959
- .on("touchend",nodeTouchEnd)
22960
-
22961
- outGroup.append("g").attr('transform','translate(-5,15)').append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10)
22962
- .on("mousedown", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);} )
22963
- .on("touchstart", function(d,i){portMouseDown(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
22964
- .on("mouseup", function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);})
22965
- .on("touchend",function(d,i){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} )
22966
- .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);})
22967
- .on("mouseout",function(d){portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);});
22968
-
22969
- outGroup.append("svg:text").attr("class","red-ui-flow-port-label").attr("x",20).attr("y",12).style("font-size","10px").text("output");
22970
- outGroup.append("svg:text").attr("class","red-ui-flow-port-label red-ui-flow-port-index").attr("x",20).attr("y",28).text(function(d,i){ return i+1});
22971
23092
 
22972
23093
  var subflowInputs = nodeLayer.selectAll(".red-ui-flow-subflow-port-input").data(activeSubflow.in,function(d,i){ return d.id;});
22973
23094
  subflowInputs.exit().remove();
@@ -23020,11 +23141,89 @@ RED.view = (function() {
23020
23141
 
23021
23142
  subflowOutputs.each(function(d,i) {
23022
23143
  if (d.dirty) {
23023
- var output = d3.select(this);
23024
- output.classed("red-ui-flow-node-selected",function(d) { return d.selected; })
23025
- output.selectAll(".red-ui-flow-port-index").text(function(d){ return d.i+1});
23026
- output.attr("transform", function(d) { return "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")"; });
23144
+
23145
+ var port_height = 40;
23146
+
23147
+ var self = this;
23148
+ var thisNode = d3.select(this);
23149
+
23027
23150
  dirtyNodes[d.id] = d;
23151
+
23152
+ var label = getPortLabel(activeSubflow, PORT_TYPE_OUTPUT, d.i) || "";
23153
+ var hideLabel = (label.length < 1)
23154
+
23155
+ var labelParts;
23156
+ if (d.resize || this.__hideLabel__ !== hideLabel || this.__label__ !== label) {
23157
+ labelParts = getLabelParts(label, "red-ui-flow-node-label");
23158
+ if (labelParts.lines.length !== this.__labelLineCount__ || this.__label__ !== label) {
23159
+ d.resize = true;
23160
+ }
23161
+ this.__label__ = label;
23162
+ this.__labelLineCount__ = labelParts.lines.length;
23163
+
23164
+ if (hideLabel) {
23165
+ d.h = Math.max(port_height,(d.outputs || 0) * 15);
23166
+ } else {
23167
+ d.h = Math.max(6+24*labelParts.lines.length,(d.outputs || 0) * 15, port_height);
23168
+ }
23169
+ this.__hideLabel__ = hideLabel;
23170
+ }
23171
+
23172
+ if (d.resize) {
23173
+ var ow = d.w;
23174
+ if (hideLabel) {
23175
+ d.w = port_height;
23176
+ } else {
23177
+ d.w = Math.max(port_height,20*(Math.ceil((labelParts.width+50+7)/20)) );
23178
+ }
23179
+ if (ow !== undefined) {
23180
+ d.x += (d.w-ow)/2;
23181
+ }
23182
+ d.resize = false;
23183
+ }
23184
+
23185
+ this.setAttribute("transform", "translate(" + (d.x-d.w/2) + "," + (d.y-d.h/2) + ")");
23186
+ // This might be the first redraw after a node has been click-dragged to start a move.
23187
+ // So its selected state might have changed since the last redraw.
23188
+ this.classList.toggle("red-ui-flow-node-selected", !!d.selected )
23189
+ if (mouse_mode != RED.state.MOVING_ACTIVE) {
23190
+ this.classList.toggle("red-ui-flow-node-disabled", d.d === true);
23191
+ this.__mainRect__.setAttribute("width", d.w)
23192
+ this.__mainRect__.setAttribute("height", d.h)
23193
+ this.__mainRect__.classList.toggle("red-ui-flow-node-highlighted",!!d.highlighted );
23194
+
23195
+ if (labelParts) {
23196
+ // The label has changed
23197
+ var sa = labelParts.lines;
23198
+ var sn = labelParts.lines.length;
23199
+ var textLines = this.__textGroup__.childNodes;
23200
+ while(textLines.length > sn) {
23201
+ textLines[textLines.length-1].remove();
23202
+ }
23203
+ for (var i=0; i<sn; i++) {
23204
+ if (i===textLines.length) {
23205
+ var line = document.createElementNS("http://www.w3.org/2000/svg","text");
23206
+ line.setAttribute("class","red-ui-flow-node-label-text");
23207
+ line.setAttribute("x",0);
23208
+ line.setAttribute("y",i*24);
23209
+ this.__textGroup__.appendChild(line);
23210
+ }
23211
+ textLines[i].textContent = sa[i];
23212
+ }
23213
+ }
23214
+
23215
+ var textClass = "red-ui-flow-node-label"+(hideLabel?" hide":"");
23216
+ this.__textGroup__.setAttribute("class", textClass);
23217
+ var yp = d.h / 2 - (this.__labelLineCount__ / 2) * 24 + 13;
23218
+
23219
+ // this.__textGroup__.classList.remove("red-ui-flow-node-label-right");
23220
+ this.__textGroup__.setAttribute("transform", "translate(48,"+yp+")");
23221
+
23222
+ this.__outputBorder__.setAttribute("d","M 40 1 l 0 "+(hideLabel?0:(d.h - 2)));
23223
+ this.__port__.setAttribute("transform","translate(-5,"+((d.h/2)-5)+")");
23224
+ this.__outputOutput__.setAttribute("transform","translate(20,"+((d.h/2)-8)+")");
23225
+ this.__outputNumber__.setAttribute("transform","translate(20,"+((d.h/2)+7)+")");
23226
+ }
23028
23227
  d.dirty = false;
23029
23228
  }
23030
23229
  });
@@ -25793,6 +25992,15 @@ RED.sidebar = (function() {
25793
25992
  var sidebar_tabs;
25794
25993
  var knownTabs = {};
25795
25994
 
25995
+ // We store the current sidebar tab id in localStorage as 'last-sidebar-tab'
25996
+ // This is restored when the editor is reloaded.
25997
+ // We use sidebar_tabs.onchange to update localStorage. However that will
25998
+ // also get triggered when the first tab gets added to the tabs - typically
25999
+ // the 'info' tab. So we use the following variable to store the retrieved
26000
+ // value from localStorage before we start adding the actual tabs
26001
+ var lastSessionSelectedTab = null;
26002
+
26003
+
25796
26004
  function addTab(title,content,closeable,visible) {
25797
26005
  var options;
25798
26006
  if (typeof title === "string") {
@@ -25968,16 +26176,16 @@ RED.sidebar = (function() {
25968
26176
  RED.events.emit("sidebar:resize");
25969
26177
  }
25970
26178
 
25971
- function showSidebar(id) {
26179
+ function showSidebar(id, skipShowSidebar) {
25972
26180
  if (id === ":first") {
25973
- id = RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"])[0]
26181
+ id = lastSessionSelectedTab || RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"])[0]
25974
26182
  }
25975
26183
  if (id) {
25976
26184
  if (!containsTab(id) && knownTabs[id]) {
25977
26185
  sidebar_tabs.addTab(knownTabs[id]);
25978
26186
  }
25979
26187
  sidebar_tabs.activateTab(id);
25980
- if (!RED.menu.isSelected("menu-item-sidebar")) {
26188
+ if (!skipShowSidebar && !RED.menu.isSelected("menu-item-sidebar")) {
25981
26189
  RED.menu.setSelected("menu-item-sidebar",true);
25982
26190
  }
25983
26191
  }
@@ -26001,6 +26209,7 @@ RED.sidebar = (function() {
26001
26209
  if (tab.toolbar) {
26002
26210
  $(tab.toolbar).show();
26003
26211
  }
26212
+ RED.settings.setLocal("last-sidebar-tab", tab.id)
26004
26213
  },
26005
26214
  onremove: function(tab) {
26006
26215
  $(tab.wrapper).hide();
@@ -26029,7 +26238,9 @@ RED.sidebar = (function() {
26029
26238
  }
26030
26239
  });
26031
26240
  RED.popover.tooltip($("#red-ui-sidebar-separator").find(".red-ui-sidebar-control-right"),RED._("keyboard.toggleSidebar"),"core:toggle-sidebar");
26032
- showSidebar();
26241
+
26242
+ lastSessionSelectedTab = RED.settings.getLocal("last-sidebar-tab")
26243
+
26033
26244
  RED.sidebar.info.init();
26034
26245
  RED.sidebar.help.init();
26035
26246
  RED.sidebar.config.init();
@@ -28088,15 +28299,17 @@ RED.sidebar.help = (function() {
28088
28299
  style: "compact",
28089
28300
  delay: 100,
28090
28301
  change: function() {
28091
- var val = $(this).val().toLowerCase();
28092
- if (val) {
28302
+ const searchFor = $(this).val().toLowerCase();
28303
+ if (searchFor) {
28093
28304
  showTOC();
28094
- var c = treeList.treeList('filter',function(item) {
28305
+ treeList.treeList('filter',function(item) {
28095
28306
  if (item.depth === 0) {
28096
28307
  return true;
28097
28308
  }
28098
- return (item.nodeType && item.nodeType.indexOf(val) > -1) ||
28099
- (item.subflowLabel && item.subflowLabel.indexOf(val) > -1)
28309
+ let found = item.nodeType && item.nodeType.toLowerCase().indexOf(searchFor) > -1;
28310
+ found = found || item.subflowLabel && item.subflowLabel.toLowerCase().indexOf(searchFor) > -1;
28311
+ found = found || item.palleteLabel && item.palleteLabel.toLowerCase().indexOf(searchFor) > -1;
28312
+ return found;
28100
28313
  },true)
28101
28314
  } else {
28102
28315
  treeList.treeList('filter',null);
@@ -28248,17 +28461,21 @@ RED.sidebar.help = (function() {
28248
28461
 
28249
28462
 
28250
28463
  moduleNames.forEach(function(moduleName) {
28251
- var module = modules[moduleName];
28252
- var nodeTypes = [];
28253
-
28254
- var setNames = Object.keys(module.sets);
28464
+ const module = modules[moduleName];
28465
+ const nodeTypes = [];
28466
+ const moduleSets = module.sets;
28467
+ const setNames = Object.keys(moduleSets);
28255
28468
  setNames.forEach(function(setName) {
28256
- module.sets[setName].types.forEach(function(nodeType) {
28469
+ const moduleSet = moduleSets[setName];
28470
+ moduleSet.types.forEach(function(nodeType) {
28257
28471
  if ($("script[data-help-name='"+nodeType+"']").length) {
28472
+ const n = {_def:RED.nodes.getType(nodeType),type:nodeType}
28473
+ n.name = getNodePaletteLabel(n);
28258
28474
  nodeTypes.push({
28259
28475
  id: "node-type:"+nodeType,
28260
28476
  nodeType: nodeType,
28261
- element:getNodeLabel({_def:RED.nodes.getType(nodeType),type:nodeType})
28477
+ palleteLabel: n.name,
28478
+ element: getNodeLabel(n)
28262
28479
  })
28263
28480
  }
28264
28481
  })
@@ -28278,18 +28495,21 @@ RED.sidebar.help = (function() {
28278
28495
  treeList.treeList("data",helpData);
28279
28496
  }
28280
28497
 
28281
- function getNodeLabel(n) {
28282
- var div = $('<div>',{class:"red-ui-node-list-item"});
28283
- var icon = RED.utils.createNodeIcon(n).appendTo(div);
28284
- var label = n.name;
28498
+ function getNodePaletteLabel(n) {
28499
+ let label = n.name;
28285
28500
  if (!label && n._def && n._def.paletteLabel) {
28286
28501
  try {
28287
28502
  label = (typeof n._def.paletteLabel === "function" ? n._def.paletteLabel.call(n._def) : n._def.paletteLabel)||"";
28288
28503
  } catch (err) {
28289
28504
  }
28290
28505
  }
28291
- label = label || n.type;
28292
- $('<div>',{class:"red-ui-node-label"}).text(n.name||n.type).appendTo(icon);
28506
+ return label || n.type;
28507
+ }
28508
+
28509
+ function getNodeLabel(n) {
28510
+ const div = $('<div>',{class:"red-ui-node-list-item"});
28511
+ const icon = RED.utils.createNodeIcon(n).appendTo(div);
28512
+ $('<div>',{class:"red-ui-node-label"}).text(getNodePaletteLabel(n)).appendTo(icon);
28293
28513
  return div;
28294
28514
  }
28295
28515
 
@@ -32424,9 +32644,10 @@ RED.editor = (function() {
32424
32644
  editState.changed = true;
32425
32645
  }
32426
32646
  if (!node._def.defaults || !node._def.defaults.hasOwnProperty("icon")) {
32427
- var icon = $("#red-ui-editor-node-icon").val()||""
32647
+ var icon = $("#red-ui-editor-node-icon").val()||"";
32428
32648
  if (!this.isDefaultIcon) {
32429
- if (icon !== node.icon) {
32649
+ if ((icon !== node.icon) &&
32650
+ (icon !== "")) {
32430
32651
  editState.changes.icon = node.icon;
32431
32652
  node.icon = icon;
32432
32653
  editState.changed = true;
@@ -32490,14 +32711,14 @@ RED.editor = (function() {
32490
32711
  if (showLabel) {
32491
32712
  // Default to show label
32492
32713
  if (node.l !== false) {
32493
- editState.changes.l = node.l
32714
+ editState.changes.l = node.l;
32494
32715
  editState.changed = true;
32495
32716
  }
32496
32717
  node.l = false;
32497
32718
  } else {
32498
32719
  // Node has showLabel:false (eg link nodes)
32499
32720
  if (node.hasOwnProperty('l') && node.l) {
32500
- editState.changes.l = node.l
32721
+ editState.changes.l = node.l;
32501
32722
  editState.changed = true;
32502
32723
  }
32503
32724
  delete node.l;
@@ -32507,20 +32728,20 @@ RED.editor = (function() {
32507
32728
  if (showLabel) {
32508
32729
  // Default to show label
32509
32730
  if (node.hasOwnProperty('l') && !node.l) {
32510
- editState.changes.l = node.l
32731
+ editState.changes.l = node.l;
32511
32732
  editState.changed = true;
32512
32733
  }
32513
32734
  delete node.l;
32514
32735
  } else {
32515
32736
  if (!node.l) {
32516
- editState.changes.l = node.l
32737
+ editState.changes.l = node.l;
32517
32738
  editState.changed = true;
32518
32739
  }
32519
32740
  node.l = true;
32520
32741
  }
32521
32742
  }
32522
32743
  }
32523
- }
32744
+ };
32524
32745
  });
32525
32746
 
32526
32747
  function buildAppearanceForm(container,node) {
@@ -32553,10 +32774,10 @@ RED.editor = (function() {
32553
32774
  var categories = RED.palette.getCategories();
32554
32775
  categories.sort(function(A,B) {
32555
32776
  return A.label.localeCompare(B.label);
32556
- })
32777
+ });
32557
32778
  categories.forEach(function(cat) {
32558
32779
  categorySelector.append($("<option/>").val(cat.id).text(cat.label));
32559
- })
32780
+ });
32560
32781
  categorySelector.append($("<option/>").attr('disabled',true).text("---"));
32561
32782
  categorySelector.append($("<option/>").val("_custom_").text(RED._("palette.addCategory")));
32562
32783
 
@@ -32569,7 +32790,7 @@ RED.editor = (function() {
32569
32790
  $("#subflow-appearance-input-category").width(250);
32570
32791
  $("#subflow-appearance-input-custom-category").hide();
32571
32792
  }
32572
- })
32793
+ });
32573
32794
 
32574
32795
  $("#subflow-appearance-input-category").val(node.category||"subflows");
32575
32796
  var userCount = 0;
@@ -32593,7 +32814,7 @@ RED.editor = (function() {
32593
32814
  $("#node-input-show-label").toggleButton({
32594
32815
  enabledLabel: RED._("editor.show"),
32595
32816
  disabledLabel: RED._("editor.hide")
32596
- })
32817
+ });
32597
32818
 
32598
32819
  if (!node.hasOwnProperty("l")) {
32599
32820
  // Show label unless def.showLabel set to false
@@ -32619,7 +32840,7 @@ RED.editor = (function() {
32619
32840
  "#E9967A", "#F3B567", "#FDD0A2",
32620
32841
  "#FDF0C2", "#FFAAAA", "#FFCC66",
32621
32842
  "#FFF0F0", "#FFFFFF"
32622
- ]
32843
+ ];
32623
32844
 
32624
32845
  RED.editor.colorPicker.create({
32625
32846
  id: "red-ui-editor-node-color",
@@ -32634,9 +32855,9 @@ RED.editor = (function() {
32634
32855
  nodeDiv.css('backgroundColor',colour);
32635
32856
  var borderColor = RED.utils.getDarkerColor(colour);
32636
32857
  if (borderColor !== colour) {
32637
- nodeDiv.css('border-color',borderColor)
32858
+ nodeDiv.css('border-color',borderColor);
32638
32859
  }
32639
- })
32860
+ });
32640
32861
  }
32641
32862
 
32642
32863
 
@@ -32653,7 +32874,7 @@ RED.editor = (function() {
32653
32874
  nodeDiv.css('backgroundColor',colour);
32654
32875
  var borderColor = RED.utils.getDarkerColor(colour);
32655
32876
  if (borderColor !== colour) {
32656
- nodeDiv.css('border-color',borderColor)
32877
+ nodeDiv.css('border-color',borderColor);
32657
32878
  }
32658
32879
 
32659
32880
  var iconContainer = $('<div/>',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
@@ -32681,7 +32902,7 @@ RED.editor = (function() {
32681
32902
 
32682
32903
  RED.popover.tooltip(iconButton, function() {
32683
32904
  return $("#red-ui-editor-node-icon").val() || RED._("editor.default");
32684
- })
32905
+ });
32685
32906
  $('<input type="hidden" id="red-ui-editor-node-icon">').val(node.icon).appendTo(iconRow);
32686
32907
  }
32687
32908
 
@@ -32806,11 +33027,11 @@ RED.editor = (function() {
32806
33027
  });
32807
33028
  rows.sort(function(A,B) {
32808
33029
  return A.i-B.i;
32809
- })
33030
+ });
32810
33031
  rows.forEach(function(r,i) {
32811
33032
  r.r.find("label").text((i+1)+".");
32812
33033
  r.r.appendTo(outputsDiv);
32813
- })
33034
+ });
32814
33035
  if (rows.length === 0) {
32815
33036
  buildLabelRow("output",i,"").appendTo(outputsDiv);
32816
33037
  } else {
@@ -32856,7 +33077,7 @@ RED.editor = (function() {
32856
33077
  clear.on("click", function(evt) {
32857
33078
  evt.preventDefault();
32858
33079
  input.val("");
32859
- })
33080
+ });
32860
33081
  }
32861
33082
  return result;
32862
33083
  }
@@ -32890,6 +33111,12 @@ RED.editor = (function() {
32890
33111
  }
32891
33112
  var v = $(this).val();
32892
33113
  hasNonBlankLabel = hasNonBlankLabel || v!== "";
33114
+
33115
+ // mark changed output port labels as dirty
33116
+ if (node.type === "subflow" && (!node.outputLabels || node.outputLabels[index] !== v)) {
33117
+ node.out[index].dirty = true;
33118
+ }
33119
+
32893
33120
  newValue[index] = v;
32894
33121
  });
32895
33122
 
@@ -32898,6 +33125,12 @@ RED.editor = (function() {
32898
33125
  changes.outputLabels = node.outputLabels;
32899
33126
  node.outputLabels = newValue;
32900
33127
  changed = true;
33128
+
33129
+ // trigger redraw of dirty port labels
33130
+ if (node.type === "subflow") {
33131
+ RED.view.redraw();
33132
+ }
33133
+
32901
33134
  }
32902
33135
  return changed;
32903
33136
  }
@@ -39042,23 +39275,26 @@ RED.clipboard = (function() {
39042
39275
  if (truncated) {
39043
39276
  msg += "_truncated";
39044
39277
  }
39045
- navigator.clipboard.writeText(value).then(function () {
39046
- if (element) {
39047
- var popover = RED.popover.create({
39048
- target: element,
39049
- direction: 'left',
39050
- size: 'small',
39051
- content: RED._(msg)
39052
- });
39053
- setTimeout(function() {
39054
- popover.close();
39055
- },1000);
39056
- popover.open();
39057
- }
39058
- if (currentFocus) {
39059
- $(currentFocus).focus();
39060
- }
39061
- }).catch(err => { console.error("Failed to copy:",err) });
39278
+ var clipboardHidden = $('<textarea type="text" id="red-ui-clipboard-hidden" tabIndex="-1">').appendTo(document.body);
39279
+ clipboardHidden.val(value).focus().select();
39280
+ var result = document.execCommand("copy");
39281
+ if (result && element) {
39282
+ var popover = RED.popover.create({
39283
+ target: element,
39284
+ direction: 'left',
39285
+ size: 'small',
39286
+ content: RED._(msg)
39287
+ });
39288
+ setTimeout(function() {
39289
+ popover.close();
39290
+ },1000);
39291
+ popover.open();
39292
+ }
39293
+ clipboardHidden.remove();
39294
+ if (currentFocus) {
39295
+ $(currentFocus).focus();
39296
+ }
39297
+ return result;
39062
39298
  }
39063
39299
 
39064
39300
  function importNodes(nodesStr,addFlow) {
@@ -40656,10 +40892,22 @@ RED.search = (function() {
40656
40892
  }
40657
40893
  l = l||n.label||n.name||n.id||"";
40658
40894
 
40659
-
40660
40895
  var properties = ['id','type','name','label','info'];
40661
- if (n._def && n._def.defaults) {
40662
- properties = properties.concat(Object.keys(n._def.defaults));
40896
+ const node_def = n && n._def;
40897
+ if (node_def) {
40898
+ if (node_def.defaults) {
40899
+ properties = properties.concat(Object.keys(node_def.defaults));
40900
+ }
40901
+ if (n.type !== "group" && node_def.paletteLabel && node_def.paletteLabel !== node_def.type) {
40902
+ try {
40903
+ const label = ("" + (typeof node_def.paletteLabel === "function" ? node_def.paletteLabel.call(node_def) : node_def.paletteLabel)).toLowerCase();
40904
+ if(label && label !== (""+node_def.type).toLowerCase()) {
40905
+ indexProperty(n, l, label);
40906
+ }
40907
+ } catch(err) {
40908
+ console.warn(`error indexing ${l}`, err);
40909
+ }
40910
+ }
40663
40911
  }
40664
40912
  for (var i=0;i<properties.length;i++) {
40665
40913
  if (n.hasOwnProperty(properties[i])) {
@@ -41298,18 +41546,19 @@ RED.actionList = (function() {
41298
41546
  createDialog();
41299
41547
  }
41300
41548
  dialog.slideDown(300);
41301
- searchInput.searchBox('value',v)
41549
+ searchInput.searchBox('value',v);
41302
41550
  searchResults.editableList('empty');
41303
41551
  results = [];
41304
41552
  var actions = RED.actions.list();
41305
41553
  actions.sort(function(A,B) {
41306
- return A.id.localeCompare(B.id);
41554
+ var Akey = A.label;
41555
+ var Bkey = B.label;
41556
+ return Akey.localeCompare(Bkey);
41307
41557
  });
41308
41558
  actions.forEach(function(action) {
41309
- action.label = action.id.replace(/:/,": ").replace(/-/g," ").replace(/(^| )./g,function() { return arguments[0].toUpperCase()});
41310
41559
  action._label = action.label.toLowerCase();
41311
- searchResults.editableList('addItem',action)
41312
- })
41560
+ searchResults.editableList('addItem',action);
41561
+ });
41313
41562
  RED.events.emit("actionList:open");
41314
41563
  visible = true;
41315
41564
  }
@@ -43912,6 +44161,13 @@ RED.userSettings = (function() {
43912
44161
  // {setting:"theme", label:"Theme",options:function(done){ done([{val:'',text:'default'}].concat(RED.settings.theme("themes"))) }},
43913
44162
  // ]
43914
44163
  // },
44164
+ {
44165
+ title: "menu.label.view.view",
44166
+ options: [
44167
+ {setting:"view-store-zoom",label:"menu.label.view.storeZoom", default: false, toggle:true, onchange: function(val) { if (!val) { RED.settings.removeLocal("zoom-level")}}},
44168
+ {setting:"view-store-position",label:"menu.label.view.storePosition", default: false, toggle:true, onchange: function(val) { if (!val) { RED.settings.removeLocal("scroll-positions")}}},
44169
+ ]
44170
+ },
43915
44171
  {
43916
44172
  title: "menu.label.view.grid",
43917
44173
  options: [
@@ -45299,6 +45555,9 @@ RED.projects = (function() {
45299
45555
  }
45300
45556
  }).appendTo(row);
45301
45557
 
45558
+ row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-open"></div>').hide().appendTo(container);
45559
+ $('<span style="display: flex; align-items: center;"><input style="padding:0; margin: 0 5px 0 0" checked type="checkbox" id="red-ui-projects-dialog-screen-clear-context"> <label for="red-ui-projects-dialog-screen-clear-context" style="padding:0; margin: 0"> <span data-i18n="projects.create.clearContext"></span></label></span>').appendTo(row).i18n();
45560
+
45302
45561
  row = $('<div class="form-row red-ui-projects-dialog-screen-create-row red-ui-projects-dialog-screen-create-row-empty red-ui-projects-dialog-screen-create-row-clone"></div>').appendTo(container);
45303
45562
  $('<label for="red-ui-projects-dialog-screen-create-project-name">'+RED._("projects.create.project-name")+'</label>').appendTo(row);
45304
45563
 
@@ -45588,7 +45847,8 @@ RED.projects = (function() {
45588
45847
  };
45589
45848
  }
45590
45849
  } else if (projectType === 'open') {
45591
- return switchProject(selectedProject.name,function(err,data) {
45850
+ var clearContext = $("#red-ui-projects-dialog-screen-clear-context").prop("checked")
45851
+ return switchProject(selectedProject.name, clearContext, function(err,data) {
45592
45852
  if (err) {
45593
45853
  if (err.code !== 'credentials_load_failed') {
45594
45854
  console.log(RED._("projects.create.unexpected_error"),err)
@@ -45682,7 +45942,7 @@ RED.projects = (function() {
45682
45942
  }
45683
45943
  }
45684
45944
 
45685
- function switchProject(name,done) {
45945
+ function switchProject(name,clearContext,done) {
45686
45946
  RED.deploy.setDeployInflight(true);
45687
45947
  RED.projects.settings.switchProject(name);
45688
45948
  sendRequest({
@@ -45701,7 +45961,7 @@ RED.projects = (function() {
45701
45961
  '*': done
45702
45962
  },
45703
45963
  }
45704
- },{active:true}).then(function() {
45964
+ },{active:true, clearContext:clearContext}).then(function() {
45705
45965
  dialog.dialog( "close" );
45706
45966
  RED.events.emit("project:change", {name:name});
45707
45967
  }).always(function() {
@@ -45774,7 +46034,7 @@ RED.projects = (function() {
45774
46034
  dialogHeight = 590 - (750 - winHeight);
45775
46035
  }
45776
46036
  $(".red-ui-projects-dialog-box").height(dialogHeight);
45777
- $(".red-ui-projects-dialog-project-list-inner-container").height(Math.max(500,dialogHeight) - 180);
46037
+ $(".red-ui-projects-dialog-project-list-inner-container").height(Math.max(500,dialogHeight) - 210);
45778
46038
  dialog.dialog('option','title',screen.title||"");
45779
46039
  dialog.dialog("open");
45780
46040
  }