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/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(); 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"); 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

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.

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; } diff --git a/packages/node_modules/@node-red/runtime/lib/index.js b/packages/node_modules/@node-red/runtime/lib/index.js index 3ae9a8d06..d1bbdb8b2 100644 --- a/packages/node_modules/@node-red/runtime/lib/index.js +++ b/packages/node_modules/@node-red/runtime/lib/index.js @@ -220,7 +220,7 @@ var reinstallTimeout; function reinstallModules(moduleList) { const promises = []; const reinstallList = []; - const installRetry = 30000; + var installRetry = 30000; if (settings.hasOwnProperty('autoInstallModulesRetry')) { log.warn(log._("server.deprecatedOption",{old:"autoInstallModulesRetry", new:"externalModules.autoInstallRetry"})); installRetry = settings.autoInstallModulesRetry;