mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Merge remote-tracking branch 'upstream/dev' into dev
This commit is contained in:
commit
8fa1d4def5
@ -1033,7 +1033,7 @@ RED.view = (function() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateLinkPath(origX,origY, destX, destY, sc) {
|
function generateLinkPath(origX,origY, destX, destY, sc, hasStatus = false) {
|
||||||
var dy = destY-origY;
|
var dy = destY-origY;
|
||||||
var dx = destX-origX;
|
var dx = destX-origX;
|
||||||
var delta = Math.sqrt(dy*dy+dx*dx);
|
var delta = Math.sqrt(dy*dy+dx*dx);
|
||||||
@ -1050,62 +1050,110 @@ RED.view = (function() {
|
|||||||
} else {
|
} else {
|
||||||
scale = 0.4-0.2*(Math.max(0,(node_width-Math.min(Math.abs(dx),Math.abs(dy)))/node_width));
|
scale = 0.4-0.2*(Math.max(0,(node_width-Math.min(Math.abs(dx),Math.abs(dy)))/node_width));
|
||||||
}
|
}
|
||||||
|
function genCP(cp) {
|
||||||
|
return ` M ${cp[0]-5} ${cp[1]} h 10 M ${cp[0]} ${cp[1]-5} v 10 `
|
||||||
|
}
|
||||||
if (dx*sc > 0) {
|
if (dx*sc > 0) {
|
||||||
return "M "+origX+" "+origY+
|
let cp = [
|
||||||
" C "+(origX+sc*(node_width*scale))+" "+(origY+scaleY*node_height)+" "+
|
[(origX+sc*(node_width*scale)), (origY+scaleY*node_height)],
|
||||||
(destX-sc*(scale)*node_width)+" "+(destY-scaleY*node_height)+" "+
|
[(destX-sc*(scale)*node_width), (destY-scaleY*node_height)]
|
||||||
destX+" "+destY
|
]
|
||||||
|
return `M ${origX} ${origY} C ${cp[0][0]} ${cp[0][1]} ${cp[1][0]} ${cp[1][1]} ${destX} ${destY}`
|
||||||
|
// + ` ${genCP(cp[0])} ${genCP(cp[1])}`
|
||||||
} else {
|
} else {
|
||||||
|
let topX, topY, bottomX, bottomY
|
||||||
|
let cp
|
||||||
|
let midX = Math.floor(destX-dx/2);
|
||||||
|
let midY = Math.floor(destY-dy/2);
|
||||||
|
if (Math.abs(dy) < 10) {
|
||||||
|
bottomY = Math.max(origY, destY) + (hasStatus?35:25)
|
||||||
|
let startCurveHeight = bottomY - origY
|
||||||
|
let endCurveHeight = bottomY - destY
|
||||||
|
cp = [
|
||||||
|
[ origX + sc*15 , origY ],
|
||||||
|
[ origX + sc*25 , origY + 5 ],
|
||||||
|
[ origX + sc*25 , origY + startCurveHeight/2 ],
|
||||||
|
|
||||||
var midX = Math.floor(destX-dx/2);
|
[ origX + sc*25 , origY + startCurveHeight - 5 ],
|
||||||
var midY = Math.floor(destY-dy/2);
|
[ origX + sc*15 , origY + startCurveHeight ],
|
||||||
//
|
[ origX , origY + startCurveHeight ],
|
||||||
if (dy === 0) {
|
|
||||||
midY = destY + node_height;
|
[ destX - sc*15, origY + startCurveHeight ],
|
||||||
}
|
[ destX - sc*25, origY + startCurveHeight - 5 ],
|
||||||
var cp_height = node_height/2;
|
[ destX - sc*25, destY + endCurveHeight/2 ],
|
||||||
var y1 = (destY + midY)/2
|
|
||||||
var topX =origX + sc*node_width*scale;
|
[ destX - sc*25, destY + 5 ],
|
||||||
var topY = dy>0?Math.min(y1 - dy/2 , origY+cp_height):Math.max(y1 - dy/2 , origY-cp_height);
|
[ destX - sc*15, destY ],
|
||||||
var bottomX = destX - sc*node_width*scale;
|
[ destX, destY ],
|
||||||
var bottomY = dy>0?Math.max(y1, destY-cp_height):Math.min(y1, destY+cp_height);
|
]
|
||||||
var x1 = (origX+topX)/2;
|
|
||||||
var scy = dy>0?1:-1;
|
return "M "+origX+" "+origY+
|
||||||
var cp = [
|
" C "+
|
||||||
// Orig -> Top
|
cp[0][0]+" "+cp[0][1]+" "+
|
||||||
[x1,origY],
|
cp[1][0]+" "+cp[1][1]+" "+
|
||||||
[topX,dy>0?Math.max(origY, topY-cp_height):Math.min(origY, topY+cp_height)],
|
cp[2][0]+" "+cp[2][1]+" "+
|
||||||
// Top -> Mid
|
" C " +
|
||||||
// [Mirror previous cp]
|
cp[3][0]+" "+cp[3][1]+" "+
|
||||||
[x1,dy>0?Math.min(midY, topY+cp_height):Math.max(midY, topY-cp_height)],
|
|
||||||
// Mid -> Bottom
|
|
||||||
// [Mirror previous cp]
|
|
||||||
[bottomX,dy>0?Math.max(midY, bottomY-cp_height):Math.min(midY, bottomY+cp_height)],
|
|
||||||
// Bottom -> Dest
|
|
||||||
// [Mirror previous cp]
|
|
||||||
[(destX+bottomX)/2,destY]
|
|
||||||
];
|
|
||||||
if (cp[2][1] === topY+scy*cp_height) {
|
|
||||||
if (Math.abs(dy) < cp_height*10) {
|
|
||||||
cp[1][1] = topY-scy*cp_height/2;
|
|
||||||
cp[3][1] = bottomY-scy*cp_height/2;
|
|
||||||
}
|
|
||||||
cp[2][0] = topX;
|
|
||||||
}
|
|
||||||
return "M "+origX+" "+origY+
|
|
||||||
" C "+
|
|
||||||
cp[0][0]+" "+cp[0][1]+" "+
|
|
||||||
cp[1][0]+" "+cp[1][1]+" "+
|
|
||||||
topX+" "+topY+
|
|
||||||
" S "+
|
|
||||||
cp[2][0]+" "+cp[2][1]+" "+
|
|
||||||
midX+" "+midY+
|
|
||||||
" S "+
|
|
||||||
cp[3][0]+" "+cp[3][1]+" "+
|
|
||||||
bottomX+" "+bottomY+
|
|
||||||
" S "+
|
|
||||||
cp[4][0]+" "+cp[4][1]+" "+
|
cp[4][0]+" "+cp[4][1]+" "+
|
||||||
destX+" "+destY
|
cp[5][0]+" "+cp[5][1]+" "+
|
||||||
|
" h "+dx+
|
||||||
|
" C "+
|
||||||
|
cp[6][0]+" "+cp[6][1]+" "+
|
||||||
|
cp[7][0]+" "+cp[7][1]+" "+
|
||||||
|
cp[8][0]+" "+cp[8][1]+" "+
|
||||||
|
" C " +
|
||||||
|
cp[9][0]+" "+cp[9][1]+" "+
|
||||||
|
cp[10][0]+" "+cp[10][1]+" "+
|
||||||
|
cp[11][0]+" "+cp[11][1]+" "
|
||||||
|
// +genCP(cp[0])+genCP(cp[1])+genCP(cp[2])+genCP(cp[3])+genCP(cp[4])
|
||||||
|
// +genCP(cp[5])+genCP(cp[6])+genCP(cp[7])+genCP(cp[8])+genCP(cp[9])+genCP(cp[10])
|
||||||
|
} else {
|
||||||
|
var cp_height = node_height/2;
|
||||||
|
var y1 = (destY + midY)/2
|
||||||
|
topX = origX + sc*node_width*scale;
|
||||||
|
topY = dy>0?Math.min(y1 - dy/2 , origY+cp_height):Math.max(y1 - dy/2 , origY-cp_height);
|
||||||
|
bottomX = destX - sc*node_width*scale;
|
||||||
|
bottomY = dy>0?Math.max(y1, destY-cp_height):Math.min(y1, destY+cp_height);
|
||||||
|
var x1 = (origX+topX)/2;
|
||||||
|
var scy = dy>0?1:-1;
|
||||||
|
cp = [
|
||||||
|
// Orig -> Top
|
||||||
|
[x1,origY],
|
||||||
|
[topX,dy>0?Math.max(origY, topY-cp_height):Math.min(origY, topY+cp_height)],
|
||||||
|
// Top -> Mid
|
||||||
|
// [Mirror previous cp]
|
||||||
|
[x1,dy>0?Math.min(midY, topY+cp_height):Math.max(midY, topY-cp_height)],
|
||||||
|
// Mid -> Bottom
|
||||||
|
// [Mirror previous cp]
|
||||||
|
[bottomX,dy>0?Math.max(midY, bottomY-cp_height):Math.min(midY, bottomY+cp_height)],
|
||||||
|
// Bottom -> Dest
|
||||||
|
// [Mirror previous cp]
|
||||||
|
[(destX+bottomX)/2,destY]
|
||||||
|
];
|
||||||
|
if (cp[2][1] === topY+scy*cp_height) {
|
||||||
|
if (Math.abs(dy) < cp_height*10) {
|
||||||
|
cp[1][1] = topY-scy*cp_height/2;
|
||||||
|
cp[3][1] = bottomY-scy*cp_height/2;
|
||||||
|
}
|
||||||
|
cp[2][0] = topX;
|
||||||
|
}
|
||||||
|
return "M "+origX+" "+origY+
|
||||||
|
" C "+
|
||||||
|
cp[0][0]+" "+cp[0][1]+" "+
|
||||||
|
cp[1][0]+" "+cp[1][1]+" "+
|
||||||
|
topX+" "+topY+
|
||||||
|
" S "+
|
||||||
|
cp[2][0]+" "+cp[2][1]+" "+
|
||||||
|
midX+" "+midY+
|
||||||
|
" S "+
|
||||||
|
cp[3][0]+" "+cp[3][1]+" "+
|
||||||
|
bottomX+" "+bottomY+
|
||||||
|
" S "+
|
||||||
|
cp[4][0]+" "+cp[4][1]+" "+
|
||||||
|
destX+" "+destY
|
||||||
|
|
||||||
|
// +genCP(cp[0])+genCP(cp[1])+genCP(cp[2])+genCP(cp[3])+genCP(cp[4])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1722,7 +1770,7 @@ RED.view = (function() {
|
|||||||
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
|
var portY = -((numOutputs-1)/2)*13 +13*sourcePort;
|
||||||
|
|
||||||
var sc = (drag_line.portType === PORT_TYPE_OUTPUT)?1:-1;
|
var sc = (drag_line.portType === PORT_TYPE_OUTPUT)?1:-1;
|
||||||
drag_line.el.attr("d",generateLinkPath(drag_line.node.x+sc*drag_line.node.w/2,drag_line.node.y+portY,mousePos[0],mousePos[1],sc));
|
drag_line.el.attr("d",generateLinkPath(drag_line.node.x+sc*drag_line.node.w/2,drag_line.node.y+portY,mousePos[0],mousePos[1],sc, !!drag_line.node.status));
|
||||||
}
|
}
|
||||||
d3.event.preventDefault();
|
d3.event.preventDefault();
|
||||||
} else if (mouse_mode == RED.state.MOVING) {
|
} else if (mouse_mode == RED.state.MOVING) {
|
||||||
@ -4112,21 +4160,27 @@ RED.view = (function() {
|
|||||||
nodeEl.__statusGroup__.style.display = "none";
|
nodeEl.__statusGroup__.style.display = "none";
|
||||||
} else {
|
} else {
|
||||||
nodeEl.__statusGroup__.style.display = "inline";
|
nodeEl.__statusGroup__.style.display = "inline";
|
||||||
|
let backgroundWidth = 12
|
||||||
var fill = status_colours[d.status.fill]; // Only allow our colours for now
|
var fill = status_colours[d.status.fill]; // Only allow our colours for now
|
||||||
if (d.status.shape == null && fill == null) {
|
if (d.status.shape == null && fill == null) {
|
||||||
|
backgroundWidth = 0
|
||||||
nodeEl.__statusShape__.style.display = "none";
|
nodeEl.__statusShape__.style.display = "none";
|
||||||
|
nodeEl.__statusBackground__.setAttribute("x", 17)
|
||||||
nodeEl.__statusGroup__.setAttribute("transform","translate(-14,"+(d.h+3)+")");
|
nodeEl.__statusGroup__.setAttribute("transform","translate(-14,"+(d.h+3)+")");
|
||||||
} else {
|
} else {
|
||||||
nodeEl.__statusGroup__.setAttribute("transform","translate(3,"+(d.h+3)+")");
|
nodeEl.__statusGroup__.setAttribute("transform","translate(3,"+(d.h+3)+")");
|
||||||
var statusClass = "red-ui-flow-node-status-"+(d.status.shape||"dot")+"-"+d.status.fill;
|
var statusClass = "red-ui-flow-node-status-"+(d.status.shape||"dot")+"-"+d.status.fill;
|
||||||
nodeEl.__statusShape__.style.display = "inline";
|
nodeEl.__statusShape__.style.display = "inline";
|
||||||
nodeEl.__statusShape__.setAttribute("class","red-ui-flow-node-status "+statusClass);
|
nodeEl.__statusShape__.setAttribute("class","red-ui-flow-node-status "+statusClass);
|
||||||
|
nodeEl.__statusBackground__.setAttribute("x", 3)
|
||||||
}
|
}
|
||||||
if (d.status.hasOwnProperty('text')) {
|
if (d.status.hasOwnProperty('text')) {
|
||||||
nodeEl.__statusLabel__.textContent = d.status.text;
|
nodeEl.__statusLabel__.textContent = d.status.text;
|
||||||
} else {
|
} else {
|
||||||
nodeEl.__statusLabel__.textContent = "";
|
nodeEl.__statusLabel__.textContent = "";
|
||||||
}
|
}
|
||||||
|
const textSize = nodeEl.__statusLabel__.getBBox()
|
||||||
|
nodeEl.__statusBackground__.setAttribute('width', backgroundWidth + textSize.width + 6)
|
||||||
}
|
}
|
||||||
delete d.dirtyStatus;
|
delete d.dirtyStatus;
|
||||||
}
|
}
|
||||||
@ -4532,17 +4586,30 @@ RED.view = (function() {
|
|||||||
statusEl.style.display = "none";
|
statusEl.style.display = "none";
|
||||||
node[0][0].__statusGroup__ = statusEl;
|
node[0][0].__statusGroup__ = statusEl;
|
||||||
|
|
||||||
var statusRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
var statusBackground = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
||||||
statusRect.setAttribute("class","red-ui-flow-node-status");
|
statusBackground.setAttribute("class","red-ui-flow-node-status-background");
|
||||||
statusRect.setAttribute("x",6);
|
statusBackground.setAttribute("x",3);
|
||||||
statusRect.setAttribute("y",1);
|
statusBackground.setAttribute("y",-1);
|
||||||
statusRect.setAttribute("width",9);
|
statusBackground.setAttribute("width",200);
|
||||||
statusRect.setAttribute("height",9);
|
statusBackground.setAttribute("height",13);
|
||||||
statusRect.setAttribute("rx",2);
|
statusBackground.setAttribute("rx",1);
|
||||||
statusRect.setAttribute("ry",2);
|
statusBackground.setAttribute("ry",1);
|
||||||
statusRect.setAttribute("stroke-width","3");
|
|
||||||
statusEl.appendChild(statusRect);
|
statusEl.appendChild(statusBackground);
|
||||||
node[0][0].__statusShape__ = statusRect;
|
node[0][0].__statusBackground__ = statusBackground;
|
||||||
|
|
||||||
|
|
||||||
|
var statusIcon = document.createElementNS("http://www.w3.org/2000/svg","rect");
|
||||||
|
statusIcon.setAttribute("class","red-ui-flow-node-status");
|
||||||
|
statusIcon.setAttribute("x",6);
|
||||||
|
statusIcon.setAttribute("y",1);
|
||||||
|
statusIcon.setAttribute("width",9);
|
||||||
|
statusIcon.setAttribute("height",9);
|
||||||
|
statusIcon.setAttribute("rx",2);
|
||||||
|
statusIcon.setAttribute("ry",2);
|
||||||
|
statusIcon.setAttribute("stroke-width","3");
|
||||||
|
statusEl.appendChild(statusIcon);
|
||||||
|
node[0][0].__statusShape__ = statusIcon;
|
||||||
|
|
||||||
var statusLabel = document.createElementNS("http://www.w3.org/2000/svg","text");
|
var statusLabel = document.createElementNS("http://www.w3.org/2000/svg","text");
|
||||||
statusLabel.setAttribute("class","red-ui-flow-node-status-label");
|
statusLabel.setAttribute("class","red-ui-flow-node-status-label");
|
||||||
@ -5067,7 +5134,7 @@ RED.view = (function() {
|
|||||||
// " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+
|
// " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+
|
||||||
// (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+
|
// (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+
|
||||||
// d.x2+" "+d.y2;
|
// d.x2+" "+d.y2;
|
||||||
var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1);
|
var path = generateLinkPath(d.x1,d.y1,d.x2,d.y2,1, !!(d.source.status || d.target.status));
|
||||||
if (/NaN/.test(path)) {
|
if (/NaN/.test(path)) {
|
||||||
path = ""
|
path = ""
|
||||||
}
|
}
|
||||||
|
@ -304,7 +304,11 @@ g.red-ui-flow-node-selected {
|
|||||||
stroke: var(--red-ui-node-status-colors-#{"" + $current-color});
|
stroke: var(--red-ui-node-status-colors-#{"" + $current-color});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.red-ui-flow-node-status-background {
|
||||||
|
stroke: none;
|
||||||
|
fill: var(--red-ui-view-background);
|
||||||
|
fill-opacity: 0.9;
|
||||||
|
}
|
||||||
.red-ui-flow-node-status-label {
|
.red-ui-flow-node-status-label {
|
||||||
@include disable-selection;
|
@include disable-selection;
|
||||||
stroke-width: 0;
|
stroke-width: 0;
|
||||||
|
@ -650,10 +650,9 @@ class Flow {
|
|||||||
// Delegate status to any nodes using this config node
|
// Delegate status to any nodes using this config node
|
||||||
for (let userNode in node.users) {
|
for (let userNode in node.users) {
|
||||||
if (node.users.hasOwnProperty(userNode)) {
|
if (node.users.hasOwnProperty(userNode)) {
|
||||||
node.users[userNode]._flow.handleStatus(node,statusMessage,node.users[userNode],true);
|
handled = node.users[userNode]._flow.handleStatus(node,statusMessage,node.users[userNode],true) || handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handled = true;
|
|
||||||
} else {
|
} else {
|
||||||
const candidateNodes = [];
|
const candidateNodes = [];
|
||||||
this.statusNodes.forEach(targetStatusNode => {
|
this.statusNodes.forEach(targetStatusNode => {
|
||||||
@ -737,10 +736,9 @@ class Flow {
|
|||||||
// Delegate status to any nodes using this config node
|
// Delegate status to any nodes using this config node
|
||||||
for (let userNode in node.users) {
|
for (let userNode in node.users) {
|
||||||
if (node.users.hasOwnProperty(userNode)) {
|
if (node.users.hasOwnProperty(userNode)) {
|
||||||
node.users[userNode]._flow.handleError(node,logMessage,msg,node.users[userNode]);
|
handled = node.users[userNode]._flow.handleError(node,logMessage,msg,node.users[userNode]) || handled;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handled = true;
|
|
||||||
} else {
|
} else {
|
||||||
const candidateNodes = [];
|
const candidateNodes = [];
|
||||||
this.catchNodes.forEach(targetCatchNode => {
|
this.catchNodes.forEach(targetCatchNode => {
|
||||||
|
Loading…
Reference in New Issue
Block a user