@node-red/editor-client 3.1.0-beta.4 → 3.1.1

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();
@@ -822,7 +842,7 @@ var RED = (function() {
822
842
  }
823
843
  menuOptions.push({id:"menu-item-help",
824
844
  label: RED.settings.theme("menu.menu-item-help.label",RED._("menu.label.help")),
825
- href: RED.settings.theme("menu.menu-item-help.url","http://nodered.org/docs")
845
+ href: RED.settings.theme("menu.menu-item-help.url","https://nodered.org/docs")
826
846
  });
827
847
  menuOptions.push({id:"menu-item-node-red-version", label:"v"+RED.settings.version, onselect: "core:show-about" });
828
848
 
@@ -4493,8 +4513,8 @@ RED.nodes = (function() {
4493
4513
 
4494
4514
  if (node && node._def.onremove) {
4495
4515
  // Deprecated: never documented but used by some early nodes
4496
- console.log("Deprecated API warning: node type ",node.type," has an onremove function - should be oneditremove - please report");
4497
- node._def.onremove.call(n);
4516
+ console.log("Deprecated API warning: node type ",node.type," has an onremove function - should be oneditdelete - please report");
4517
+ node._def.onremove.call(node);
4498
4518
  }
4499
4519
  return {links:removedLinks,nodes:removedNodes};
4500
4520
  }
@@ -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,32 @@ 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
+ const result = RED.utils.validateTypedProperty(v, ptype, opt)
8491
+ if (result === true || opt) {
8492
+ // Valid, or opt provided - return result as-is
8493
+ return result
8507
8494
  }
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;
8495
+ // No opt - need to return false for backwards compatibilty
8496
+ return false
8529
8497
  }
8530
8498
  }
8531
-
8532
- return {
8533
- initialize: initialize,
8534
- init: init,
8535
- };
8536
- })();
8537
- ;/**
8499
+ };;/**
8538
8500
  * Copyright JS Foundation and other contributors, http://js.foundation
8539
8501
  *
8540
8502
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -8637,28 +8599,8 @@ RED.utils = (function() {
8637
8599
 
8638
8600
  renderer.code = function (code, lang) {
8639
8601
  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 {
8602
+ return `<pre class='mermaid'>${code}</pre>`;
8603
+ } else {
8662
8604
  return "<pre><code>" +code +"</code></pre>";
8663
8605
  }
8664
8606
  };
@@ -9453,6 +9395,51 @@ RED.utils = (function() {
9453
9395
  }
9454
9396
  }
9455
9397
 
9398
+ /**
9399
+ * Checks a typed property is valid according to the type.
9400
+ * Returns true if valid.
9401
+ * Return String error message if invalid
9402
+ * @param {*} propertyType
9403
+ * @param {*} propertyValue
9404
+ * @returns true if valid, String if invalid
9405
+ */
9406
+ function validateTypedProperty(propertyValue, propertyType, opt) {
9407
+
9408
+ let error
9409
+ if (propertyType === 'json') {
9410
+ try {
9411
+ JSON.parse(propertyValue);
9412
+ } catch(err) {
9413
+ error = RED._("validator.errors.invalid-json", {
9414
+ error: err.message
9415
+ })
9416
+ }
9417
+ } else if (propertyType === 'msg' || propertyType === 'flow' || propertyType === 'global' ) {
9418
+ if (!RED.utils.validatePropertyExpression(propertyValue)) {
9419
+ error = RED._("validator.errors.invalid-prop")
9420
+ }
9421
+ } else if (propertyType === 'num') {
9422
+ if (!/^NaN$|^[+-]?[0-9]*\.?[0-9]*([eE][-+]?[0-9]+)?$|^[+-]?(0b|0B)[01]+$|^[+-]?(0o|0O)[0-7]+$|^[+-]?(0x|0X)[0-9a-fA-F]+$/.test(propertyValue)) {
9423
+ error = RED._("validator.errors.invalid-num")
9424
+ }
9425
+ } else if (propertyType === 'jsonata') {
9426
+ try {
9427
+ jsonata(propertyValue)
9428
+ } catch(err) {
9429
+ error = RED._("validator.errors.invalid-expr", {
9430
+ error: err.message
9431
+ })
9432
+ }
9433
+ }
9434
+ if (error) {
9435
+ if (opt && opt.label) {
9436
+ return opt.label+': '+error
9437
+ }
9438
+ return error
9439
+ }
9440
+ return true
9441
+ }
9442
+
9456
9443
  function getMessageProperty(msg,expr) {
9457
9444
  var result = null;
9458
9445
  var msgPropParts;
@@ -9987,7 +9974,8 @@ RED.utils = (function() {
9987
9974
  getDarkerColor: getDarkerColor,
9988
9975
  parseModuleList: parseModuleList,
9989
9976
  checkModuleAllowed: checkModuleAllowed,
9990
- getBrowserInfo: getBrowserInfo
9977
+ getBrowserInfo: getBrowserInfo,
9978
+ validateTypedProperty: validateTypedProperty
9991
9979
  }
9992
9980
  })();
