mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Merge pull request #4244 from Steve-Mcl/3877-fix-touch-join-junc
3877-fix-touch-join-junc
This commit is contained in:
		| @@ -1305,6 +1305,39 @@ RED.view.tools = (function() { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Determine if a point is within a node | ||||
|      * @param {*} node - A Node or Junction node | ||||
|      * @param {[Number,Number]} mouse_position The x,y position of the mouse | ||||
|      * @param {Number} [marginX=0] - A margin to add or deduct from the x position (to increase the hit area) | ||||
|      * @param {Number} [marginY=0] - A margin to add or deduct from the y position (to increase the hit area) | ||||
|      * @returns  | ||||
|      */ | ||||
|     function isPointInNode (node, [x, y], marginX, marginY) { | ||||
|         marginX = marginX || 0 | ||||
|         marginY = marginY || 0 | ||||
|  | ||||
|         let w = node.w || 10 // junctions dont have any w or h value | ||||
|         let h = node.h || 10 | ||||
|         let x1, x2, y1, y2 | ||||
|          | ||||
|         if (node.type === "junction" || node.type === "group") { | ||||
|             // x/y is the top left of the node | ||||
|             x1 = node.x | ||||
|             y1 = node.y | ||||
|             x2 = node.x + w | ||||
|             y2 = node.y + h | ||||
|         } else { | ||||
|             // x/y is the center of the node | ||||
|             const [xMid, yMid] =  [w/2, h/2] | ||||
|             x1 = node.x - xMid | ||||
|             y1 = node.y - yMid | ||||
|             x2 = node.x + xMid | ||||
|             y2 = node.y + yMid | ||||
|         } | ||||
|         return (x >= (x1 - marginX) && x <= (x2 + marginX) && y >= (y1 - marginY) && y <= (y2 + marginY)) | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         init: function() { | ||||
|             RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); }) | ||||
| @@ -1387,7 +1420,8 @@ RED.view.tools = (function() { | ||||
|          * @param  {Number} dy | ||||
|          */ | ||||
|         moveSelection: moveSelection, | ||||
|         calculateGridSnapOffsets: calculateGridSnapOffsets | ||||
|         calculateGridSnapOffsets: calculateGridSnapOffsets, | ||||
|         isPointInNode: isPointInNode | ||||
|     } | ||||
|  | ||||
| })(); | ||||
|   | ||||
| @@ -101,7 +101,7 @@ RED.view = (function() { | ||||
|  | ||||
|     // Note: these are the permitted status colour aliases. The actual RGB values | ||||
|     //       are set in the CSS - flow.scss/colors.scss | ||||
|     var status_colours = { | ||||
|     const status_colours = { | ||||
|         "red":    "#c00", | ||||
|         "green":  "#5a8", | ||||
|         "yellow": "#F9DF31", | ||||
| @@ -110,19 +110,32 @@ RED.view = (function() { | ||||
|         "gray":   "#d3d3d3" | ||||
|     } | ||||
|  | ||||
|     var PORT_TYPE_INPUT = 1; | ||||
|     var PORT_TYPE_OUTPUT = 0; | ||||
|     const PORT_TYPE_INPUT = 1; | ||||
|     const PORT_TYPE_OUTPUT = 0; | ||||
|  | ||||
|     var chart; | ||||
|     var outer; | ||||
|     /** | ||||
|      * The jQuery object for the workspace chart `#red-ui-workspace-chart` div element | ||||
|      * @type {JQuery<HTMLElement>} #red-ui-workspace-chart HTML Element  | ||||
|      */  | ||||
|     let chart; | ||||
|     /** | ||||
|      * The d3 object `#red-ui-workspace-chart` svg element | ||||
|      * @type {d3.Selection<HTMLElement, Any, Any, Any>} | ||||
|      */  | ||||
|     let outer; | ||||
|     /**  | ||||
|      * The d3 object `#red-ui-workspace-chart` svg element (specifically for events) | ||||
|      * @type {d3.Selection<d3.BaseType, any, any, any>} | ||||
|      */ | ||||
|     var eventLayer; | ||||
|     var gridLayer; | ||||
|     var linkLayer; | ||||
|     var junctionLayer; | ||||
|     var dragGroupLayer; | ||||
|     var groupSelectLayer; | ||||
|     var nodeLayer; | ||||
|     var groupLayer; | ||||
|  | ||||
|     /** @type {SVGGElement} */ let gridLayer; | ||||
|     /** @type {SVGGElement} */ let linkLayer; | ||||
|     /** @type {SVGGElement} */ let junctionLayer; | ||||
|     /** @type {SVGGElement} */ let dragGroupLayer; | ||||
|     /** @type {SVGGElement} */ let groupSelectLayer; | ||||
|     /** @type {SVGGElement} */ let nodeLayer; | ||||
|     /** @type {SVGGElement} */ let groupLayer; | ||||
|     var drag_lines; | ||||
|  | ||||
|     const movingSet = (function() { | ||||
| @@ -391,16 +404,6 @@ RED.view = (function() { | ||||
|                     touchStartTime = setTimeout(function() { | ||||
|                         touchStartTime = null; | ||||
|                         showTouchMenu(obj,pos); | ||||
|                         //lasso = eventLayer.append("rect") | ||||
|                         //    .attr("ox",point[0]) | ||||
|                         //    .attr("oy",point[1]) | ||||
|                         //    .attr("rx",2) | ||||
|                         //    .attr("ry",2) | ||||
|                         //    .attr("x",point[0]) | ||||
|                         //    .attr("y",point[1]) | ||||
|                         //    .attr("width",0) | ||||
|                         //    .attr("height",0) | ||||
|                         //    .attr("class","nr-ui-view-lasso"); | ||||
|                     },touchLongPressTimeout); | ||||
|                 } | ||||
|                 d3.event.preventDefault(); | ||||
| @@ -3094,22 +3097,38 @@ RED.view = (function() { | ||||
|             } | ||||
|         } | ||||
|         document.body.style.cursor = ""; | ||||
|  | ||||
|         if (mouse_mode == RED.state.JOINING || mouse_mode == RED.state.QUICK_JOINING) { | ||||
|             if (typeof TouchEvent != "undefined" && evt instanceof TouchEvent) { | ||||
|                 var found = false; | ||||
|                 RED.nodes.eachNode(function(n) { | ||||
|                     if (n.z == RED.workspaces.active()) { | ||||
|                         var hw = n.w/2; | ||||
|                         var hh = n.h/2; | ||||
|                         if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] && | ||||
|                             n.y-hh<mouse_position[1] && n.y+hh>mouse_position[1]) { | ||||
|                                 found = true; | ||||
|                                 mouseup_node = n; | ||||
|                                 portType = mouseup_node.inputs>0?PORT_TYPE_INPUT:PORT_TYPE_OUTPUT; | ||||
|                                 portIndex = 0; | ||||
|                 if (RED.view.DEBUG) { console.warn("portMouseUp: TouchEvent", mouse_mode,d,portType,portIndex); } | ||||
|                 const direction = drag_lines[0].portType === PORT_TYPE_INPUT ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT | ||||
|                 let found = false; | ||||
|                 for (let nodeIdx = 0; nodeIdx < activeNodes.length; nodeIdx++) { | ||||
|                     const n = activeNodes[nodeIdx]; | ||||
|                     if (RED.view.tools.isPointInNode(n, mouse_position)) { | ||||
|                         found = true; | ||||
|                         mouseup_node = n; | ||||
|                         // portType = mouseup_node.inputs > 0 ? PORT_TYPE_INPUT : PORT_TYPE_OUTPUT; | ||||
|                         portType = direction; | ||||
|                         portIndex = 0; | ||||
|                         break | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 if (!found && drag_lines.length > 0 && !drag_lines[0].virtualLink) { | ||||
|                     for (let juncIdx = 0; juncIdx < activeJunctions.length; juncIdx++) { | ||||
|                         // NOTE: a junction is 10px x 10px but the target area is expanded to 30wx20h by adding padding to the bounding box | ||||
|                         const jNode = activeJunctions[juncIdx]; | ||||
|                         if (RED.view.tools.isPointInNode(jNode, mouse_position, 20, 10)) { | ||||
|                             found = true; | ||||
|                             mouseup_node = jNode; | ||||
|                             portType = direction; | ||||
|                             portIndex = 0; | ||||
|                             break | ||||
|                         } | ||||
|                     } | ||||
|                 }); | ||||
|                 } | ||||
|  | ||||
|                 if (!found && activeSubflow) { | ||||
|                     var subflowPorts = []; | ||||
|                     if (activeSubflow.status) { | ||||
| @@ -3121,16 +3140,13 @@ RED.view = (function() { | ||||
|                     if (activeSubflow.out) { | ||||
|                         subflowPorts = subflowPorts.concat(activeSubflow.out) | ||||
|                     } | ||||
|                     for (var i=0;i<subflowPorts.length;i++) { | ||||
|                         var n = subflowPorts[i]; | ||||
|                         var hw = n.w/2; | ||||
|                         var hh = n.h/2; | ||||
|                         if (n.x-hw<mouse_position[0] && n.x+hw> mouse_position[0] && | ||||
|                             n.y-hh<mouse_position[1] && n.y+hh>mouse_position[1]) { | ||||
|                                 found = true; | ||||
|                                 mouseup_node = n; | ||||
|                                 portType = mouseup_node.direction === "in"?PORT_TYPE_OUTPUT:PORT_TYPE_INPUT; | ||||
|                                 portIndex = 0; | ||||
|                     for (var i = 0; i < subflowPorts.length; i++) { | ||||
|                         const sf = subflowPorts[i]; | ||||
|                         if (RED.view.tools.isPointInNode(sf, mouse_position)) { | ||||
|                             found = true; | ||||
|                             mouseup_node = sf; | ||||
|                             portType = mouseup_node.direction === "in" ? PORT_TYPE_OUTPUT : PORT_TYPE_INPUT; | ||||
|                             portIndex = 0; | ||||
|                             break; | ||||
|                         } | ||||
|                     } | ||||
| @@ -5015,16 +5031,25 @@ RED.view = (function() { | ||||
|                 contents.appendChild(junctionOutput); | ||||
|                 junctionOutput.addEventListener("mouseup", portMouseUpProxy); | ||||
|                 junctionOutput.addEventListener("mousedown", portMouseDownProxy); | ||||
|  | ||||
|                 junctionOutput.addEventListener("mouseover", junctionMouseOverProxy); | ||||
|                 junctionOutput.addEventListener("mouseout", junctionMouseOutProxy); | ||||
|                 junctionOutput.addEventListener("touchmove", junctionMouseOverProxy); | ||||
|                 junctionOutput.addEventListener("touchend", portMouseUpProxy); | ||||
|                 junctionOutput.addEventListener("touchstart", portMouseDownProxy); | ||||
|  | ||||
|                 junctionInput.addEventListener("mouseover", junctionMouseOverProxy); | ||||
|                 junctionInput.addEventListener("mouseout", junctionMouseOutProxy); | ||||
|                 junctionInput.addEventListener("touchmove", junctionMouseOverProxy); | ||||
|                 junctionInput.addEventListener("touchend", portMouseUpProxy); | ||||
|                 junctionInput.addEventListener("touchstart", portMouseDownProxy); | ||||
|  | ||||
|                 junctionBack.addEventListener("mouseover", junctionMouseOverProxy); | ||||
|                 junctionBack.addEventListener("mouseout", junctionMouseOutProxy); | ||||
|                 junctionBack.addEventListener("touchmove", junctionMouseOverProxy); | ||||
|  | ||||
|                 // These handlers expect to be registered as d3 events | ||||
|                 d3.select(junctionBack).on("mousedown", nodeMouseDown).on("mouseup", nodeMouseUp); | ||||
|                 d3.select(junctionBack).on("touchstart", nodeMouseDown).on("touchend", nodeMouseUp); | ||||
|  | ||||
|                 junction[0][0].appendChild(contents); | ||||
|             }) | ||||
|   | ||||
| @@ -107,7 +107,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject name of node as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_NODE_NAME", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_NODE_NAME", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -125,7 +125,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of node as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_NODE_ID", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_NODE_ID", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -143,7 +143,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject path of node as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_NODE_PATH", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_NODE_PATH", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -162,7 +162,7 @@ describe('inject node', function() { | ||||
|  | ||||
|  | ||||
|     it('inject name of flow as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_FLOW_NAME", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_FLOW_NAME", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "flow", type: "tab", label: "FLOW" }, | ||||
|                    ]; | ||||
| @@ -182,7 +182,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of flow as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_FLOW_ID", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_FLOW_ID", payloadType: "env", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "flow", type: "tab", name: "FLOW" }, | ||||
|                    ]; | ||||
| @@ -202,7 +202,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject name of group as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_GROUP_NAME", payloadType: "env", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_GROUP_NAME", payloadType: "env", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "g0", type: "group", name: "GROUP" }, | ||||
|                    ]; | ||||
| @@ -222,7 +222,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of group as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "NR_GROUP_ID", payloadType: "env", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "NR_GROUP_ID", payloadType: "env", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "g0", type: "group", name: "GROUP" }, | ||||
|                    ]; | ||||
| @@ -243,7 +243,7 @@ describe('inject node', function() { | ||||
|  | ||||
|  | ||||
|     it('inject name of node as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_NODE_NAME}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_NODE_NAME}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -261,7 +261,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of node as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_NODE_ID}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_NODE_ID}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -279,7 +279,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject path of node as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_NODE_PATH}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_NODE_PATH}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}]; | ||||
|         helper.load(injectNode, flow, function () { | ||||
|             var n1 = helper.getNode("n1"); | ||||
| @@ -298,7 +298,7 @@ describe('inject node', function() { | ||||
|  | ||||
|  | ||||
|     it('inject name of flow as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_FLOW_NAME}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_FLOW_NAME}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "flow", type: "tab", label: "FLOW" }, | ||||
|                    ]; | ||||
| @@ -318,7 +318,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of flow as environment variable ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_FLOW_ID}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_FLOW_ID}", payloadType: "str", wires: [["n2"]], z: "flow"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "flow", type: "tab", name: "FLOW" }, | ||||
|                    ]; | ||||
| @@ -338,7 +338,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject name of group as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_GROUP_NAME}", payloadType: "str", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_GROUP_NAME}", payloadType: "str", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "g0", type: "group", name: "GROUP" }, | ||||
|                    ]; | ||||
| @@ -358,7 +358,7 @@ describe('inject node', function() { | ||||
|     }); | ||||
|  | ||||
|     it('inject id of group as environment variable by substitution ', function (done) { | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topnic: "t1", payload: "${NR_GROUP_ID}", payloadType: "str", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|         var flow = [{id: "n1", type: "inject", name: "NAME", topic: "t1", payload: "${NR_GROUP_ID}", payloadType: "str", wires: [["n2"]], z: "flow", g: "g0"}, | ||||
|                     {id: "n2", type: "helper"}, | ||||
|                     {id: "g0", type: "group", name: "GROUP" }, | ||||
|                    ]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user