mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			4456-fix-g
			...
			link-effec
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | b1a706f811 | ||
|  | c27dd336d9 | ||
|  | 5e9ff98c49 | ||
|  | 50cb074172 | ||
|  | 510a09ecba | 
| @@ -594,7 +594,9 @@ RED.nodes = (function() { | ||||
|             } | ||||
|             allNodes.addNode(n); | ||||
|             if (!nodeLinks[n.id]) { | ||||
|                 nodeLinks[n.id] = {in:[],out:[]}; | ||||
|                 nodeLinks[n.id] = { | ||||
|                     inCount:[],outCount:[],in:[],out:[] | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|         RED.events.emit('nodes:add',n); | ||||
| @@ -604,15 +606,19 @@ RED.nodes = (function() { | ||||
|         if (l.source) { | ||||
|             // Possible the node hasn't been added yet | ||||
|             if (!nodeLinks[l.source.id]) { | ||||
|                 nodeLinks[l.source.id] = {in:[],out:[]}; | ||||
|                 nodeLinks[l.source.id] = {inCount:[],outCount:[],in:[],out:[]}; | ||||
|             } | ||||
|             nodeLinks[l.source.id].out.push(l); | ||||
|             nodeLinks[l.source.id].outCount[l.sourcePort] = (nodeLinks[l.source.id].outCount[l.sourcePort] || 0) + 1 | ||||
|             l.source.dirty = true; | ||||
|         } | ||||
|         if (l.target) { | ||||
|             if (!nodeLinks[l.target.id]) { | ||||
|                 nodeLinks[l.target.id] = {in:[],out:[]}; | ||||
|                 nodeLinks[l.target.id] = {inCount:[],outCount:[],in:[],out:[]}; | ||||
|             } | ||||
|             nodeLinks[l.target.id].in.push(l); | ||||
|             nodeLinks[l.target.id].inCount[0] = (nodeLinks[l.target.id].inCount[0] || 0) + 1 | ||||
|             l.target.dirty = true; | ||||
|         } | ||||
|         if (l.source.z === l.target.z && linkTabMap[l.source.z]) { | ||||
|             linkTabMap[l.source.z].push(l); | ||||
| @@ -761,15 +767,19 @@ RED.nodes = (function() { | ||||
|         if (index != -1) { | ||||
|             links.splice(index,1); | ||||
|             if (l.source && nodeLinks[l.source.id]) { | ||||
|                 l.source.dirty = true; | ||||
|                 var sIndex = nodeLinks[l.source.id].out.indexOf(l) | ||||
|                 if (sIndex !== -1) { | ||||
|                     nodeLinks[l.source.id].out.splice(sIndex,1) | ||||
|                     nodeLinks[l.source.id].outCount[l.sourcePort]-- | ||||
|                 } | ||||
|             } | ||||
|             if (l.target && nodeLinks[l.target.id]) { | ||||
|                 l.target.dirty = true; | ||||
|                 var tIndex = nodeLinks[l.target.id].in.indexOf(l) | ||||
|                 if (tIndex !== -1) { | ||||
|                     nodeLinks[l.target.id].in.splice(tIndex,1) | ||||
|                     nodeLinks[l.target.id].inCount[0]-- | ||||
|                 } | ||||
|             } | ||||
|             if (l.source.z === l.target.z && linkTabMap[l.source.z]) { | ||||
| @@ -2706,6 +2716,20 @@ RED.nodes = (function() { | ||||
|             } | ||||
|             return []; | ||||
|         }, | ||||
|         getNodeLinkCount: function(id,portType,index) { | ||||
|             // We *could* just let callers use `getNodeLinks` and get the | ||||
|             // the length for themselves. However, that function creates | ||||
|             // a clone of the array - which is needless work if all you | ||||
|             // want is the length | ||||
|             if (nodeLinks[id]) { | ||||
|                 if (portType === 1) { | ||||
|                     return nodeLinks[id].inCount[index] || 0 | ||||
|                 } else { | ||||
|                     return nodeLinks[id].outCount[index] || 0 | ||||
|                 } | ||||
|             } | ||||
|             return 0; | ||||
|         }, | ||||
|         addWorkspace: addWorkspace, | ||||
|         removeWorkspace: removeWorkspace, | ||||
|         getWorkspaceOrder: function() { return workspacesOrder }, | ||||
|   | ||||
| @@ -37,6 +37,8 @@ RED.view = (function() { | ||||
|         node_height = 30, | ||||
|         dblClickInterval = 650; | ||||
|  | ||||
|     var ARROW_HEADS = false; | ||||
|  | ||||
|     var touchLongPressTimeout = 1000, | ||||
|         startTouchDistance = 0, | ||||
|         startTouchCenter = [], | ||||
| @@ -835,8 +837,9 @@ RED.view = (function() { | ||||
|         } else { | ||||
|             scale = 0.4-0.2*(Math.max(0,(node_width-Math.min(Math.abs(dx),Math.abs(dy)))/node_width)); | ||||
|         } | ||||
|         var result; | ||||
|         if (dx*sc > 0) { | ||||
|             return "M "+origX+" "+origY+ | ||||
|             result = "M "+origX+" "+origY+ | ||||
|                 " C "+(origX+sc*(node_width*scale))+" "+(origY+scaleY*node_height)+" "+ | ||||
|                 (destX-sc*(scale)*node_width)+" "+(destY-scaleY*node_height)+" "+ | ||||
|                 destX+" "+destY | ||||
| @@ -877,7 +880,7 @@ RED.view = (function() { | ||||
|                 } | ||||
|                 cp[2][0] = topX; | ||||
|             } | ||||
|             return "M "+origX+" "+origY+ | ||||
|             result = "M "+origX+" "+origY+ | ||||
|                 " C "+ | ||||
|                    cp[0][0]+" "+cp[0][1]+" "+ | ||||
|                    cp[1][0]+" "+cp[1][1]+" "+ | ||||
| @@ -892,6 +895,7 @@ RED.view = (function() { | ||||
|                     cp[4][0]+" "+cp[4][1]+" "+ | ||||
|                     destX+" "+destY | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     function addNode(type,x,y) { | ||||
| @@ -4131,6 +4135,11 @@ RED.view = (function() { | ||||
|  | ||||
|                 } | ||||
|  | ||||
|                 node[0][0].__portGroup__ = document.createElementNS("http://www.w3.org/2000/svg","g"); | ||||
|                 node[0][0].__portGroup__.__data__ = d; | ||||
|                 nodeContents.appendChild(node[0][0].__portGroup__); | ||||
|  | ||||
|  | ||||
|                 var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect"); | ||||
|                 mainRect.__data__ = d; | ||||
|                 mainRect.setAttribute("class", "red-ui-flow-node "+(d.type == "unknown"?"red-ui-flow-node-unknown":"")); | ||||
| @@ -4334,7 +4343,7 @@ RED.view = (function() { | ||||
|                             this.__textGroup__.setAttribute("transform", "translate(38,"+yp+")"); | ||||
|                         } | ||||
|  | ||||
|                         var inputPorts = thisNode.selectAll(".red-ui-flow-port-input"); | ||||
|                         var inputPorts = d3.select(this.__portGroup__).selectAll(".red-ui-flow-port-input"); | ||||
|                         if ((!isLink || (showAllLinkPorts === -1 && !activeLinkNodes[d.id])) && d.inputs === 0 && !inputPorts.empty()) { | ||||
|                             inputPorts.each(function(d,i) { | ||||
|                                 RED.hooks.trigger("viewRemovePort",{ | ||||
| @@ -4345,8 +4354,9 @@ RED.view = (function() { | ||||
|                                     portIndex: 0 | ||||
|                                 }) | ||||
|                             }).remove(); | ||||
|                             this.__inputs__ = []; | ||||
|                         } else if (((isLink && (showAllLinkPorts===PORT_TYPE_INPUT||activeLinkNodes[d.id]))|| d.inputs === 1) && inputPorts.empty()) { | ||||
|                             var inputGroup = thisNode.append("g").attr("class","red-ui-flow-port-input"); | ||||
|                             var inputGroup = d3.select(this.__portGroup__).append("g").attr("class","red-ui-flow-port-input"); | ||||
|                             var inputGroupPorts; | ||||
|  | ||||
|                             if (d.type === "link in") { | ||||
| @@ -4355,7 +4365,8 @@ RED.view = (function() { | ||||
|                                     .attr("r",5) | ||||
|                                     .attr("class","red-ui-flow-port red-ui-flow-link-port") | ||||
|                             } else { | ||||
|                                 inputGroupPorts = inputGroup.append("rect").attr("class","red-ui-flow-port").attr("rx",3).attr("ry",3).attr("width",10).attr("height",10) | ||||
|                                 inputGroupPorts = inputGroup.append("path").attr("class","red-ui-flow-port-background").attr("d","M5 -1.5 h -16 v 13 h 16 z") | ||||
|                                 inputGroup.append("path").attr("class","red-ui-flow-port red-ui-flow-port-shape").attr("d","M5 0 h -3 c -4 0 -4 0 -4 4 v 2 c 0 4 0 4 4 4 h 3 z ") | ||||
|                             } | ||||
|                             inputGroup[0][0].__port__ = inputGroupPorts[0][0]; | ||||
|                             inputGroupPorts[0][0].__data__ = this.__data__; | ||||
| @@ -4367,6 +4378,8 @@ RED.view = (function() { | ||||
|                                 .on("touchend",function(d){portMouseUp(d,PORT_TYPE_INPUT,0);d3.event.preventDefault();} ) | ||||
|                                 .on("mouseover",function(d){portMouseOver(d3.select(this),d,PORT_TYPE_INPUT,0);}) | ||||
|                                 .on("mouseout",function(d) {portMouseOut(d3.select(this),d,PORT_TYPE_INPUT,0);}); | ||||
|  | ||||
|                             this.__inputs__.push(inputGroup[0][0]); | ||||
|                             RED.hooks.trigger("viewAddPort",{node:d,el: this, port: inputGroup[0][0], portType: "input", portIndex: 0}) | ||||
|                         } | ||||
|                         var numOutputs = d.outputs; | ||||
| @@ -4403,15 +4416,19 @@ RED.view = (function() { | ||||
|                                     portPort.setAttribute("cy",5); | ||||
|                                     portPort.setAttribute("r",5); | ||||
|                                     portPort.setAttribute("class","red-ui-flow-port red-ui-flow-link-port"); | ||||
|                                     portGroup.appendChild(portPort); | ||||
|                                 } else { | ||||
|                                     portPort = document.createElementNS("http://www.w3.org/2000/svg","rect"); | ||||
|                                     portPort.setAttribute("rx",3); | ||||
|                                     portPort.setAttribute("ry",3); | ||||
|                                     portPort.setAttribute("width",10); | ||||
|                                     portPort.setAttribute("height",10); | ||||
|                                     portPort.setAttribute("class","red-ui-flow-port"); | ||||
|  | ||||
|                                     portPort = document.createElementNS("http://www.w3.org/2000/svg","path"); | ||||
|                                     portPort.setAttribute("d","M5 -1.5 h 16 v 13 h -16 z "); | ||||
|                                     portPort.setAttribute("class","red-ui-flow-port-background"); | ||||
|                                     portGroup.appendChild(portPort); | ||||
|  | ||||
|                                     var visiblePort = document.createElementNS("http://www.w3.org/2000/svg","path"); | ||||
|                                     visiblePort.setAttribute("d","M5 0 h 4 c 4 0 4 0 4 4 v 2 c 0 4 0 4 -4 4 h -4 z "); | ||||
|                                     visiblePort.setAttribute("class","red-ui-flow-port red-ui-flow-port-shape"); | ||||
|                                     portGroup.appendChild(visiblePort); | ||||
|                                 } | ||||
|                                 portGroup.appendChild(portPort); | ||||
|                                 portGroup.__port__ = portPort; | ||||
|                                 portPort.__data__ = this.__data__; | ||||
|                                 portPort.__portType__ = PORT_TYPE_OUTPUT; | ||||
| @@ -4423,7 +4440,7 @@ RED.view = (function() { | ||||
|                                 portPort.addEventListener("mouseover", portMouseOverProxy); | ||||
|                                 portPort.addEventListener("mouseout", portMouseOutProxy); | ||||
|  | ||||
|                                 this.appendChild(portGroup); | ||||
|                                 this.__portGroup__.appendChild(portGroup); | ||||
|                                 this.__outputs__.push(portGroup); | ||||
|                                 RED.hooks.trigger("viewAddPort",{node:d,el: this, port: portGroup, portType: "output", portIndex: portIndex}) | ||||
|                             } else { | ||||
| @@ -4514,6 +4531,14 @@ RED.view = (function() { | ||||
|                         // }); | ||||
|                     } | ||||
|  | ||||
|                     for (var i=0,l=this.__outputs__.length;i<l;i++) { | ||||
|                         this.__outputs__[i].classList.toggle("red-ui-flow-port-connected",RED.nodes.getNodeLinkCount(d.id,PORT_TYPE_OUTPUT,i) > 0 ) | ||||
|                     } | ||||
|                     for (var i=0,l=this.__inputs__.length;i<l;i++) { | ||||
|                         this.__inputs__[i].classList.toggle("red-ui-flow-port-connected",RED.nodes.getNodeLinkCount(d.id,PORT_TYPE_INPUT,i) > 0 ) | ||||
|                     } | ||||
|  | ||||
|  | ||||
|                     if (d.dirtyStatus) { | ||||
|                         redrawStatus(d,this); | ||||
|                     } | ||||
| @@ -4594,18 +4619,14 @@ RED.view = (function() { | ||||
|                     d.y1 = d.source.y+y; | ||||
|                     d.x2 = d.target.x-d.target.w/2; | ||||
|                     d.y2 = d.target.y; | ||||
|  | ||||
|                     // return "M "+d.x1+" "+d.y1+ | ||||
|                     //     " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+ | ||||
|                     //     (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+ | ||||
|                     //     d.x2+" "+d.y2; | ||||
|                     var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1); | ||||
|                     var targetOffset = ARROW_HEADS?(d.link?16:13):0 | ||||
|                     var path = generateLinkPath(d.x1+5,d.y1,d.x2-targetOffset,d.y2,1); | ||||
|                     if (/NaN/.test(path)) { | ||||
|                         path = "" | ||||
|                     } | ||||
|                     this.__pathBack__.setAttribute("d",path); | ||||
|                     this.__pathOutline__.setAttribute("d",path); | ||||
|                     this.__pathLine__.setAttribute("d",path); | ||||
|                     this.__pathLine__.setAttribute("d",path + (ARROW_HEADS?"m0 0, l 0 -2 l 3 2 l -3 2 z":"")); | ||||
|                     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); | ||||
|                 } | ||||
|   | ||||
| @@ -196,6 +196,12 @@ $view-background: $secondary-background; | ||||
| $view-select-mode-background: $secondary-background-selected; | ||||
| $view-grid-color: #eee; | ||||
|  | ||||
| $link-color: #999; | ||||
| $link-link-color: #aaa; | ||||
| $link-disabled-color: #ccc; | ||||
| $link-link-active-color: #ff7f0e; | ||||
| $link-unknown-color: #f00; | ||||
|  | ||||
| $node-label-color: #333; | ||||
| $node-port-label-color: #888; | ||||
| $node-border: #999; | ||||
| @@ -203,8 +209,13 @@ $node-border-unknown: #f33; | ||||
| $node-border-placeholder: #aaa; | ||||
| $node-background-placeholder: #eee; | ||||
|  | ||||
| $node-port-border: $node-border; | ||||
| $node-port-border-connected: $link-color; | ||||
|  | ||||
| $node-port-background: #d9d9d9; | ||||
| $node-port-background-hover: #eee; | ||||
| $node-port-background-connected: $link-color; | ||||
|  | ||||
| $node-icon-color: #fff; | ||||
| $node-icon-background-color: rgba(0,0,0,0.05); | ||||
| $node-icon-background-color-fill: #000; | ||||
| @@ -232,12 +243,6 @@ $node-status-colors: ( | ||||
| $node-selected-color: #ff7f0e; | ||||
| $port-selected-color: #ff7f0e; | ||||
|  | ||||
| $link-color: #999; | ||||
| $link-link-color: #aaa; | ||||
| $link-disabled-color: #ccc; | ||||
| $link-link-active-color: #ff7f0e; | ||||
| $link-unknown-color: #f00; | ||||
|  | ||||
| $clipboard-textarea-background: #F3E7E7; | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -185,12 +185,29 @@ | ||||
| } | ||||
|  | ||||
| .red-ui-flow-port { | ||||
|     stroke: $node-border; | ||||
|     stroke: $node-port-border; | ||||
|     stroke-width: 1; | ||||
|     fill: $node-port-background; | ||||
|     cursor: crosshair; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-port-background { | ||||
|     opacity: 0; | ||||
|     stroke: none; | ||||
|     fill: #f00; | ||||
|     cursor: crosshair; | ||||
| } | ||||
| .red-ui-flow-port-shape { | ||||
|     pointer-events: none; | ||||
|     cursor: crosshair; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-port-connected .red-ui-flow-port { | ||||
|     fill:  $node-port-background-connected; | ||||
|     stroke: $node-port-border-connected; | ||||
| } | ||||
|  | ||||
|  | ||||
| .red-ui-flow-node-error { | ||||
|     fill: $node-status-error-background; | ||||
|     stroke: $node-status-error-border; | ||||
| @@ -280,9 +297,10 @@ g.red-ui-flow-node-selected { | ||||
|     text-anchor:start; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-port-hovered { | ||||
|     stroke: $port-selected-color; | ||||
|     fill:  $port-selected-color; | ||||
| .red-ui-flow-port-hovered:not(.red-ui-flow-port-background), | ||||
| .red-ui-flow-port-background.red-ui-flow-port-hovered + .red-ui-flow-port-shape { | ||||
|     stroke: $port-selected-color !important; | ||||
|     fill:  $port-selected-color !important; | ||||
| } | ||||
|  | ||||
| .red-ui-flow-subflow-port { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user