From a9b12e517262dad26e1bd4bafa2d4e72c9c01dee Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Nov 2021 23:24:57 +0000 Subject: [PATCH 01/70] Add search history to main search box --- .../editor-client/locales/en-US/editor.json | 2 + .../editor-client/src/js/ui/search.js | 67 ++++++++++++++++++- .../editor-client/src/sass/search.scss | 22 ++++++ 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json index 0e60d17e3..40086fe75 100755 --- a/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json +++ b/packages/node_modules/@node-red/editor-client/locales/en-US/editor.json @@ -890,6 +890,8 @@ "addTitle": "add an item" }, "search": { + "history": "Search history", + "clear": "clear all", "empty": "No matches found", "addNode": "add a node..." }, diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/search.js b/packages/node_modules/@node-red/editor-client/src/js/ui/search.js index 02c7735a7..8b6b18927 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/search.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/search.js @@ -22,6 +22,7 @@ RED.search = (function() { var selected = -1; var visible = false; + var searchHistory = []; var index = {}; var currentResults = []; var previousActiveElement; @@ -196,6 +197,20 @@ RED.search = (function() { } } + function populateSearchHistory() { + if (searchHistory.length > 0) { + searchResults.editableList('addItem',{ + historyHeader: true + }); + searchHistory.forEach(function(entry) { + searchResults.editableList('addItem',{ + history: true, + value: entry + }); + }) + } + + } function createDialog() { dialog = $("
",{id:"red-ui-search",class:"red-ui-search"}).appendTo("#red-ui-main-container"); var searchDiv = $("
",{class:"red-ui-search-container"}).appendTo(dialog); @@ -204,7 +219,12 @@ RED.search = (function() { change: function() { searchResults.editableList('empty'); selected = -1; - currentResults = search($(this).val()); + var value = $(this).val(); + if (value === "") { + populateSearchHistory(); + return; + } + currentResults = search(value); if (currentResults.length > 0) { for (i=0;i 0) { reveal(currentResults[Math.max(0,selected)].node); } @@ -292,7 +317,32 @@ RED.search = (function() { addItem: function(container,i,object) { var node = object.node; var div; - if (object.more) { + if (object.historyHeader) { + container.parent().addClass("red-ui-search-historyHeader") + $('
',{class:"red-ui-search-empty"}).text(RED._("search.history")).appendTo(container); + $('').text(RED._("search.clear")).appendTo(container).on("click", function(evt) { + evt.preventDefault(); + searchHistory = []; + searchResults.editableList('empty'); + }); + } else if (object.history) { + container.parent().addClass("red-ui-search-history") + div = $('',{href:'#',class:"red-ui-search-result"}).appendTo(container); + div.text(object.value); + div.on("click", function(evt) { + evt.preventDefault(); + searchInput.searchBox('value',object.value) + searchInput.focus(); + }) + $('').appendTo(container).on("click", function(evt) { + evt.preventDefault(); + var index = searchHistory.indexOf(object.value); + searchHistory.splice(index,1); + searchResults.editableList('removeItem', object); + }); + + + } else if (object.more) { container.parent().addClass("red-ui-search-more") div = $('',{href:'#',class:"red-ui-search-result red-ui-search-empty"}).appendTo(container); div.text(RED._("palette.editor.more",{count:object.more.results.length-object.more.start})); @@ -347,6 +397,12 @@ RED.search = (function() { } function reveal(node) { + var searchVal = searchInput.val(); + var existingIndex = searchHistory.indexOf(searchVal); + if (existingIndex > -1) { + searchHistory.splice(existingIndex,1); + } + searchHistory.unshift(searchInput.val()); hide(); RED.view.reveal(node.id); } @@ -365,9 +421,14 @@ RED.search = (function() { if (dialog === null) { createDialog(); + } else { + searchResults.editableList('empty'); } dialog.slideDown(300); searchInput.searchBox('value',v) + if (!v || v === "") { + populateSearchHistory(); + } RED.events.emit("search:open"); visible = true; } 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 bf20aae4a..ac82d67bd 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 @@ -204,6 +204,28 @@ font-style: italic; color: $form-placeholder-color; } +.red-ui-search-history { + button { + display: none; + position: absolute; + top: 8px; + right: 7px; + } + + &:hover button { + display: inline; + } +} +.red-ui-search-historyHeader { + button { + position: absolute; + top: 10px; + right: 7px; + } +} +.red-ui-search-history-result { + +} .red-ui-search-result-action { color: $primary-text-color; From 720a1632735e271ce0b0438c4636d7ed9a14b132 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 15 Nov 2021 23:38:01 +0000 Subject: [PATCH 02/70] Bump dev version --- CHANGELOG.md | 5 +++++ package.json | 2 +- .../node_modules/@node-red/editor-api/package.json | 6 +++--- .../node_modules/@node-red/editor-client/package.json | 2 +- packages/node_modules/@node-red/nodes/package.json | 2 +- packages/node_modules/@node-red/registry/package.json | 4 ++-- packages/node_modules/@node-red/runtime/package.json | 6 +++--- packages/node_modules/@node-red/util/package.json | 2 +- packages/node_modules/node-red/package.json | 10 +++++----- 9 files changed, 22 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66ea3ddf9..b297e93ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +#### 2.2.0-beta.1: Beta Release + + + + #### 2.1.3: Maintenance Release Runtime diff --git a/package.json b/package.json index 1cca9671e..b23e52876 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "2.1.3", + "version": "2.2.0-beta.1", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", diff --git a/packages/node_modules/@node-red/editor-api/package.json b/packages/node_modules/@node-red/editor-api/package.json index a7c741a40..19d488b52 100644 --- a/packages/node_modules/@node-red/editor-api/package.json +++ b/packages/node_modules/@node-red/editor-api/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-api", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/util": "2.1.3", - "@node-red/editor-client": "2.1.3", + "@node-red/util": "2.2.0-beta.1", + "@node-red/editor-client": "2.2.0-beta.1", "bcryptjs": "2.4.3", "body-parser": "1.19.0", "clone": "2.1.2", diff --git a/packages/node_modules/@node-red/editor-client/package.json b/packages/node_modules/@node-red/editor-client/package.json index 47f9157ff..e7b23139e 100644 --- a/packages/node_modules/@node-red/editor-client/package.json +++ b/packages/node_modules/@node-red/editor-client/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/editor-client", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/@node-red/nodes/package.json b/packages/node_modules/@node-red/nodes/package.json index 09db74976..03b101969 100644 --- a/packages/node_modules/@node-red/nodes/package.json +++ b/packages/node_modules/@node-red/nodes/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/nodes", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/@node-red/registry/package.json b/packages/node_modules/@node-red/registry/package.json index dbe534b3a..c40176645 100644 --- a/packages/node_modules/@node-red/registry/package.json +++ b/packages/node_modules/@node-red/registry/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/registry", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,7 +16,7 @@ } ], "dependencies": { - "@node-red/util": "2.1.3", + "@node-red/util": "2.2.0-beta.1", "clone": "2.1.2", "fs-extra": "10.0.0", "semver": "7.3.5", diff --git a/packages/node_modules/@node-red/runtime/package.json b/packages/node_modules/@node-red/runtime/package.json index 00081720b..a25a26d09 100644 --- a/packages/node_modules/@node-red/runtime/package.json +++ b/packages/node_modules/@node-red/runtime/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/runtime", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "main": "./lib/index.js", "repository": { @@ -16,8 +16,8 @@ } ], "dependencies": { - "@node-red/registry": "2.1.3", - "@node-red/util": "2.1.3", + "@node-red/registry": "2.2.0-beta.1", + "@node-red/util": "2.2.0-beta.1", "async-mutex": "0.3.2", "clone": "2.1.2", "express": "4.17.1", diff --git a/packages/node_modules/@node-red/util/package.json b/packages/node_modules/@node-red/util/package.json index c4a1e1018..0005ed292 100644 --- a/packages/node_modules/@node-red/util/package.json +++ b/packages/node_modules/@node-red/util/package.json @@ -1,6 +1,6 @@ { "name": "@node-red/util", - "version": "2.1.3", + "version": "2.2.0-beta.1", "license": "Apache-2.0", "repository": { "type": "git", diff --git a/packages/node_modules/node-red/package.json b/packages/node_modules/node-red/package.json index b79f38334..0f1ef3015 100644 --- a/packages/node_modules/node-red/package.json +++ b/packages/node_modules/node-red/package.json @@ -1,6 +1,6 @@ { "name": "node-red", - "version": "2.1.3", + "version": "2.2.0-beta.1", "description": "Low-code programming for event-driven applications", "homepage": "http://nodered.org", "license": "Apache-2.0", @@ -31,10 +31,10 @@ "flow" ], "dependencies": { - "@node-red/editor-api": "2.1.3", - "@node-red/runtime": "2.1.3", - "@node-red/util": "2.1.3", - "@node-red/nodes": "2.1.3", + "@node-red/editor-api": "2.2.0-beta.1", + "@node-red/runtime": "2.2.0-beta.1", + "@node-red/util": "2.2.0-beta.1", + "@node-red/nodes": "2.2.0-beta.1", "basic-auth": "2.0.1", "bcryptjs": "2.4.3", "express": "4.17.1", From 5856d043ca89a09dc91df55941916edd7823c172 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 5 Dec 2021 19:52:47 +0000 Subject: [PATCH 03/70] Add node wiring actions --- .../editor-client/src/js/ui/view-tools.js | 87 ++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js index 9b3977448..7d92f6491 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js @@ -725,6 +725,90 @@ RED.view.tools = (function() { } } + + function wireSeriesOfNodes() { + var selection = RED.view.selection(); + if (selection.nodes) { + if (selection.nodes.length > 1) { + var i = 0; + var newLinks = []; + while (i < selection.nodes.length - 1) { + var nodeA = selection.nodes[i]; + var nodeB = selection.nodes[i+1]; + if (nodeA.outputs > 0 && nodeB.inputs > 0) { + var existingLinks = RED.nodes.filterLinks({ + source: nodeA, + target: nodeB, + sourcePort: 0 + }) + if (existingLinks.length === 0) { + var newLink = { + source: nodeA, + target: nodeB, + sourcePort: 0 + } + RED.nodes.addLink(newLink); + newLinks.push(newLink); + } + } + i++; + } + if (newLinks.length > 0) { + RED.history.push({ + t: 'add', + links: newLinks, + dirty: RED.nodes.dirty() + }) + RED.nodes.dirty(true); + RED.view.redraw(true); + } + } + } + } + + function wireNodeToMultiple() { + var selection = RED.view.selection(); + if (selection.nodes) { + if (selection.nodes.length > 1) { + var sourceNode = selection.nodes[0]; + if (sourceNode.outputs === 0) { + return; + } + var i = 1; + var newLinks = []; + while (i < selection.nodes.length) { + var targetNode = selection.nodes[i]; + if (targetNode.inputs > 0) { + var existingLinks = RED.nodes.filterLinks({ + source: sourceNode, + target: targetNode, + sourcePort: Math.min(sourceNode.outputs-1,i-1) + }) + if (existingLinks.length === 0) { + var newLink = { + source: sourceNode, + target: targetNode, + sourcePort: Math.min(sourceNode.outputs-1,i-1) + } + RED.nodes.addLink(newLink); + newLinks.push(newLink); + } + } + i++; + } + if (newLinks.length > 0) { + RED.history.push({ + t: 'add', + links: newLinks, + dirty: RED.nodes.dirty() + }) + RED.nodes.dirty(true); + RED.view.redraw(true); + } + } + } + } + return { init: function() { RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); }) @@ -783,7 +867,8 @@ RED.view.tools = (function() { RED.actions.add("core:distribute-selection-horizontally", function() { distributeSelection('h') }) RED.actions.add("core:distribute-selection-vertically", function() { distributeSelection('v') }) - + RED.actions.add("core:wire-series-of-nodes", function() { wireSeriesOfNodes() }) + RED.actions.add("core:wire-node-to-multiple", function() { wireNodeToMultiple() }) // RED.actions.add("core:add-node", function() { addNode() }) }, From 7bb7149f4cd1ad2948797c1c4910abc2e1fcdf2e Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Sun, 5 Dec 2021 23:23:57 +0000 Subject: [PATCH 04/70] Snap nodes on grid using either edge as reference --- .../@node-red/editor-client/src/js/ui/view.js | 55 ++++++++++++++++--- 1 file changed, 46 insertions(+), 9 deletions(-) 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 166cb2901..3044487bb 100755 --- 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 @@ -412,26 +412,56 @@ RED.view = (function() { var historyEvent = result.historyEvent; var nn = result.node; + RED.nodes.add(nn); + var showLabel = RED.utils.getMessageProperty(RED.settings.get('editor'),"view.view-node-show-label"); if (showLabel !== undefined && (nn._def.hasOwnProperty("showLabel")?nn._def.showLabel:true) && !nn._def.defaults.hasOwnProperty("l")) { nn.l = showLabel; } var helperOffset = d3.touches(ui.helper.get(0))[0]||d3.mouse(ui.helper.get(0)); + var helperWidth = ui.helper.width(); + var helperHeight = ui.helper.height(); var mousePos = d3.touches(this)[0]||d3.mouse(this); - mousePos[1] += this.scrollTop + ((nn.h/2)-helperOffset[1]); - mousePos[0] += this.scrollLeft + ((nn.w/2)-helperOffset[0]); + try { + var isLink = (nn.type === "link in" || nn.type === "link out") + var hideLabel = nn.hasOwnProperty('l')?!nn.l : isLink; + + var label = RED.utils.getNodeLabel(nn, nn.type); + var labelParts = getLabelParts(label, "red-ui-flow-node-label"); + if (hideLabel) { + nn.w = node_height; + nn.h = Math.max(node_height,(nn.outputs || 0) * 15); + } else { + nn.w = Math.max(node_width,20*(Math.ceil((labelParts.width+50+(nn._def.inputs>0?7:0))/20)) ); + nn.h = Math.max(6+24*labelParts.lines.length,(nn.outputs || 0) * 15, 30); + } + } catch(err) { + } + + mousePos[1] += this.scrollTop + ((helperHeight/2)-helperOffset[1]); + mousePos[0] += this.scrollLeft + ((helperWidth/2)-helperOffset[0]); mousePos[1] /= scaleFactor; mousePos[0] /= scaleFactor; - if (snapGrid) { - mousePos[0] = gridSize*(Math.ceil(mousePos[0]/gridSize)); - mousePos[1] = gridSize*(Math.ceil(mousePos[1]/gridSize)); - } nn.x = mousePos[0]; nn.y = mousePos[1]; + if (snapGrid) { + var gridOffset = [0,0]; + var offsetLeft = nn.x-(gridSize*Math.round((nn.x-nn.w/2)/gridSize)+nn.w/2); + var offsetRight = nn.x-(gridSize*Math.round((nn.x+nn.w/2)/gridSize)-nn.w/2); + if (Math.abs(offsetLeft) < Math.abs(offsetRight)) { + gridOffset[0] = offsetLeft + } else { + gridOffset[0] = offsetRight + } + gridOffset[1] = nn.y-(gridSize*Math.round(nn.y/gridSize)); + nn.x -= gridOffset[0]; + nn.y -= gridOffset[1]; + } + var spliceLink = $(ui.helper).data("splice"); if (spliceLink) { // TODO: DRY - droppable/nodeMouseDown/canvasMouseUp/showQuickAddDialog @@ -452,7 +482,6 @@ RED.view = (function() { historyEvent.removedLinks = [spliceLink]; } - RED.nodes.add(nn); var group = $(ui.helper).data("group"); if (group) { @@ -1515,8 +1544,16 @@ RED.view = (function() { gridOffset[0] = node.n.x-(gridSize*Math.floor(node.n.x/gridSize))-gridSize/2; gridOffset[1] = node.n.y-(gridSize*Math.floor(node.n.y/gridSize))-gridSize/2; } else { - gridOffset[0] = node.n.x-(gridSize*Math.floor((node.n.x-node.n.w/2)/gridSize)+node.n.w/2); - gridOffset[1] = node.n.y-(gridSize*Math.floor(node.n.y/gridSize)); + var offsetLeft = node.n.x-(gridSize*Math.round((node.n.x-node.n.w/2)/gridSize)+node.n.w/2); + var offsetRight = node.n.x-(gridSize*Math.round((node.n.x+node.n.w/2)/gridSize)-node.n.w/2); + // gridOffset[0] = node.n.x-(gridSize*Math.floor((node.n.x-node.n.w/2)/gridSize)+node.n.w/2); + if (Math.abs(offsetLeft) < Math.abs(offsetRight)) { + gridOffset[0] = offsetLeft + } else { + gridOffset[0] = offsetRight + } + gridOffset[1] = node.n.y-(gridSize*Math.round(node.n.y/gridSize)); + // console.log(offsetLeft, offsetRight); } if (gridOffset[0] !== 0 || gridOffset[1] !== 0) { for (i = 0; i Date: Tue, 7 Dec 2021 09:19:27 +0000 Subject: [PATCH 05/70] Allow multiple links to be selected by ctrl-click --- .../@node-red/editor-client/src/js/ui/view.js | 249 ++++++++++-------- 1 file changed, 145 insertions(+), 104 deletions(-) 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 166cb2901..227a217aa 100755 --- 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 @@ -63,7 +63,8 @@ RED.view = (function() { var activeGroups = []; var dirtyGroups = {}; - var selected_link = null; + var selectedLinks = []; + var mousedown_link = null; var mousedown_node = null; var mousedown_group = null; @@ -909,7 +910,7 @@ RED.view = (function() { return; } if (!mousedown_node && !mousedown_link && !mousedown_group) { - selected_link = null; + selectedLinks = []; updateSelection(); } if (mouse_mode === 0) { @@ -1348,7 +1349,7 @@ RED.view = (function() { return; } - if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && !mousedown_group && selected_link == null) { + if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && !mousedown_group && selectedLinks.length === 0) { return; } @@ -1372,16 +1373,18 @@ RED.view = (function() { // Get all the wires we need to detach. var links = []; var existingLinks = []; - if (selected_link && - ((mousedown_port_type === PORT_TYPE_OUTPUT && - selected_link.source === mousedown_node && - selected_link.sourcePort === mousedown_port_index - ) || - (mousedown_port_type === PORT_TYPE_INPUT && - selected_link.target === mousedown_node - )) - ) { - existingLinks = [selected_link]; + if (selectedLinks.length > 0) { + selectedLinks.forEach(function(link) { + if (((mousedown_port_type === PORT_TYPE_OUTPUT && + link.source === mousedown_node && + link.sourcePort === mousedown_port_index + ) || + (mousedown_port_type === PORT_TYPE_INPUT && + link.target === mousedown_node + ))) { + existingLinks.push(link); + } + }) } else { var filter; if (mousedown_port_type === PORT_TYPE_OUTPUT) { @@ -1419,7 +1422,7 @@ RED.view = (function() { } else if (mousedown_node && !quickAddLink) { showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]); } - selected_link = null; + selectedLinks = []; } mousePos = mouse_position; for (i=0;i 0) { + selectedLinks.forEach(function(link) { + if (link.link) { + activeLinks.push(link); + activeLinkNodes[link.source.id] = link.source; + link.source.dirty = true; + activeLinkNodes[link.target.id] = link.target; + link.target.dirty = true; + } + }) } } else { selection.flows = workspaceSelection; @@ -2066,6 +2073,10 @@ RED.view = (function() { return value.map(function(n) { return n.id }) } else if (key === 'link') { return value.source.id+":"+value.sourcePort+":"+value.target.id; + } else if (key === 'links') { + return value.map(function(link) { + link.source.id+":"+link.sourcePort+":"+link.target.id; + }); } return value; }); @@ -2135,7 +2146,7 @@ RED.view = (function() { updateActiveNodes(); updateSelection(); redraw(); - } else if (movingSet.length() > 0 || selected_link != null) { + } else if (movingSet.length() > 0 || selectedLinks.length > 0) { var result; var node; var removedNodes = []; @@ -2234,71 +2245,81 @@ RED.view = (function() { RED.nodes.dirty(true); } } - var historyEvent; - if (selected_link && selected_link.link) { - var sourceId = selected_link.source.id; - var targetId = selected_link.target.id; - var sourceIdIndex = selected_link.target.links.indexOf(sourceId); - var targetIdIndex = selected_link.source.links.indexOf(targetId); + var linkRemoveHistoryEvents = []; + if (selectedLinks.length > 0) { + selectedLinks.forEach(function(link) { + if (link.link) { + var sourceId = link.source.id; + var targetId = link.target.id; + var sourceIdIndex = link.target.links.indexOf(sourceId); + var targetIdIndex = link.source.links.indexOf(targetId); - historyEvent = { - t:"multi", - events: [ - { - t: "edit", - node: selected_link.source, - changed: selected_link.source.changed, - changes: { - links: $.extend(true,{},{v:selected_link.source.links}).v - } - }, - { - t: "edit", - node: selected_link.target, - changed: selected_link.target.changed, - changes: { - links: $.extend(true,{},{v:selected_link.target.links}).v - } - } + linkRemoveHistoryEvents.push({ + t:"multi", + events: [ + { + t: "edit", + node: link.source, + changed: link.source.changed, + changes: { + links: $.extend(true,{},{v:link.source.links}).v + } + }, + { + t: "edit", + node: link.target, + changed: link.target.changed, + changes: { + links: $.extend(true,{},{v:link.target.links}).v + } + } - ], - dirty:RED.nodes.dirty() - } - RED.nodes.dirty(true); - selected_link.source.changed = true; - selected_link.target.changed = true; - selected_link.target.links.splice(sourceIdIndex,1); - selected_link.source.links.splice(targetIdIndex,1); - selected_link.source.dirty = true; - selected_link.target.dirty = true; + ], + dirty:startDirty + }) - } else { - if (selected_link) { - RED.nodes.removeLink(selected_link); - removedLinks.push(selected_link); - } - RED.nodes.dirty(true); - historyEvent = { - t:"delete", - nodes:removedNodes, - links:removedLinks, - groups: removedGroups, - subflowOutputs:removedSubflowOutputs, - subflowInputs:removedSubflowInputs, - subflow: { - id: activeSubflow?activeSubflow.id:undefined, - instances: subflowInstances - }, - dirty:startDirty - }; - if (removedSubflowStatus) { - historyEvent.subflow.status = removedSubflowStatus; - } + link.source.changed = true; + link.target.changed = true; + link.target.links.splice(sourceIdIndex,1); + link.source.links.splice(targetIdIndex,1); + link.source.dirty = true; + link.target.dirty = true; + + } else { + RED.nodes.removeLink(link); + removedLinks.push(link); + } + }) + } + RED.nodes.dirty(true); + var historyEvent = { + t:"delete", + nodes:removedNodes, + links:removedLinks, + groups: removedGroups, + subflowOutputs:removedSubflowOutputs, + subflowInputs:removedSubflowInputs, + subflow: { + id: activeSubflow?activeSubflow.id:undefined, + instances: subflowInstances + }, + dirty:startDirty + }; + if (removedSubflowStatus) { + historyEvent.subflow.status = removedSubflowStatus; + } + if (linkRemoveHistoryEvents.length > 0) { + linkRemoveHistoryEvents.unshift(historyEvent); + RED.history.push({ + t:"multi", + events: linkRemoveHistoryEvents + }) + } else { + RED.history.push(historyEvent); } - RED.history.push(historyEvent); - selected_link = null; + selectedLinks = []; updateActiveNodes(); updateSelection(); redraw(); @@ -2709,7 +2730,9 @@ RED.view = (function() { } else { resetMouseVars(); } - selected_link = select_link; + //TODO: selectedLinks + console.log("Wanted to set selected_link (1)",select_link) + // selected_link = select_link; mousedown_link = select_link; if (select_link) { updateSelection(); @@ -2721,7 +2744,9 @@ RED.view = (function() { resetMouseVars(); hideDragLines(); - selected_link = select_link; + if (select_link) { + selectedLinks = [select_link]; + } mousedown_link = select_link; if (select_link) { updateSelection(); @@ -3212,7 +3237,7 @@ RED.view = (function() { mousedown_node.selected = true; movingSet.add(mousedown_node); } - selected_link = null; + selectedLinks = []; if (d3.event.button != 2) { mouse_mode = RED.state.MOVING; var mouse = d3.touches(this)[0]||d3.mouse(this); @@ -3338,19 +3363,33 @@ RED.view = (function() { d3.event.stopPropagation(); return; } - mousedown_link = d; - clearSelection(); - selected_link = mousedown_link; - updateSelection(); - redraw(); - focusView(); - d3.event.stopPropagation(); - if (d3.event.metaKey || d3.event.ctrlKey) { - d3.select(this).classed("red-ui-flow-link-splice",true); - var point = d3.mouse(this); - var clickedGroup = getGroupAt(point[0],point[1]); - showQuickAddDialog({position:point, splice:selected_link, group:clickedGroup}); - } + mousedown_link = d; + + if (selectedLinks.length === 0 || !(d3.event.metaKey || d3.event.ctrlKey)) { + clearSelection(); + } + if (d3.event.metaKey || d3.event.ctrlKey) { + var linkIndex = selectedLinks.indexOf(mousedown_link); + if (linkIndex === -1) { + selectedLinks.push(mousedown_link); + } else { + if (selectedLinks.length !== 1) { + selectedLinks.splice(linkIndex,1); + } + } + } else { + selectedLinks.push(mousedown_link); + } + updateSelection(); + redraw(); + focusView(); + d3.event.stopPropagation(); + if (selectedLinks.length === 1 && selectedLinks[0] === mousedown_link && (d3.event.metaKey || d3.event.ctrlKey)) { + d3.select(this).classed("red-ui-flow-link-splice",true); + var point = d3.mouse(this); + var clickedGroup = getGroupAt(point[0],point[1]); + showQuickAddDialog({position:point, splice:mousedown_link, group:clickedGroup}); + } } function linkTouchStart(d) { if (mouse_mode === RED.state.SELECTING_NODE) { @@ -3359,7 +3398,7 @@ RED.view = (function() { } mousedown_link = d; clearSelection(); - selected_link = mousedown_link; + selectedLinks = [mousedown_link]; updateSelection(); redraw(); focusView(); @@ -3595,7 +3634,7 @@ RED.view = (function() { function showTouchMenu(obj,pos) { var mdn = mousedown_node; var options = []; - options.push({name:"delete",disabled:(movingSet.length()===0 && selected_link === null),onselect:function() {deleteSelection();}}); + options.push({name:"delete",disabled:(movingSet.length()===0 && selectedLinks.length === 0),onselect:function() {deleteSelection();}}); options.push({name:"cut",disabled:(movingSet.length()===0),onselect:function() {copySelection();deleteSelection();}}); options.push({name:"copy",disabled:(movingSet.length()===0),onselect:function() {copySelection();}}); options.push({name:"paste",disabled:(clipboard.length===0),onselect:function() {importNodes(clipboard, {generateIds: true, touchImport: true});}}); @@ -4352,7 +4391,7 @@ RED.view = (function() { link.exit().remove(); link.each(function(d) { var link = d3.select(this); - if (d.added || d===selected_link || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) { + if (d.added || selectedLinks.includes(d) || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) { var numOutputs = d.source.outputs || 1; var sourcePort = d.sourcePort || 0; var y = -((numOutputs-1)/2)*13 +13*sourcePort; @@ -4375,7 +4414,7 @@ RED.view = (function() { this.__pathLine__.classList.toggle("red-ui-flow-node-disabled",!!(d.source.d || d.target.d)); this.__pathLine__.classList.toggle("red-ui-flow-subflow-link", !d.link && activeSubflow); } - this.classList.toggle("red-ui-flow-link-selected", !!(d===selected_link||d.selected)); + this.classList.toggle("red-ui-flow-link-selected", !!(selectedLinks.includes(d)||d.selected)); var connectedToUnknown = !!(d.target.type == "unknown" || d.source.type == "unknown"); this.classList.toggle("red-ui-flow-link-unknown",!!(d.target.type == "unknown" || d.source.type == "unknown")) @@ -5083,8 +5122,10 @@ RED.view = (function() { if (allNodes.size > 0) { selection.nodes = Array.from(allNodes); } - if (selected_link != null) { - selection.link = selected_link; + if (selectedLinks.length > 0) { + selection.link = selectedLinks[0]; + // TODO: clone the array + selection.links = selectedLinks; } return selection; } From ecaf866613665c58e55bf396938831da10581ea6 Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Tue, 7 Dec 2021 09:29:11 +0000 Subject: [PATCH 06/70] Fix serialisation of selection in view --- packages/node_modules/@node-red/editor-client/src/js/ui/view.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 227a217aa..10347b76a 100755 --- 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 @@ -2075,7 +2075,7 @@ RED.view = (function() { return value.source.id+":"+value.sourcePort+":"+value.target.id; } else if (key === 'links') { return value.map(function(link) { - link.source.id+":"+link.sourcePort+":"+link.target.id; + return link.source.id+":"+link.sourcePort+":"+link.target.id; }); } return value; From 6ae42eb787d81104709bbd5d073e4f82b5aaa854 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 10 Dec 2021 15:21:43 +0000 Subject: [PATCH 07/70] Let JSON parser attempt to parse buffers if they contain strings and add/fix test --- .../@node-red/nodes/core/parsers/70-JSON.js | 6 +- test/nodes/core/parsers/70-JSON_spec.js | 80 ++++++++++++++----- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js b/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js index a68edc681..e16c4ec23 100644 --- a/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js +++ b/packages/node_modules/@node-red/nodes/core/parsers/70-JSON.js @@ -49,7 +49,11 @@ module.exports = function(RED) { } var value = RED.util.getMessageProperty(msg,node.property); if (value !== undefined) { - if (typeof value === "string") { + if (typeof value === "string" || Buffer.isBuffer(value)) { + // if (Buffer.isBuffer(value) && node.action !== "obj") { + // node.warn(RED._("json.errors.dropped")); done(); + // } + // else if (node.action === "" || node.action === "obj") { try { RED.util.setMessageProperty(msg,node.property,JSON.parse(value)); diff --git a/test/nodes/core/parsers/70-JSON_spec.js b/test/nodes/core/parsers/70-JSON_spec.js index ad469bbd5..32c5062e8 100644 --- a/test/nodes/core/parsers/70-JSON_spec.js +++ b/test/nodes/core/parsers/70-JSON_spec.js @@ -50,6 +50,24 @@ describe('JSON node', function() { }); }); + it('should convert a buffer of a valid json string to a javascript object', function(done) { + var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]}, + {id:"jn2", type:"helper"}]; + helper.load(jsonNode, flow, function() { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn2.on("input", function(msg) { + msg.should.have.property('topic', 'bar'); + msg.payload.should.have.property('employees'); + msg.payload.employees[0].should.have.property('firstName', 'John'); + msg.payload.employees[0].should.have.property('lastName', 'Smith'); + done(); + }); + var jsonString = Buffer.from('{"employees":[{"firstName":"John", "lastName":"Smith"}]}'); + jn1.receive({payload:jsonString,topic: "bar"}); + }); + }); + it('should convert a javascript object to a json string', function(done) { var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, {id:"jn2", type:"helper"}]; @@ -166,29 +184,55 @@ describe('JSON node', function() { }); }); - it('should log an error if asked to parse something thats not json or js', function(done) { - var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + it('should log an error if asked to parse an invalid json string in a buffer', function(done) { + var flow = [{id:"jn1",type:"json",action:"obj",wires:[["jn2"]]}, {id:"jn2", type:"helper"}]; helper.load(jsonNode, flow, function() { - var jn1 = helper.getNode("jn1"); - var jn2 = helper.getNode("jn2"); - setTimeout(function() { - try { - var logEvents = helper.log().args.filter(function(evt) { - return evt[0].type == "json"; - }); - logEvents.should.have.length(1); - logEvents[0][0].should.have.a.property('msg'); - logEvents[0][0].msg.toString().should.eql('json.errors.dropped-object'); - done(); - } catch(err) { - done(err); - } - },50); - jn1.receive({payload:Buffer.from("a")}); + try { + var jn1 = helper.getNode("jn1"); + var jn2 = helper.getNode("jn2"); + jn1.receive({payload:Buffer.from('{"name":foo}'),topic: "bar"}); + setTimeout(function() { + try { + var logEvents = helper.log().args.filter(function(evt) { + return evt[0].type == "json"; + }); + logEvents.should.have.length(1); + logEvents[0][0].should.have.a.property('msg'); + logEvents[0][0].msg.should.startWith("Unexpected token o"); + logEvents[0][0].should.have.a.property('level',helper.log().ERROR); + done(); + } catch(err) { done(err) } + },20); + } catch(err) { + done(err); + } }); }); + // it('should log an error if asked to parse something thats not json or js and not in force object mode', function(done) { + // var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, + // {id:"jn2", type:"helper"}]; + // helper.load(jsonNode, flow, function() { + // var jn1 = helper.getNode("jn1"); + // var jn2 = helper.getNode("jn2"); + // setTimeout(function() { + // try { + // var logEvents = helper.log().args.filter(function(evt) { + // return evt[0].type == "json"; + // }); + // logEvents.should.have.length(1); + // logEvents[0][0].should.have.a.property('msg'); + // logEvents[0][0].msg.toString().should.eql('json.errors.dropped'); + // done(); + // } catch(err) { + // done(err); + // } + // },50); + // jn1.receive({payload:Buffer.from("abcd")}); + // }); + // }); + it('should pass straight through if no payload set', function(done) { var flow = [{id:"jn1",type:"json",wires:[["jn2"]]}, {id:"jn2", type:"helper"}]; From 43651135f3d891c287f43bd07cfdedc2d13af74c Mon Sep 17 00:00:00 2001 From: Nick O'Leary Date: Mon, 13 Dec 2021 21:02:55 +0000 Subject: [PATCH 08/70] Replace selectedLinks array with wrapped Set object --- .../@node-red/editor-client/src/js/ui/view.js | 91 ++++++++++++------- 1 file changed, 58 insertions(+), 33 deletions(-) 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 10347b76a..776bb0962 100755 --- 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 @@ -63,8 +63,6 @@ RED.view = (function() { var activeGroups = []; var dirtyGroups = {}; - var selectedLinks = []; - var mousedown_link = null; var mousedown_node = null; var mousedown_group = null; @@ -160,6 +158,31 @@ RED.view = (function() { return api; })(); + var selectedLinks = (function() { + var links = new Set(); + return { + add: function(link) { + links.add(link); + link.selected = true; + }, + remove: function(link) { + links.delete(link); + link.selected = false; + }, + clear: function() { + links.forEach(function(link) { link.selected = false }) + links.clear(); + }, + length: function() { + return links.size; + }, + forEach: function(func) { links.forEach(func) }, + has: function(link) { return links.has(link) }, + toArray: function() { return Array.from(links) } + } + })(); + + function init() { chart = $("#red-ui-workspace-chart"); @@ -910,7 +933,7 @@ RED.view = (function() { return; } if (!mousedown_node && !mousedown_link && !mousedown_group) { - selectedLinks = []; + selectedLinks.clear(); updateSelection(); } if (mouse_mode === 0) { @@ -1349,7 +1372,7 @@ RED.view = (function() { return; } - if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && !mousedown_group && selectedLinks.length === 0) { + if (mouse_mode != RED.state.QUICK_JOINING && mouse_mode != RED.state.IMPORT_DRAGGING && !mousedown_node && !mousedown_group && selectedLinks.length() === 0) { return; } @@ -1373,7 +1396,7 @@ RED.view = (function() { // Get all the wires we need to detach. var links = []; var existingLinks = []; - if (selectedLinks.length > 0) { + if (selectedLinks.length() > 0) { selectedLinks.forEach(function(link) { if (((mousedown_port_type === PORT_TYPE_OUTPUT && link.source === mousedown_node && @@ -1422,7 +1445,7 @@ RED.view = (function() { } else if (mousedown_node && !quickAddLink) { showDragLines([{node:mousedown_node,port:mousedown_port_index,portType:mousedown_port_type}]); } - selectedLinks = []; + selectedLinks.clear(); } mousePos = mouse_position; for (i=0;i 0) { + if (activeFlowLinks.length === 0 && selectedLinks.length() > 0) { selectedLinks.forEach(function(link) { if (link.link) { activeLinks.push(link); @@ -2146,7 +2169,7 @@ RED.view = (function() { updateActiveNodes(); updateSelection(); redraw(); - } else if (movingSet.length() > 0 || selectedLinks.length > 0) { + } else if (movingSet.length() > 0 || selectedLinks.length() > 0) { var result; var node; var removedNodes = []; @@ -2247,7 +2270,7 @@ RED.view = (function() { } var linkRemoveHistoryEvents = []; - if (selectedLinks.length > 0) { + if (selectedLinks.length() > 0) { selectedLinks.forEach(function(link) { if (link.link) { var sourceId = link.source.id; @@ -2319,7 +2342,7 @@ RED.view = (function() { RED.history.push(historyEvent); } - selectedLinks = []; + selectedLinks.clear(); updateActiveNodes(); updateSelection(); redraw(); @@ -2730,12 +2753,13 @@ RED.view = (function() { } else { resetMouseVars(); } - //TODO: selectedLinks - console.log("Wanted to set selected_link (1)",select_link) - // selected_link = select_link; mousedown_link = select_link; if (select_link) { + selectedLinks.clear(); + selectedLinks.add(select_link); updateSelection(); + } else { + selectedLinks.clear(); } } redraw(); @@ -2745,7 +2769,8 @@ RED.view = (function() { resetMouseVars(); hideDragLines(); if (select_link) { - selectedLinks = [select_link]; + selectedLinks.clear(); + selectedLinks.add(select_link); } mousedown_link = select_link; if (select_link) { @@ -3237,7 +3262,7 @@ RED.view = (function() { mousedown_node.selected = true; movingSet.add(mousedown_node); } - selectedLinks = []; + selectedLinks.clear(); if (d3.event.button != 2) { mouse_mode = RED.state.MOVING; var mouse = d3.touches(this)[0]||d3.mouse(this); @@ -3365,26 +3390,25 @@ RED.view = (function() { } mousedown_link = d; - if (selectedLinks.length === 0 || !(d3.event.metaKey || d3.event.ctrlKey)) { + if (selectedLinks.length() === 0 || !(d3.event.metaKey || d3.event.ctrlKey)) { clearSelection(); } if (d3.event.metaKey || d3.event.ctrlKey) { - var linkIndex = selectedLinks.indexOf(mousedown_link); - if (linkIndex === -1) { - selectedLinks.push(mousedown_link); + if (!selectedLinks.has(mousedown_link)) { + selectedLinks.add(mousedown_link); } else { - if (selectedLinks.length !== 1) { - selectedLinks.splice(linkIndex,1); + if (selectedLinks.length() !== 1) { + selectedLinks.remove(mousedown_link); } } } else { - selectedLinks.push(mousedown_link); + selectedLinks.add(mousedown_link); } updateSelection(); redraw(); focusView(); d3.event.stopPropagation(); - if (selectedLinks.length === 1 && selectedLinks[0] === mousedown_link && (d3.event.metaKey || d3.event.ctrlKey)) { + if (!mousedown_link.link && selectedLinks.length() === 1 && selectedLinks.has(mousedown_link) && (d3.event.metaKey || d3.event.ctrlKey)) { d3.select(this).classed("red-ui-flow-link-splice",true); var point = d3.mouse(this); var clickedGroup = getGroupAt(point[0],point[1]); @@ -3398,7 +3422,8 @@ RED.view = (function() { } mousedown_link = d; clearSelection(); - selectedLinks = [mousedown_link]; + selectedLinks.clear(); + selectedLinks.add(mousedown_link); updateSelection(); redraw(); focusView(); @@ -3634,7 +3659,7 @@ RED.view = (function() { function showTouchMenu(obj,pos) { var mdn = mousedown_node; var options = []; - options.push({name:"delete",disabled:(movingSet.length()===0 && selectedLinks.length === 0),onselect:function() {deleteSelection();}}); + options.push({name:"delete",disabled:(movingSet.length()===0 && selectedLinks.length() === 0),onselect:function() {deleteSelection();}}); options.push({name:"cut",disabled:(movingSet.length()===0),onselect:function() {copySelection();deleteSelection();}}); options.push({name:"copy",disabled:(movingSet.length()===0),onselect:function() {copySelection();}}); options.push({name:"paste",disabled:(clipboard.length===0),onselect:function() {importNodes(clipboard, {generateIds: true, touchImport: true});}}); @@ -4391,7 +4416,7 @@ RED.view = (function() { link.exit().remove(); link.each(function(d) { var link = d3.select(this); - if (d.added || selectedLinks.includes(d) || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) { + if (d.added || d.selected || dirtyNodes[d.source.id] || dirtyNodes[d.target.id]) { var numOutputs = d.source.outputs || 1; var sourcePort = d.sourcePort || 0; var y = -((numOutputs-1)/2)*13 +13*sourcePort; @@ -4414,7 +4439,8 @@ RED.view = (function() { this.__pathLine__.classList.toggle("red-ui-flow-node-disabled",!!(d.source.d || d.target.d)); this.__pathLine__.classList.toggle("red-ui-flow-subflow-link", !d.link && activeSubflow); } - this.classList.toggle("red-ui-flow-link-selected", !!(selectedLinks.includes(d)||d.selected)); + + this.classList.toggle("red-ui-flow-link-selected", !!d.selected); var connectedToUnknown = !!(d.target.type == "unknown" || d.source.type == "unknown"); this.classList.toggle("red-ui-flow-link-unknown",!!(d.target.type == "unknown" || d.source.type == "unknown")) @@ -5122,10 +5148,9 @@ RED.view = (function() { if (allNodes.size > 0) { selection.nodes = Array.from(allNodes); } - if (selectedLinks.length > 0) { - selection.link = selectedLinks[0]; - // TODO: clone the array - selection.links = selectedLinks; + if (selectedLinks.length() > 0) { + selection.links = selectedLinks.toArray(); + selection.link = selection.links[0]; } return selection; } From 2cad42870e137b5e2d8430d7cf9287f7538ee952 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 17 Dec 2021 09:58:10 +0000 Subject: [PATCH 09/70] chaneg exec, file and inject node to use node.debug rather than -v flag --- .../@node-red/nodes/core/common/20-inject.js | 12 ++++-------- .../@node-red/nodes/core/function/90-exec.js | 6 +++--- .../@node-red/nodes/core/storage/10-file.js | 4 +--- 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/common/20-inject.js b/packages/node_modules/@node-red/nodes/core/common/20-inject.js index 7e25b1a1d..2c18e6ab7 100644 --- a/packages/node_modules/@node-red/nodes/core/common/20-inject.js +++ b/packages/node_modules/@node-red/nodes/core/common/20-inject.js @@ -75,16 +75,12 @@ module.exports = function(RED) { node.repeaterSetup = function () { if (this.repeat && !isNaN(this.repeat) && this.repeat > 0) { this.repeat = this.repeat * 1000; - if (RED.settings.verbose) { - this.log(RED._("inject.repeat", this)); - } + this.debug(RED._("inject.repeat", this)); this.interval_id = setInterval(function() { node.emit("input", {}); }, this.repeat); } else if (this.crontab) { - if (RED.settings.verbose) { - this.log(RED._("inject.crontab", this)); - } + this.debug(RED._("inject.crontab", this)); this.cronjob = scheduleTask(this.crontab,() => { node.emit("input", {})}); } }; @@ -148,10 +144,10 @@ module.exports = function(RED) { } if (this.interval_id != null) { clearInterval(this.interval_id); - if (RED.settings.verbose) { this.log(RED._("inject.stopped")); } + this.debug(RED._("inject.stopped")); } else if (this.cronjob != null) { this.cronjob.stop(); - if (RED.settings.verbose) { this.log(RED._("inject.stopped")); } + this.debug(RED._("inject.stopped")); delete this.cronjob; } }; diff --git a/packages/node_modules/@node-red/nodes/core/function/90-exec.js b/packages/node_modules/@node-red/nodes/core/function/90-exec.js index cf4168ae8..2ae9947dd 100644 --- a/packages/node_modules/@node-red/nodes/core/function/90-exec.js +++ b/packages/node_modules/@node-red/nodes/core/function/90-exec.js @@ -86,7 +86,7 @@ module.exports = function(RED) { }); var cmd = arg.shift(); /* istanbul ignore else */ - if (RED.settings.verbose) { node.log(cmd+" ["+arg+"]"); } + node.debug(cmd+" ["+arg+"]"); child = spawn(cmd,arg,node.spawnOpt); node.status({fill:"blue",shape:"dot",text:"pid:"+child.pid}); var unknownCommand = (child.pid === undefined); @@ -136,7 +136,7 @@ module.exports = function(RED) { } else { /* istanbul ignore else */ - if (RED.settings.verbose) { node.log(arg); } + node.debug(arg); child = exec(arg, node.execOpt, function (error, stdout, stderr) { var msg2, msg3; delete msg.payload; @@ -155,7 +155,7 @@ module.exports = function(RED) { if (error.signal) { msg3.payload.signal = error.signal; } if (error.code === null) { node.status({fill:"red",shape:"dot",text:"killed"}); } else { node.status({fill:"red",shape:"dot",text:"error:"+error.code}); } - if (RED.settings.verbose) { node.log('error:' + error); } + node.debug('error:' + error); } else if (node.oldrc === "false") { msg3 = RED.util.cloneMessage(msg); diff --git a/packages/node_modules/@node-red/nodes/core/storage/10-file.js b/packages/node_modules/@node-red/nodes/core/storage/10-file.js index 079b4e82f..ba81125fe 100644 --- a/packages/node_modules/@node-red/nodes/core/storage/10-file.js +++ b/packages/node_modules/@node-red/nodes/core/storage/10-file.js @@ -71,9 +71,7 @@ module.exports = function(RED) { node.error(RED._("file.errors.deletefail",{error:err.toString()}),msg); } else { - if (RED.settings.verbose) { - node.log(RED._("file.status.deletedfile",{file:filename})); - } + node.debug(RED._("file.status.deletedfile",{file:filename})); nodeSend(msg); } done(); From 828888490a7c6262d8041fdeb09ea82fcbce5fce Mon Sep 17 00:00:00 2001 From: Kunihiko Toumura Date: Tue, 21 Dec 2021 18:10:42 +0900 Subject: [PATCH 10/70] check availability of config node on deploy --- .../@node-red/editor-client/src/js/ui/deploy.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js b/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js index fdff99a69..a407fc6cd 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/deploy.js @@ -333,6 +333,16 @@ RED.deploy = (function() { var unknownNodes = []; var invalidNodes = []; + RED.nodes.eachConfig(function(node) { + if (!node.valid && !node.d) { + invalidNodes.push(getNodeInfo(node)); + } + if (node.type === "unknown") { + if (unknownNodes.indexOf(node.name) == -1) { + unknownNodes.push(node.name); + } + } + }); RED.nodes.eachNode(function(node) { if (!node.valid && !node.d) { invalidNodes.push(getNodeInfo(node)); From 0937837b7fc5b28786d0306078208ff0631337e6 Mon Sep 17 00:00:00 2001 From: Dave Conway-Jones Date: Fri, 24 Dec 2021 16:18:00 +0000 Subject: [PATCH 11/70] Add TLS config option to TCP client nodes (not yet when in server mode) --- .../nodes/core/network/31-tcpin.html | 130 +++++++++++++-- .../@node-red/nodes/core/network/31-tcpin.js | 149 +++++++++++++++--- 2 files changed, 242 insertions(+), 37 deletions(-) diff --git a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html index 39e987851..3569f33e7 100644 --- a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html +++ b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.html @@ -23,9 +23,17 @@
-