@node-red/editor-client 3.1.0 → 3.1.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
@@ -589,6 +589,15 @@ var RED = (function() {
589
589
  ]
590
590
  }
591
591
  }
592
+ } else if (notificationId === 'restart-required') {
593
+ options.buttons = [
594
+ {
595
+ text: RED._("common.label.close"),
596
+ click: function() {
597
+ persistentNotifications[notificationId].hideNotification();
598
+ }
599
+ }
600
+ ]
592
601
  }
593
602
  if (!persistentNotifications.hasOwnProperty(notificationId)) {
594
603
  persistentNotifications[notificationId] = RED.notify(text,options);
@@ -616,6 +625,10 @@ var RED = (function() {
616
625
  RED.view.redrawStatus(node);
617
626
  }
618
627
  });
628
+
629
+ let pendingNodeRemovedNotifications = []
630
+ let pendingNodeRemovedTimeout
631
+
619
632
  RED.comms.subscribe("notification/node/#",function(topic,msg) {
620
633
  var i,m;
621
634
  var typeList;
@@ -653,8 +666,15 @@ var RED = (function() {
653
666
  m = msg[i];
654
667
  info = RED.nodes.removeNodeSet(m.id);
655
668
  if (info.added) {
656
- typeList = "<ul><li>"+m.types.map(RED.utils.sanitize).join("</li><li>")+"</li></ul>";
657
- RED.notify(RED._("palette.event.nodeRemoved", {count:m.types.length})+typeList,"success");
669
+ pendingNodeRemovedNotifications = pendingNodeRemovedNotifications.concat(m.types.map(RED.utils.sanitize))
670
+ if (pendingNodeRemovedTimeout) {
671
+ clearTimeout(pendingNodeRemovedTimeout)
672
+ }
673
+ pendingNodeRemovedTimeout = setTimeout(function () {
674
+ typeList = "<ul><li>"+pendingNodeRemovedNotifications.join("</li><li>")+"</li></ul>";
675
+ RED.notify(RED._("palette.event.nodeRemoved", {count:pendingNodeRemovedNotifications.length})+typeList,"success");
676
+ pendingNodeRemovedNotifications = []
677
+ }, 200)
658
678
  }
659
679
  }
660
680
  loadIconList();
@@ -5894,6 +5914,12 @@ RED.nodes = (function() {
5894
5914
  }
5895
5915
  node._config.x = node.x;
5896
5916
  node._config.y = node.y;
5917
+ if (n.hasOwnProperty('w')) {
5918
+ node.w = n.w
5919
+ }
5920
+ if (n.hasOwnProperty('h')) {
5921
+ node.h = n.h
5922
+ }
5897
5923
  } else if (n.type.substring(0,7) === "subflow") {
5898
5924
  var parentId = n.type.split(":")[1];
5899
5925
  var subflow = subflow_denylist[parentId]||subflow_map[parentId]||getSubflow(parentId);
@@ -8445,96 +8471,35 @@ RED.validators = {
8445
8471
  return opt ? RED._("validator.errors.invalid-regexp") : false;
8446
8472
  };
8447
8473
  },
8448
- typedInput: function(ptypeName,isConfig,mopt) {
8474
+ typedInput: function(ptypeName, isConfig, mopt) {
8475
+ let options = ptypeName
8476
+ if (typeof ptypeName === 'string' ) {
8477
+ options = {}
8478
+ options.typeField = ptypeName
8479
+ options.isConfig = isConfig
8480
+ options.allowBlank = false
8481
+ }
8449
8482
  return function(v, opt) {
8450
- var ptype = $("#node-"+(isConfig?"config-":"")+"input-"+ptypeName).val() || this[ptypeName];
8451
- if (ptype === 'json') {
8452
- try {
8453
- JSON.parse(v);
8454
- return true;
8455
- } catch(err) {
8456
- if (opt && opt.label) {
8457
- return RED._("validator.errors.invalid-json-prop", {
8458
- error: err.message,
8459
- prop: opt.label,
8460
- });
8461
- }
8462
- return opt ? RED._("validator.errors.invalid-json", {
8463
- error: err.message
8464
- }) : false;
8465
- }
8466
- } else if (ptype === 'msg' || ptype === 'flow' || ptype === 'global' ) {
8467
- if (RED.utils.validatePropertyExpression(v)) {
8468
- return true;
8469
- }
8470
- if (opt && opt.label) {
8471
- return RED._("validator.errors.invalid-prop-prop", {
8472
- prop: opt.label
8473
- });
8474
- }
8475
- return opt ? RED._("validator.errors.invalid-prop") : false;
8476
- } else if (ptype === 'num') {
8477
- if (/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/.test(v)) {
8478
- return true;
8479
- }
8480
- if (opt && opt.label) {
8481
- return RED._("validator.errors.invalid-num-prop", {
8482
- prop: opt.label
8483
- });
8484
- }
8485
- return opt ? RED._("validator.errors.invalid-num") : false;
8483
+ let ptype = options.type
8484
+ if (!ptype && options.typeField) {
8485
+ ptype = $("#node-"+(options.isConfig?"config-":"")+"input-"+options.typeField).val() || this[options.typeField];
8486
8486
  }
8487
- return true;
8488
- };
8489
- }
8490
- };
8491
- ;// Mermaid diagram stub library for on-demand dynamic loading
8492
- // Will be overwritten after script loading by $.getScript
8493
- var mermaid = (function () {
8494
- var enabled /* = undefined */;
8495
-
8496
- var initializing = false;
8497
- var initCalled = false;
8498
-
8499
- function initialize(opt) {
8500
- if (enabled === undefined) {
8501
- if (RED.settings.markdownEditor &&
8502
- RED.settings.markdownEditor.mermaid) {
8503
- enabled = RED.settings.markdownEditor.mermaid.enabled;
8487
+ if (options.allowBlank && v === '') {
8488
+ return true
8504
8489
  }
8505
- else {
8506
- enabled = true;
8490
+ if (options.allowUndefined && v === undefined) {
8491
+ return true
8507
8492
  }
8508
- }
8509
- if (enabled) {
8510
- initializing = true;
8511
- $.getScript("vendor/mermaid/mermaid.min.js",
8512
- function (data, stat, jqxhr) {
8513
- $(".mermaid").show();
8514
- // invoke loaded mermaid API
8515
- initializing = false;
8516
- mermaid.initialize(opt);
8517
- if (initCalled) {
8518
- mermaid.init();
8519
- initCalled = false;
8520
- }
8521
- });
8522
- }
8523
- }
8524
-
8525
- function init() {
8526
- if (initializing) {
8527
- $(".mermaid").hide();
8528
- initCalled = true;
8493
+ const result = RED.utils.validateTypedProperty(v, ptype, opt)
8494
+ if (result === true || opt) {
8495
+ // Valid, or opt provided - return result as-is
8496
+ return result
8497
+ }
8498
+ // No opt - need to return false for backwards compatibilty
8499
+ return false
8529
8500
  }
8530
8501
  }
8531
-
8532
- return {
8533
- initialize: initialize,
8534
- init: init,
8535
- };
8536
- })();
8537
- ;/**
8502
+ };;/**
8538
8503
  * Copyright JS Foundation and other contributors, http://js.foundation
8539
8504
  *
8540
8505
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8637,28 +8602,8 @@ RED.utils = (function() {
8637
8602
 
8638
8603
  renderer.code = function (code, lang) {
8639
8604
  if(lang === "mermaid") {
8640
- // mermaid diagram rendering
8641
- if (mermaidIsEnabled === undefined) {
8642
- if (RED.settings.markdownEditor &&
8643
- RED.settings.markdownEditor.mermaid) {
8644
- mermaidIsEnabled = RED.settings.markdownEditor.mermaid.enabled;
8645
- }
8646
- else {
8647
- mermaidIsEnabled = true;
8648
- }
8649
- }
8650
- if (mermaidIsEnabled) {
8651
- if (!mermaidIsInitialized) {
8652
- mermaidIsInitialized = true;
8653
- mermaid.initialize({startOnLoad:false});
8654
- }
8655
- return `<pre class='mermaid'>${code}</pre>`;
8656
- }
8657
- else {
8658
- return `<details><summary>${RED._("markdownEditor.mermaid.summary")}</summary><pre><code>${code}</code></pre></details>`;
8659
- }
8660
- }
8661
- else {
8605
+ return `<pre class='mermaid'>${code}</pre>`;
8606
+ } else {
8662
8607
  return "<pre><code>" +code +"</code></pre>";
8663
8608
  }
8664
8609
  };
@@ -9453,6 +9398,51 @@ RED.utils = (function() {
9453
9398
  }
9454
9399
  }
9455
9400
 
9401
+ /**
9402
+ * Checks a typed property is valid according to the type.
9403
+ * Returns true if valid.
9404
+ * Return String error message if invalid
9405
+ * @param {*} propertyType
9406
+ * @param {*} propertyValue
9407
+ * @returns true if valid, String if invalid
9408
+ */
9409
+ function validateTypedProperty(propertyValue, propertyType, opt) {
9410
+
9411
+ let error
9412
+ if (propertyType === 'json') {
9413
+ try {
9414
+ JSON.parse(propertyValue);
9415
+ } catch(err) {
9416
+ error = RED._("validator.errors.invalid-json", {
9417
+ error: err.message
9418
+ })
9419
+ }
9420
+ } else if (propertyType === 'msg' || propertyType === 'flow' || propertyType === 'global' ) {
9421
+ if (!RED.utils.validatePropertyExpression(propertyValue)) {
9422
+ error = RED._("validator.errors.invalid-prop")
9423
+ }
9424
+ } else if (propertyType === 'num') {
9425
+ if (!/^NaN$|^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$|^[+-]?(0b|0B)[01]+$|^[+-]?(0o|0O)[0-7]+$|^[+-]?(0x|0X)[0-9a-fA-F]+$/.test(propertyValue)) {
9426
+ error = RED._("validator.errors.invalid-num")
9427
+ }
9428
+ } else if (propertyType === 'jsonata') {
9429
+ try {
9430
+ jsonata(propertyValue)
9431
+ } catch(err) {
9432
+ error = RED._("validator.errors.invalid-expr", {
9433
+ error: err.message
9434
+ })
9435
+ }
9436
+ }
9437
+ if (error) {
9438
+ if (opt && opt.label) {
9439
+ return opt.label+': '+error
9440
+ }
9441
+ return error
9442
+ }
9443
+ return true
9444
+ }
9445
+
9456
9446
  function getMessageProperty(msg,expr) {
9457
9447
  var result = null;
9458
9448
  var msgPropParts;
@@ -9987,7 +9977,8 @@ RED.utils = (function() {
9987
9977
  getDarkerColor: getDarkerColor,
9988
9978
  parseModuleList: parseModuleList,
9989
9979
  checkModuleAllowed: checkModuleAllowed,
9990
- getBrowserInfo: getBrowserInfo
9980
+ getBrowserInfo: getBrowserInfo,
9981
+ validateTypedProperty: validateTypedProperty
9991
9982
  }
9992
9983
  })();
9993
9984
  ;/**
@@ -14274,7 +14265,9 @@ RED.stack = (function() {
14274
14265
  valueLabel: contextLabel
14275
14266
  },
14276
14267
  str: {value:"str",label:"string",icon:"red/images/typedInput/az.svg"},
14277
- num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate:/^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$/},
14268
+ num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate: function(v) {
14269
+ return (true === RED.utils.validateTypedProperty(v, "num"));
14270
+ } },
14278
14271
  bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]},
14279
14272
  json: {
14280
14273
  value:"json",
@@ -19586,6 +19579,8 @@ RED.keyboard = (function() {
19586
19579
 
19587
19580
  RED.workspaces = (function() {
19588
19581
 
19582
+ const documentTitle = document.title;
19583
+
19589
19584
  var activeWorkspace = 0;
19590
19585
  var workspaceIndex = 0;
19591
19586
 
@@ -19908,12 +19903,18 @@ RED.workspaces = (function() {
19908
19903
  $("#red-ui-workspace-chart").show();
19909
19904
  activeWorkspace = tab.id;
19910
19905
  window.location.hash = 'flow/'+tab.id;
19906
+ if (tab.label) {
19907
+ document.title = `${documentTitle} : ${tab.label}`
19908
+ } else {
19909
+ document.title = documentTitle
19910
+ }
19911
19911
  $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled", !!tab.disabled);
19912
19912
  $("#red-ui-workspace").toggleClass("red-ui-workspace-locked", !!tab.locked);
19913
19913
  } else {
19914
19914
  $("#red-ui-workspace-chart").hide();
19915
19915
  activeWorkspace = 0;
19916
19916
  window.location.hash = '';
19917
+ document.title = documentTitle
19917
19918
  }
19918
19919
  event.workspace = activeWorkspace;
19919
19920
  RED.events.emit("workspace:change",event);
@@ -24710,7 +24711,7 @@ RED.view = (function() {
24710
24711
  nodeEl.__statusGroup__.style.display = "none";
24711
24712
  } else {
24712
24713
  nodeEl.__statusGroup__.style.display = "inline";
24713
- let backgroundWidth = 12
24714
+ let backgroundWidth = 15
24714
24715
  var fill = status_colours[d.status.fill]; // Only allow our colours for now
24715
24716
  if (d.status.shape == null && fill == null) {
24716
24717
  backgroundWidth = 0
@@ -24730,7 +24731,11 @@ RED.view = (function() {
24730
24731
  nodeEl.__statusLabel__.textContent = "";
24731
24732
  }
24732
24733
  const textSize = nodeEl.__statusLabel__.getBBox()
24733
- nodeEl.__statusBackground__.setAttribute('width', backgroundWidth + textSize.width + 6)
24734
+ backgroundWidth += textSize.width
24735
+ if (backgroundWidth > 0 && textSize.width > 0) {
24736
+ backgroundWidth += 6
24737
+ }
24738
+ nodeEl.__statusBackground__.setAttribute('width', backgroundWidth)
24734
24739
  }
24735
24740
  delete d.dirtyStatus;
24736
24741
  }
@@ -25142,8 +25147,8 @@ RED.view = (function() {
25142
25147
  statusBackground.setAttribute("y",-1);
25143
25148
  statusBackground.setAttribute("width",200);
25144
25149
  statusBackground.setAttribute("height",13);
25145
- statusBackground.setAttribute("rx",1);
25146
- statusBackground.setAttribute("ry",1);
25150
+ statusBackground.setAttribute("rx",2);
25151
+ statusBackground.setAttribute("ry",2);
25147
25152
 
25148
25153
  statusEl.appendChild(statusBackground);
25149
25154
  node[0][0].__statusBackground__ = statusBackground;
@@ -30149,7 +30154,7 @@ RED.sidebar.info = (function() {
30149
30154
  }
30150
30155
  $(this).toggleClass('expanded',!isExpanded);
30151
30156
  });
30152
- mermaid.init();
30157
+ RED.editor.mermaid.render()
30153
30158
  }
30154
30159
 
30155
30160
  var tips = (function() {
@@ -31387,6 +31392,7 @@ RED.sidebar.help = (function() {
31387
31392
  $(this).toggleClass('expanded',!isExpanded);
31388
31393
  })
31389
31394
  helpSection.parent().scrollTop(0);
31395
+ RED.editor.mermaid.render()
31390
31396
  }
31391
31397
 
31392
31398
  function set(html,title) {
@@ -33696,8 +33702,9 @@ RED.editor = (function() {
33696
33702
  var valid = validateNodeProperty(node, definition, prop, properties[prop]);
33697
33703
  if ((typeof valid) === "string") {
33698
33704
  result.push(valid);
33699
- }
33700
- else if(!valid) {
33705
+ } else if (Array.isArray(valid)) {
33706
+ result = result.concat(valid)
33707
+ } else if(!valid) {
33701
33708
  result.push(prop);
33702
33709
  }
33703
33710
  }
@@ -33746,7 +33753,7 @@ RED.editor = (function() {
33746
33753
  // If the validator takes two arguments, it is a 3.x validator that
33747
33754
  // can return a String to mean 'invalid' and provide a reason
33748
33755
  if ((definition[property].validate.length === 2) &&
33749
- ((typeof valid) === "string")) {
33756
+ ((typeof valid) === "string") || Array.isArray(valid)) {
33750
33757
  return valid;
33751
33758
  } else {
33752
33759
  // Otherwise, a 2.x returns a truth-like/false-like value that
@@ -33762,6 +33769,17 @@ RED.editor = (function() {
33762
33769
  error: err.message
33763
33770
  });
33764
33771
  }
33772
+ } else if (valid) {
33773
+ // If the validator is not provided in node property => Check if the input has a validator
33774
+ if ("category" in node._def) {
33775
+ const isConfig = node._def.category === "config";
33776
+ const prefix = isConfig ? "node-config-input" : "node-input";
33777
+ const input = $("#"+prefix+"-"+property);
33778
+ const isTypedInput = input.length > 0 && input.next(".red-ui-typedInput-container").length > 0;
33779
+ if (isTypedInput) {
33780
+ valid = input.typedInput("validate");
33781
+ }
33782
+ }
33765
33783
  }
33766
33784
  if (valid && definition[property].type && RED.nodes.getType(definition[property].type) && !("validate" in definition[property])) {
33767
33785
  if (!value || value == "_ADD_") {
@@ -36928,7 +36946,7 @@ RED.editor = (function() {
36928
36946
  var i=0,l=bufferBinValue.length;
36929
36947
  var c = 0;
36930
36948
  for(i=0;i<l;i++) {
36931
- var d = parseInt(bufferBinValue[i]);
36949
+ var d = parseInt(Number(bufferBinValue[i]));
36932
36950
  if (!isString && (isNaN(d) || d < 0 || d > 255)) {
36933
36951
  valid = false;
36934
36952
  break;
@@ -39396,7 +39414,7 @@ RED.editor = (function() {
39396
39414
  var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
39397
39415
  $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
39398
39416
  $(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
39399
- mermaid.init();
39417
+ RED.editor.mermaid.render()
39400
39418
  },200);
39401
39419
  })
39402
39420
  if (options.header) {
@@ -39405,7 +39423,7 @@ RED.editor = (function() {
39405
39423
 
39406
39424
  if (value) {
39407
39425
  $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
39408
- mermaid.init();
39426
+ RED.editor.mermaid.render()
39409
39427
  }
39410
39428
  panels = RED.panels.create({
39411
39429
  id:"red-ui-editor-type-markdown-panels",
@@ -39511,6 +39529,60 @@ RED.editor = (function() {
39511
39529
  }
39512
39530
  RED.editor.registerTypeEditor("_markdown", definition);
39513
39531
  })();
39532
+ ;RED.editor.mermaid = (function () {
39533
+ let initializing = false
39534
+ let loaded = false
39535
+ let pendingEvals = []
39536
+ let diagramIds = 0
39537
+
39538
+ function render(selector = '.mermaid') {
39539
+ // $(selector).hide()
39540
+ if (!loaded) {
39541
+ pendingEvals.push(selector)
39542
+
39543
+ if (!initializing) {
39544
+ initializing = true
39545
+ $.getScript(
39546
+ 'vendor/mermaid/mermaid.min.js',
39547
+ function (data, stat, jqxhr) {
39548
+ mermaid.initialize({
39549
+ startOnLoad: false,
39550
+ theme: RED.settings.get('mermaid', {}).theme
39551
+ })
39552
+ loaded = true
39553
+ while(pendingEvals.length > 0) {
39554
+ const pending = pendingEvals.shift()
39555
+ render(pending)
39556
+ }
39557
+ }
39558
+ )
39559
+ }
39560
+ } else {
39561
+ const nodes = document.querySelectorAll(selector)
39562
+
39563
+ nodes.forEach(async node => {
39564
+ if (!node.getAttribute('mermaid-processed')) {
39565
+ const mermaidContent = node.innerText
39566
+ node.setAttribute('mermaid-processed', true)
39567
+ try {
39568
+ const { svg } = await mermaid.render('mermaid-render-'+Date.now()+'-'+(diagramIds++), mermaidContent);
39569
+ node.innerHTML = svg
39570
+ } catch (err) {
39571
+ $('<div>').css({
39572
+ fontSize: '0.8em',
39573
+ border: '1px solid var(--red-ui-border-color-error)',
39574
+ padding: '5px',
39575
+ marginBottom: '10px',
39576
+ }).text(err.toString()).prependTo(node)
39577
+ }
39578
+ }
39579
+ })
39580
+ }
39581
+ }
39582
+ return {
39583
+ render: render,
39584
+ };
39585
+ })();
39514
39586
  ;/**
39515
39587
  * Copyright JS Foundation and other contributors, http://js.foundation
39516
39588
  *
@@ -40771,12 +40843,10 @@ RED.editor.codeEditor.monaco = (function() {
40771
40843
 
40772
40844
  //Unbind ctrl-Enter (default action is to insert a newline in editor) This permits the shortcut to close the tray.
40773
40845
  try {
40774
- ed._standaloneKeybindingService.addDynamicKeybinding(
40775
- '-editor.action.insertLineAfter', // command ID prefixed by '-'
40776
- null, // keybinding
40777
- () => {} // need to pass an empty handler
40778
- );
40779
- } catch (error) { }
40846
+ monaco.editor.addKeybindingRule({keybinding: 0, command: "-editor.action.insertLineAfter"});
40847
+ } catch (error) {
40848
+ console.warn(error)
40849
+ }
40780
40850
 
40781
40851
  ed.nodered = {
40782
40852
  refreshModuleLibs: refreshModuleLibs //expose this for function node externalModules refresh
@@ -44985,7 +45055,7 @@ RED.search = (function() {
44985
45055
  }
44986
45056
 
44987
45057
  menuItems.push(
44988
- { onselect: 'core:show-action-list', onpostselect: function () { } }
45058
+ { onselect: 'core:show-action-list', label: RED._("contextMenu.showActionList"), onpostselect: function () { } }
44989
45059
  )
44990
45060
 
44991
45061
  const insertOptions = []
@@ -45049,16 +45119,16 @@ RED.search = (function() {
45049
45119
  const nodeOptions = []
45050
45120
  if (!hasMultipleSelection && !isGroup) {
45051
45121
  nodeOptions.push(
45052
- { onselect: 'core:show-node-help' },
45122
+ { onselect: 'core:show-node-help', label: RED._('menu.label.showNodeHelp') },
45053
45123
  null
45054
45124
  )
45055
45125
  }
45056
45126
  nodeOptions.push(
45057
- { onselect: 'core:enable-selected-nodes' },
45058
- { onselect: 'core:disable-selected-nodes' },
45127
+ { onselect: 'core:enable-selected-nodes', label: RED._('menu.label.enableSelectedNodes') },
45128
+ { onselect: 'core:disable-selected-nodes', label: RED._('menu.label.disableDelectedNodes') },
45059
45129
  null,
45060
- { onselect: 'core:show-selected-node-labels' },
45061
- { onselect: 'core:hide-selected-node-labels' }
45130
+ { onselect: 'core:show-selected-node-labels', label: RED._('menu.label.showSelectedNodeLabels') },
45131
+ { onselect: 'core:hide-selected-node-labels', label: RED._('menu.label.hideSelectedNodeLabels') }
45062
45132
  )
45063
45133
  menuItems.push({
45064
45134
  label: RED._('sidebar.info.node'),
@@ -45067,8 +45137,8 @@ RED.search = (function() {
45067
45137
  menuItems.push({
45068
45138
  label: RED._('sidebar.info.group'),
45069
45139
  options: [
45070
- { onselect: 'core:group-selection' },
45071
- { onselect: 'core:ungroup-selection', disabled: !hasGroup },
45140
+ { onselect: 'core:group-selection', label: RED._("menu.label.groupSelection") },
45141
+ { onselect: 'core:ungroup-selection', label: RED._("menu.label.ungroupSelection"), disabled: !hasGroup },
45072
45142
  ]
45073
45143
  })
45074
45144
  if (hasGroup) {
@@ -45084,8 +45154,8 @@ RED.search = (function() {
45084
45154
  }
45085
45155
  menuItems[menuItems.length - 1].options.push(
45086
45156
  null,
45087
- { onselect: 'core:copy-group-style', disabled: !hasGroup },
45088
- { onselect: 'core:paste-group-style', disabled: !hasGroup}
45157
+ { onselect: 'core:copy-group-style', label: RED._("keyboard.copyGroupStyle"), disabled: !hasGroup },
45158
+ { onselect: 'core:paste-group-style', label: RED._("keyboard.pasteGroupStyle"), disabled: !hasGroup}
45089
45159
  )
45090
45160
  }
45091
45161
  if (canEdit && hasMultipleSelection) {
@@ -45109,16 +45179,16 @@ RED.search = (function() {
45109
45179
 
45110
45180
  menuItems.push(
45111
45181
  null,
45112
- { onselect: 'core:undo', disabled: RED.history.list().length === 0 },
45113
- { onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
45182
+ { onselect: 'core:undo', label: RED._("keyboard.undoChange"), disabled: RED.history.list().length === 0 },
45183
+ { onselect: 'core:redo', label: RED._("keyboard.redoChange"), disabled: RED.history.listRedo().length === 0 },
45114
45184
  null,
45115
45185
  { onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !canEdit || !hasSelection },
45116
45186
  { onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
45117
45187
  { onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !canEdit || !RED.view.clipboard() },
45118
- { onselect: 'core:delete-selection', disabled: !canEdit || !canDelete },
45188
+ { onselect: 'core:delete-selection', label: RED._('keyboard.deleteSelected'), disabled: !canEdit || !canDelete },
45119
45189
  { onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
45120
45190
  { onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
45121
- { onselect: 'core:select-all-nodes' },
45191
+ { onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") },
45122
45192
  )
45123
45193
  }
45124
45194
 
@@ -45742,7 +45812,7 @@ RED.actionList = (function() {
45742
45812
  }
45743
45813
  }
45744
45814
  function applyFilter(filter,type,def) {
45745
- return !filter ||
45815
+ return !def || !filter ||
45746
45816
  (
45747
45817
  (!filter.spliceMultiple) &&
45748
45818
  (!filter.type || type === filter.type) &&
@@ -50885,7 +50955,7 @@ RED.projects.settings = (function() {
50885
50955
  var description = addTargetToExternalLinks($('<span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(desc)+'">'+desc+'</span>')).appendTo(container);
50886
50956
  description.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
50887
50957
  setTimeout(function () {
50888
- mermaid.init();
50958
+ RED.editor.mermaid.render()
50889
50959
  }, 200);
50890
50960
  }
50891
50961
 
@@ -53493,9 +53563,9 @@ RED.sidebar.versionControl = (function() {
53493
53563
  $.getJSON("projects/"+activeProject.name+"/commits/"+entry.sha,function(result) {
53494
53564
  result.project = activeProject;
53495
53565
  result.parents = entry.parents;
53496
- result.oldRev = entry.sha+"~1";
53566
+ result.oldRev = entry.parents[0].length !== 0 ? entry.sha+"~1" : entry.sha;
53497
53567
  result.newRev = entry.sha;
53498
- result.oldRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7)+"~1";
53568
+ result.oldRevTitle = entry.parents[0].length !== 0 ? RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7)+"~1" : " ";
53499
53569
  result.newRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7);
53500
53570
  result.date = humanizeSinceDate(parseInt(entry.date));
53501
53571
  RED.diff.showCommitDiff(result);