From 49b85e3f73643886c6b0c9091104e9eef2752d38 Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:52:18 +0100 Subject: [PATCH 01/16] Allow actions show-next-tab and previous to loop --- .../@node-red/editor-client/src/js/ui/common/tabs.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js index d9dc4b289..544a8636c 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js @@ -607,6 +607,9 @@ RED.tabs = (function() { while(previous.length > 0 && previous.hasClass("hide-tab")) { previous = previous.prev(); } + if (previous.length === 0) { + previous = ul.find("li.red-ui-tab:not(.hide-tab)").last(); + } return previous; } function findNextVisibleTab(li) { @@ -617,6 +620,9 @@ RED.tabs = (function() { while(next.length > 0 && next.hasClass("hide-tab")) { next = next.next(); } + if (next.length === 0) { + next = ul.find("li.red-ui-tab:not(.hide-tab)").first(); + } return next; } function showTab(id) { From 4b906734c9d735ff2b6ada36307a88cb3dfb31e8 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sat, 6 Dec 2025 00:21:16 +0900 Subject: [PATCH 02/16] Fix debug tab to copy displayed value --- .../@node-red/editor-client/src/js/ui/utils.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js index cc570cd13..94e06297a 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js @@ -265,7 +265,13 @@ RED.utils = (function() { var copyPayload = $('').appendTo(copyTools).on("click", function(e) { e.preventDefault(); e.stopPropagation(); - RED.clipboard.copyText(msg,copyPayload,"clipboard.copyMessageValue"); + var payloadToCopy; + if (typeof msg === "number") { + payloadToCopy = obj.find(".red-ui-debug-msg-type-number").first().text(); + } else { + payloadToCopy = msg; + } + RED.clipboard.copyText(payloadToCopy, copyPayload, "clipboard.copyMessageValue"); }) RED.popover.tooltip(copyPayload,RED._("node-red:debug.sidebar.copyPayload")); if (enablePinning && strippedKey !== undefined && strippedKey !== '') { From 2c7a15ecb2a2b5c09463be9fea88fc151a4b05dc Mon Sep 17 00:00:00 2001 From: GogoVega <92022724+GogoVega@users.noreply.github.com> Date: Sun, 7 Dec 2025 12:04:59 +0100 Subject: [PATCH 03/16] Move the logic to the right place --- .../@node-red/editor-client/src/js/ui/common/tabs.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js index 544a8636c..7ae05e770 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/tabs.js @@ -443,12 +443,18 @@ RED.tabs = (function() { } function activatePreviousTab() { var previous = findPreviousVisibleTab(); + if (previous.length === 0) { + previous = ul.find("li.red-ui-tab:not(.hide-tab)").last(); + } if (previous.length > 0) { activateTab(previous.find("a")); } } function activateNextTab() { var next = findNextVisibleTab(); + if (next.length === 0) { + next = ul.find("li.red-ui-tab:not(.hide-tab)").first(); + } if (next.length > 0) { activateTab(next.find("a")); } @@ -607,9 +613,6 @@ RED.tabs = (function() { while(previous.length > 0 && previous.hasClass("hide-tab")) { previous = previous.prev(); } - if (previous.length === 0) { - previous = ul.find("li.red-ui-tab:not(.hide-tab)").last(); - } return previous; } function findNextVisibleTab(li) { @@ -620,9 +623,6 @@ RED.tabs = (function() { while(next.length > 0 && next.hasClass("hide-tab")) { next = next.next(); } - if (next.length === 0) { - next = ul.find("li.red-ui-tab:not(.hide-tab)").first(); - } return next; } function showTab(id) { From 811aaa9df446a2cccf9a043858d8c22cc6e3ab4c Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Mon, 29 Dec 2025 22:25:57 +0900 Subject: [PATCH 04/16] Fix scrolling issue in Git config UI --- .../@node-red/editor-client/src/sass/projects.scss | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/projects.scss b/packages/node_modules/@node-red/editor-client/src/sass/projects.scss index f6bd57375..b94504ba5 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/projects.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/projects.scss @@ -830,7 +830,13 @@ div.red-ui-projects-dialog-ssh-public-key { } #red-ui-settings-tab-gitconfig { + position: absolute; + top: 0; + right: 0; + left: 0; + bottom: 0; padding: 8px 20px 20px; + overflow-y: auto; } .red-ui-settings-section-description { color: var(--red-ui-secondary-text-color); From a2fdb198d61472c0d55fd9998ad4abbefb5609d6 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Mon, 29 Dec 2025 23:30:02 +0900 Subject: [PATCH 05/16] Fix list size in Git config UI --- .../node_modules/@node-red/editor-client/src/sass/projects.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/projects.scss b/packages/node_modules/@node-red/editor-client/src/sass/projects.scss index b94504ba5..176c430b0 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/projects.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/projects.scss @@ -755,6 +755,7 @@ div.red-ui-projects-dialog-ssh-public-key { } .red-ui-projects-dialog-list { + display: block; position: relative; .red-ui-editableList-container { padding: 1px; From a401ea9216b10a07e22659092eb99b7a8fb95403 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 30 Dec 2025 00:47:11 +0900 Subject: [PATCH 06/16] Stricter validator for flow file name in project feature --- .../@node-red/editor-client/src/js/ui/projects/projects.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js index f32e14c33..a49b0dd08 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/projects/projects.js @@ -720,7 +720,7 @@ RED.projects = (function() { var validateForm = function() { var valid = true; var flowFile = projectFlowFileInput.val(); - if (flowFile === "" || !/\.json$/.test(flowFile)) { + if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) { valid = false; if (!projectFlowFileInput.hasClass("input-error")) { projectFlowFileInput.addClass("input-error"); @@ -1142,7 +1142,7 @@ RED.projects = (function() { } else if (projectType === 'empty') { var flowFile = projectFlowFileInput.val(); - if (flowFile === "" || !/\.json$/.test(flowFile)) { + if (flowFile === "" || !/^[a-zA-Z0-9\-_]+\.json$/.test(flowFile)) { valid = false; if (!projectFlowFileInput.hasClass("input-error")) { projectFlowFileInput.addClass("input-error"); From 01ae461911f2a9e7c3f9b3415a1a493b7cf30402 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Tue, 30 Dec 2025 01:01:51 +0900 Subject: [PATCH 07/16] Expand folder to avoid error in library --- .../node_modules/@node-red/editor-client/src/js/ui/library.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js index 64b1f1547..a94bfb67c 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/library.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/library.js @@ -327,7 +327,7 @@ RED.library = (function() { icon: 'fa fa-cube', label: options.type, path: "", - expanded: false, + expanded: true, children: function(done, item) { loadLibraryFolder(lib.id, options.url, "", function(children) { item.children = children; From 187ce3bea4bd431282383448d8390b2f80d21474 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Fri, 2 Jan 2026 14:37:30 +0900 Subject: [PATCH 08/16] Fix invalid node size in quick add dialog --- .../node_modules/@node-red/editor-client/src/sass/search.scss | 1 + .../@node-red/editor-client/src/sass/ui/common/editableList.scss | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/search.scss b/packages/node_modules/@node-red/editor-client/src/sass/search.scss index 66ade8798..726c13714 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/search.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/search.scss @@ -80,6 +80,7 @@ width: 18px; height: 15px; margin-top: 1px; + flex-shrink: 0; } .red-ui-search-result-node-port { position: absolute; diff --git a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss index 00b79b54a..4b8873fee 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/ui/common/editableList.scss @@ -21,6 +21,7 @@ padding: 2px 16px 2px 4px; font-size: 0.9em; } + overflow-x: hidden; } .red-ui-editableList-container { padding: 5px; From d8f9139d2e316d4ff4f46d7f6696e04269169079 Mon Sep 17 00:00:00 2001 From: Piotr Bogun Date: Fri, 2 Jan 2026 16:15:40 -0600 Subject: [PATCH 09/16] Add check for junction node type in the quick add menu --- .../node_modules/@node-red/editor-client/src/js/ui/view.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js index c459de1ff..111b5df2a 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js @@ -6545,6 +6545,9 @@ RED.view = (function() { suggestedNodes = [suggestedNodes] } suggestedNodes = suggestedNodes.filter(n => { + if (n.type === 'junction') { + return true + } const def = RED.nodes.getType(n.type) if (def?.set && def.set.enabled === false) { // Exclude disabled node set From 8c594ac62753237530da75bbd62f82410254ecfe Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sat, 3 Jan 2026 14:31:46 +0900 Subject: [PATCH 10/16] Decrement count of http requests after error --- .../node_modules/@node-red/nodes/core/network/21-httprequest.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js index 33d9c3044..5194c7b01 100644 --- a/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js +++ b/packages/node_modules/@node-red/nodes/core/network/21-httprequest.js @@ -688,6 +688,7 @@ in your Node-RED user directory (${RED.settings.userDir}). if (!sendErrorsToCatch) { nodeSend(msg); } + node.count--; nodeDone(); }); }); From bcbd364ddd97f61ff562b337fdd6f20a44cfe502 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sat, 3 Jan 2026 17:04:01 +0900 Subject: [PATCH 11/16] Add tooltip to delete button --- .../@node-red/editor-client/src/js/ui/common/editableList.js | 2 ++ packages/node_modules/@node-red/nodes/core/network/05-tls.html | 3 +++ 2 files changed, 5 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js index ab9c8a837..b5117aea0 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js @@ -340,8 +340,10 @@ var deleteButton = $('',{href:"#",class:"red-ui-editableList-item-remove red-ui-button red-ui-button-small"}).appendTo(li); $('',{class:"fa fa-remove"}).appendTo(deleteButton); li.addClass("red-ui-editableList-item-removable"); + var removeTip = RED.popover.tooltip(deleteButton, RED._("common.label.delete")); deleteButton.on("click", function(evt) { evt.preventDefault(); + removeTip.close(); var data = row.data('data'); li.addClass("red-ui-editableList-item-deleting") li.fadeOut(300, function() { diff --git a/packages/node_modules/@node-red/nodes/core/network/05-tls.html b/packages/node_modules/@node-red/nodes/core/network/05-tls.html index 8414e98ca..caadae6b5 100644 --- a/packages/node_modules/@node-red/nodes/core/network/05-tls.html +++ b/packages/node_modules/@node-red/nodes/core/network/05-tls.html @@ -167,12 +167,15 @@ $("#tls-config-button-cert-clear").on("click", function() { clearNameData("cert"); }); + RED.popover.tooltip($("#tls-config-button-cert-clear"), RED._("common.label.delete")); $("#tls-config-button-key-clear").on("click", function() { clearNameData("key"); }); + RED.popover.tooltip($("#tls-config-button-key-clear"), RED._("common.label.delete")); $("#tls-config-button-ca-clear").on("click", function() { clearNameData("ca"); }); + RED.popover.tooltip($("#tls-config-button-ca-clear"), RED._("common.label.delete")); if (RED.settings.tlsConfigDisableLocalFiles) { $("#node-config-row-uselocalfiles").hide(); From cc1662ab5cfb27a7bb056edcf26ae641788f8e8d Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 4 Jan 2026 16:17:16 +0900 Subject: [PATCH 12/16] Fix status node to retrieve status from all nodes --- .../@node-red/nodes/core/common/25-status.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/common/25-status.js b/packages/node_modules/@node-red/nodes/core/common/25-status.js index 8c56e2030..c494883b7 100644 --- a/packages/node_modules/@node-red/nodes/core/common/25-status.js +++ b/packages/node_modules/@node-red/nodes/core/common/25-status.js @@ -20,13 +20,15 @@ module.exports = function(RED) { function StatusNode(n) { RED.nodes.createNode(this,n); var node = this; - this.scope = n.scope || []; + this.scope = n.scope; // auto-filter out any directly connected nodes to avoid simple loopback - const w = this.wires.flat(); - for (let i=0; i < this.scope.length; i++) { - if (w.includes(this.scope[i])) { - this.scope.splice(i, 1); + if (Array.isArray(this.scope)) { + const w = this.wires.flat(); + for (let i = 0; i < this.scope.length; i++) { + if (w.includes(this.scope[i])) { + this.scope.splice(i, 1); + } } } From a05dbb0067d52cf0b88e0b6b80ceb7de4416cd13 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 4 Jan 2026 16:19:13 +0900 Subject: [PATCH 13/16] Fix typo in test case of status node --- test/nodes/core/common/25-status_spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/nodes/core/common/25-status_spec.js b/test/nodes/core/common/25-status_spec.js index 9457d4372..af5b9dab2 100644 --- a/test/nodes/core/common/25-status_spec.js +++ b/test/nodes/core/common/25-status_spec.js @@ -15,7 +15,7 @@ **/ var should = require("should"); -var catchNode = require("nr-test-utils").require("@node-red/nodes/core/common/25-status.js"); +var statusNode = require("nr-test-utils").require("@node-red/nodes/core/common/25-status.js"); var helper = require("node-red-node-test-helper"); describe('status Node', function() { @@ -27,7 +27,7 @@ describe('status Node', function() { it('should output a message when called', function(done) { var flow = [ { id:"n1", type:"status", name:"status", wires:[["n2"]], scope:[] }, {id:"n2", type:"helper"} ]; - helper.load(catchNode, flow, function() { + helper.load(statusNode, flow, function() { var n1 = helper.getNode("n1"); var n2 = helper.getNode("n2"); n1.should.have.property('name', 'status'); From e108554ea043abd87e650623116cd0b53a95dd88 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 4 Jan 2026 17:36:18 +0900 Subject: [PATCH 14/16] Support source information in complete node --- packages/node_modules/@node-red/runtime/lib/flows/Flow.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js index 02b976a32..f96a67780 100644 --- a/packages/node_modules/@node-red/runtime/lib/flows/Flow.js +++ b/packages/node_modules/@node-red/runtime/lib/flows/Flow.js @@ -699,6 +699,13 @@ class Flow { let toSend = msg; this.completeNodeMap[node.id].forEach((completeNode,index) => { toSend = redUtil.cloneMessage(msg); + toSend.complete = { + source: { + id: node.id, + type: node.type, + name: node.name + } + }; completeNode.receive(toSend); }) } From 4bc6d0a9bd1b133901c3f41a31991417374c1dd7 Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Sun, 4 Jan 2026 19:17:28 +0900 Subject: [PATCH 15/16] Use TextDecoder() to decode UTF-8 characters --- .../node_modules/@node-red/editor-client/src/js/ui/utils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js index cc570cd13..d060cec42 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js @@ -593,7 +593,7 @@ RED.utils = (function() { var sr = $('').appendTo(stringRow); var stringEncoding = ""; try { - stringEncoding = String.fromCharCode.apply(null, new Uint16Array(data)) + stringEncoding = new TextDecoder().decode(new Uint8Array(data)); } catch(err) { console.log(err); } From f4b8af9c29421eaf4bfeb17ac1285b58ca3ee38a Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 5 Jan 2026 17:14:49 +0000 Subject: [PATCH 16/16] Update body-parser --- package.json | 2 +- packages/node_modules/@node-red/editor-api/package.json | 2 +- packages/node_modules/@node-red/nodes/package.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 666d5b0db..703369642 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "async-mutex": "0.5.0", "basic-auth": "2.0.1", "bcryptjs": "3.0.2", - "body-parser": "1.20.3", + "body-parser": "1.20.4", "chalk": "^4.1.2", "cheerio": "1.0.0-rc.10", "clone": "2.1.2", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index d15b85f3e..fa42984c3 100644 --- a/packages/node_modules/@node-red/editor-api/package.json +++ b/packages/node_modules/@node-red/editor-api/package.json @@ -19,7 +19,7 @@ "@node-red/util": "4.1.2", "@node-red/editor-client": "4.1.2", "bcryptjs": "3.0.2", - "body-parser": "1.20.3", + "body-parser": "1.20.4", "clone": "2.1.2", "cors": "2.8.5", "express-session": "1.18.2", diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json index dd83cb393..e6913da41 100644 --- a/packages/node_modules/@node-red/nodes/package.json +++ b/packages/node_modules/@node-red/nodes/package.json @@ -18,7 +18,7 @@ "acorn": "8.15.0", "acorn-walk": "8.3.4", "ajv": "8.17.1", - "body-parser": "1.20.3", + "body-parser": "1.20.4", "cheerio": "1.0.0-rc.10", "content-type": "1.0.5", "cookie-parser": "1.4.7",