mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add right-click context menu to workspace
This commit is contained in:
		| @@ -192,6 +192,7 @@ module.exports = function(grunt) { | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/library.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/notifications.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/search.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/actionList.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/typeSearch.js", | ||||
|                     "packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js", | ||||
|   | ||||
							
								
								
									
										175
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/contextMenu.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,175 @@ | ||||
| RED.contextMenu = (function() { | ||||
|  | ||||
|     let menu; | ||||
|     function createMenu() { | ||||
|         // menu = RED.popover.menu({ | ||||
|         //     options: [ | ||||
|         //         { | ||||
|         //             label: 'delete selection', | ||||
|         //             onselect: function() { | ||||
|         //                 RED.actions.invoke('core:delete-selection') | ||||
|         //                 RED.view.focus() | ||||
|         //             } | ||||
|         //         }, | ||||
|         //         { label: 'world' } | ||||
|         //     ], | ||||
|         //     width: 200, | ||||
|         // }) | ||||
|  | ||||
|  | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     function disposeMenu() { | ||||
|         $(document).off("mousedown.red-ui-workspace-context-menu"); | ||||
|         if (menu) { | ||||
|             menu.remove(); | ||||
|         } | ||||
|         menu = null; | ||||
|     } | ||||
|     function show(options) { | ||||
|         if (menu) { | ||||
|             menu.remove() | ||||
|         } | ||||
|  | ||||
|         const selection = RED.view.selection() | ||||
|         const hasSelection = (selection.nodes && selection.nodes.length > 0); | ||||
|         const hasMultipleSelection = hasSelection && selection.nodes.length > 1; | ||||
|         const hasLinks = selection.links && selection.links.length > 0; | ||||
|         const isSingleLink = !hasSelection && hasLinks && selection.links.length === 1 | ||||
|         const isMultipleLinks = !hasSelection && hasLinks && selection.links.length > 1 | ||||
|         const canDelete = hasSelection || hasLinks | ||||
|         const isGroup = hasSelection && selection.nodes.length === 1 && selection.nodes[0].type === 'group' | ||||
|  | ||||
|         const canRemoveFromGroup = hasSelection && !!selection.nodes[0].g | ||||
|  | ||||
|  | ||||
|         const menuItems = [ | ||||
|             { onselect: 'core:show-action-list', onpostselect: function() {} }, | ||||
|             { | ||||
|                 label: 'Insert', | ||||
|                 options: [ | ||||
|                     { | ||||
|                         label: 'Node', | ||||
|                         onselect: function() { | ||||
|                             RED.view.showQuickAddDialog({ | ||||
|                                 position: [ options.x - offset.left, options.y - offset.top ], | ||||
|                                 touchTrigger: true, | ||||
|                                 splice: isSingleLink?selection.links[0]:undefined, | ||||
|                                 // spliceMultiple: isMultipleLinks | ||||
|                             }) | ||||
|                         } | ||||
|                     }, | ||||
|                     { | ||||
|                         label: 'Junction', | ||||
|                         onselect: 'core:split-wires-with-junctions', | ||||
|                         disabled: hasSelection || !hasLinks | ||||
|                     }, | ||||
|                     { | ||||
|                         label: 'Link Nodes', | ||||
|                         onselect: 'core:split-wire-with-link-nodes', | ||||
|                         disabled: hasSelection || !hasLinks | ||||
|                     } | ||||
|                 ] | ||||
|  | ||||
|  | ||||
|  | ||||
|             } | ||||
|         ] | ||||
|         // menuItems.push( | ||||
|         //     { | ||||
|         //         label: (isSingleLink || isMultipleLinks)?'Insert into wire...':'Add node...', | ||||
|         //         onselect: function() { | ||||
|         //             RED.view.showQuickAddDialog({ | ||||
|         //                 position: [ options.x - offset.left, options.y - offset.top ], | ||||
|         //                 touchTrigger: true, | ||||
|         //                 splice: isSingleLink?selection.links[0]:undefined, | ||||
|         //                 spliceMultiple: isMultipleLinks | ||||
|         //             }) | ||||
|         //         } | ||||
|         //     }, | ||||
|         // ) | ||||
|         // if (hasLinks && !hasSelection) { | ||||
|         //     menuItems.push({ onselect: 'core:split-wires-with-junctions', label: 'Insert junction'}) | ||||
|         // } | ||||
|         menuItems.push( | ||||
|             null, | ||||
|             { onselect: 'core:undo', disabled: RED.history.list().length === 0 }, | ||||
|             { onselect: 'core:redo', disabled: RED.history.listRedo().length === 0 }, | ||||
|             null, | ||||
|             { onselect: 'core:cut-selection-to-internal-clipboard', label: RED._("keyboard.cutNode"), disabled: !hasSelection}, | ||||
|             { onselect: 'core:copy-selection-to-internal-clipboard', label: RED._("keyboard.copyNode"), disabled: !hasSelection }, | ||||
|             { onselect: 'core:paste-from-internal-clipboard', label: RED._("keyboard.pasteNode"), disabled: !RED.view.clipboard() }, | ||||
|             { onselect: 'core:delete-selection', disabled: !canDelete }, | ||||
|             { onselect: 'core:show-export-dialog', label: RED._("menu.label.export") }, | ||||
|             { onselect: 'core:select-all-nodes' }, | ||||
|         ) | ||||
|  | ||||
|         if (hasSelection) { | ||||
|             menuItems.push( | ||||
|                 null, | ||||
|                 isGroup | ||||
|                 ? { onselect: 'core:ungroup-selection', disabled: !isGroup } | ||||
|                 : { onselect: 'core:group-selection', disabled: !hasSelection } | ||||
|             ) | ||||
|             if (canRemoveFromGroup) { | ||||
|                 menuItems.push({ onselect: 'core:remove-selection-from-group', label: RED._("menu.label.groupRemoveSelection") }) | ||||
|             } | ||||
|  | ||||
|         } | ||||
|         const offset = $("#red-ui-workspace-chart").offset() | ||||
|         menu = RED.menu.init({ | ||||
|             direction: 'right', | ||||
|             onpreselect: function() { | ||||
|                 disposeMenu() | ||||
|             }, | ||||
|             onpostselect: function() { | ||||
|                 RED.view.focus() | ||||
|             }, | ||||
|             options: menuItems | ||||
|         }); | ||||
|  | ||||
|         menu.attr("id","red-ui-workspace-context-menu"); | ||||
|         menu.css({ | ||||
|             position: "absolute" | ||||
|         }) | ||||
|         menu.appendTo("body"); | ||||
|  | ||||
|         // TODO: prevent the menu from overflowing the window. | ||||
|  | ||||
|         var top = options.y | ||||
|         var left = options.x | ||||
|  | ||||
|         if (top+menu.height()-$(document).scrollTop() > $(window).height()) { | ||||
|             top -= (top+menu.height())-$(window).height() + 22; | ||||
|         } | ||||
|         if (left+menu.width()-$(document).scrollLeft() > $(window).width()) { | ||||
|             left -= (left+menu.width())-$(window).width() + 18; | ||||
|         } | ||||
|         menu.css({ | ||||
|             top: top+"px", | ||||
|             left: left+"px" | ||||
|         }) | ||||
|         $(".red-ui-menu.red-ui-menu-dropdown").hide(); | ||||
|         $(document).on("mousedown.red-ui-workspace-context-menu", function(evt) { | ||||
|             if (menu && menu[0].contains(evt.target)) { | ||||
|                 return | ||||
|             } | ||||
|             disposeMenu() | ||||
|         }); | ||||
|         menu.show(); | ||||
|  | ||||
|         // menu.show({ | ||||
|         //     target: $('#red-ui-main-container'), | ||||
|         //     x: options.x, | ||||
|         //     y: options.y | ||||
|         // }) | ||||
|  | ||||
|  | ||||
|     } | ||||
|  | ||||
|     return { | ||||
|         show: show | ||||
|     } | ||||
| })() | ||||
| @@ -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 ) | ||||
|  | ||||
|   | ||||
| @@ -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) { | ||||
|   | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user