',{class:"red-ui-search-result-node"}).appendTo(div);
if (object.type === "junction") {
nodeDiv.addClass("red-ui-palette-icon-junction");
+ } else if (/^_action_:/.test(object.type)) {
+ nodeDiv.addClass("red-ui-palette-icon-junction")
} else {
var colour = RED.utils.getNodeColor(object.type,def);
nodeDiv.css('backgroundColor',colour);
@@ -182,11 +186,14 @@ RED.typeSearch = (function() {
var iconContainer = $('
',{class:"red-ui-palette-icon-container"}).appendTo(nodeDiv);
RED.utils.createIconElement(icon_url, iconContainer, false);
- if (object.type !== "junction" && def.inputs > 0) {
- $('
',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv);
- }
- if (object.type !== "junction" && def.outputs > 0) {
- $('
',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv);
+
+ if (!/^_action_:/.test(object.type) && object.type !== "junction") {
+ if (def.inputs > 0) {
+ $('
',{class:"red-ui-search-result-node-port"}).appendTo(nodeDiv);
+ }
+ if (def.outputs > 0) {
+ $('
',{class:"red-ui-search-result-node-port red-ui-search-result-node-output"}).appendTo(nodeDiv);
+ }
}
var contentDiv = $('
',{class:"red-ui-search-result-description"}).appendTo(div);
@@ -207,7 +214,9 @@ RED.typeSearch = (function() {
}
function confirm(def) {
hide();
- typesUsed[def.type] = Date.now();
+ if (!/^_action_:/.test(def.type)) {
+ typesUsed[def.type] = Date.now();
+ }
addCallback(def.type);
}
@@ -316,6 +325,7 @@ RED.typeSearch = (function() {
function applyFilter(filter,type,def) {
return !filter ||
(
+ (!filter.spliceMultiple) &&
(!filter.type || type === filter.type) &&
(!filter.input || type === 'junction' || def.inputs > 0) &&
(!filter.output || type === 'junction' || def.outputs > 0)
@@ -330,6 +340,13 @@ RED.typeSearch = (function() {
'inject','debug','function','change','switch','junction'
].filter(function(t) { return applyFilter(opts.filter,t,RED.nodes.getType(t)); });
+ // if (opts.filter && opts.filter.input && opts.filter.output && !opts.filter.type) {
+ // if (opts.filter.spliceMultiple) {
+ // common.push('_action_:core:split-wires-with-junctions')
+ // }
+ // common.push('_action_:core:split-wire-with-link-nodes')
+ // }
+
var recentlyUsed = Object.keys(typesUsed);
recentlyUsed.sort(function(a,b) {
return typesUsed[b]-typesUsed[a];
@@ -354,6 +371,8 @@ RED.typeSearch = (function() {
var itemDef = RED.nodes.getType(common[i]);
if (common[i] === 'junction') {
itemDef = { inputs:1, outputs: 1, label: 'junction', type: 'junction'}
+ } else if (/^_action_:/.test(common[i]) ) {
+ itemDef = { inputs:1, outputs: 1, label: common[i], type: common[i]}
}
if (itemDef) {
item = {
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
index c3ea0ddd1..2c4cdca6b 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
@@ -1032,6 +1032,8 @@ RED.utils = (function() {
return "font-awesome/fa-circle-o"
} else if (def.category === 'config') {
return RED.settings.apiRootUrl+"icons/node-red/cog.svg"
+ } else if ((node && /^_action_:/.test(node.type)) || /^_action_:/.test(def.type)) {
+ return "font-awesome/fa-cogs"
} else if (node && node.type === 'tab') {
return "red-ui-icons/red-ui-icons-flow"
// return RED.settings.apiRootUrl+"images/subflow_tab.svg"
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js
index 699e5f222..888fb4d7f 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view-tools.js
@@ -336,17 +336,17 @@ RED.view.tools = (function() {
}
- function addNode() {
- var selection = RED.view.selection();
- if (selection.nodes && selection.nodes.length === 1 && selection.nodes[0].outputs > 0) {
- var selectedNode = selection.nodes[0];
- RED.view.showQuickAddDialog([
- selectedNode.x + selectedNode.w + 50,selectedNode.y
- ])
- } else {
- RED.view.showQuickAddDialog();
- }
- }
+ // function addNode() {
+ // var selection = RED.view.selection();
+ // if (selection.nodes && selection.nodes.length === 1 && selection.nodes[0].outputs > 0) {
+ // var selectedNode = selection.nodes[0];
+ // RED.view.showQuickAddDialog([
+ // selectedNode.x + selectedNode.w + 50,selectedNode.y
+ // ])
+ // } else {
+ // RED.view.showQuickAddDialog();
+ // }
+ // }
function gotoNearestNode(direction) {
@@ -815,6 +815,9 @@ RED.view.tools = (function() {
*/
function splitWiresWithLinkNodes(wires) {
let wiresToSplit = wires || RED.view.selection().links;
+ if (!wiresToSplit) {
+ return
+ }
if (!Array.isArray(wiresToSplit)) {
wiresToSplit = [wiresToSplit];
}
@@ -1047,6 +1050,135 @@ RED.view.tools = (function() {
}
}
+ function addJunctionsToWires(wires) {
+ let wiresToSplit = wires || RED.view.selection().links;
+ if (!wiresToSplit) {
+ return
+ }
+ if (!Array.isArray(wiresToSplit)) {
+ wiresToSplit = [wiresToSplit];
+ }
+ if (wiresToSplit.length === 0) {
+ return;
+ }
+
+ var removedLinks = new Set()
+ var addedLinks = []
+ var addedJunctions = []
+
+ var groupedLinks = {}
+ wiresToSplit.forEach(function(l) {
+ var sourceId = l.source.id+":"+l.sourcePort
+ groupedLinks[sourceId] = groupedLinks[sourceId] || []
+ groupedLinks[sourceId].push(l)
+
+ groupedLinks[l.target.id] = groupedLinks[l.target.id] || []
+ groupedLinks[l.target.id].push(l)
+ });
+ var linkGroups = Object.keys(groupedLinks)
+ linkGroups.sort(function(A,B) {
+ return groupedLinks[B].length - groupedLinks[A].length
+ })
+ linkGroups.forEach(function(gid) {
+ var links = groupedLinks[gid]
+ var junction = {
+ _def: {defaults:{}},
+ type: 'junction',
+ z: RED.workspaces.active(),
+ id: RED.nodes.id(),
+ x: 0,
+ y: 0,
+ w: 0, h: 0,
+ outputs: 1,
+ inputs: 1,
+ dirty: true
+ }
+ links = links.filter(function(l) { return !removedLinks.has(l) })
+ if (links.length === 0) {
+ return
+ }
+ let pointCount = 0
+ links.forEach(function(l) {
+ if (l._sliceLocation) {
+ junction.x += l._sliceLocation.x
+ junction.y += l._sliceLocation.y
+ delete l._sliceLocation
+ pointCount++
+ } else {
+ junction.x += l.source.x + l.source.w/2 + l.target.x - l.target.w/2
+ junction.y += l.source.y + l.target.y
+ pointCount += 2
+ }
+ })
+ junction.x = Math.round(junction.x/pointCount)
+ junction.y = Math.round(junction.y/pointCount)
+ if (RED.view.snapGrid) {
+ let gridSize = RED.view.gridSize()
+ junction.x = (gridSize*Math.round(junction.x/gridSize));
+ junction.y = (gridSize*Math.round(junction.y/gridSize));
+ }
+
+ var nodeGroups = new Set()
+
+ RED.nodes.addJunction(junction)
+ addedJunctions.push(junction)
+ let newLink
+ if (gid === links[0].source.id+":"+links[0].sourcePort) {
+ newLink = {
+ source: links[0].source,
+ sourcePort: links[0].sourcePort,
+ target: junction
+ }
+ } else {
+ newLink = {
+ source: junction,
+ sourcePort: 0,
+ target: links[0].target
+ }
+ }
+ addedLinks.push(newLink)
+ RED.nodes.addLink(newLink)
+ links.forEach(function(l) {
+ removedLinks.add(l)
+ RED.nodes.removeLink(l)
+ let newLink
+ if (gid === l.target.id) {
+ newLink = {
+ source: l.source,
+ sourcePort: l.sourcePort,
+ target: junction
+ }
+ } else {
+ newLink = {
+ source: junction,
+ sourcePort: 0,
+ target: l.target
+ }
+ }
+ addedLinks.push(newLink)
+ RED.nodes.addLink(newLink)
+ nodeGroups.add(l.source.g || "__NONE__")
+ nodeGroups.add(l.target.g || "__NONE__")
+ })
+ if (nodeGroups.size === 1) {
+ var group = nodeGroups.values().next().value
+ if (group !== "__NONE__") {
+ RED.group.addToGroup(RED.nodes.group(group), junction)
+ }
+ }
+ })
+ if (addedJunctions.length > 0) {
+ RED.history.push({
+ t: 'add',
+ links: addedLinks,
+ junctions: addedJunctions,
+ removedLinks: Array.from(removedLinks)
+ })
+ RED.nodes.dirty(true)
+ }
+ RED.view.redraw(true);
+ }
+
return {
init: function() {
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
@@ -1109,6 +1241,7 @@ RED.view.tools = (function() {
RED.actions.add("core:wire-node-to-multiple", function() { wireNodeToMultiple() })
RED.actions.add("core:split-wire-with-link-nodes", function () { splitWiresWithLinkNodes() });
+ RED.actions.add("core:split-wires-with-junctions", function () { addJunctionsToWires() });
RED.actions.add("core:generate-node-names", generateNodeNames )
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 5ac9525ff..9f28d7191 100755
--- 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
@@ -206,7 +206,15 @@ RED.view = (function() {
function init() {
chart = $("#red-ui-workspace-chart");
-
+ chart.on('contextmenu', function(evt) {
+ evt.preventDefault()
+ evt.stopPropagation()
+ RED.contextMenu.show({
+ x:evt.clientX-5,
+ y:evt.clientY-5
+ })
+ return false
+ })
outer = d3.select("#red-ui-workspace-chart")
.append("svg:svg")
.attr("width", space_width)
@@ -992,7 +1000,10 @@ RED.view = (function() {
scroll_position = [chart.scrollLeft(),chart.scrollTop()];
return;
}
- if (!mousedown_node && !mousedown_link && !mousedown_group) {
+ if (d3.event.button === 2) {
+ return
+ }
+ if (!mousedown_node && !mousedown_link && !mousedown_group && !d3.event.shiftKey) {
selectedLinks.clear();
updateSelection();
}
@@ -1046,6 +1057,7 @@ RED.view = (function() {
options = options || {};
var point = options.position || lastClickPosition;
var spliceLink = options.splice;
+ var spliceMultipleLinks = options.spliceMultiple
var targetGroup = options.group;
var touchTrigger = options.touchTrigger;
@@ -1058,6 +1070,10 @@ RED.view = (function() {
var ox = point[0];
var oy = point[1];
+ const offset = $("#red-ui-workspace-chart").offset()
+ var clientX = ox + offset.left
+ var clientY = oy + offset.top
+
if (RED.settings.get("editor").view['view-snap-grid']) {
// eventLayer.append("circle").attr("cx",point[0]).attr("cy",point[1]).attr("r","2").attr('fill','red')
point[0] = Math.round(point[0] / gridSize) * gridSize;
@@ -1109,8 +1125,12 @@ RED.view = (function() {
}
hideDragLines();
}
- if (spliceLink) {
- filter = {input:true, output:true}
+ if (spliceLink || spliceMultipleLinks) {
+ filter = {
+ input:true,
+ output:true,
+ spliceMultiple: spliceMultipleLinks
+ }
}
var rebuildQuickAddLink = function() {
@@ -1135,8 +1155,8 @@ RED.view = (function() {
var lastAddedWidth;
RED.typeSearch.show({
- x:d3.event.clientX-mainPos.left-node_width/2 - (ox-point[0]),
- y:d3.event.clientY-mainPos.top+ node_height/2 + 5 - (oy-point[1]),
+ x:clientX-mainPos.left-node_width/2 - (ox-point[0]),
+ y:clientY-mainPos.top+ node_height/2 + 5 - (oy-point[1]),
disableFocus: touchTrigger,
filter: filter,
move: function(dx,dy) {
@@ -1164,7 +1184,7 @@ RED.view = (function() {
hideDragLines();
redraw();
},
- add: function(type,keepAdding) {
+ add: function(type, keepAdding) {
if (touchTrigger) {
keepAdding = false;
resetMouseVars();
@@ -1172,7 +1192,13 @@ RED.view = (function() {
var nn;
var historyEvent;
- if (type === 'junction') {
+ if (/^_action_:/.test(type)) {
+ const actionName = type.substring(9)
+ quickAddActive = false;
+ ghostNode.remove();
+ RED.actions.invoke(actionName)
+ return
+ } else if (type === 'junction') {
nn = {
_def: {defaults:{}},
type: 'junction',
@@ -1844,8 +1870,20 @@ RED.view = (function() {
}
}
})
-
-
+ activeLinks.forEach(function(link) {
+ if (!link.selected) {
+ var sourceY = link.source.y
+ var targetY = link.target.y
+ var sourceX = link.source.x+(link.source.w/2) + 10
+ var targetX = link.target.x-(link.target.w/2) - 10
+ if (
+ sourceX > x && sourceX < x2 && sourceY > y && sourceY < y2 &&
+ targetX > x && targetX < x2 && targetY > y && targetY < y2
+ ) {
+ selectedLinks.add(link);
+ }
+ }
+ })
// var selectionChanged = false;
// do {
@@ -1893,114 +1931,118 @@ RED.view = (function() {
slicePath = null;
RED.view.redraw(true);
} else if (mouse_mode == RED.state.SLICING_JUNCTION) {
- var removedLinks = new Set()
- var addedLinks = []
- var addedJunctions = []
-
- var groupedLinks = {}
- selectedLinks.forEach(function(l) {
- var sourceId = l.source.id+":"+l.sourcePort
- groupedLinks[sourceId] = groupedLinks[sourceId] || []
- groupedLinks[sourceId].push(l)
-
- groupedLinks[l.target.id] = groupedLinks[l.target.id] || []
- groupedLinks[l.target.id].push(l)
- });
- var linkGroups = Object.keys(groupedLinks)
- linkGroups.sort(function(A,B) {
- return groupedLinks[B].length - groupedLinks[A].length
- })
- linkGroups.forEach(function(gid) {
- var links = groupedLinks[gid]
- var junction = {
- _def: {defaults:{}},
- type: 'junction',
- z: RED.workspaces.active(),
- id: RED.nodes.id(),
- x: 0,
- y: 0,
- w: 0, h: 0,
- outputs: 1,
- inputs: 1,
- dirty: true
- }
- links = links.filter(function(l) { return !removedLinks.has(l) })
- if (links.length === 0) {
- return
- }
- links.forEach(function(l) {
- junction.x += l._sliceLocation.x
- junction.y += l._sliceLocation.y
- })
- junction.x = Math.round(junction.x/links.length)
- junction.y = Math.round(junction.y/links.length)
- if (snapGrid) {
- junction.x = (gridSize*Math.round(junction.x/gridSize));
- junction.y = (gridSize*Math.round(junction.y/gridSize));
- }
-
- var nodeGroups = new Set()
-
- RED.nodes.addJunction(junction)
- addedJunctions.push(junction)
- let newLink
- if (gid === links[0].source.id+":"+links[0].sourcePort) {
- newLink = {
- source: links[0].source,
- sourcePort: links[0].sourcePort,
- target: junction
- }
- } else {
- newLink = {
- source: junction,
- sourcePort: 0,
- target: links[0].target
- }
- }
- addedLinks.push(newLink)
- RED.nodes.addLink(newLink)
- links.forEach(function(l) {
- removedLinks.add(l)
- RED.nodes.removeLink(l)
- let newLink
- if (gid === l.target.id) {
- newLink = {
- source: l.source,
- sourcePort: l.sourcePort,
- target: junction
- }
- } else {
- newLink = {
- source: junction,
- sourcePort: 0,
- target: l.target
- }
- }
- addedLinks.push(newLink)
- RED.nodes.addLink(newLink)
- nodeGroups.add(l.source.g || "__NONE__")
- nodeGroups.add(l.target.g || "__NONE__")
- })
- if (nodeGroups.size === 1) {
- var group = nodeGroups.values().next().value
- if (group !== "__NONE__") {
- RED.group.addToGroup(RED.nodes.group(group), junction)
- }
- }
- })
+ RED.actions.invoke("core:split-wires-with-junctions")
slicePath.remove();
slicePath = null;
- if (addedJunctions.length > 0) {
- RED.history.push({
- t: 'add',
- links: addedLinks,
- junctions: addedJunctions,
- removedLinks: Array.from(removedLinks)
- })
- RED.nodes.dirty(true)
- }
- RED.view.redraw(true);
+ // var removedLinks = new Set()
+ // var addedLinks = []
+ // var addedJunctions = []
+ //
+ // var groupedLinks = {}
+ // selectedLinks.forEach(function(l) {
+ // var sourceId = l.source.id+":"+l.sourcePort
+ // groupedLinks[sourceId] = groupedLinks[sourceId] || []
+ // groupedLinks[sourceId].push(l)
+ //
+ // groupedLinks[l.target.id] = groupedLinks[l.target.id] || []
+ // groupedLinks[l.target.id].push(l)
+ // });
+ // var linkGroups = Object.keys(groupedLinks)
+ // linkGroups.sort(function(A,B) {
+ // return groupedLinks[B].length - groupedLinks[A].length
+ // })
+ // linkGroups.forEach(function(gid) {
+ // var links = groupedLinks[gid]
+ // var junction = {
+ // _def: {defaults:{}},
+ // type: 'junction',
+ // z: RED.workspaces.active(),
+ // id: RED.nodes.id(),
+ // x: 0,
+ // y: 0,
+ // w: 0, h: 0,
+ // outputs: 1,
+ // inputs: 1,
+ // dirty: true
+ // }
+ // links = links.filter(function(l) { return !removedLinks.has(l) })
+ // if (links.length === 0) {
+ // return
+ // }
+ // links.forEach(function(l) {
+ // junction.x += l._sliceLocation.x
+ // junction.y += l._sliceLocation.y
+ // })
+ // junction.x = Math.round(junction.x/links.length)
+ // junction.y = Math.round(junction.y/links.length)
+ // if (snapGrid) {
+ // junction.x = (gridSize*Math.round(junction.x/gridSize));
+ // junction.y = (gridSize*Math.round(junction.y/gridSize));
+ // }
+ //
+ // var nodeGroups = new Set()
+ //
+ // RED.nodes.addJunction(junction)
+ // addedJunctions.push(junction)
+ // let newLink
+ // if (gid === links[0].source.id+":"+links[0].sourcePort) {
+ // newLink = {
+ // source: links[0].source,
+ // sourcePort: links[0].sourcePort,
+ // target: junction
+ // }
+ // } else {
+ // newLink = {
+ // source: junction,
+ // sourcePort: 0,
+ // target: links[0].target
+ // }
+ // }
+ // addedLinks.push(newLink)
+ // RED.nodes.addLink(newLink)
+ // links.forEach(function(l) {
+ // removedLinks.add(l)
+ // RED.nodes.removeLink(l)
+ // let newLink
+ // if (gid === l.target.id) {
+ // newLink = {
+ // source: l.source,
+ // sourcePort: l.sourcePort,
+ // target: junction
+ // }
+ // } else {
+ // newLink = {
+ // source: junction,
+ // sourcePort: 0,
+ // target: l.target
+ // }
+ // }
+ // addedLinks.push(newLink)
+ // RED.nodes.addLink(newLink)
+ // nodeGroups.add(l.source.g || "__NONE__")
+ // nodeGroups.add(l.target.g || "__NONE__")
+ // })
+ // if (nodeGroups.size === 1) {
+ // var group = nodeGroups.values().next().value
+ // if (group !== "__NONE__") {
+ // RED.group.addToGroup(RED.nodes.group(group), junction)
+ // }
+ // }
+ // })
+ // slicePath.remove();
+ // slicePath = null;
+ //
+ // if (addedJunctions.length > 0) {
+ // RED.history.push({
+ // t: 'add',
+ // links: addedLinks,
+ // junctions: addedJunctions,
+ // removedLinks: Array.from(removedLinks)
+ // })
+ // RED.nodes.dirty(true)
+ // }
+ // RED.view.redraw(true);
}
if (mouse_mode == RED.state.MOVING_ACTIVE) {
if (movingSet.length() > 0) {
diff --git a/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss b/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss
index 98ab3bd3b..4104fd83e 100644
--- a/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss
+++ b/packages/node_modules/@node-red/editor-client/src/sass/dropdownMenu.scss
@@ -46,7 +46,7 @@
& > li > a,
& > li > a:focus {
display: block;
- padding: 4px 12px 4px 32px;
+ padding: 4px 20px 4px 12px;
clear: both;
font-weight: normal;
line-height: 20px;
@@ -54,7 +54,10 @@
white-space: normal !important;
outline: none;
}
-
+ & > li.pull-left > a,
+ & > li.pull-left > a:focus {
+ padding: 4px 12px 4px 32px;
+ }
& > .active > a,
& > .active > a:hover,
& > .active > a:focus {
@@ -145,8 +148,8 @@
position: relative;
& > .red-ui-menu-dropdown {
top: 0;
- left: 100%;
- margin-top: -6px;
+ left: calc(100% - 5px);
+ margin-top: 0;
margin-left: -1px;
}
&.open > .red-ui-menu-dropdown,
@@ -175,10 +178,10 @@
}
}
-.red-ui-menu-dropdown-submenu>a:after {
+.red-ui-menu-dropdown-submenu.pull-left>a:after {
display: none;
}
-.red-ui-menu-dropdown-submenu>a:before {
+.red-ui-menu-dropdown-submenu.pull-left>a:before {
display: block;
float: left;
width: 0;
@@ -192,7 +195,25 @@
border-width: 5px 5px 5px 0;
content: " ";
}
-
+.red-ui-menu-dropdown-direction-right {
+ .red-ui-menu-dropdown-submenu>a:after {
+ display: none;
+ }
+ .red-ui-menu-dropdown-submenu>a:before {
+ display: block;
+ float: right;
+ width: 0;
+ height: 0;
+ margin-top: 5px;
+ margin-right: -15px;
+ /* Caret Arrow */
+ border-color: transparent;
+ border-left-color: $menuCaret;
+ border-style: solid;
+ border-width: 5px 0 5px 5px;
+ content: " ";
+ }
+}
.red-ui-menu-dropdown-submenu.disabled > a:before {
border-right-color: $menuCaret;
}