diff --git a/packages/node_modules/@node-red/editor-client/src/js/nodes.js b/packages/node_modules/@node-red/editor-client/src/js/nodes.js index 45f3f8668..08333777e 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/nodes.js +++ b/packages/node_modules/@node-red/editor-client/src/js/nodes.js @@ -1090,6 +1090,11 @@ RED.nodes = (function() { return false; } + function getDownstreamNodes(node) { + const downstreamLinks = nodeLinks[node.id].out + const downstreamNodes = new Set(downstreamLinks.map(l => l.target)) + return Array.from(downstreamNodes) + } function getAllDownstreamNodes(node) { return getAllFlowNodes(node,'down').filter(function(n) { return n !== node }); } @@ -3086,6 +3091,7 @@ RED.nodes = (function() { getAllFlowNodes: getAllFlowNodes, getAllUpstreamNodes: getAllUpstreamNodes, getAllDownstreamNodes: getAllDownstreamNodes, + getDownstreamNodes: getDownstreamNodes, getNodeIslands: getNodeIslands, createExportableNodeSet: createExportableNodeSet, createCompleteNodeSet: createCompleteNodeSet, diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js index ff31bef3b..b63cdc1a2 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js @@ -82,15 +82,15 @@ RED.contextMenu = (function () { dirty: true, moved: true } + const junction = RED.nodes.addJunction(nn); const historyEvent = { dirty: RED.nodes.dirty(), t: 'add', - junctions: [nn] + junctions: [junction] } - RED.nodes.addJunction(nn); RED.history.push(historyEvent); RED.nodes.dirty(true); - RED.view.select({nodes: [nn] }); + RED.view.select({nodes: [junction] }); RED.view.redraw(true) }, disabled: !canEdit 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 72bf7038b..7114b6c47 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 @@ -3095,8 +3095,25 @@ RED.view = (function() { (drag_line.portType === PORT_TYPE_INPUT && mouseup_node.type === "subflow" && (mouseup_node.direction === "status" || mouseup_node.direction === "out")) || (drag_line.portType === PORT_TYPE_OUTPUT && mouseup_node.type === "subflow" && mouseup_node.direction === "in") )) { + let hasJunctionLoop = false + if (link.source.type === 'junction' && link.target.type === 'junction') { + // This is joining two junctions together. We want to avoid creating a loop + // of pure junction nodes as there is no way to break out of it. + + const visited = new Set() + let toVisit = [link.target] + while (toVisit.length > 0) { + const next = toVisit.shift() + if (next === link.source) { + hasJunctionLoop = true + break + } + visited.add(next) + toVisit = toVisit.concat(RED.nodes.getDownstreamNodes(next).filter(n => n.type === 'junction' && !visited.has(n))) + } + } var existingLink = RED.nodes.filterLinks({source:src,target:dst,sourcePort: src_port}).length !== 0; - if (!existingLink) { + if (!hasJunctionLoop && !existingLink) { RED.nodes.addLink(link); addedLinks.push(link); }