mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			CSV-fix-n-
			...
			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