diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
index 2c4cdca6b..2f30f1dc4 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/utils.js
@@ -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
}
})();
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js
index 1df8c4bd1..d6a14e3cb 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view-annotations.js
@@ -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
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js
index a3001e474..2a29c7d10 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view-navigator.js
@@ -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 = $('
').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 = $('
').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: $('')
- })
+ 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: $('')
+ })
$("#red-ui-view-navigate").on("click", function(evt) {
evt.preventDefault();
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
index 6de33872e..37084d5cb 100755
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/view.js
@@ -700,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 }
})
@@ -713,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) {
@@ -4233,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)
@@ -4248,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;
@@ -4420,10 +4421,11 @@ RED.view = (function() {
}
for (var i=0; i