1
0
mirror of https://github.com/node-red/node-red.git synced 2023-10-10 13:36:53 +02:00

Massively reduce our dependency on d3 to render the view

This is a slightly scary set of changes to be making. It overhauls
how the view is rendered.

Rather than use d3 for every single part of generating the view,
we new use native DOM functions as much as possible.

d3 is still used for the basic heavy lifting of working out what
nodes/links etc need to be added/removed from the view. But once
it comes to rendering them, d3 is side-lined as much as possible.

There's room for further improvement. This change focusses on Nodes
and Links. It has not touched groups, subflow-ports and link-nodes.
This commit is contained in:
Nick O'Leary 2020-06-10 00:45:20 +01:00
parent 97fd34150f
commit c061487a16
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
7 changed files with 556 additions and 541 deletions

View File

@ -206,9 +206,6 @@ RED.history = (function() {
RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) { RED.nodes.filterNodes({type:"subflow:"+subflow.id}).forEach(function(n) {
n.inputs = subflow.in.length; n.inputs = subflow.in.length;
n.outputs = subflow.out.length; n.outputs = subflow.out.length;
while (n.outputs > n.ports.length) {
n.ports.push(n.ports.length);
}
n.resize = true; n.resize = true;
n.dirty = true; n.dirty = true;
}); });
@ -413,6 +410,7 @@ RED.history = (function() {
} }
} }
} }
ev.node.__outputs = inverseEv.changes.outputs;
RED.editor.updateNodeProperties(ev.node,outputMap); RED.editor.updateNodeProperties(ev.node,outputMap);
RED.editor.validateNode(ev.node); RED.editor.validateNode(ev.node);
} }

View File

@ -206,13 +206,7 @@ RED.nodes = (function() {
if (n._def.category == "config") { if (n._def.category == "config") {
configNodes[n.id] = n; configNodes[n.id] = n;
} else { } else {
n.ports = [];
if (n.wires && (n.wires.length > n.outputs)) { n.outputs = n.wires.length; } if (n.wires && (n.wires.length > n.outputs)) { n.outputs = n.wires.length; }
if (n.outputs) {
for (var i=0;i<n.outputs;i++) {
n.ports.push(i);
}
}
n.dirty = true; n.dirty = true;
updateConfigNodeUsers(n); updateConfigNodeUsers(n);
if (n._def.category == "subflows" && typeof n.i === "undefined") { if (n._def.category == "subflows" && typeof n.i === "undefined") {

View File

@ -2,6 +2,14 @@
var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; var isIE11 = !!window.MSInputMethodContext && !!document.documentMode;
if (isIE11) { if (isIE11) {
// IE11 DOMTokenList.toggle does not support the two-argument variety
window.DOMTokenList.prototype.toggle = function(cl,bo) {
if (arguments.length === 1) {
bo = !this.contains(cl);
}
this[!!bo?"add":"remove"](cl);
}
// IE11 does not provide classList on SVGElements // IE11 does not provide classList on SVGElements
if (! ("classList" in SVGElement.prototype)) { if (! ("classList" in SVGElement.prototype)) {
Object.defineProperty(SVGElement.prototype, 'classList', Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'classList')); Object.defineProperty(SVGElement.prototype, 'classList', Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'classList'));

View File

@ -204,32 +204,28 @@ RED.editor = (function() {
node.dirty = true; node.dirty = true;
node.dirtyStatus = true; node.dirtyStatus = true;
var removedLinks = []; var removedLinks = [];
if (node.ports) { if (outputMap) {
if (outputMap) { RED.nodes.eachLink(function(l) {
RED.nodes.eachLink(function(l) { if (l.source === node) {
if (l.source === node && outputMap.hasOwnProperty(l.sourcePort)) { if (outputMap.hasOwnProperty(l.sourcePort)) {
if (outputMap[l.sourcePort] === "-1") { if (outputMap[l.sourcePort] === "-1") {
removedLinks.push(l); removedLinks.push(l);
} else { } else {
l.sourcePort = outputMap[l.sourcePort]; l.sourcePort = outputMap[l.sourcePort];
} }
} }
});
}
if (node.outputs < node.ports.length) {
while (node.outputs < node.ports.length) {
node.ports.pop();
} }
});
}
if (node.hasOwnProperty("__outputs")) {
if (node.outputs < node.__outputs) {
RED.nodes.eachLink(function(l) { RED.nodes.eachLink(function(l) {
if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) { if (l.source === node && l.sourcePort >= node.outputs && removedLinks.indexOf(l) === -1) {
removedLinks.push(l); removedLinks.push(l);
} }
}); });
} else if (node.outputs > node.ports.length) {
while (node.outputs > node.ports.length) {
node.ports.push(node.ports.length);
}
} }
delete node.__outputs;
} }
node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs))); node.inputs = Math.min(1,Math.max(0,parseInt(node.inputs)));
if (isNaN(node.inputs)) { if (isNaN(node.inputs)) {
@ -1505,6 +1501,10 @@ RED.editor = (function() {
} }
}, },
open: function(tray, done) { open: function(tray, done) {
if (editing_node.hasOwnProperty('outputs')) {
editing_node.__outputs = editing_node.outputs;
}
var trayFooter = tray.find(".red-ui-tray-footer"); var trayFooter = tray.find(".red-ui-tray-footer");
var trayBody = tray.find('.red-ui-tray-body'); var trayBody = tray.find('.red-ui-tray-body');
trayBody.parent().css('overflow','hidden'); trayBody.parent().css('overflow','hidden');

View File

@ -105,7 +105,7 @@ RED.palette = (function() {
for (var i=0;i<words.length;i++) { for (var i=0;i<words.length;i++) {
var word = words[i]; var word = words[i];
var sep = (i == 0) ? "" : " "; var sep = (i == 0) ? "" : " ";
var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label", 0); var newWidth = RED.view.calculateTextWidth(currentLine+sep+word, "red-ui-palette-label");
if (newWidth < nodeWidth) { if (newWidth < nodeWidth) {
currentLine += sep +word; currentLine += sep +word;
} else { } else {
@ -113,12 +113,12 @@ RED.palette = (function() {
displayLines.push(currentLine); displayLines.push(currentLine);
} }
while (true) { while (true) {
var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label", 0); var wordWidth = RED.view.calculateTextWidth(word, "red-ui-palette-label");
if (wordWidth >= nodeWidth) { if (wordWidth >= nodeWidth) {
// break word if too wide // break word if too wide
for(var j = word.length; j > 0; j--) { for(var j = word.length; j > 0; j--) {
var s = word.substring(0, j); var s = word.substring(0, j);
var width = RED.view.calculateTextWidth(s, "red-ui-palette-label", 0); var width = RED.view.calculateTextWidth(s, "red-ui-palette-label");
if (width < nodeWidth) { if (width < nodeWidth) {
displayLines.push(s); displayLines.push(s);
word = word.substring(j); word = word.substring(j);

View File

@ -284,9 +284,6 @@ RED.subflow = (function() {
} }
n.inputs = activeSubflow.in.length; n.inputs = activeSubflow.in.length;
n.outputs = activeSubflow.out.length; n.outputs = activeSubflow.out.length;
while (n.outputs < n.ports.length) {
n.ports.pop();
}
n.resize = true; n.resize = true;
n.dirty = true; n.dirty = true;
RED.editor.updateNodeProperties(n); RED.editor.updateNodeProperties(n);

File diff suppressed because it is too large Load Diff