9993
9981
  ;/**
@@ -14274,7 +14262,9 @@ RED.stack = (function() {
14274
14262
  valueLabel: contextLabel
14275
14263
  },
14276
14264
  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]+)?$/},
14265
+ num: {value:"num",label:"number",icon:"red/images/typedInput/09.svg",validate: function(v) {
14266
+ return (true === RED.utils.validateTypedProperty(v, "num"));
14267
+ } },
14278
14268
  bool: {value:"bool",label:"boolean",icon:"red/images/typedInput/bool.svg",options:["true","false"]},
14279
14269
  json: {
14280
14270
  value:"json",
@@ -17426,9 +17416,10 @@ RED.diagnostics = (function () {
17426
17416
  }
17427
17417
  if (localNode && remoteNode && typeof localNode[d] === "string") {
17428
17418
  if (/\n/.test(localNode[d]) || /\n/.test(remoteNode[d])) {
17429
- $('<button class="red-ui-button red-ui-button-small red-ui-diff-text-diff-button"><i class="fa fa-file-o"> <i class="fa fa-caret-left"></i> <i class="fa fa-caret-right"></i> <i class="fa fa-file-o"></i></button>').on("click", function() {
17419
+ var textDiff = $('<button class="red-ui-button red-ui-button-small red-ui-diff-text-diff-button"><i class="fa fa-file-o"> <i class="fa fa-caret-left"></i> <i class="fa fa-caret-right"></i> <i class="fa fa-file-o"></i></button>').on("click", function() {
17430
17420
  showTextDiff(localNode[d],remoteNode[d]);
17431
17421
  }).appendTo(propertyNameCell);
17422
+ RED.popover.tooltip(textDiff, RED._("diff.compareChanges"));
17432
17423
  }
17433
17424
  }
17434
17425
 
@@ -19585,6 +19576,8 @@ RED.keyboard = (function() {
19585
19576
 
19586
19577
  RED.workspaces = (function() {
19587
19578
 
19579
+ const documentTitle = document.title;
19580
+
19588
19581
  var activeWorkspace = 0;
19589
19582
  var workspaceIndex = 0;
19590
19583
 
@@ -19907,12 +19900,18 @@ RED.workspaces = (function() {
19907
19900
  $("#red-ui-workspace-chart").show();
19908
19901
  activeWorkspace = tab.id;
19909
19902
  window.location.hash = 'flow/'+tab.id;
19903
+ if (tab.label) {
19904
+ document.title = `${documentTitle} : ${tab.label}`
19905
+ } else {
19906
+ document.title = documentTitle
19907
+ }
19910
19908
  $("#red-ui-workspace").toggleClass("red-ui-workspace-disabled", !!tab.disabled);
19911
19909
  $("#red-ui-workspace").toggleClass("red-ui-workspace-locked", !!tab.locked);
19912
19910
  } else {
19913
19911
  $("#red-ui-workspace-chart").hide();
19914
19912
  activeWorkspace = 0;
19915
19913
  window.location.hash = '';
19914
+ document.title = documentTitle
19916
19915
  }
19917
19916
  event.workspace = activeWorkspace;
19918
19917
  RED.events.emit("workspace:change",event);
@@ -20824,11 +20823,21 @@ RED.view = (function() {
20824
20823
  return api
20825
20824
  })()
20826
20825
 
20826
+ const isMac = RED.utils.getBrowserInfo().os === 'mac'
20827
+ // 'Control' is the main modifier key for mouse actions. On Windows,
20828
+ // that is the standard Ctrl key. On Mac that is the Cmd key.
20829
+ function isControlPressed (event) {
20830
+ return (isMac && event.metaKey) || (!isMac && event.ctrlKey)
20831
+ }
20827
20832
 
20828
20833
  function init() {
20829
20834
 
20830
20835
  chart = $("#red-ui-workspace-chart");
20831
20836
  chart.on('contextmenu', function(evt) {
20837
+ if (RED.view.DEBUG) {
20838
+ console.warn("contextmenu", { mouse_mode, event: d3.event });
20839
+ }
20840
+ mouse_mode = RED.state.DEFAULT
20832
20841
  evt.preventDefault()
20833
20842
  evt.stopPropagation()
20834
20843
  RED.contextMenu.show({
@@ -21712,7 +21721,7 @@ RED.view = (function() {
21712
21721
  lasso = null;
21713
21722
  }
21714
21723
  if (d3.event.touches || d3.event.button === 0) {
21715
- if ((mouse_mode === 0 || mouse_mode === RED.state.QUICK_JOINING) && (d3.event.metaKey || d3.event.ctrlKey) && !(d3.event.altKey || d3.event.shiftKey)) {
21724
+ if ((mouse_mode === 0 || mouse_mode === RED.state.QUICK_JOINING) && isControlPressed(d3.event) && !(d3.event.altKey || d3.event.shiftKey)) {
21716
21725
  // Trigger quick add dialog
21717
21726
  d3.event.stopPropagation();
21718
21727
  clearSelection();
@@ -21722,7 +21731,7 @@ RED.view = (function() {
21722
21731
  clickedGroup = clickedGroup || RED.nodes.group(drag_lines[0].node.g)
21723
21732
  }
21724
21733
  showQuickAddDialog({ position: point, group: clickedGroup });
21725
- } else if (mouse_mode === 0 && !(d3.event.metaKey || d3.event.ctrlKey)) {
21734
+ } else if (mouse_mode === 0 && !isControlPressed(d3.event)) {
21726
21735
  // CTRL not being held
21727
21736
  if (!d3.event.altKey) {
21728
21737
  // ALT not held (shift is allowed) Trigger lasso
@@ -21920,6 +21929,7 @@ RED.view = (function() {
21920
21929
  }
21921
21930
  historyEvent = {
21922
21931
  t:'add',
21932
+ dirty: RED.nodes.dirty(),
21923
21933
  junctions:[nn]
21924
21934
  }
21925
21935
  } else {
@@ -24061,7 +24071,7 @@ RED.view = (function() {
24061
24071
  d3.event.preventDefault()
24062
24072
  document.getSelection().removeAllRanges()
24063
24073
  if (d.type != "subflow") {
24064
- if (/^subflow:/.test(d.type) && (d3.event.ctrlKey || d3.event.metaKey)) {
24074
+ if (/^subflow:/.test(d.type) && isControlPressed(d3.event)) {
24065
24075
  RED.workspaces.show(d.type.substring(8));
24066
24076
  } else {
24067
24077
  RED.editor.edit(d);
@@ -24225,12 +24235,12 @@ RED.view = (function() {
24225
24235
  d.type !== 'junction'
24226
24236
  lastClickNode = mousedown_node;
24227
24237
 
24228
- if (d.selected && (d3.event.ctrlKey||d3.event.metaKey)) {
24238
+ if (d.selected && isControlPressed(d3.event)) {
24229
24239
  mousedown_node.selected = false;
24230
24240
  movingSet.remove(mousedown_node);
24231
24241
  } else {
24232
24242
  if (d3.event.shiftKey) {
24233
- if (!(d3.event.ctrlKey||d3.event.metaKey)) {
24243
+ if (!isControlPressed(d3.event)) {
24234
24244
  clearSelection();
24235
24245
  }
24236
24246
  var clickPosition = (d3.event.offsetX/scaleFactor - mousedown_node.x)
@@ -24399,10 +24409,10 @@ RED.view = (function() {
24399
24409
  }
24400
24410
  mousedown_link = d;
24401
24411
 
24402
- if (!(d3.event.metaKey || d3.event.ctrlKey)) {
24412
+ if (!isControlPressed(d3.event)) {
24403
24413
  clearSelection();
24404
24414
  }
24405
- if (d3.event.metaKey || d3.event.ctrlKey) {
24415
+ if (isControlPressed(d3.event)) {
24406
24416
  if (!selectedLinks.has(mousedown_link)) {
24407
24417
  selectedLinks.add(mousedown_link);
24408
24418
  } else {
@@ -24417,7 +24427,7 @@ RED.view = (function() {
24417
24427
  redraw();
24418
24428
  focusView();
24419
24429
  d3.event.stopPropagation();
24420
- if (!mousedown_link.link && movingSet.length() === 0 && (d3.event.touches || d3.event.button === 0) && selectedLinks.length() === 1 && selectedLinks.has(mousedown_link) && (d3.event.metaKey || d3.event.ctrlKey)) {
24430
+ if (!mousedown_link.link && movingSet.length() === 0 && (d3.event.touches || d3.event.button === 0) && selectedLinks.length() === 1 && selectedLinks.has(mousedown_link) && isControlPressed(d3.event)) {
24421
24431
  d3.select(this).classed("red-ui-flow-link-splice",true);
24422
24432
  var point = d3.mouse(this);
24423
24433
  var clickedGroup = getGroupAt(point[0],point[1]);
@@ -24498,7 +24508,7 @@ RED.view = (function() {
24498
24508
  );
24499
24509
  lastClickNode = g;
24500
24510
 
24501
- if (g.selected && (d3.event.ctrlKey||d3.event.metaKey)) {
24511
+ if (g.selected && isControlPressed(d3.event)) {
24502
24512
  selectedGroups.remove(g);
24503
24513
  d3.event.stopPropagation();
24504
24514
  } else {
@@ -24698,7 +24708,7 @@ RED.view = (function() {
24698
24708
  nodeEl.__statusGroup__.style.display = "none";
24699
24709
  } else {
24700
24710
  nodeEl.__statusGroup__.style.display = "inline";
24701
- let backgroundWidth = 12
24711
+ let backgroundWidth = 15
24702
24712
  var fill = status_colours[d.status.fill]; // Only allow our colours for now
24703
24713
  if (d.status.shape == null && fill == null) {
24704
24714
  backgroundWidth = 0
@@ -24718,7 +24728,11 @@ RED.view = (function() {
24718
24728
  nodeEl.__statusLabel__.textContent = "";
24719
24729
  }
24720
24730
  const textSize = nodeEl.__statusLabel__.getBBox()
24721
- nodeEl.__statusBackground__.setAttribute('width', backgroundWidth + textSize.width + 6)
24731
+ backgroundWidth += textSize.width
24732
+ if (backgroundWidth > 0 && textSize.width > 0) {
24733
+ backgroundWidth += 6
24734
+ }
24735
+ nodeEl.__statusBackground__.setAttribute('width', backgroundWidth)
24722
24736
  }
24723
24737
  delete d.dirtyStatus;
24724
24738
  }
@@ -25130,8 +25144,8 @@ RED.view = (function() {
25130
25144
  statusBackground.setAttribute("y",-1);
25131
25145
  statusBackground.setAttribute("width",200);
25132
25146
  statusBackground.setAttribute("height",13);
25133
- statusBackground.setAttribute("rx",1);
25134
- statusBackground.setAttribute("ry",1);
25147
+ statusBackground.setAttribute("rx",2);
25148
+ statusBackground.setAttribute("ry",2);
25135
25149
 
25136
25150
  statusEl.appendChild(statusBackground);
25137
25151
  node[0][0].__statusBackground__ = statusBackground;
@@ -30137,7 +30151,7 @@ RED.sidebar.info = (function() {
30137
30151
  }
30138
30152
  $(this).toggleClass('expanded',!isExpanded);
30139
30153
  });
30140
- mermaid.init();
30154
+ RED.editor.mermaid.render()
30141
30155
  }
30142
30156
 
30143
30157
  var tips = (function() {
@@ -31375,6 +31389,7 @@ RED.sidebar.help = (function() {
31375
31389
  $(this).toggleClass('expanded',!isExpanded);
31376
31390
  })
31377
31391
  helpSection.parent().scrollTop(0);
31392
+ RED.editor.mermaid.render()
31378
31393
  }
31379
31394
 
31380
31395
  function set(html,title) {
@@ -32139,11 +32154,11 @@ RED.sidebar.context = (function() {
32139
32154
  var obj = $(propRow.children()[0]);
32140
32155
  obj.text(k);
32141
32156
  var tools = $('<span class="button-group"></span>');
32142
-
32157
+ const urlSafeK = encodeURIComponent(k)
32143
32158
  var refreshItem = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-refresh"></i></button>').appendTo(tools).on("click", function(e) {
32144
32159
  e.preventDefault();
32145
32160
  e.stopPropagation();
32146
- $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) {
32161
+ $.getJSON(baseUrl+"/"+urlSafeK+"?store="+v.store, function(data) {
32147
32162
  if (data.msg !== payload || data.format !== format) {
32148
32163
  payload = data.msg;
32149
32164
  format = data.format;
@@ -32179,11 +32194,12 @@ RED.sidebar.context = (function() {
32179
32194
  $('<button class="red-ui-button primary" data-i18n="common.label.delete"></button>').appendTo(bg).on("click", function(e) {
32180
32195
  e.preventDefault();
32181
32196
  popover.close();
32197
+ const urlSafeK = encodeURIComponent(k)
32182
32198
  $.ajax({
32183
- url: baseUrl+"/"+k+"?store="+v.store,
32199
+ url: baseUrl+"/"+urlSafeK+"?store="+v.store,
32184
32200
  type: "DELETE"
32185
32201
  }).done(function(data,textStatus,xhr) {
32186
- $.getJSON(baseUrl+"/"+k+"?store="+v.store, function(data) {
32202
+ $.getJSON(baseUrl+"/"+urlSafeK+"?store="+v.store, function(data) {
32187
32203
  if (data.format === 'undefined') {
32188
32204
  propRow.remove();
32189
32205
  if (container.children().length === 0) {
@@ -32747,6 +32763,7 @@ RED.palette.editor = (function() {
32747
32763
  // if there is only 1 catalog, hide the select
32748
32764
  if (catalogEntries.length > 1) {
32749
32765
  catalogSelection.prepend(`<option value="all">${RED._('palette.editor.allCatalogs')}</option>`)
32766
+ catalogSelection.val('all')
32750
32767
  catalogSelection.removeAttr('disabled') // permit the user to select a catalog
32751
32768
  }
32752
32769
  // refresh the searchInput counter and trigger a change
@@ -32776,7 +32793,7 @@ RED.palette.editor = (function() {
32776
32793
  function refreshFilteredItems() {
32777
32794
  packageList.editableList('empty');
32778
32795
  var currentFilter = searchInput.searchBox('value').trim();
32779
- if (currentFilter === ""){
32796
+ if (currentFilter === "" && loadedList.length > 20){
32780
32797
  packageList.editableList('addItem',{count:loadedList.length})
32781
32798
  return;
32782
32799
  }
@@ -33146,7 +33163,7 @@ RED.palette.editor = (function() {
33146
33163
  delay: 300,
33147
33164
  change: function() {
33148
33165
  var searchTerm = $(this).val().trim().toLowerCase();
33149
- if (searchTerm.length > 0) {
33166
+ if (searchTerm.length > 0 || loadedList.length < 20) {
33150
33167
  filteredList = loadedList.filter(function(m) {
33151
33168
  return (m.index.indexOf(searchTerm) > -1);
33152
33169
  }).map(function(f) { return {info:f}});
@@ -33170,6 +33187,7 @@ RED.palette.editor = (function() {
33170
33187
  const sortRelevance = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle selected"><i class="fa fa-sort-amount-desc"></i></a>').appendTo(sortGroup);
33171
33188
  const sortAZ = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle"><i class="fa fa-sort-alpha-asc"></i></a>').appendTo(sortGroup);
33172
33189
  const sortRecent = $('<a href="#" class="red-ui-palette-editor-install-sort-option red-ui-sidebar-header-button-toggle"><i class="fa fa-calendar"></i></a>').appendTo(sortGroup);
33190
+ RED.popover.tooltip(sortRelevance,RED._("palette.editor.sortRelevance"));
33173
33191
  RED.popover.tooltip(sortAZ,RED._("palette.editor.sortAZ"));
33174
33192
  RED.popover.tooltip(sortRecent,RED._("palette.editor.sortRecent"));
33175
33193
 
@@ -33681,8 +33699,9 @@ RED.editor = (function() {
33681
33699
  var valid = validateNodeProperty(node, definition, prop, properties[prop]);
33682
33700
  if ((typeof valid) === "string") {
33683
33701
  result.push(valid);
33684
- }
33685
- else if(!valid) {
33702
+ } else if (Array.isArray(valid)) {
33703
+ result = result.concat(valid)
33704
+ } else if(!valid) {
33686
33705
  result.push(prop);
33687
33706
  }
33688
33707
  }
@@ -33731,7 +33750,7 @@ RED.editor = (function() {
33731
33750
  // If the validator takes two arguments, it is a 3.x validator that
33732
33751
  // can return a String to mean 'invalid' and provide a reason
33733
33752
  if ((definition[property].validate.length === 2) &&
33734
- ((typeof valid) === "string")) {
33753
+ ((typeof valid) === "string") || Array.isArray(valid)) {
33735
33754
  return valid;
33736
33755
  } else {
33737
33756
  // Otherwise, a 2.x returns a truth-like/false-like value that
@@ -33747,6 +33766,17 @@ RED.editor = (function() {
33747
33766
  error: err.message
33748
33767
  });
33749
33768
  }
33769
+ } else if (valid) {
33770
+ // If the validator is not provided in node property => Check if the input has a validator
33771
+ if ("category" in node._def) {
33772
+ const isConfig = node._def.category === "config";
33773
+ const prefix = isConfig ? "node-config-input" : "node-input";
33774
+ const input = $("#"+prefix+"-"+property);
33775
+ const isTypedInput = input.length > 0 && input.next(".red-ui-typedInput-container").length > 0;
33776
+ if (isTypedInput) {
33777
+ valid = input.typedInput("validate");
33778
+ }
33779
+ }
33750
33780
  }
33751
33781
  if (valid && definition[property].type && RED.nodes.getType(definition[property].type) && !("validate" in definition[property])) {
33752
33782
  if (!value || value == "_ADD_") {
@@ -35881,7 +35911,7 @@ RED.editor = (function() {
35881
35911
  }
35882
35912
 
35883
35913
  $('<div class="form-row">'+
35884
- '<label for="node-input-show-label-btn" data-i18n="editor.label"></label>'+
35914
+ '<label for="node-input-show-label" data-i18n="editor.label"></label>'+
35885
35915
  '<span style="margin-right: 2px;"/>'+
35886
35916
  '<input type="checkbox" id="node-input-show-label"/>'+
35887
35917
  '</div>').appendTo(dialogForm);
@@ -36913,7 +36943,7 @@ RED.editor = (function() {
36913
36943
  var i=0,l=bufferBinValue.length;
36914
36944
  var c = 0;
36915
36945
  for(i=0;i<l;i++) {
36916
- var d = parseInt(bufferBinValue[i]);
36946
+ var d = parseInt(Number(bufferBinValue[i]));
36917
36947
  if (!isString && (isNaN(d) || d < 0 || d > 255)) {
36918
36948
  valid = false;
36919
36949
  break;
@@ -39381,7 +39411,7 @@ RED.editor = (function() {
39381
39411
  var currentScrollTop = $(".red-ui-editor-type-markdown-panel-preview").scrollTop();
39382
39412
  $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
39383
39413
  $(".red-ui-editor-type-markdown-panel-preview").scrollTop(currentScrollTop);
39384
- mermaid.init();
39414
+ RED.editor.mermaid.render()
39385
39415
  },200);
39386
39416
  })
39387
39417
  if (options.header) {
@@ -39390,7 +39420,7 @@ RED.editor = (function() {
39390
39420
 
39391
39421
  if (value) {
39392
39422
  $(".red-ui-editor-type-markdown-panel-preview").html(RED.utils.renderMarkdown(expressionEditor.getValue()));
39393
- mermaid.init();
39423
+ RED.editor.mermaid.render()
39394
39424
  }
39395
39425
  panels = RED.panels.create({
39396
39426
  id:"red-ui-editor-type-markdown-panels",
@@ -39496,6 +39526,60 @@ RED.editor = (function() {
39496
39526
  }
39497
39527
  RED.editor.registerTypeEditor("_markdown", definition);
39498
39528
  })();
39529
+ ;RED.editor.mermaid = (function () {
39530
+ let initializing = false
39531
+ let loaded = false
39532
+ let pendingEvals = []
39533
+ let diagramIds = 0
39534
+
39535
+ function render(selector = '.mermaid') {
39536
+ // $(selector).hide()
39537
+ if (!loaded) {
39538
+ pendingEvals.push(selector)
39539
+
39540
+ if (!initializing) {
39541
+ initializing = true
39542
+ $.getScript(
39543
+ 'vendor/mermaid/mermaid.min.js',
39544
+ function (data, stat, jqxhr) {
39545
+ mermaid.initialize({
39546
+ startOnLoad: false,
39547
+ theme: RED.settings.get('mermaid', {}).theme
39548
+ })
39549
+ loaded = true
39550
+ while(pendingEvals.length > 0) {
39551
+ const pending = pendingEvals.shift()
39552
+ render(pending)
39553
+ }
39554
+ }
39555
+ )
39556
+ }
39557
+ } else {
39558
+ const nodes = document.querySelectorAll(selector)
39559
+
39560
+ nodes.forEach(async node => {
39561
+ if (!node.getAttribute('mermaid-processed')) {
39562
+ const mermaidContent = node.innerText
39563
+ node.setAttribute('mermaid-processed', true)
39564
+ try {
39565
+ const { svg } = await mermaid.render('mermaid-render-'+Date.now()+'-'+(diagramIds++), mermaidContent);
39566
+ node.innerHTML = svg
39567
+ } catch (err) {
39568
+ $('<div>').css({
39569
+ fontSize: '0.8em',
39570
+ border: '1px solid var(--red-ui-border-color-error)',
39571
+ padding: '5px',
39572
+ marginBottom: '10px',
39573
+ }).text(err.toString()).prependTo(node)
39574
+ }
39575
+ }
39576
+ })
39577
+ }
39578
+ }
39579
+ return {
39580
+ render: render,
39581
+ };
39582
+ })();
39499
39583
  ;/**
39500
39584
  * Copyright JS Foundation and other contributors, http://js.foundation
39501
39585
  *
@@ -40756,12 +40840,10 @@ RED.editor.codeEditor.monaco = (function() {
40756
40840
 
40757
40841
  //Unbind ctrl-Enter (default action is to insert a newline in editor) This permits the shortcut to close the tray.
40758
40842
  try {
40759
- ed._standaloneKeybindingService.addDynamicKeybinding(
40760
- '-editor.action.insertLineAfter', // command ID prefixed by '-'
40761
- null, // keybinding
40762
- () => {} // need to pass an empty handler
40763
- );
40764
- } catch (error) { }
40843
+ monaco.editor.addKeybindingRule({keybinding: 0, command: "-editor.action.insertLineAfter"});
40844
+ } catch (error) {
40845
+ console.warn(error)
40846
+ }
40765
40847
 
40766
40848
  ed.nodered = {
40767
40849
  refreshModuleLibs: refreshModuleLibs //expose this for function node externalModules refresh
@@ -45094,8 +45176,8 @@ RED.search = (function() {
45094
45176
 
45095
45177
  menuItems.push(
45096
45178
  null,
45097
- { onselect: 'core:undo', disabled: RED.history.list().length === 0 },
45098
- { onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 },
45179
+ { onselect: 'core:undo', label: RED._("keyboard.undoChange"), disabled: RED.history.list().length === 0 },
45180
+ { onselect: 'core:redo', label: RED._("keyboard.redoChange"), disabled: RED.history.listRedo().length === 0 },
45099
45181
  null,
45100
45182
  { onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !canEdit || !hasSelection },
45101
45183
  { onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection },
@@ -45103,7 +45185,7 @@ RED.search = (function() {
45103
45185
  { onselect: 'core:delete-selection', disabled: !canEdit || !canDelete },
45104
45186
  { onselect: 'core:delete-selection-and-reconnect', label: RED._('keyboard.deleteReconnect'), disabled: !canEdit || !canDelete },
45105
45187
  { onselect: 'core:show-export-dialog', label: RED._("menu.label.export") },
45106
- { onselect: 'core:select-all-nodes' },
45188
+ { onselect: 'core:select-all-nodes', label: RED._("keyboard.selectAll") },
45107
45189
  )
45108
45190
  }
45109
45191
 
@@ -45727,7 +45809,7 @@ RED.actionList = (function() {
45727
45809
  }
45728
45810
  }
45729
45811
  function applyFilter(filter,type,def) {
45730
- return !filter ||
45812
+ return !def || !filter ||
45731
45813
  (
45732
45814
  (!filter.spliceMultiple) &&
45733
45815
  (!filter.type || type === filter.type) &&
@@ -45766,6 +45848,7 @@ RED.actionList = (function() {
45766
45848
  items.push({type:t,def: def, label:getTypeLabel(t,def)});
45767
45849
  }
45768
45850
  });
45851
+ items.push({ type: 'junction', def: { inputs:1, outputs: 1, label: 'junction', type: 'junction'}, label: 'junction' })
45769
45852
  items.sort(sortTypeLabels);
45770
45853
 
45771
45854
  var commonCount = 0;
@@ -50869,7 +50952,7 @@ RED.projects.settings = (function() {
50869
50952
  var description = addTargetToExternalLinks($('<span class="red-ui-text-bidi-aware" dir=\"'+RED.text.bidi.resolveBaseTextDir(desc)+'">'+desc+'</span>')).appendTo(container);
50870
50953
  description.find(".red-ui-text-bidi-aware").contents().filter(function() { return this.nodeType === 3 && this.textContent.trim() !== "" }).wrap( "<span></span>" );
50871
50954
  setTimeout(function () {
50872
- mermaid.init();
50955
+ RED.editor.mermaid.render()
50873
50956
  }, 200);
50874
50957
  }
50875
50958
 
@@ -53477,9 +53560,9 @@ RED.sidebar.versionControl = (function() {
53477
53560
  $.getJSON("projects/"+activeProject.name+"/commits/"+entry.sha,function(result) {
53478
53561
  result.project = activeProject;
53479
53562
  result.parents = entry.parents;
53480
- result.oldRev = entry.sha+"~1";
53563
+ result.oldRev = entry.parents[0].length !== 0 ? entry.sha+"~1" : entry.sha;
53481
53564
  result.newRev = entry.sha;
53482
- result.oldRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7)+"~1";
53565
+ result.oldRevTitle = entry.parents[0].length !== 0 ? RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7)+"~1" : " ";
53483
53566
  result.newRevTitle = RED._("sidebar.project.versionControl.commitCapital")+" "+entry.sha.substring(0,7);
53484
53567
  result.date = humanizeSinceDate(parseInt(entry.date));
53485
53568
  RED.diff.showCommitDiff(result);