From 01888ff078d8b5dd6a781024891460cc493e0e72 Mon Sep 17 00:00:00 2001 From: Andreas Heissenberger Date: Mon, 3 May 2021 17:23:27 +0200 Subject: [PATCH 01/11] fix "installRetry" was declared a constant and changed --- packages/node_modules/@node-red/runtime/lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index c09d202f9..2ab47d7b3 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -218,7 +218,7 @@ var reinstallTimeout; function reinstallModules(moduleList) { const promises = []; const reinstallList = []; - const installRetry = 30000; + let installRetry = 30000; if (settings.hasOwnProperty('autoInstallModulesRetry')) { log.warn(log._("server.deprecatedOption",{old:"autoInstallModulesRetry", new:"externalModules.autoInstallRetry"})); installRetry = settings.autoInstallModulesRetry; From 54c9d27fd8f61dc57bbda9ece3e4e6009ac00ea9 Mon Sep 17 00:00:00 2001 From: Andreas Heissenberger Date: Mon, 3 May 2021 17:35:50 +0200 Subject: [PATCH 02/11] fix --- packages/node_modules/@node-red/runtime/lib/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 2ab47d7b3..e76db4c04 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -218,7 +218,7 @@ var reinstallTimeout; function reinstallModules(moduleList) { const promises = []; const reinstallList = []; - let installRetry = 30000; + var installRetry = 30000; if (settings.hasOwnProperty('autoInstallModulesRetry')) { log.warn(log._("server.deprecatedOption",{old:"autoInstallModulesRetry", new:"externalModules.autoInstallRetry"})); installRetry = settings.autoInstallModulesRetry; From 5c31bd54e41ac0801d642e4fced9e93b9e6487be Mon Sep 17 00:00:00 2001 From: Kazuhito Yokoi Date: Thu, 6 May 2021 20:09:35 +0900 Subject: [PATCH 03/11] Fix incorrect shortcut keys in info tips --- .../node_modules/@node-red/editor-client/src/js/ui/tab-info.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js index bf03d2146..9f97aa7b4 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js @@ -477,7 +477,7 @@ RED.sidebar.info = (function() { return; } } - while ((m=/(\[(.*?)\])/.exec(tip))) { + while ((m=/(\[([a-z]*?)\])/.exec(tip))) { tip = tip.replace(m[1],RED.keyboard.formatKey(m[2])); } tipBox.html(tip).fadeIn(200); From eddddc6c9bc67d87962d64dad3f05a8548ab4a95 Mon Sep 17 00:00:00 2001 From: Hiroyasu Nishiyama Date: Mon, 10 May 2021 23:39:23 +0900 Subject: [PATCH 04/11] fix duplicate csv node example (#2980) --- ...Specify column names in input message.json | 79 +++++++++++++------ 1 file changed, 53 insertions(+), 26 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/examples/parser/csv/08 - Specify column names in input message.json b/packages/node_modules/@node-red/nodes/examples/parser/csv/08 - Specify column names in input message.json index b1b337a06..85901ba36 100644 --- a/packages/node_modules/@node-red/nodes/examples/parser/csv/08 - Specify column names in input message.json +++ b/packages/node_modules/@node-red/nodes/examples/parser/csv/08 - Specify column names in input message.json @@ -1,18 +1,18 @@ [ { - "id": "2ebdd51e.c5d17a", + "id": "b05816ab.7f2b08", "type": "comment", - "z": "4b63452d.672afc", - "name": "Convert array of JavaScript objects to CSV with column name header", - "info": "CSV node can convert an array of JavaScript objects to multi-line CSV text with column name header at first line.", - "x": 390, - "y": 1200, + "z": "c6ffdacd.d887e8", + "name": "Specify column names in input message", + "info": "Column names can be specified by `columns` property of incoming message.\n", + "x": 240, + "y": 200, "wires": [] }, { - "id": "2b4d538d.ada07c", + "id": "39205b5c.690684", "type": "inject", - "z": "4b63452d.672afc", + "z": "c6ffdacd.d887e8", "name": "", "props": [ { @@ -30,41 +30,41 @@ "topic": "", "payload": "", "payloadType": "date", - "x": 260, - "y": 1260, + "x": 200, + "y": 260, "wires": [ [ - "3e5c9e8.5065b62" + "526b59ba.2fa068" ] ] }, { - "id": "db02c7be.0984e8", + "id": "b78a407e.2d083", "type": "csv", - "z": "4b63452d.672afc", + "z": "c6ffdacd.d887e8", "name": "", "sep": ",", "hdrin": false, "hdrout": "all", "multi": "one", "ret": "\\n", - "temp": "kind,price", + "temp": "", "skip": "0", "strings": true, "include_empty_strings": "", "include_null_values": "", - "x": 600, - "y": 1260, + "x": 750, + "y": 260, "wires": [ [ - "61f8b772.ddb1f8" + "8b7084dd.986f68" ] ] }, { - "id": "3e5c9e8.5065b62", + "id": "526b59ba.2fa068", "type": "template", - "z": "4b63452d.672afc", + "z": "c6ffdacd.d887e8", "name": "JS object", "field": "payload", "fieldType": "msg", @@ -72,18 +72,18 @@ "syntax": "plain", "template": "[\n {\n \"kind\": \"Apple\",\n \"price\": 100,\n \"origin\": \"Canada\"\n },\n {\n \"kind\": \"Orange\",\n \"price\": 120,\n \"origin\": \"USA\"\n },\n {\n \"kind\": \"Banana\",\n \"price\": 80,\n \"origin\": \"Philippines\"\n }\n]", "output": "json", - "x": 430, - "y": 1260, + "x": 370, + "y": 260, "wires": [ [ - "db02c7be.0984e8" + "b204077a.227778" ] ] }, { - "id": "61f8b772.ddb1f8", + "id": "8b7084dd.986f68", "type": "debug", - "z": "4b63452d.672afc", + "z": "c6ffdacd.d887e8", "name": "", "active": true, "tosidebar": true, @@ -92,8 +92,35 @@ "complete": "false", "statusVal": "", "statusType": "auto", - "x": 780, - "y": 1260, + "x": 930, + "y": 260, "wires": [] + }, + { + "id": "b204077a.227778", + "type": "change", + "z": "c6ffdacd.d887e8", + "name": "", + "rules": [ + { + "t": "set", + "p": "columns", + "pt": "msg", + "to": "kind,price", + "tot": "str" + } + ], + "action": "", + "property": "", + "from": "", + "to": "", + "reg": false, + "x": 570, + "y": 260, + "wires": [ + [ + "b78a407e.2d083" + ] + ] } ] \ No newline at end of file From e641b0a965f3992330872a8e11d4850b94e63c5d Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 10 May 2021 21:02:54 +0100 Subject: [PATCH 05/11] Fix scaling issues when dragging nodes into scaled workspace --- .../editor-client/src/js/ui/palette.js | 17 +++++++---------- .../@node-red/editor-client/src/js/ui/view.js | 10 +++++++--- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js index 0cb202051..09f4758f1 100755 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/palette.js @@ -320,12 +320,12 @@ RED.palette = (function() { var paletteNode = getPaletteNode(nt); ui.originalPosition.left = paletteNode.offset().left; mouseX = ui.position.left - paletteWidth + (ui.helper.width()/2) + chart.scrollLeft(); - mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop(); + mouseY = ui.position.top - paletteTop + (ui.helper.height()/2) + chart.scrollTop() + 10; if (!groupTimer) { groupTimer = setTimeout(function() { - mouseX /= RED.view.scale(); - mouseY /= RED.view.scale(); - var group = RED.view.getGroupAtPoint(mouseX,mouseY); + var mx = mouseX / RED.view.scale(); + var my = mouseY / RED.view.scale(); + var group = RED.view.getGroupAtPoint(mx,my); if (group !== hoverGroup) { if (hoverGroup) { document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered"); @@ -357,23 +357,20 @@ RED.palette = (function() { svgRect.width = 1; svgRect.height = 1; nodes = chartSVG.getIntersectionList(svgRect,chartSVG); - mouseX /= RED.view.scale(); - mouseY /= RED.view.scale(); } else { // Firefox doesn't do getIntersectionList and that // makes us sad - mouseX /= RED.view.scale(); - mouseY /= RED.view.scale(); nodes = RED.view.getLinksAtPoint(mouseX,mouseY); } - + var mx = mouseX / RED.view.scale(); + var my = mouseY / RED.view.scale(); for (var i=0;i Date: Tue, 11 May 2021 14:10:40 +0100 Subject: [PATCH 06/11] Prevent error whilst drag/drop importing from leaving dropTarget visible Fixes #2982 --- .../editor-client/src/js/ui/clipboard.js | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js b/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js index caffe5793..ded08b024 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/clipboard.js @@ -1260,22 +1260,27 @@ RED.clipboard = (function() { hideDropTarget(); }) .on("drop",function(event) { - if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { - var data = event.originalEvent.dataTransfer.getData("text/plain"); - data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1); - importNodes(data); - } else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { - var files = event.originalEvent.dataTransfer.files; - if (files.length === 1) { - var file = files[0]; - var reader = new FileReader(); - reader.onload = (function(theFile) { - return function(e) { - importNodes(e.target.result); - }; - })(file); - reader.readAsText(file); + try { + if ($.inArray("text/plain",event.originalEvent.dataTransfer.types) != -1) { + var data = event.originalEvent.dataTransfer.getData("text/plain"); + data = data.substring(data.indexOf('['),data.lastIndexOf(']')+1); + importNodes(data); + } else if ($.inArray("Files",event.originalEvent.dataTransfer.types) != -1) { + var files = event.originalEvent.dataTransfer.files; + if (files.length === 1) { + var file = files[0]; + var reader = new FileReader(); + reader.onload = (function(theFile) { + return function(e) { + importNodes(e.target.result); + }; + })(file); + reader.readAsText(file); + } } + } catch(err) { + // Ensure any errors throw above doesn't stop the drop target from + // being hidden. } hideDropTarget(); event.preventDefault(); From ed3aa8189f2a0e59de71cf9bf0ac539e1a02d91a Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 May 2021 14:45:53 +0100 Subject: [PATCH 07/11] Shrink default notification box Also reduces Inject/Debug notification display time as 5 seconds is a long time for a message telling you it worked --- .../@node-red/editor-client/src/sass/notifications.scss | 3 ++- .../node_modules/@node-red/nodes/core/common/20-inject.html | 2 +- .../node_modules/@node-red/nodes/core/common/21-debug.html | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss b/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss index 497ca78cd..e2617f995 100644 --- a/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss +++ b/packages/node_modules/@node-red/editor-client/src/sass/notifications.scss @@ -25,7 +25,7 @@ .red-ui-notification { box-sizing: border-box; position: relative; - padding: 14px 18px; + padding: 8px 18px 0px; margin-bottom: 4px; box-shadow: 0 1px 1px 1px $shadow; background-color: $secondary-background; @@ -35,6 +35,7 @@ overflow: hidden; .ui-dialog-buttonset { margin-top: 20px; + margin-bottom: 10px; } } .red-ui-notification p:first-child { diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.html b/packages/node_modules/@node-red/nodes/core/common/20-inject.html index 717752377..bb22ee90f 100644 --- a/packages/node_modules/@node-red/nodes/core/common/20-inject.html +++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.html @@ -636,7 +636,7 @@ url: "inject/"+this.id, type:"POST", success: function(resp) { - RED.notify(node._("inject.success",{label:label}),{type:"success",id:"inject"}); + RED.notify(node._("inject.success",{label:label}),{type:"success",id:"inject", timeout: 2000}); }, error: function(jqXHR,textStatus,errorThrown) { if (jqXHR.status == 404) { diff --git a/packages/node_modules/@node-red/nodes/core/common/21-debug.html b/packages/node_modules/@node-red/nodes/core/common/21-debug.html index 8691dfbea..886ed68fa 100644 --- a/packages/node_modules/@node-red/nodes/core/common/21-debug.html +++ b/packages/node_modules/@node-red/nodes/core/common/21-debug.html @@ -129,9 +129,9 @@ RED.history.push(historyEvent); RED.view.redraw(); if (xhr.status == 200) { - RED.notify(node._("debug.notification.activated",{label:label}),"success"); + RED.notify(node._("debug.notification.activated",{label:label}),{type: "success", timeout: 2000}); } else if (xhr.status == 201) { - RED.notify(node._("debug.notification.deactivated",{label:label}),"success"); + RED.notify(node._("debug.notification.deactivated",{label:label}),{type: "success", timeout: 2000}); } }); } From ade318bb78945044b828f227e287a8a00c7c49cf Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 May 2021 15:58:01 +0100 Subject: [PATCH 08/11] Support mousewheel scroll in tab bar --- .../editor-client/src/js/ui/common/tabs.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) 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 baaac7a8b..bcc0aef32 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 @@ -100,7 +100,22 @@ RED.tabs = (function() { if (options.scrollable) { wrapper.addClass("red-ui-tabs-scrollable"); scrollContainer.addClass("red-ui-tabs-scroll-container"); - scrollContainer.on("scroll",updateScroll); + scrollContainer.on("scroll",function(evt) { + // Generated by trackpads - not mousewheel + updateScroll(evt); + }); + scrollContainer.on("wheel", function(evt) { + if (evt.originalEvent.deltaX === 0) { + // Prevent the scroll event from firing + evt.preventDefault(); + + // Assume this is wheel event which might not trigger + // the scroll event, so do things manually + var sl = scrollContainer.scrollLeft(); + sl -= evt.originalEvent.deltaY; + scrollContainer.scrollLeft(sl); + } + }) scrollLeft = $('
').appendTo(wrapper).find("a"); scrollLeft.on('mousedown',function(evt) { scrollEventHandler(evt,'-=150') }).on('click',function(evt){ evt.preventDefault();}); scrollRight = $('
').appendTo(wrapper).find("a"); From d8d384a9796f5e9415c58e1b7ad8d091e0d37420 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 May 2021 16:42:00 +0100 Subject: [PATCH 09/11] Fix plugin loading when browser sends unrecognised lang --- .../@node-red/editor-api/lib/admin/plugins.js | 10 ++++------ .../node_modules/@node-red/runtime/lib/api/plugins.js | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/node_modules/@node-red/editor-api/lib/admin/plugins.js b/packages/node_modules/@node-red/editor-api/lib/admin/plugins.js index 3d49a7e8a..ac6c6f701 100644 --- a/packages/node_modules/@node-red/editor-api/lib/admin/plugins.js +++ b/packages/node_modules/@node-red/editor-api/lib/admin/plugins.js @@ -17,9 +17,8 @@ module.exports = { }) } else { opts.lang = apiUtils.determineLangFromHeaders(req.acceptsLanguages()); - if (/[^a-z\-\*]/i.test(opts.lang)) { - res.json({}); - return; + if (/[^0-9a-z=\-\*]/i.test(opts.lang)) { + opts.lang = "en-US"; } runtimeAPI.plugins.getPluginConfigs(opts).then(function(configs) { res.send(configs); @@ -32,9 +31,8 @@ module.exports = { lang: req.query.lng, req: apiUtils.getRequestLogObject(req) } - if (/[^a-z\-\*]/i.test(opts.lang)) { - res.json({}); - return; + if (/[^0-9a-z=\-\*]/i.test(opts.lang)) { + opts.lang = "en-US"; } runtimeAPI.plugins.getPluginCatalogs(opts).then(function(result) { res.json(result); diff --git a/packages/node_modules/@node-red/runtime/lib/api/plugins.js b/packages/node_modules/@node-red/runtime/lib/api/plugins.js index 076638640..21703508c 100644 --- a/packages/node_modules/@node-red/runtime/lib/api/plugins.js +++ b/packages/node_modules/@node-red/runtime/lib/api/plugins.js @@ -58,7 +58,7 @@ var api = module.exports = { * @memberof @node-red/runtime_plugins */ getPluginConfigs: async function(opts) { - if (/[^a-z\-]/i.test(opts.lang)) { + if (/[^0-9a-z=\-\*]/i.test(opts.lang)) { throw new Error("Invalid language: "+opts.lang) return; } From 8f7686cd7b37ea8dbdabe09182c1c9a435b2a1b0 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 May 2021 16:42:32 +0100 Subject: [PATCH 10/11] Handle sidebar tab that no longer exists when setting first active --- .../node_modules/@node-red/editor-client/src/js/ui/sidebar.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js b/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js index bc1bbf287..7402870d4 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/sidebar.js @@ -199,7 +199,7 @@ RED.sidebar = (function() { id = RED.settings.get("editor.sidebar.order",["info", "help", "version-control", "debug"])[0] } if (id) { - if (!containsTab(id)) { + if (!containsTab(id) && knownTabs[id]) { sidebar_tabs.addTab(knownTabs[id]); } sidebar_tabs.activateTab(id); From 6aa5968863b075b8310d1dac60bc943769828347 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 11 May 2021 17:14:53 +0100 Subject: [PATCH 11/11] Fix Function tab label names in the node help text Closes #2978 --- .../nodes/locales/en-US/function/10-function.html | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html index dd13b6732..831021917 100644 --- a/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html +++ b/packages/node_modules/@node-red/nodes/locales/en-US/function/10-function.html @@ -21,9 +21,10 @@ the body of the message.

The function is expected to return a message object (or multiple message objects), but can choose to return nothing in order to halt a flow.

-

The Setup tab contains code that will be run whenever the node is started. - The Close tab contains code that will be run when the node is stopped.

-

If an promise object is returned from the setup code, input message processing starts after its completion.

+

The On Start tab contains code that will be run whenever the node is started. + The On Stop tab contains code that will be run when the node is stopped.

+

If the On Start code returns a Promise object, the node will not start handling messages + until the promise is resolved.

Details

See the online documentation for more information on writing functions.