mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Compare commits
	
		
			5 Commits
		
	
	
		
			undo-histo
			...
			phase-out-
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2350540a98 | ||
| 
						 | 
					c021c4020e | ||
| 
						 | 
					11a6925ae4 | ||
| 
						 | 
					24ff5262d9 | ||
| 
						 | 
					c24d7fafa9 | 
@@ -152,6 +152,7 @@ module.exports = function(grunt) {
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/history.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/validators.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/ui/utils.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/ui/utils-domselection.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/ui/common/editableList.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/ui/common/treeList.js",
 | 
			
		||||
                    "packages/node_modules/@node-red/editor-client/src/js/ui/common/checkboxSet.js",
 | 
			
		||||
 
 | 
			
		||||
@@ -267,7 +267,7 @@ RED.keyboard = (function() {
 | 
			
		||||
                    return resolveKeyEvent(evt);
 | 
			
		||||
                }
 | 
			
		||||
                if (Object.keys(handler).length > 0) {
 | 
			
		||||
                    // check if there's a potential combined handler initiated by this keyCode 
 | 
			
		||||
                    // check if there's a potential combined handler initiated by this keyCode
 | 
			
		||||
                    for (let h in handler) {
 | 
			
		||||
                        if (matchHandlerToEvent(evt,handler[h]) > -1) {
 | 
			
		||||
                            partialState = handler;
 | 
			
		||||
@@ -298,21 +298,21 @@ RED.keyboard = (function() {
 | 
			
		||||
            return resolveKeyEvent(evt);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    d3.select(window).on("keydown",function() {
 | 
			
		||||
    document.addEventListener("keydown", function(event) {
 | 
			
		||||
        if (!handlersActive) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (metaKeyCodes[d3.event.keyCode]) {
 | 
			
		||||
        if (metaKeyCodes[event.keyCode]) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        var handler = resolveKeyEvent(d3.event);
 | 
			
		||||
        var handler = resolveKeyEvent(event);
 | 
			
		||||
        if (handler && handler.ondown) {
 | 
			
		||||
            if (typeof handler.ondown === "string") {
 | 
			
		||||
                RED.actions.invoke(handler.ondown);
 | 
			
		||||
            } else {
 | 
			
		||||
                handler.ondown();
 | 
			
		||||
            }
 | 
			
		||||
            d3.event.preventDefault();
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -299,7 +299,7 @@ RED.palette = (function() {
 | 
			
		||||
                    RED.view.focus();
 | 
			
		||||
                },
 | 
			
		||||
                stop: function() {
 | 
			
		||||
                    d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
 | 
			
		||||
                    document.querySelectorAll(".red-ui-flow-link-splice").forEach(n => { n.classList.remove("red-ui-flow-link-splice") })
 | 
			
		||||
                    if (hoverGroup) {
 | 
			
		||||
                        document.getElementById("group_select_"+hoverGroup.id).classList.remove("red-ui-flow-group-hovered");
 | 
			
		||||
                    }
 | 
			
		||||
@@ -358,26 +358,26 @@ RED.palette = (function() {
 | 
			
		||||
                                var mx = mouseX / RED.view.scale();
 | 
			
		||||
                                var my = mouseY / RED.view.scale();
 | 
			
		||||
                                for (var i=0;i<nodes.length;i++) {
 | 
			
		||||
                                    var node = d3.select(nodes[i]);
 | 
			
		||||
                                    if (node.classed('red-ui-flow-link-background') && !node.classed('red-ui-flow-link-link')) {
 | 
			
		||||
                                        var length = nodes[i].getTotalLength();
 | 
			
		||||
                                    var node = nodes[i];
 | 
			
		||||
                                    if (node.classList.contains('red-ui-flow-link-background') && !node.classList.contains('red-ui-flow-link-link')) {
 | 
			
		||||
                                        var length = node.getTotalLength();
 | 
			
		||||
                                        for (var j=0;j<length;j+=10) {
 | 
			
		||||
                                            var p = nodes[i].getPointAtLength(j);
 | 
			
		||||
                                            var p = node.getPointAtLength(j);
 | 
			
		||||
                                            var d2 = ((p.x-mx)*(p.x-mx))+((p.y-my)*(p.y-my));
 | 
			
		||||
                                            if (d2 < 200 && d2 < bestDistance) {
 | 
			
		||||
                                                bestDistance = d2;
 | 
			
		||||
                                                bestLink = nodes[i];
 | 
			
		||||
                                                bestLink = node;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
                                if (activeSpliceLink && activeSpliceLink !== bestLink) {
 | 
			
		||||
                                    d3.select(activeSpliceLink.parentNode).classed('red-ui-flow-link-splice',false);
 | 
			
		||||
                                    activeSpliceLink.parentNode.classList.remove('red-ui-flow-link-splice');
 | 
			
		||||
                                }
 | 
			
		||||
                                if (bestLink) {
 | 
			
		||||
                                    d3.select(bestLink.parentNode).classed('red-ui-flow-link-splice',true)
 | 
			
		||||
                                    bestLink.parentNode.classList.add('red-ui-flow-link-splice');
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    d3.select('.red-ui-flow-link-splice').classed('red-ui-flow-link-splice',false);
 | 
			
		||||
                                    document.querySelectorAll(".red-ui-flow-link-splice").forEach(n => { n.classList.remove("red-ui-flow-link-splice") })
 | 
			
		||||
                                }
 | 
			
		||||
                                if (activeSpliceLink !== bestLink) {
 | 
			
		||||
                                    if (bestLink) {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,26 +27,24 @@ RED.touch.radialMenu = (function() {
 | 
			
		||||
    function createRadial(obj,pos,options) {
 | 
			
		||||
        isActive = true;
 | 
			
		||||
        try {
 | 
			
		||||
            touchMenu = d3.select("body").append("div").classed("red-ui-editor-radial-menu",true)
 | 
			
		||||
                .on('touchstart',function() {
 | 
			
		||||
            touchMenu = $('<div>', {class: 'red-ui-editor-radial-menu'}).appendTo('body')
 | 
			
		||||
                .on('touchstart',function(evt) {
 | 
			
		||||
                    hide();
 | 
			
		||||
                    d3.event.preventDefault();
 | 
			
		||||
                    evt.preventDefault();
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var menu = touchMenu.append("div")
 | 
			
		||||
                .style({
 | 
			
		||||
            var menu = $('<div>').appendTo(touchMenu).css({
 | 
			
		||||
                    top: (pos[1]-80)+"px",
 | 
			
		||||
                    left:(pos[0]-80)+"px",
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
            var menuOpts = [];
 | 
			
		||||
            var createMenuOpt = function(x,y,opt) {
 | 
			
		||||
                opt.el = menu.append("div").classed("red-ui-editor-radial-menu-opt",true)
 | 
			
		||||
                    .style({
 | 
			
		||||
                opt.el = $('<div>', {class: 'red-ui-editor-radial-menu-opt'}).appendTo(menu)
 | 
			
		||||
                    .css({
 | 
			
		||||
                        top: (y+80-25)+"px",
 | 
			
		||||
                        left:(x+80-25)+"px"
 | 
			
		||||
                    })
 | 
			
		||||
                    .classed("red-ui-editor-radial-menu-opt-disabled",!!opt.disabled)
 | 
			
		||||
                    .toggleClass("red-ui-editor-radial-menu-opt-disabled",!!opt.disabled)
 | 
			
		||||
 | 
			
		||||
                opt.el.html(opt.name);
 | 
			
		||||
 | 
			
		||||
@@ -54,16 +52,16 @@ RED.touch.radialMenu = (function() {
 | 
			
		||||
                opt.y = y;
 | 
			
		||||
                menuOpts.push(opt);
 | 
			
		||||
 | 
			
		||||
                opt.el.on('touchstart',function() {
 | 
			
		||||
                    opt.el.classed("red-ui-editor-radial-menu-opt-active",true)
 | 
			
		||||
                    d3.event.preventDefault();
 | 
			
		||||
                    d3.event.stopPropagation();
 | 
			
		||||
                opt.el.on('touchstart',function(evt) {
 | 
			
		||||
                    opt.el.toggleClass("red-ui-editor-radial-menu-opt-active",true)
 | 
			
		||||
                    evt.preventDefault();
 | 
			
		||||
                    evt.stopPropagation();
 | 
			
		||||
                });
 | 
			
		||||
                opt.el.on('touchend',function() {
 | 
			
		||||
                opt.el.on('touchend',function(evt) {
 | 
			
		||||
                    hide();
 | 
			
		||||
                    opt.onselect();
 | 
			
		||||
                    d3.event.preventDefault();
 | 
			
		||||
                    d3.event.stopPropagation();
 | 
			
		||||
                    evt.preventDefault();
 | 
			
		||||
                    evt.stopPropagation();
 | 
			
		||||
                });
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
@@ -88,8 +86,8 @@ RED.touch.radialMenu = (function() {
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            obj.on('touchend.radial',function() {
 | 
			
		||||
                    obj.on('touchend.radial',null);
 | 
			
		||||
                    obj.on('touchmenu.radial',null);
 | 
			
		||||
                    obj.off('touchend.radial');
 | 
			
		||||
                    obj.off('touchmenu.radial');
 | 
			
		||||
 | 
			
		||||
                    if (activeOption) {
 | 
			
		||||
                        try {
 | 
			
		||||
@@ -103,9 +101,9 @@ RED.touch.radialMenu = (function() {
 | 
			
		||||
                    }
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            obj.on('touchmove.radial',function() {
 | 
			
		||||
            obj.on('touchmove.radial',function(evt) {
 | 
			
		||||
            try {
 | 
			
		||||
                var touch0 = d3.event.touches.item(0);
 | 
			
		||||
                var touch0 = evt.touches.item(0);
 | 
			
		||||
                var p = [touch0.pageX - pos[0],touch0.pageY-pos[1]];
 | 
			
		||||
                for (var i=0;i<menuOpts.length;i++) {
 | 
			
		||||
                    var opt = menuOpts[i];
 | 
			
		||||
@@ -119,7 +117,7 @@ RED.touch.radialMenu = (function() {
 | 
			
		||||
                            if (opt === activeOption) {
 | 
			
		||||
                                activeOption = null;
 | 
			
		||||
                            }
 | 
			
		||||
                            opt.el.classed("selected",false);
 | 
			
		||||
                            opt.el.toggleClass("selected",false);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										61
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/utils-domselection.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								packages/node_modules/@node-red/editor-client/src/js/ui/utils-domselection.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Modelled after `d3.selection` this provides a way to keep a mapping of
 | 
			
		||||
 * DOM Nodes with a data collection.
 | 
			
		||||
 *
 | 
			
		||||
 * The goal here is not to reproduce d3 functionality as-is, but to provide an
 | 
			
		||||
 * api that is specific to what we need to do
 | 
			
		||||
 *
 | 
			
		||||
 * const domSelection = RED.utils.domSelection(container, selector, createNode, eachNode)
 | 
			
		||||
 *
 | 
			
		||||
 * - container - a DOM Node that is the container of the DOM Nodes to track
 | 
			
		||||
 * - selector - CSS selector to get the DOM nodes to track
 | 
			
		||||
 * - createNode - function called when a DOM node must be created for a piece of data.
 | 
			
		||||
 *                `this` is the data item. Should return the DOM Node. It will
 | 
			
		||||
 *                get added to the container.
 | 
			
		||||
 * - eachNode - function called for each DOM node/data item in the selection
 | 
			
		||||
 *
 | 
			
		||||
 * DomSelection.refresh(data) - called whenever the selection should be refreshed.
 | 
			
		||||
 *  Data is expected to be an array of objects that contain an 'id' property
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
RED.utils.domSelection = (function() {
 | 
			
		||||
 | 
			
		||||
    class DomSelection {
 | 
			
		||||
        constructor(container, selector, createNode, eachNode) {
 | 
			
		||||
            this.container = container
 | 
			
		||||
            this.selector = selector
 | 
			
		||||
            this.createNode = createNode
 | 
			
		||||
            this.eachNode = eachNode
 | 
			
		||||
            this.data = []
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        refresh(data) {
 | 
			
		||||
            const domNodes = this.container.querySelectorAll(this.selector)
 | 
			
		||||
            const domItems = new Map()
 | 
			
		||||
            const dataLength = data.length
 | 
			
		||||
            const domLength = domNodes.length
 | 
			
		||||
            for (let i = 0; i < domLength; i++) {
 | 
			
		||||
                const domNode = domNodes[i]
 | 
			
		||||
                if (domNode.__data__) {
 | 
			
		||||
                    domItems.set(domNode.__data__.id, domNode)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            for (let i = 0; i < dataLength; i++) {
 | 
			
		||||
                const datum = data[i]
 | 
			
		||||
                let domNode = domItems.get(datum.id)
 | 
			
		||||
                if (!domNode) {
 | 
			
		||||
                    domNode = this.createNode.call(datum)
 | 
			
		||||
                    this.container.appendChild(domNode)
 | 
			
		||||
                    domNode.__data__ = datum
 | 
			
		||||
                } else {
 | 
			
		||||
                    domItems.delete(datum.id)
 | 
			
		||||
                }
 | 
			
		||||
                this.eachNode.call(datum, domNode)
 | 
			
		||||
            }
 | 
			
		||||
            for (const remainingDomNodes of domItems) {
 | 
			
		||||
                remainingDomNodes[1].remove()
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    return (container, selector, createNode, eachNode) => new DomSelection(container, selector, createNode, eachNode)
 | 
			
		||||
})()
 | 
			
		||||
@@ -1397,6 +1397,17 @@ RED.utils = (function() {
 | 
			
		||||
        return r;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function createSVGElement(tag, attrs = {}, parent) {
 | 
			
		||||
        const element = document.createElementNS('http://www.w3.org/2000/svg', tag)
 | 
			
		||||
        for (const k in attrs) {
 | 
			
		||||
            element.setAttribute(k, attrs[k])
 | 
			
		||||
        }
 | 
			
		||||
        if (parent) {
 | 
			
		||||
            parent.appendChild(element)
 | 
			
		||||
        }
 | 
			
		||||
        return element
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return {
 | 
			
		||||
        createObjectElement: createObjectElement,
 | 
			
		||||
        getMessageProperty: getMessageProperty,
 | 
			
		||||
@@ -1420,6 +1431,7 @@ RED.utils = (function() {
 | 
			
		||||
        getDarkerColor: getDarkerColor,
 | 
			
		||||
        parseModuleList: parseModuleList,
 | 
			
		||||
        checkModuleAllowed: checkModuleAllowed,
 | 
			
		||||
        getBrowserInfo: getBrowserInfo
 | 
			
		||||
        getBrowserInfo: getBrowserInfo,
 | 
			
		||||
        createSVGElement: createSVGElement
 | 
			
		||||
    }
 | 
			
		||||
})();
 | 
			
		||||
 
 | 
			
		||||
@@ -91,8 +91,7 @@ RED.view.annotations = (function() {
 | 
			
		||||
    function addAnnotation(id,evt) {
 | 
			
		||||
        var opts = annotations[id];
 | 
			
		||||
        evt.el.__annotations__ = evt.el.__annotations__ || [];
 | 
			
		||||
        var annotationGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
        annotationGroup.setAttribute("class",opts.class || "");
 | 
			
		||||
        var annotationGroup = RED.utils.createSVGElement("g", { class: opts.class || '' })
 | 
			
		||||
        evt.el.__annotations__.push({
 | 
			
		||||
            id:id,
 | 
			
		||||
            element: annotationGroup
 | 
			
		||||
 
 | 
			
		||||
@@ -15,133 +15,128 @@
 | 
			
		||||
 **/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 RED.view.navigator = (function() {
 | 
			
		||||
RED.view.navigator = (function() {
 | 
			
		||||
    var nav_scale = 25;
 | 
			
		||||
    var nav_width = 5000/nav_scale;
 | 
			
		||||
    var nav_height = 5000/nav_scale;
 | 
			
		||||
 | 
			
		||||
     var nav_scale = 25;
 | 
			
		||||
     var nav_width = 5000/nav_scale;
 | 
			
		||||
     var nav_height = 5000/nav_scale;
 | 
			
		||||
    var navContainer;
 | 
			
		||||
    var navBox;
 | 
			
		||||
    var navBorder;
 | 
			
		||||
    var scrollPos;
 | 
			
		||||
    var scaleFactor;
 | 
			
		||||
    var chartSize;
 | 
			
		||||
    var dimensions;
 | 
			
		||||
    var isDragging;
 | 
			
		||||
    var isShowing = false;
 | 
			
		||||
 | 
			
		||||
     var navContainer;
 | 
			
		||||
     var navBox;
 | 
			
		||||
     var navBorder;
 | 
			
		||||
     var navVis;
 | 
			
		||||
     var scrollPos;
 | 
			
		||||
     var scaleFactor;
 | 
			
		||||
     var chartSize;
 | 
			
		||||
     var dimensions;
 | 
			
		||||
     var isDragging;
 | 
			
		||||
     var isShowing = false;
 | 
			
		||||
    var domSelection
 | 
			
		||||
 | 
			
		||||
     function refreshNodes() {
 | 
			
		||||
         if (!isShowing) {
 | 
			
		||||
             return;
 | 
			
		||||
         }
 | 
			
		||||
         var navNode = navVis.selectAll(".red-ui-navigator-node").data(RED.view.getActiveNodes(),function(d){return d.id});
 | 
			
		||||
         navNode.exit().remove();
 | 
			
		||||
         navNode.enter().insert("rect")
 | 
			
		||||
             .attr('class','red-ui-navigator-node')
 | 
			
		||||
             .attr("pointer-events", "none");
 | 
			
		||||
         navNode.each(function(d) {
 | 
			
		||||
             d3.select(this).attr("x",function(d) { return (d.x-d.w/2)/nav_scale })
 | 
			
		||||
             .attr("y",function(d) { return (d.y-d.h/2)/nav_scale })
 | 
			
		||||
             .attr("width",function(d) { return Math.max(9,d.w/nav_scale) })
 | 
			
		||||
             .attr("height",function(d) { return Math.max(3,d.h/nav_scale) })
 | 
			
		||||
             .attr("fill",function(d) { return RED.utils.getNodeColor(d.type,d._def);})
 | 
			
		||||
         });
 | 
			
		||||
     }
 | 
			
		||||
     function onScroll() {
 | 
			
		||||
         if (!isDragging) {
 | 
			
		||||
             resizeNavBorder();
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
     function resizeNavBorder() {
 | 
			
		||||
         if (navBorder) {
 | 
			
		||||
             scaleFactor = RED.view.scale();
 | 
			
		||||
             chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
 | 
			
		||||
             scrollPos = [$("#red-ui-workspace-chart").scrollLeft(),$("#red-ui-workspace-chart").scrollTop()];
 | 
			
		||||
             navBorder.attr('x',scrollPos[0]/nav_scale)
 | 
			
		||||
                      .attr('y',scrollPos[1]/nav_scale)
 | 
			
		||||
                      .attr('width',chartSize[0]/nav_scale/scaleFactor)
 | 
			
		||||
                      .attr('height',chartSize[1]/nav_scale/scaleFactor)
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
     function toggle() {
 | 
			
		||||
         if (!isShowing) {
 | 
			
		||||
             isShowing = true;
 | 
			
		||||
             $("#red-ui-view-navigate").addClass("selected");
 | 
			
		||||
             resizeNavBorder();
 | 
			
		||||
             refreshNodes();
 | 
			
		||||
             $("#red-ui-workspace-chart").on("scroll",onScroll);
 | 
			
		||||
             navContainer.fadeIn(200);
 | 
			
		||||
         } else {
 | 
			
		||||
             isShowing = false;
 | 
			
		||||
             navContainer.fadeOut(100);
 | 
			
		||||
             $("#red-ui-workspace-chart").off("scroll",onScroll);
 | 
			
		||||
             $("#red-ui-view-navigate").removeClass("selected");
 | 
			
		||||
         }
 | 
			
		||||
     }
 | 
			
		||||
    function refreshNodes() {
 | 
			
		||||
        if (!isShowing) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        domSelection.refresh(RED.view.getActiveNodes())
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
     return {
 | 
			
		||||
         init: function() {
 | 
			
		||||
    function onScroll() {
 | 
			
		||||
        if (!isDragging) {
 | 
			
		||||
            resizeNavBorder();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    function resizeNavBorder() {
 | 
			
		||||
        if (navBorder) {
 | 
			
		||||
            scaleFactor = RED.view.scale();
 | 
			
		||||
            chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
 | 
			
		||||
            scrollPos = [$("#red-ui-workspace-chart").scrollLeft(),$("#red-ui-workspace-chart").scrollTop()];
 | 
			
		||||
 | 
			
		||||
             $(window).on("resize", resizeNavBorder);
 | 
			
		||||
             RED.events.on("sidebar:resize",resizeNavBorder);
 | 
			
		||||
             RED.actions.add("core:toggle-navigator",toggle);
 | 
			
		||||
             var hideTimeout;
 | 
			
		||||
            navBorder.attr('x', scrollPos[0]/nav_scale)
 | 
			
		||||
            navBorder.attr('y', scrollPos[1]/nav_scale)
 | 
			
		||||
            navBorder.attr('width',chartSize[0]/nav_scale/scaleFactor)
 | 
			
		||||
            navBorder.attr('height',chartSize[1]/nav_scale/scaleFactor)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    function toggle() {
 | 
			
		||||
        if (!isShowing) {
 | 
			
		||||
            isShowing = true;
 | 
			
		||||
            $("#red-ui-view-navigate").addClass("selected");
 | 
			
		||||
            resizeNavBorder();
 | 
			
		||||
            refreshNodes();
 | 
			
		||||
            $("#red-ui-workspace-chart").on("scroll",onScroll);
 | 
			
		||||
            navContainer.fadeIn(200);
 | 
			
		||||
        } else {
 | 
			
		||||
            isShowing = false;
 | 
			
		||||
            navContainer.fadeOut(100);
 | 
			
		||||
            $("#red-ui-workspace-chart").off("scroll",onScroll);
 | 
			
		||||
            $("#red-ui-view-navigate").removeClass("selected");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
             navContainer = $('<div>').css({
 | 
			
		||||
                 "position":"absolute",
 | 
			
		||||
                 "bottom":$("#red-ui-workspace-footer").height(),
 | 
			
		||||
                 "right":0,
 | 
			
		||||
                 zIndex: 1
 | 
			
		||||
             }).appendTo("#red-ui-workspace").hide();
 | 
			
		||||
    return {
 | 
			
		||||
        init: function() {
 | 
			
		||||
 | 
			
		||||
             navBox = d3.select(navContainer[0])
 | 
			
		||||
                 .append("svg:svg")
 | 
			
		||||
                 .attr("width", nav_width)
 | 
			
		||||
                 .attr("height", nav_height)
 | 
			
		||||
                 .attr("pointer-events", "all")
 | 
			
		||||
                 .attr("id","red-ui-navigator-canvas")
 | 
			
		||||
            $(window).on("resize", resizeNavBorder);
 | 
			
		||||
            RED.events.on("sidebar:resize",resizeNavBorder);
 | 
			
		||||
            RED.actions.add("core:toggle-navigator",toggle);
 | 
			
		||||
 | 
			
		||||
             navBox.append("rect").attr("x",0).attr("y",0).attr("width",nav_width).attr("height",nav_height).style({
 | 
			
		||||
                 fill:"none",
 | 
			
		||||
                 stroke:"none",
 | 
			
		||||
                 pointerEvents:"all"
 | 
			
		||||
             }).on("mousedown", function() {
 | 
			
		||||
                 // Update these in case they have changed
 | 
			
		||||
                 scaleFactor = RED.view.scale();
 | 
			
		||||
                 chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
 | 
			
		||||
                 dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor];
 | 
			
		||||
                 var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
 | 
			
		||||
                 var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
 | 
			
		||||
                 navBorder.attr('x',newX).attr('y',newY);
 | 
			
		||||
                 isDragging = true;
 | 
			
		||||
                 $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
 | 
			
		||||
                 $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
 | 
			
		||||
             }).on("mousemove", function() {
 | 
			
		||||
                 if (!isDragging) { return }
 | 
			
		||||
                 if (d3.event.buttons === 0) {
 | 
			
		||||
                     isDragging = false;
 | 
			
		||||
                     return;
 | 
			
		||||
                 }
 | 
			
		||||
                 var newX = Math.max(0,Math.min(d3.event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
 | 
			
		||||
                 var newY = Math.max(0,Math.min(d3.event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
 | 
			
		||||
                 navBorder.attr('x',newX).attr('y',newY);
 | 
			
		||||
                 $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
 | 
			
		||||
                 $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
 | 
			
		||||
             }).on("mouseup", function() {
 | 
			
		||||
                 isDragging = false;
 | 
			
		||||
             })
 | 
			
		||||
            navContainer = $('<div>').css({
 | 
			
		||||
                "position":"absolute",
 | 
			
		||||
                "bottom":$("#red-ui-workspace-footer").height(),
 | 
			
		||||
                "right":0,
 | 
			
		||||
                zIndex: 1
 | 
			
		||||
            }).appendTo("#red-ui-workspace").hide();
 | 
			
		||||
 | 
			
		||||
             navBorder = navBox.append("rect").attr("class","red-ui-navigator-border")
 | 
			
		||||
            navBox = $(RED.utils.createSVGElement('svg', {id: "red-ui-navigator-canvas", width: nav_width, height: nav_height, 'pointer-events': 'all'})).appendTo(navContainer)
 | 
			
		||||
 | 
			
		||||
             navVis = navBox.append("svg:g")
 | 
			
		||||
            const navBoxBody = $(RED.utils.createSVGElement("rect", { x: 0, y: 0, width: nav_width, height: nav_height, fill: 'none', stroke: 'none', 'pointer-events': 'all'}))
 | 
			
		||||
            .css({'cursor': 'pointer'})
 | 
			
		||||
            navBoxBody.on('mousedown',function(event) {
 | 
			
		||||
                // Update these in case they have changed
 | 
			
		||||
                scaleFactor = RED.view.scale();
 | 
			
		||||
                chartSize = [ $("#red-ui-workspace-chart").width(), $("#red-ui-workspace-chart").height()];
 | 
			
		||||
                dimensions = [chartSize[0]/nav_scale/scaleFactor, chartSize[1]/nav_scale/scaleFactor];
 | 
			
		||||
                var newX = Math.max(0,Math.min(event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
 | 
			
		||||
                var newY = Math.max(0,Math.min(event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
 | 
			
		||||
                navBorder.attr('x',newX)
 | 
			
		||||
                navBorder.attr('y',newY);
 | 
			
		||||
                isDragging = true;
 | 
			
		||||
                $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
 | 
			
		||||
                $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
 | 
			
		||||
            }).on('mousemove', function(event) {
 | 
			
		||||
                if (!isDragging) { return }
 | 
			
		||||
                if (event.buttons === 0) {
 | 
			
		||||
                    isDragging = false;
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                var newX = Math.max(0,Math.min(event.offsetX+dimensions[0]/2,nav_width)-dimensions[0]);
 | 
			
		||||
                var newY = Math.max(0,Math.min(event.offsetY+dimensions[1]/2,nav_height)-dimensions[1]);
 | 
			
		||||
                navBorder.attr('x',newX)
 | 
			
		||||
                navBorder.attr('y',newY);
 | 
			
		||||
                $("#red-ui-workspace-chart").scrollLeft(newX*nav_scale*scaleFactor);
 | 
			
		||||
                $("#red-ui-workspace-chart").scrollTop(newY*nav_scale*scaleFactor);
 | 
			
		||||
            }).on('mouseup', function() {
 | 
			
		||||
                isDragging = false;
 | 
			
		||||
            }).appendTo(navBox)
 | 
			
		||||
 | 
			
		||||
             RED.statusBar.add({
 | 
			
		||||
                 id: "view-navigator",
 | 
			
		||||
                 align: "right",
 | 
			
		||||
                 element: $('<button class="red-ui-footer-button-toggle single" id="red-ui-view-navigate"><i class="fa fa-map-o"></i></button>')
 | 
			
		||||
             })
 | 
			
		||||
            navBorder = $(RED.utils.createSVGElement("rect", { "class": "red-ui-navigator-border" })).appendTo(navBox)
 | 
			
		||||
 | 
			
		||||
            const navVis = $(RED.utils.createSVGElement('g')).appendTo(navBox)
 | 
			
		||||
 | 
			
		||||
            domSelection = RED.utils.domSelection(navVis[0], '.red-ui-navigator-node', function() {
 | 
			
		||||
                return RED.utils.createSVGElement('rect', { class: 'red-ui-navigator-node', 'pointer-events': 'none' })
 | 
			
		||||
            }, function(node) {
 | 
			
		||||
                node.setAttribute('x', (this.x-this.w/2)/nav_scale)
 | 
			
		||||
                node.setAttribute('y', (this.y-this.h/2)/nav_scale)
 | 
			
		||||
                node.setAttribute('width', Math.max(9,this.w/nav_scale))
 | 
			
		||||
                node.setAttribute('height', Math.max(3,this.h/nav_scale))
 | 
			
		||||
                node.setAttribute('fill', RED.utils.getNodeColor(this.type,this._def))
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            RED.statusBar.add({
 | 
			
		||||
                id: "view-navigator",
 | 
			
		||||
                align: "right",
 | 
			
		||||
                element: $('<button class="red-ui-footer-button-toggle single" id="red-ui-view-navigate"><i class="fa fa-map-o"></i></button>')
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
            $("#red-ui-view-navigate").on("click", function(evt) {
 | 
			
		||||
                evt.preventDefault();
 | 
			
		||||
 
 | 
			
		||||
@@ -294,25 +294,13 @@ RED.view = (function() {
 | 
			
		||||
                    ]
 | 
			
		||||
                    startTouchDistance = Math.sqrt((a*a)+(b*b));
 | 
			
		||||
                } else {
 | 
			
		||||
                    var obj = d3.select(document.body);
 | 
			
		||||
                    touch0 = d3.event.touches.item(0);
 | 
			
		||||
                    var pos = [touch0.pageX,touch0.pageY];
 | 
			
		||||
                    startTouchCenter = [touch0.pageX,touch0.pageY];
 | 
			
		||||
                    startTouchDistance = 0;
 | 
			
		||||
                    var point = d3.touches(this)[0];
 | 
			
		||||
                    touchStartTime = setTimeout(function() {
 | 
			
		||||
                        touchStartTime = null;
 | 
			
		||||
                        showTouchMenu(obj,pos);
 | 
			
		||||
                        //lasso = eventLayer.append("rect")
 | 
			
		||||
                        //    .attr("ox",point[0])
 | 
			
		||||
                        //    .attr("oy",point[1])
 | 
			
		||||
                        //    .attr("rx",2)
 | 
			
		||||
                        //    .attr("ry",2)
 | 
			
		||||
                        //    .attr("x",point[0])
 | 
			
		||||
                        //    .attr("y",point[1])
 | 
			
		||||
                        //    .attr("width",0)
 | 
			
		||||
                        //    .attr("height",0)
 | 
			
		||||
                        //    .attr("class","nr-ui-view-lasso");
 | 
			
		||||
                        showTouchMenu(document.body,pos);
 | 
			
		||||
                    },touchLongPressTimeout);
 | 
			
		||||
                }
 | 
			
		||||
                d3.event.preventDefault();
 | 
			
		||||
@@ -712,11 +700,11 @@ RED.view = (function() {
 | 
			
		||||
            type: "badge",
 | 
			
		||||
            class: "red-ui-flow-node-changed",
 | 
			
		||||
            element: function() {
 | 
			
		||||
                var changeBadge = document.createElementNS("http://www.w3.org/2000/svg","circle");
 | 
			
		||||
                changeBadge.setAttribute("cx",5);
 | 
			
		||||
                changeBadge.setAttribute("cy",5);
 | 
			
		||||
                changeBadge.setAttribute("r",5);
 | 
			
		||||
                return changeBadge;
 | 
			
		||||
                return RED.utils.createSVGElement("circle", {
 | 
			
		||||
                    cx: 5,
 | 
			
		||||
                    cy: 5,
 | 
			
		||||
                    r: 5
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            show: function(n) { return n.changed||n.moved }
 | 
			
		||||
        })
 | 
			
		||||
@@ -725,9 +713,9 @@ RED.view = (function() {
 | 
			
		||||
            type: "badge",
 | 
			
		||||
            class: "red-ui-flow-node-error",
 | 
			
		||||
            element: function(d) {
 | 
			
		||||
                var errorBadge = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                errorBadge.setAttribute("d","M 0,9 l 10,0 -5,-8 z");
 | 
			
		||||
                return errorBadge
 | 
			
		||||
                return RED.utils.createSVGElement("path", {
 | 
			
		||||
                    d: "M 0,9 l 10,0 -5,-8 z"
 | 
			
		||||
                })
 | 
			
		||||
            },
 | 
			
		||||
            tooltip: function(d) {
 | 
			
		||||
                if (d.validationErrors && d.validationErrors.length > 0) {
 | 
			
		||||
@@ -3703,13 +3691,12 @@ RED.view = (function() {
 | 
			
		||||
    }
 | 
			
		||||
    function nodeTouchStart(d) {
 | 
			
		||||
        if (RED.view.DEBUG) { console.warn("nodeTouchStart", mouse_mode,d); }
 | 
			
		||||
        var obj = d3.select(this);
 | 
			
		||||
        var touch0 = d3.event.touches.item(0);
 | 
			
		||||
        var pos = [touch0.pageX,touch0.pageY];
 | 
			
		||||
        startTouchCenter = [touch0.pageX,touch0.pageY];
 | 
			
		||||
        startTouchDistance = 0;
 | 
			
		||||
        touchStartTime = setTimeout(function() {
 | 
			
		||||
            showTouchMenu(obj,pos);
 | 
			
		||||
            showTouchMenu(this,pos);
 | 
			
		||||
        },touchLongPressTimeout);
 | 
			
		||||
        nodeMouseDown.call(this,d)
 | 
			
		||||
        d3.event.preventDefault();
 | 
			
		||||
@@ -3868,12 +3855,11 @@ RED.view = (function() {
 | 
			
		||||
        focusView();
 | 
			
		||||
        d3.event.stopPropagation();
 | 
			
		||||
 | 
			
		||||
        var obj = d3.select(document.body);
 | 
			
		||||
        var touch0 = d3.event.touches.item(0);
 | 
			
		||||
        var pos = [touch0.pageX,touch0.pageY];
 | 
			
		||||
        touchStartTime = setTimeout(function() {
 | 
			
		||||
            touchStartTime = null;
 | 
			
		||||
            showTouchMenu(obj,pos);
 | 
			
		||||
            showTouchMenu(document.body,pos);
 | 
			
		||||
        },touchLongPressTimeout);
 | 
			
		||||
        d3.event.preventDefault();
 | 
			
		||||
    }
 | 
			
		||||
@@ -4247,13 +4233,14 @@ RED.view = (function() {
 | 
			
		||||
                    d.resize = true;
 | 
			
		||||
                    d.dirty = true;
 | 
			
		||||
 | 
			
		||||
                    var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                    var mainRect = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                        class: "red-ui-flow-subflow-port",
 | 
			
		||||
                        rx: 8,
 | 
			
		||||
                        ry: 8,
 | 
			
		||||
                        width: 40,
 | 
			
		||||
                        height: 40,
 | 
			
		||||
                    })
 | 
			
		||||
                    mainRect.__data__ = d;
 | 
			
		||||
                    mainRect.setAttribute("class", "red-ui-flow-subflow-port");
 | 
			
		||||
                    mainRect.setAttribute("rx", 8);
 | 
			
		||||
                    mainRect.setAttribute("ry", 8);
 | 
			
		||||
                    mainRect.setAttribute("width", 40);
 | 
			
		||||
                    mainRect.setAttribute("height", 40);
 | 
			
		||||
                    node[0][0].__mainRect__ = mainRect;
 | 
			
		||||
                    d3.select(mainRect)
 | 
			
		||||
                        .on("mouseup",nodeMouseUp)
 | 
			
		||||
@@ -4262,50 +4249,50 @@ RED.view = (function() {
 | 
			
		||||
                        .on("touchend",nodeTouchEnd)
 | 
			
		||||
                    nodeContents.appendChild(mainRect);
 | 
			
		||||
 | 
			
		||||
                    var output_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                    output_groupEl.setAttribute("x",0);
 | 
			
		||||
                    output_groupEl.setAttribute("y",0);
 | 
			
		||||
                    var output_groupEl = RED.utils.createSVGElement("g", { x: 0, y: 0 })
 | 
			
		||||
                    node[0][0].__outputLabelGroup__ = output_groupEl;
 | 
			
		||||
 | 
			
		||||
                    var output_output = document.createElementNS("http://www.w3.org/2000/svg","text");
 | 
			
		||||
                    output_output.setAttribute("class","red-ui-flow-port-label");
 | 
			
		||||
                    var output_output = RED.utils.createSVGElement("text", { class: "red-ui-flow-port-label" })
 | 
			
		||||
                    output_output.style["font-size"] = "10px";
 | 
			
		||||
                    output_output.textContent = "output";
 | 
			
		||||
                    output_groupEl.appendChild(output_output);
 | 
			
		||||
                    node[0][0].__outputOutput__ = output_output;
 | 
			
		||||
 | 
			
		||||
                    var output_number = document.createElementNS("http://www.w3.org/2000/svg","text");
 | 
			
		||||
                    output_number.setAttribute("class","red-ui-flow-port-label red-ui-flow-port-index");
 | 
			
		||||
                    output_number.setAttribute("x",0);
 | 
			
		||||
                    output_number.setAttribute("y",0);
 | 
			
		||||
                    var output_number = RED.utils.createSVGElement("text", {
 | 
			
		||||
                        class: "red-ui-flow-port-label red-ui-flow-port-index",
 | 
			
		||||
                        x: 0,
 | 
			
		||||
                        y: 0
 | 
			
		||||
                    })
 | 
			
		||||
                    output_number.textContent = d.i+1;
 | 
			
		||||
                    output_groupEl.appendChild(output_number);
 | 
			
		||||
                    node[0][0].__outputNumber__ = output_number;
 | 
			
		||||
 | 
			
		||||
                    var output_border = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                    output_border.setAttribute("d","M 40 1 l 0 38")
 | 
			
		||||
                    output_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
 | 
			
		||||
                    var output_border = RED.utils.createSVGElement("path", {
 | 
			
		||||
                        d: "M 40 1 l 0 38",
 | 
			
		||||
                        class: "red-ui-flow-node-icon-shade-border"
 | 
			
		||||
                    })
 | 
			
		||||
                    output_groupEl.appendChild(output_border);
 | 
			
		||||
                    node[0][0].__outputBorder__ = output_border;
 | 
			
		||||
 | 
			
		||||
                    nodeContents.appendChild(output_groupEl);
 | 
			
		||||
 | 
			
		||||
                    var text = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                    text.setAttribute("class","red-ui-flow-port-label");
 | 
			
		||||
                    text.setAttribute("transform","translate(38,0)");
 | 
			
		||||
                    text.setAttribute('style', 'fill : #888');  // hard coded here!
 | 
			
		||||
                    var text = RED.utils.createSVGElement("g", {
 | 
			
		||||
                        class: "red-ui-flow-port-label",
 | 
			
		||||
                        transform: "translate(38,0)",
 | 
			
		||||
                        style: 'fill : #888'  // hard coded here!
 | 
			
		||||
                    })
 | 
			
		||||
                    node[0][0].__textGroup__ = text;
 | 
			
		||||
                    nodeContents.append(text);
 | 
			
		||||
 | 
			
		||||
                    var portEl = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                    portEl.setAttribute('transform','translate(-5,15)')
 | 
			
		||||
                    var portEl = RED.utils.createSVGElement("g", { transform: 'translate(-5,15)'})
 | 
			
		||||
 | 
			
		||||
                    var port = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                    port.setAttribute("class","red-ui-flow-port");
 | 
			
		||||
                    port.setAttribute("rx",3);
 | 
			
		||||
                    port.setAttribute("ry",3);
 | 
			
		||||
                    port.setAttribute("width",10);
 | 
			
		||||
                    port.setAttribute("height",10);
 | 
			
		||||
                    var port = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                        class: "red-ui-flow-port",
 | 
			
		||||
                        rx: 3,
 | 
			
		||||
                        ry: 3,
 | 
			
		||||
                        width: 10,
 | 
			
		||||
                        height: 10
 | 
			
		||||
                    })
 | 
			
		||||
                    portEl.appendChild(port);
 | 
			
		||||
                    port.__data__ = d;
 | 
			
		||||
 | 
			
		||||
@@ -4434,10 +4421,11 @@ RED.view = (function() {
 | 
			
		||||
                                }
 | 
			
		||||
                                for (var i=0; i<sn; i++) {
 | 
			
		||||
                                    if (i===textLines.length) {
 | 
			
		||||
                                        var line = document.createElementNS("http://www.w3.org/2000/svg","text");
 | 
			
		||||
                                        line.setAttribute("class","red-ui-flow-node-label-text");
 | 
			
		||||
                                        line.setAttribute("x",0);
 | 
			
		||||
                                        line.setAttribute("y",i*24);
 | 
			
		||||
                                        var line = RED.utils.createSVGElement("text", {
 | 
			
		||||
                                            class: "red-ui-flow-node-label-text",
 | 
			
		||||
                                            x: 0,
 | 
			
		||||
                                            y: i*24
 | 
			
		||||
                                        });
 | 
			
		||||
                                        this.__textGroup__.appendChild(line);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    textLines[i].textContent = sa[i];
 | 
			
		||||
@@ -4507,32 +4495,35 @@ RED.view = (function() {
 | 
			
		||||
                d.resize = true;
 | 
			
		||||
 | 
			
		||||
                if (d._def.button) {
 | 
			
		||||
                    var buttonGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                    var buttonGroup = RED.utils.createSVGElement("g", {
 | 
			
		||||
                        class: "red-ui-flow-node-button",
 | 
			
		||||
                        transform: "translate("+((d._def.align == "right") ? 94 : -25)+",2)"
 | 
			
		||||
                    })
 | 
			
		||||
                    buttonGroup.__data__ = d;
 | 
			
		||||
                    buttonGroup.setAttribute("transform", "translate("+((d._def.align == "right") ? 94 : -25)+",2)");
 | 
			
		||||
                    buttonGroup.setAttribute("class","red-ui-flow-node-button");
 | 
			
		||||
                    node[0][0].__buttonGroup__ = buttonGroup;
 | 
			
		||||
 | 
			
		||||
                    var bgBackground = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                    var bgBackground = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                        class: "red-ui-flow-node-button-background",
 | 
			
		||||
                        rx: 5,
 | 
			
		||||
                        ry: 5,
 | 
			
		||||
                        width: 32,
 | 
			
		||||
                        height: node_height-4
 | 
			
		||||
                    })
 | 
			
		||||
                    bgBackground.__data__ = d;
 | 
			
		||||
                    bgBackground.setAttribute("class","red-ui-flow-node-button-background");
 | 
			
		||||
                    bgBackground.setAttribute("rx",5);
 | 
			
		||||
                    bgBackground.setAttribute("ry",5);
 | 
			
		||||
                    bgBackground.setAttribute("width",32);
 | 
			
		||||
                    bgBackground.setAttribute("height",node_height-4);
 | 
			
		||||
                    buttonGroup.appendChild(bgBackground);
 | 
			
		||||
                    node[0][0].__buttonGroupBackground__ = bgBackground;
 | 
			
		||||
 | 
			
		||||
                    var bgButton = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                    var bgButton = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                        class: "red-ui-flow-node-button-button",
 | 
			
		||||
                        x: d._def.align == "right"? 11:5,
 | 
			
		||||
                        y: 4,
 | 
			
		||||
                        rx: 4,
 | 
			
		||||
                        ry: 4,
 | 
			
		||||
                        width: 16,
 | 
			
		||||
                        height: node_height-12,
 | 
			
		||||
                        fill: RED.utils.getNodeColor(d.type,d._def)
 | 
			
		||||
                    })
 | 
			
		||||
                    bgButton.__data__ = d;
 | 
			
		||||
                    bgButton.setAttribute("class","red-ui-flow-node-button-button");
 | 
			
		||||
                    bgButton.setAttribute("x", d._def.align == "right"? 11:5);
 | 
			
		||||
                    bgButton.setAttribute("y",4);
 | 
			
		||||
                    bgButton.setAttribute("rx",4);
 | 
			
		||||
                    bgButton.setAttribute("ry",4);
 | 
			
		||||
                    bgButton.setAttribute("width",16);
 | 
			
		||||
                    bgButton.setAttribute("height",node_height-12);
 | 
			
		||||
                    bgButton.setAttribute("fill", RED.utils.getNodeColor(d.type,d._def));
 | 
			
		||||
                    d3.select(bgButton)
 | 
			
		||||
                        .on("mousedown",function(d) {if (!lasso && isButtonEnabled(d)) {focusView();d3.select(this).attr("fill-opacity",0.2);d3.event.preventDefault(); d3.event.stopPropagation();}})
 | 
			
		||||
                        .on("mouseup",function(d) {if (!lasso && isButtonEnabled(d)) { d3.select(this).attr("fill-opacity",0.4);d3.event.preventDefault();d3.event.stopPropagation();}})
 | 
			
		||||
@@ -4553,12 +4544,13 @@ RED.view = (function() {
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                var mainRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                var mainRect = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                    class: "red-ui-flow-node "+(d.type == "unknown"?"red-ui-flow-node-unknown":""),
 | 
			
		||||
                    rx: 5,
 | 
			
		||||
                    ry: 5,
 | 
			
		||||
                    fill: RED.utils.getNodeColor(d.type,d._def)
 | 
			
		||||
                })
 | 
			
		||||
                mainRect.__data__ = d;
 | 
			
		||||
                mainRect.setAttribute("class", "red-ui-flow-node "+(d.type == "unknown"?"red-ui-flow-node-unknown":""));
 | 
			
		||||
                mainRect.setAttribute("rx", 5);
 | 
			
		||||
                mainRect.setAttribute("ry", 5);
 | 
			
		||||
                mainRect.setAttribute("fill", RED.utils.getNodeColor(d.type,d._def));
 | 
			
		||||
                node[0][0].__mainRect__ = mainRect;
 | 
			
		||||
                d3.select(mainRect)
 | 
			
		||||
                    .on("mouseup",nodeMouseUp)
 | 
			
		||||
@@ -4573,61 +4565,65 @@ RED.view = (function() {
 | 
			
		||||
 | 
			
		||||
                if (d._def.icon) {
 | 
			
		||||
                    var icon_url = RED.utils.getNodeIcon(d._def,d);
 | 
			
		||||
                    var icon_groupEl = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                    icon_groupEl.__data__ = d;
 | 
			
		||||
                    icon_groupEl.setAttribute("class","red-ui-flow-node-icon-group"+("right" == d._def.align?" red-ui-flow-node-icon-group-right":""));
 | 
			
		||||
                    icon_groupEl.setAttribute("x",0);
 | 
			
		||||
                    icon_groupEl.setAttribute("y",0);
 | 
			
		||||
                    var icon_groupEl = RED.utils.createSVGElement("g", {
 | 
			
		||||
                        class: "red-ui-flow-node-icon-group"+("right" == d._def.align?" red-ui-flow-node-icon-group-right":""),
 | 
			
		||||
                        x: 0,
 | 
			
		||||
                        y: 0
 | 
			
		||||
                    })
 | 
			
		||||
                    icon_groupEl.style["pointer-events"] = "none";
 | 
			
		||||
                    icon_groupEl.__data__ = d;
 | 
			
		||||
                    node[0][0].__iconGroup__ = icon_groupEl;
 | 
			
		||||
                    var icon_shade = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                    icon_shade.setAttribute("x",0);
 | 
			
		||||
                    icon_shade.setAttribute("y",0);
 | 
			
		||||
                    icon_shade.setAttribute("class","red-ui-flow-node-icon-shade")
 | 
			
		||||
                    var icon_shade = RED.utils.createSVGElement("path", {
 | 
			
		||||
                        x: 0,
 | 
			
		||||
                        y: 0,
 | 
			
		||||
                        class: "red-ui-flow-node-icon-shade"
 | 
			
		||||
                    })
 | 
			
		||||
                    icon_groupEl.appendChild(icon_shade);
 | 
			
		||||
                    node[0][0].__iconShade__ = icon_shade;
 | 
			
		||||
 | 
			
		||||
                    var icon_group = d3.select(icon_groupEl)
 | 
			
		||||
                    createIconAttributes(icon_url, icon_group, d);
 | 
			
		||||
 | 
			
		||||
                    var icon_shade_border = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                    icon_shade_border.setAttribute("d","right" != d._def.align ? "M 30 1 l 0 "+(d.h-2) : "M 0 1 l 0 "+(d.h-2)  )
 | 
			
		||||
                    icon_shade_border.setAttribute("class", "red-ui-flow-node-icon-shade-border")
 | 
			
		||||
                    var icon_shade_border = RED.utils.createSVGElement("path", {
 | 
			
		||||
                        d: "right" != d._def.align ? "M 30 1 l 0 "+(d.h-2) : "M 0 1 l 0 "+(d.h-2),
 | 
			
		||||
                        class: "red-ui-flow-node-icon-shade-border"
 | 
			
		||||
                    })
 | 
			
		||||
                    icon_groupEl.appendChild(icon_shade_border);
 | 
			
		||||
                    node[0][0].__iconShadeBorder__ = icon_shade_border;
 | 
			
		||||
 | 
			
		||||
                    nodeContents.appendChild(icon_groupEl);
 | 
			
		||||
                }
 | 
			
		||||
                var text = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                text.setAttribute("class","red-ui-flow-node-label"+(hideLabel?" hide":"")+(d._def.align?" red-ui-flow-node-label-"+d._def.align:""));
 | 
			
		||||
                text.setAttribute("transform","translate(38,0)");
 | 
			
		||||
                // text.setAttribute("dy", ".3px");
 | 
			
		||||
                // text.setAttribute("text-anchor",d._def.align !== "right" ? "start":"end");
 | 
			
		||||
                var text = RED.utils.createSVGElement("g", {
 | 
			
		||||
                    class: "red-ui-flow-node-label"+(hideLabel?" hide":"")+(d._def.align?" red-ui-flow-node-label-"+d._def.align:""),
 | 
			
		||||
                    transform: "translate(38,0)"
 | 
			
		||||
                    // dy: ".3px",
 | 
			
		||||
                    // "text-anchor": d._def.align !== "right" ? "start":"end"
 | 
			
		||||
                })
 | 
			
		||||
                nodeContents.appendChild(text);
 | 
			
		||||
                node[0][0].__textGroup__ = text;
 | 
			
		||||
 | 
			
		||||
                var statusEl = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                // statusEl.__data__ = d;
 | 
			
		||||
                statusEl.setAttribute("class","red-ui-flow-node-status-group");
 | 
			
		||||
                var statusEl = RED.utils.createSVGElement("g", { class: "red-ui-flow-node-status-group" })
 | 
			
		||||
                statusEl.style.display = "none";
 | 
			
		||||
                node[0][0].__statusGroup__ = statusEl;
 | 
			
		||||
 | 
			
		||||
                var statusRect = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                statusRect.setAttribute("class","red-ui-flow-node-status");
 | 
			
		||||
                statusRect.setAttribute("x",6);
 | 
			
		||||
                statusRect.setAttribute("y",1);
 | 
			
		||||
                statusRect.setAttribute("width",9);
 | 
			
		||||
                statusRect.setAttribute("height",9);
 | 
			
		||||
                statusRect.setAttribute("rx",2);
 | 
			
		||||
                statusRect.setAttribute("ry",2);
 | 
			
		||||
                statusRect.setAttribute("stroke-width","3");
 | 
			
		||||
                var statusRect = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                    class: "red-ui-flow-node-status",
 | 
			
		||||
                    x: 6,
 | 
			
		||||
                    y: 1,
 | 
			
		||||
                    width: 9,
 | 
			
		||||
                    height: 9,
 | 
			
		||||
                    rx: 2,
 | 
			
		||||
                    ry: 2,
 | 
			
		||||
                    "stroke-width": 3
 | 
			
		||||
                })
 | 
			
		||||
                statusEl.appendChild(statusRect);
 | 
			
		||||
                node[0][0].__statusShape__ = statusRect;
 | 
			
		||||
 | 
			
		||||
                var statusLabel = document.createElementNS("http://www.w3.org/2000/svg","text");
 | 
			
		||||
                statusLabel.setAttribute("class","red-ui-flow-node-status-label");
 | 
			
		||||
                statusLabel.setAttribute("x",20);
 | 
			
		||||
                statusLabel.setAttribute("y",10);
 | 
			
		||||
                var statusLabel = RED.utils.createSVGElement("text", {
 | 
			
		||||
                    class: "red-ui-flow-node-status-label",
 | 
			
		||||
                    x: 20,
 | 
			
		||||
                    y: 10
 | 
			
		||||
                })
 | 
			
		||||
                statusEl.appendChild(statusLabel);
 | 
			
		||||
                node[0][0].__statusLabel__ = statusLabel;
 | 
			
		||||
 | 
			
		||||
@@ -4712,10 +4708,11 @@ RED.view = (function() {
 | 
			
		||||
                            }
 | 
			
		||||
                            for (var i=0; i<sn; i++) {
 | 
			
		||||
                                if (i===textLines.length) {
 | 
			
		||||
                                    var line = document.createElementNS("http://www.w3.org/2000/svg","text");
 | 
			
		||||
                                    line.setAttribute("class","red-ui-flow-node-label-text");
 | 
			
		||||
                                    line.setAttribute("x",0);
 | 
			
		||||
                                    line.setAttribute("y",i*24);
 | 
			
		||||
                                    var line = RED.utils.createSVGElement("text", {
 | 
			
		||||
                                        class: "red-ui-flow-node-label-text",
 | 
			
		||||
                                        x: 0,
 | 
			
		||||
                                        y: i*24
 | 
			
		||||
                                    })
 | 
			
		||||
                                    this.__textGroup__.appendChild(line);
 | 
			
		||||
                                }
 | 
			
		||||
                                textLines[i].textContent = sa[i];
 | 
			
		||||
@@ -4814,22 +4811,23 @@ RED.view = (function() {
 | 
			
		||||
                        for(var portIndex = 0; portIndex < numOutputs; portIndex++ ) {
 | 
			
		||||
                            var portGroup;
 | 
			
		||||
                            if (portIndex === this.__outputs__.length) {
 | 
			
		||||
                                portGroup = document.createElementNS("http://www.w3.org/2000/svg","g");
 | 
			
		||||
                                portGroup.setAttribute("class","red-ui-flow-port-output");
 | 
			
		||||
                                portGroup = RED.utils.createSVGElement("g", { class: "red-ui-flow-port-output" })
 | 
			
		||||
                                var portPort;
 | 
			
		||||
                                if (d.type === "link out") {
 | 
			
		||||
                                    portPort = document.createElementNS("http://www.w3.org/2000/svg","circle");
 | 
			
		||||
                                    portPort.setAttribute("cx",11);
 | 
			
		||||
                                    portPort.setAttribute("cy",5);
 | 
			
		||||
                                    portPort.setAttribute("r",5);
 | 
			
		||||
                                    portPort.setAttribute("class","red-ui-flow-port red-ui-flow-link-port");
 | 
			
		||||
                                    portPort = RED.utils.createSVGElement("circle", {
 | 
			
		||||
                                        cx: 11,
 | 
			
		||||
                                        cy: 5,
 | 
			
		||||
                                        r: 5,
 | 
			
		||||
                                        class: "red-ui-flow-port red-ui-flow-link-port"
 | 
			
		||||
                                    })
 | 
			
		||||
                                } 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 = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                                        rx: 3,
 | 
			
		||||
                                        ry: 3,
 | 
			
		||||
                                        width: 10,
 | 
			
		||||
                                        height: 10,
 | 
			
		||||
                                        class: "red-ui-flow-port"
 | 
			
		||||
                                    })
 | 
			
		||||
                                }
 | 
			
		||||
                                portGroup.appendChild(portPort);
 | 
			
		||||
                                portGroup.__port__ = portPort;
 | 
			
		||||
@@ -4981,26 +4979,28 @@ RED.view = (function() {
 | 
			
		||||
                var junction = d3.select(this);
 | 
			
		||||
                var contents = document.createDocumentFragment();
 | 
			
		||||
                // d.added = true;
 | 
			
		||||
                var junctionBack = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                junctionBack.setAttribute("class","red-ui-flow-junction-background");
 | 
			
		||||
                junctionBack.setAttribute("x",-5);
 | 
			
		||||
                junctionBack.setAttribute("y",-5);
 | 
			
		||||
                junctionBack.setAttribute("width",10);
 | 
			
		||||
                junctionBack.setAttribute("height",10);
 | 
			
		||||
                junctionBack.setAttribute("rx",3);
 | 
			
		||||
                junctionBack.setAttribute("ry",3);
 | 
			
		||||
                var junctionBack = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                    class: "red-ui-flow-junction-background",
 | 
			
		||||
                    x: -5,
 | 
			
		||||
                    y: -5,
 | 
			
		||||
                    width: 10,
 | 
			
		||||
                    height: 10,
 | 
			
		||||
                    rx: 3,
 | 
			
		||||
                    ry: 3
 | 
			
		||||
                })
 | 
			
		||||
                junctionBack.__data__ = d;
 | 
			
		||||
                this.__junctionBack__ = junctionBack;
 | 
			
		||||
                contents.appendChild(junctionBack);
 | 
			
		||||
 | 
			
		||||
                var junctionInput = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                junctionInput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-input");
 | 
			
		||||
                junctionInput.setAttribute("x",-5);
 | 
			
		||||
                junctionInput.setAttribute("y",-5);
 | 
			
		||||
                junctionInput.setAttribute("width",10);
 | 
			
		||||
                junctionInput.setAttribute("height",10);
 | 
			
		||||
                junctionInput.setAttribute("rx",3);
 | 
			
		||||
                junctionInput.setAttribute("ry",3);
 | 
			
		||||
                var junctionInput = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                    class: "red-ui-flow-junction-port red-ui-flow-junction-port-input",
 | 
			
		||||
                    x: -5,
 | 
			
		||||
                    y: -5,
 | 
			
		||||
                    width: 10,
 | 
			
		||||
                    height: 10,
 | 
			
		||||
                    rx: 3,
 | 
			
		||||
                    ry: 3
 | 
			
		||||
                })
 | 
			
		||||
                junctionInput.__data__ = d;
 | 
			
		||||
                junctionInput.__portType__ = PORT_TYPE_INPUT;
 | 
			
		||||
                junctionInput.__portIndex__ = 0;
 | 
			
		||||
@@ -5012,14 +5012,15 @@ RED.view = (function() {
 | 
			
		||||
 | 
			
		||||
                this.__junctionInput__ = junctionInput;
 | 
			
		||||
                contents.appendChild(junctionInput);
 | 
			
		||||
                var junctionOutput = document.createElementNS("http://www.w3.org/2000/svg","rect");
 | 
			
		||||
                junctionOutput.setAttribute("class","red-ui-flow-junction-port red-ui-flow-junction-port-output");
 | 
			
		||||
                junctionOutput.setAttribute("x",-5);
 | 
			
		||||
                junctionOutput.setAttribute("y",-5);
 | 
			
		||||
                junctionOutput.setAttribute("width",10);
 | 
			
		||||
                junctionOutput.setAttribute("height",10);
 | 
			
		||||
                junctionOutput.setAttribute("rx",3);
 | 
			
		||||
                junctionOutput.setAttribute("ry",3);
 | 
			
		||||
                var junctionOutput = RED.utils.createSVGElement("rect", {
 | 
			
		||||
                    class: "red-ui-flow-junction-port red-ui-flow-junction-port-output",
 | 
			
		||||
                    x: -5,
 | 
			
		||||
                    y: -5,
 | 
			
		||||
                    width: 10,
 | 
			
		||||
                    height: 10,
 | 
			
		||||
                    rx: 3,
 | 
			
		||||
                    ry: 3,
 | 
			
		||||
                })
 | 
			
		||||
                junctionOutput.__data__ = d;
 | 
			
		||||
                junctionOutput.__portType__ = PORT_TYPE_OUTPUT;
 | 
			
		||||
                junctionOutput.__portIndex__ = 0;
 | 
			
		||||
@@ -5076,9 +5077,8 @@ RED.view = (function() {
 | 
			
		||||
                var pathContents = document.createDocumentFragment();
 | 
			
		||||
 | 
			
		||||
                d.added = true;
 | 
			
		||||
                var pathBack = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                var pathBack = RED.utils.createSVGElement("path", { class: "red-ui-flow-link-background red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":"")})
 | 
			
		||||
                pathBack.__data__ = d;
 | 
			
		||||
                pathBack.setAttribute("class","red-ui-flow-link-background red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":""));
 | 
			
		||||
                this.__pathBack__ = pathBack;
 | 
			
		||||
                pathContents.appendChild(pathBack);
 | 
			
		||||
                d3.select(pathBack)
 | 
			
		||||
@@ -5114,16 +5114,17 @@ RED.view = (function() {
 | 
			
		||||
                        }
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                var pathOutline = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                var pathOutline = RED.utils.createSVGElement("path", {
 | 
			
		||||
                    class: "red-ui-flow-link-outline red-ui-flow-link-path"
 | 
			
		||||
                })
 | 
			
		||||
                pathOutline.__data__ = d;
 | 
			
		||||
                pathOutline.setAttribute("class","red-ui-flow-link-outline red-ui-flow-link-path");
 | 
			
		||||
                this.__pathOutline__ = pathOutline;
 | 
			
		||||
                pathContents.appendChild(pathOutline);
 | 
			
		||||
 | 
			
		||||
                var pathLine = document.createElementNS("http://www.w3.org/2000/svg","path");
 | 
			
		||||
                var pathLine = RED.utils.createSVGElement("path", {
 | 
			
		||||
                    class: "red-ui-flow-link-line red-ui-flow-link-path"+(d.link?" red-ui-flow-link-link":(activeSubflow?" red-ui-flow-subflow-link":""))
 | 
			
		||||
                })
 | 
			
		||||
                pathLine.__data__ = d;
 | 
			
		||||
                pathLine.setAttribute("class","red-ui-flow-link-line red-ui-flow-link-path"+
 | 
			
		||||
                    (d.link?" red-ui-flow-link-link":(activeSubflow?" red-ui-flow-subflow-link":"")));
 | 
			
		||||
                this.__pathLine__ = pathLine;
 | 
			
		||||
                pathContents.appendChild(pathLine);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user