From d6f6b41145b5bd459a275cb8f1545aba8e5c9760 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Tue, 17 Jan 2017 09:54:17 +0000
Subject: [PATCH 01/25] Fix inner reference in install fail message catalog
entry Fixes #1120
---
red/runtime/locales/en-US/runtime.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/red/runtime/locales/en-US/runtime.json b/red/runtime/locales/en-US/runtime.json
index 703a0b513..90cfbd3dc 100644
--- a/red/runtime/locales/en-US/runtime.json
+++ b/red/runtime/locales/en-US/runtime.json
@@ -28,7 +28,7 @@
"installed": "Installed module: __name__",
"install-failed": "Install failed",
"install-failed-long": "Installation of module __name__ failed:",
- "install-failed-not-found": "$t(install-failed-long) module not found",
+ "install-failed-not-found": "$t(server.install.install-failed-long) module not found",
"uninstalling": "Uninstalling module: __name__",
"uninstall-failed": "Uninstall failed",
From 0ffeb0c5afa98371b892c49a27b1f1cc313db88c Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Tue, 17 Jan 2017 20:48:05 +0000
Subject: [PATCH 02/25] Avoid creating multiple reconnect timers in websocket
node
---
nodes/core/io/22-websocket.js | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/nodes/core/io/22-websocket.js b/nodes/core/io/22-websocket.js
index 2e5808473..a42c3fcf9 100644
--- a/nodes/core/io/22-websocket.js
+++ b/nodes/core/io/22-websocket.js
@@ -36,6 +36,7 @@ module.exports = function(RED) {
node.closing = false;
function startconn() { // Connect to remote endpoint
+ node.tout = null;
var socket = new ws(node.path);
socket.setMaxListeners(0);
node.server = socket; // keep for closing
@@ -52,6 +53,7 @@ module.exports = function(RED) {
if (node.isServer) { delete node._clients[id]; node.emit('closed',Object.keys(node._clients).length); }
else { node.emit('closed'); }
if (!node.closing && !node.isServer) {
+ clearTimeout(node.tout);
node.tout = setTimeout(function() { startconn(); }, 3000); // try to reconnect every 3 secs... bit fast ?
}
});
@@ -61,6 +63,7 @@ module.exports = function(RED) {
socket.on('error', function(err) {
node.emit('erro');
if (!node.closing && !node.isServer) {
+ clearTimeout(node.tout);
node.tout = setTimeout(function() { startconn(); }, 3000); // try to reconnect every 3 secs... bit fast ?
}
});
@@ -124,7 +127,10 @@ module.exports = function(RED) {
else {
node.closing = true;
node.server.close();
- if (node.tout) { clearTimeout(node.tout); }
+ if (node.tout) {
+ clearTimeout(node.tout);
+ node.tout = null;
+ }
}
});
}
From 5ba9a0eb3fb07c252cc88a6e254ccd23966eeec6 Mon Sep 17 00:00:00 2001
From: Daisuke Baba
Date: Thu, 19 Jan 2017 16:55:57 +0900
Subject: [PATCH 03/25] Fix empty extra node help content issue
---
red/runtime/nodes/registry/loader.js | 4 +++-
.../red/runtime/nodes/registry/loader_spec.js | 21 +++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/red/runtime/nodes/registry/loader.js b/red/runtime/nodes/registry/loader.js
index dd4292c23..9917a0532 100644
--- a/red/runtime/nodes/registry/loader.js
+++ b/red/runtime/nodes/registry/loader.js
@@ -381,8 +381,10 @@ function getNodeHelp(node,lang) {
}
if (help) {
node.help[lang] = help;
+ } else if (lang === runtime.i18n.defaultLang) {
+ return null;
} else {
- node.help[lang] = node.help[runtime.i18n.defaultLang];
+ node.help[lang] = getNodeHelp(node, runtime.i18n.defaultLang);
}
}
return node.help[lang];
diff --git a/test/red/runtime/nodes/registry/loader_spec.js b/test/red/runtime/nodes/registry/loader_spec.js
index 39b25d55e..c3df70bd5 100644
--- a/test/red/runtime/nodes/registry/loader_spec.js
+++ b/test/red/runtime/nodes/registry/loader_spec.js
@@ -564,6 +564,27 @@ describe("red/nodes/registry/loader",function() {
loader.getNodeHelp(node,"fr").should.eql("foo");
fs.readFileSync.calledOnce.should.be.true();
});
+ it("loads help, defaulting to en-US content for extra nodes", function() {
+ stubs.push(sinon.stub(fs,"readFileSync", function(path) {
+ if (path.indexOf("en-US") >= 0) {
+ return 'bar';
+ }
+ throw new Error("not found");
+ }));
+ var node = {
+ template: "/tmp/node/directory/file.html",
+ help:{}
+ };
+ delete node.help['en-US'];
+
+ loader.getNodeHelp(node,"fr").should.eql("bar");
+ node.help['fr'].should.eql("bar");
+ fs.readFileSync.calledTwice.should.be.true();
+ fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/fr/file.html"));
+ fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html"));
+ loader.getNodeHelp(node,"fr").should.eql("bar");
+ fs.readFileSync.calledTwice.should.be.true();
+ });
});
});
From 57c529758e8208648ac2bb62e2d2eb9a34dc1fd0 Mon Sep 17 00:00:00 2001
From: Daisuke Baba
Date: Thu, 19 Jan 2017 17:19:41 +0900
Subject: [PATCH 04/25] Add an edge case test
---
test/red/runtime/nodes/registry/loader_spec.js | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/test/red/runtime/nodes/registry/loader_spec.js b/test/red/runtime/nodes/registry/loader_spec.js
index c3df70bd5..b7f32a2de 100644
--- a/test/red/runtime/nodes/registry/loader_spec.js
+++ b/test/red/runtime/nodes/registry/loader_spec.js
@@ -585,6 +585,24 @@ describe("red/nodes/registry/loader",function() {
loader.getNodeHelp(node,"fr").should.eql("bar");
fs.readFileSync.calledTwice.should.be.true();
});
+ it("fails to load en-US help content", function() {
+ stubs.push(sinon.stub(fs,"readFileSync", function(path) {
+ throw new Error("not found");
+ }));
+ var node = {
+ template: "/tmp/node/directory/file.html",
+ help:{}
+ };
+ delete node.help['en-US'];
+
+ should.not.exist(loader.getNodeHelp(node,"en-US"));
+ should.not.exist(node.help['en-US']);
+ fs.readFileSync.calledTwice.should.be.true();
+ fs.readFileSync.firstCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en-US/file.html"));
+ fs.readFileSync.lastCall.args[0].should.eql(path.normalize("/tmp/node/directory/locales/en/file.html"));
+ should.not.exist(loader.getNodeHelp(node,"en-US"));
+ fs.readFileSync.callCount.should.eql(4);
+ });
});
});
From 4195840b2c206db890ac34d9505d9781080d48a1 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 19 Jan 2017 11:00:22 +0000
Subject: [PATCH 05/25] make links in added info open in blank page rather than
current window
---
editor/js/ui/tab-info.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/editor/js/ui/tab-info.js b/editor/js/ui/tab-info.js
index fd9e74a42..156e29292 100644
--- a/editor/js/ui/tab-info.js
+++ b/editor/js/ui/tab-info.js
@@ -124,7 +124,8 @@ RED.sidebar.info = (function() {
} else if (node._def && node._def.info) {
var info = node._def.info;
var textInfo = (typeof info === "function" ? info.call(node) : info);
- $(''+marked(textInfo)+'
').appendTo(content);
+ var ma = marked(textInfo).replace(/href=/g, 'target="_blank" href=');
+ $(''+ma+'
').appendTo(content);
//$(''+(typeof info === "function" ? info.call(node) : info)+'
';
}
From daca78b6cd078d859b51a10dbad471498ecc642b Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 19 Jan 2017 13:24:21 +0000
Subject: [PATCH 06/25] Ensure links do not span tabs in the editor
---
editor/js/nodes.js | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/editor/js/nodes.js b/editor/js/nodes.js
index e3a906bf6..40e9806ba 100644
--- a/editor/js/nodes.js
+++ b/editor/js/nodes.js
@@ -1004,9 +1004,13 @@ RED.nodes = (function() {
var wires = (n.wires[w1] instanceof Array)?n.wires[w1]:[n.wires[w1]];
for (var w2=0;w2",node_map[wires[w2]].id);
+ }
}
}
}
From 540472a093ce6835cd1f3449b27d4a81ab9f9dee Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 19 Jan 2017 13:52:38 +0000
Subject: [PATCH 07/25] Ensure all a tags have blank target in info sidebar
---
editor/js/ui/tab-info.js | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/editor/js/ui/tab-info.js b/editor/js/ui/tab-info.js
index 156e29292..f96fbdbf3 100644
--- a/editor/js/ui/tab-info.js
+++ b/editor/js/ui/tab-info.js
@@ -66,6 +66,15 @@ RED.sidebar.info = (function() {
return value;
}
+ function addTargetToExternalLinks(el) {
+ $(el).find("a").each(function(el) {
+ var href = $(this).attr('href');
+ if (/^https?:/.test(href)) {
+ $(this).attr('target','_blank');
+ }
+ });
+ return el;
+ }
function refresh(node) {
tips.stop();
$(content).empty();
@@ -117,15 +126,14 @@ RED.sidebar.info = (function() {
$(" ").appendTo(content);
if (!subflowNode && node.type != "comment") {
var helpText = $("script[data-help-name$='"+node.type+"']").html()||"";
- $(''+helpText+'
').appendTo(content);
+ addTargetToExternalLinks($(''+helpText+'
').appendTo(content));
}
if (subflowNode) {
- $(''+marked(subflowNode.info||"")+'
').appendTo(content);
+ addTargetToExternalLinks($(''+marked(subflowNode.info||"")+'
').appendTo(content));
} else if (node._def && node._def.info) {
var info = node._def.info;
var textInfo = (typeof info === "function" ? info.call(node) : info);
- var ma = marked(textInfo).replace(/href=/g, 'target="_blank" href=');
- $(''+ma+'
').appendTo(content);
+ addTargetToExternalLinks($(''+marked(textInfo)+'
').appendTo(content));
//$(''+(typeof info === "function" ? info.call(node) : info)+'
';
}
From 3fdeb38bb74738d8097cf1b823558b151df062ff Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Sat, 21 Jan 2017 23:49:20 +0000
Subject: [PATCH 08/25] Ensure auth-tokens are removed when no user is
specified in settings
---
editor/js/settings.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/editor/js/settings.js b/editor/js/settings.js
index ae01c66dc..b26dfe990 100644
--- a/editor/js/settings.js
+++ b/editor/js/settings.js
@@ -102,7 +102,7 @@ RED.settings = (function () {
url: 'settings',
success: function (data) {
setProperties(data);
- if (RED.settings.user && RED.settings.user.anonymous) {
+ if (!RED.settings.user || RED.settings.user.anonymous) {
RED.settings.remove("auth-tokens");
}
console.log("Node-RED: " + data.version);
From fd6f7cd8813a5e5359ca5cfca4049003ab8d3bff Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 23 Jan 2017 13:57:06 +0000
Subject: [PATCH 09/25] Display debug node name in debug panel if its known
---
nodes/core/core/58-debug.html | 2 +-
nodes/core/core/lib/debug/debug-utils.js | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/nodes/core/core/58-debug.html b/nodes/core/core/58-debug.html
index d53623162..c421c0604 100644
--- a/nodes/core/core/58-debug.html
+++ b/nodes/core/core/58-debug.html
@@ -170,7 +170,7 @@
this.handleDebugMessage = function(t,o) {
var sourceNode = RED.nodes.node(o.id) || RED.nodes.node(o.z);
if (sourceNode) {
- o._source = {id:sourceNode.id,z:sourceNode.z};
+ o._source = {id:sourceNode.id,z:sourceNode.z,name:sourceNode.name};
}
RED.debug.handleDebugMessage(o);
diff --git a/nodes/core/core/lib/debug/debug-utils.js b/nodes/core/core/lib/debug/debug-utils.js
index ad18dab2c..9c9f48661 100644
--- a/nodes/core/core/lib/debug/debug-utils.js
+++ b/nodes/core/core/lib/debug/debug-utils.js
@@ -205,7 +205,7 @@ RED.debug = (function() {
var metaRow = $('
').appendTo(msg);
$(''+ getTimestamp()+' ').appendTo(metaRow);
if (sourceNode) {
- $('',{href:"#",class:"debug-message-name"}).html('node: '+sourceNode.id)
+ $(' ',{href:"#",class:"debug-message-name"}).html('node: '+(sourceNode.name||sourceNode.id))
.appendTo(metaRow)
.click(function(evt) {
evt.preventDefault();
From 7759aacb359f479dfe3943fb22ba041f63eab18d Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 23 Jan 2017 15:34:34 +0000
Subject: [PATCH 10/25] Ensure custom mustache context parent set in Template
node fixes #1126
---
nodes/core/core/80-template.js | 48 ++++++++++++++----------
test/nodes/core/core/80-template_spec.js | 12 ++++++
2 files changed, 40 insertions(+), 20 deletions(-)
diff --git a/nodes/core/core/80-template.js b/nodes/core/core/80-template.js
index c03388b30..4637da06f 100644
--- a/nodes/core/core/80-template.js
+++ b/nodes/core/core/80-template.js
@@ -19,11 +19,11 @@ module.exports = function(RED) {
var mustache = require("mustache");
/**
- * Custom Mustache Context capable to resolve message property and node
- * flow and global context
+ * Custom Mustache Context capable to resolve message property and node
+ * flow and global context
*/
- function NodeContext(msg, nodeContext) {
- this.msgContext = new mustache.Context(msg);
+ function NodeContext(msg, nodeContext,parent) {
+ this.msgContext = new mustache.Context(msg,parent);
this.nodeContext = nodeContext;
}
@@ -31,26 +31,34 @@ module.exports = function(RED) {
NodeContext.prototype.lookup = function (name) {
// try message first:
- var value = this.msgContext.lookup(name);
- if (value !== undefined) {
- return value;
- }
-
- // try node context:
- var dot = name.indexOf(".");
- if (dot > 0) {
- var contextName = name.substr(0, dot);
- var variableName = name.substr(dot + 1);
-
- if (contextName === "flow" && this.nodeContext.flow) {
- return this.nodeContext.flow.get(variableName);
+ try {
+ var value = this.msgContext.lookup(name);
+ if (value !== undefined) {
+ return value;
}
- else if (contextName === "global" && this.nodeContext.global) {
- return this.nodeContext.global.get(variableName);
+
+ // try node context:
+ var dot = name.indexOf(".");
+ if (dot > 0) {
+ var contextName = name.substr(0, dot);
+ var variableName = name.substr(dot + 1);
+
+ if (contextName === "flow" && this.nodeContext.flow) {
+ return this.nodeContext.flow.get(variableName);
+ }
+ else if (contextName === "global" && this.nodeContext.global) {
+ return this.nodeContext.global.get(variableName);
+ }
}
+ }catch(err) {
+ throw err;
}
}
+ NodeContext.prototype.push = function push (view) {
+ return new NodeContext(view, this.nodeContext,this.msgContext);
+ };
+
function TemplateNode(n) {
RED.nodes.createNode(this,n);
this.name = n.name;
@@ -64,7 +72,7 @@ module.exports = function(RED) {
try {
var value;
if (node.syntax === "mustache") {
- value = mustache.render(node.template, new NodeContext(msg, node.context()));
+ value = mustache.render(node.template,new NodeContext(msg, node.context()));
} else {
value = node.template;
}
diff --git a/test/nodes/core/core/80-template_spec.js b/test/nodes/core/core/80-template_spec.js
index 315aef6ae..811e7f179 100644
--- a/test/nodes/core/core/80-template_spec.js
+++ b/test/nodes/core/core/80-template_spec.js
@@ -166,6 +166,18 @@ describe('template node', function() {
});
});
+ it('should handle block contexts objects', function(done) {
+ var flow = [{id:"n1", type:"template", template: "A{{#payload.A}}{{payload.A}}{{.}}{{/payload.A}}B",wires:[["n2"]]},{id:"n2",type:"helper"}];
+ helper.load(templateNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ msg.should.have.property('payload','AabcabcB');
+ done();
+ });
+ n1.receive({payload:{A:"abc"}});
+ });
+ });
it('should raise error if passed bad template', function(done) {
var flow = [{id:"n1", type:"template", field: "payload", template: "payload={{payload",wires:[["n2"]]},{id:"n2",type:"helper"}];
helper.load(templateNode, flow, function() {
From 1324f5e59c7f096551bd2c856e0c19dd337725ef Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 23 Jan 2017 15:57:37 +0000
Subject: [PATCH 11/25] Update CHANGELOG for 0.16.2
---
CHANGELOG.md | 11 +++++++++++
package.json | 2 +-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a7f67ba22..af804b1d8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+#### 0.16.2: Maintenance Release
+
+ - Ensure custom mustache context parent set in Template node fixes #1126
+ - Display debug node name in debug panel if its known
+ - Ensure auth-tokens are removed when no user is specified in settings
+ - Ensure all a tags have blank target in info sidebar
+ - Ensure links do not span tabs in the editor
+ - Avoid creating multiple reconnect timers in websocket node
+ - Fix inner reference in install fail message catalog entry Fixes #1120
+ - Display buffer data properly for truncated buffers under Object property
+
#### 0.16.1: Maintenance Release
- Add colour swatches to debug when hex colour matched
diff --git a/package.json b/package.json
index 005b0e2ae..0c67d361d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name" : "node-red",
- "version" : "0.16.1",
+ "version" : "0.16.2",
"description" : "A visual tool for wiring the Internet of Things",
"homepage" : "http://nodered.org",
"license" : "Apache-2.0",
From 939768eec0193b6dc907ae490cd863547fab0035 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Sat, 28 Jan 2017 14:44:47 +0000
Subject: [PATCH 12/25] Cache auth details to save needlessly recalculating
hashes
---
red.js | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/red.js b/red.js
index 8969f2e4c..2cea58be2 100755
--- a/red.js
+++ b/red.js
@@ -196,6 +196,7 @@ try {
function basicAuthMiddleware(user,pass) {
var basicAuth = require('basic-auth');
var checkPassword;
+ var localCachedPassword;
if (pass.length == "32") {
// Assume its a legacy md5 password
checkPassword = function(p) {
@@ -207,12 +208,26 @@ function basicAuthMiddleware(user,pass) {
}
}
+ var checkPasswordAndCache = function(p) {
+ // For BasicAuth routes we know the password cannot change without
+ // a restart of Node-RED. This means we can cache the provided crypted
+ // version to save recalculating each time.
+ if (localCachedPassword === p) {
+ return true;
+ }
+ var result = checkPassword(p);
+ if (result) {
+ localCachedPassword = p;
+ }
+ return result;
+ }
+
return function(req,res,next) {
if (req.method === 'OPTIONS') {
return next();
}
var requestUser = basicAuth(req);
- if (!requestUser || requestUser.name !== user || !checkPassword(requestUser.pass)) {
+ if (!requestUser || requestUser.name !== user || !checkPasswordAndCache(requestUser.pass)) {
res.set('WWW-Authenticate', 'Basic realm=Authorization Required');
return res.sendStatus(401);
}
From 0643f149b7e4ec778d7e95208fcb566373e93674 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 30 Jan 2017 09:37:08 +0000
Subject: [PATCH 13/25] Extract line number if available from node load errors
---
red/runtime/nodes/registry/loader.js | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/red/runtime/nodes/registry/loader.js b/red/runtime/nodes/registry/loader.js
index dd4292c23..cd7d038a2 100644
--- a/red/runtime/nodes/registry/loader.js
+++ b/red/runtime/nodes/registry/loader.js
@@ -315,6 +315,18 @@ function loadNodeSet(node) {
return loadPromise;
} catch(err) {
node.err = err;
+ var stack = err.stack;
+ var message;
+ if (stack) {
+ var i = stack.indexOf(node.file);
+ if (i > -1) {
+ var excerpt = stack.substring(i+node.file.length+1,i+node.file.length+20);
+ var m = /^(\d+):(\d+)/.exec(excerpt);
+ if (m) {
+ node.err = err+" (line:"+m[1]+")";
+ }
+ }
+ }
return when.resolve(node);
}
}
From 3e021b3a752e45c1f6e8cb653bb760d5365cdb8f Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 30 Jan 2017 09:58:43 +0000
Subject: [PATCH 14/25] Fix loader test to expect line numbers in load errors
---
test/red/runtime/nodes/registry/loader_spec.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/red/runtime/nodes/registry/loader_spec.js b/test/red/runtime/nodes/registry/loader_spec.js
index 39b25d55e..7dddf826c 100644
--- a/test/red/runtime/nodes/registry/loader_spec.js
+++ b/test/red/runtime/nodes/registry/loader_spec.js
@@ -514,7 +514,7 @@ describe("red/nodes/registry/loader",function() {
node.enabled.should.be.true();
nodes.registerType.called.should.be.false();
node.should.have.property('err');
- node.err.message.should.eql("fail to require");
+ node.err.toString().should.eql("Error: fail to require (line:1)");
done();
}).otherwise(function(err) {
From 94ee465682e90adb3f0b0edac99b4dc74d87cdc2 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Thu, 2 Feb 2017 09:57:01 +0000
Subject: [PATCH 15/25] clone message before send in stay connected mode
to Fix #1137
---
nodes/core/io/31-tcpin.js | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/nodes/core/io/31-tcpin.js b/nodes/core/io/31-tcpin.js
index 709552f28..4a9650802 100644
--- a/nodes/core/io/31-tcpin.js
+++ b/nodes/core/io/31-tcpin.js
@@ -444,7 +444,7 @@ module.exports = function(RED) {
//node.log(RED._("tcpin.errors.client-connected"));
node.status({fill:"green",shape:"dot",text:"common.status.connected"});
if (clients[connection_id] && clients[connection_id].client) {
- clients[connection_id].connected = true;
+ clients[connection_id].connected = true;
clients[connection_id].client.write(clients[connection_id].msg.payload);
}
});
@@ -454,10 +454,10 @@ module.exports = function(RED) {
}
clients[connection_id].client.on('data', function(data) {
- if (node.out == "sit") { // if we are staying connected just send the buffer
+ if (node.out === "sit") { // if we are staying connected just send the buffer
if (clients[connection_id]) {
clients[connection_id].msg.payload = data;
- node.send(clients[connection_id].msg);
+ node.send(RED.util.cloneMessage(clients[connection_id].msg));
}
}
else if (node.splitc === 0) {
@@ -533,7 +533,7 @@ module.exports = function(RED) {
//console.log("END");
node.status({fill:"grey",shape:"ring",text:"common.status.disconnected"});
if (clients[connection_id] && clients[connection_id].client) {
- clients[connection_id].connected = false;
+ clients[connection_id].connected = false;
clients[connection_id].client = null;
}
});
@@ -541,7 +541,7 @@ module.exports = function(RED) {
clients[connection_id].client.on('close', function() {
//console.log("CLOSE");
if (clients[connection_id]) {
- clients[connection_id].connected = false;
+ clients[connection_id].connected = false;
}
var anyConnected = false;
From 2913e13a30ddbc35e2ca2e17629a60d7ba2b0428 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Mon, 13 Feb 2017 21:39:31 +0000
Subject: [PATCH 16/25] Misconfigured WebSocket nodes should not register msg
handlers
---
nodes/core/io/22-websocket.js | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/nodes/core/io/22-websocket.js b/nodes/core/io/22-websocket.js
index a42c3fcf9..fe1b47fdf 100644
--- a/nodes/core/io/22-websocket.js
+++ b/nodes/core/io/22-websocket.js
@@ -212,7 +212,9 @@ module.exports = function(RED) {
this.error(RED._("websocket.errors.missing-conf"));
}
this.on('close', function() {
- node.serverConfig.removeInputNode(node);
+ if (node.serverConfig) {
+ node.serverConfig.removeInputNode(node);
+ }
node.status({});
});
}
@@ -224,7 +226,7 @@ module.exports = function(RED) {
this.server = (n.client)?n.client:n.server;
this.serverConfig = RED.nodes.getNode(this.server);
if (!this.serverConfig) {
- this.error(RED._("websocket.errors.missing-conf"));
+ return this.error(RED._("websocket.errors.missing-conf"));
}
else {
// TODO: nls
From b24fac3dd88a67ca769b479638e98217dbc290c1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?=
Date: Thu, 16 Feb 2017 16:28:00 +0100
Subject: [PATCH 17/25] Use textContent to avoid manual escaping
---
editor/js/ui/view.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/editor/js/ui/view.js b/editor/js/ui/view.js
index f94059d71..346d53509 100644
--- a/editor/js/ui/view.js
+++ b/editor/js/ui/view.js
@@ -1297,7 +1297,7 @@ RED.view = (function() {
sp.className = className;
sp.style.position = "absolute";
sp.style.top = "-1000px";
- sp.innerHTML = (str||"").replace(/&/g,"&").replace(//g,">");
+ sp.textContent = (str||"");
document.body.appendChild(sp);
var w = sp.offsetWidth;
document.body.removeChild(sp);
From 37dd075309ef8709d90e90615d1049130ef25300 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Linus=20Unneb=C3=A4ck?=
Date: Thu, 16 Feb 2017 18:05:59 +0100
Subject: [PATCH 18/25] Use pre-calculated values for connection path
---
editor/js/ui/view.js | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/editor/js/ui/view.js b/editor/js/ui/view.js
index 346d53509..56e616feb 100644
--- a/editor/js/ui/view.js
+++ b/editor/js/ui/view.js
@@ -2227,10 +2227,10 @@ RED.view = (function() {
d.x2 = d.target.x-d.target.w/2;
d.y2 = d.target.y;
- return "M "+(d.source.x+d.source.w/2)+" "+(d.source.y+y)+
- " C "+(d.source.x+d.source.w/2+scale*node_width)+" "+(d.source.y+y+scaleY*node_height)+" "+
- (d.target.x-d.target.w/2-scale*node_width)+" "+(d.target.y-scaleY*node_height)+" "+
- (d.target.x-d.target.w/2)+" "+d.target.y;
+ return "M "+d.x1+" "+d.y1+
+ " C "+(d.x1+scale*node_width)+" "+(d.y1+scaleY*node_height)+" "+
+ (d.x2-scale*node_width)+" "+(d.y2-scaleY*node_height)+" "+
+ d.x2+" "+d.y2;
});
}
})
From e2a9be9cec62660060233d9f522efd75dc4c1915 Mon Sep 17 00:00:00 2001
From: Nick O'Leary
Date: Thu, 16 Feb 2017 21:41:20 +0000
Subject: [PATCH 19/25] Defer resizing tray components until they have finished
building
---
editor/js/ui/editor.js | 118 ++++++++++++++++++++------------------
editor/js/ui/tray.js | 125 ++++++++++++++++++-----------------------
2 files changed, 118 insertions(+), 125 deletions(-)
diff --git a/editor/js/ui/editor.js b/editor/js/ui/editor.js
index de1e691dd..8b772d8f6 100644
--- a/editor/js/ui/editor.js
+++ b/editor/js/ui/editor.js
@@ -430,7 +430,7 @@ RED.editor = (function() {
* @param definition - the node definition
* @param prefix - the prefix to use in the input element ids (node-input|node-config-input)
*/
- function prepareEditDialog(node,definition,prefix) {
+ function prepareEditDialog(node,definition,prefix,done) {
for (var d in definition.defaults) {
if (definition.defaults.hasOwnProperty(d)) {
if (definition.defaults[d].type) {
@@ -474,6 +474,9 @@ RED.editor = (function() {
}
}
validateNodeEditor(node,prefix);
+ if (done) {
+ done();
+ }
}
if (definition.credentials) {
@@ -791,7 +794,7 @@ RED.editor = (function() {
}
}
},
- open: function(tray) {
+ open: function(tray,done) {
if (editing_node) {
RED.sidebar.info.refresh(editing_node);
}
@@ -802,8 +805,11 @@ RED.editor = (function() {
ns = node._def.set.id;
}
var dialogForm = buildEditForm(tray,"dialog-form",type,ns);
- prepareEditDialog(node,node._def,"node-input");
- dialogForm.i18n();
+ prepareEditDialog(node,node._def,"node-input", function() {
+ dialogForm.i18n();
+ done();
+ });
+
},
close: function() {
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
@@ -888,11 +894,11 @@ RED.editor = (function() {
try {
editing_config_node._def.oneditresize.call(editing_config_node,{width:form.width(),height:form.height()});
} catch(err) {
- console.log("oneditresize",editing_node.id,editing_node.type,err.toString());
+ console.log("oneditresize",editing_config_node.id,editing_config_node.type,err.toString());
}
}
},
- open: function(tray) {
+ open: function(tray, done) {
var trayHeader = tray.find(".editor-tray-header");
var trayFooter = tray.find(".editor-tray-footer");
@@ -903,58 +909,60 @@ RED.editor = (function() {
var dialogForm = buildEditForm(tray,"node-config-dialog-edit-form",type,ns);
- prepareEditDialog(editing_config_node,node_def,"node-config-input");
- if (editing_config_node._def.exclusive) {
- $("#node-config-dialog-scope").hide();
- } else {
- $("#node-config-dialog-scope").show();
- }
- $("#node-config-dialog-scope-warning").hide();
+ prepareEditDialog(editing_config_node,node_def,"node-config-input", function() {
+ if (editing_config_node._def.exclusive) {
+ $("#node-config-dialog-scope").hide();
+ } else {
+ $("#node-config-dialog-scope").show();
+ }
+ $("#node-config-dialog-scope-warning").hide();
- var nodeUserFlows = {};
- editing_config_node.users.forEach(function(n) {
- nodeUserFlows[n.z] = true;
- });
- var flowCount = Object.keys(nodeUserFlows).length;
- var tabSelect = $("#node-config-dialog-scope").empty();
- tabSelect.off("change");
- tabSelect.append(' ');
- tabSelect.append(' ');
- RED.nodes.eachWorkspace(function(ws) {
- var workspaceLabel = ws.label;
- if (nodeUserFlows[ws.id]) {
- workspaceLabel = "* "+workspaceLabel;
- }
- tabSelect.append(''+workspaceLabel+' ');
- });
- tabSelect.append(' ');
- RED.nodes.eachSubflow(function(ws) {
- var workspaceLabel = ws.name;
- if (nodeUserFlows[ws.id]) {
- workspaceLabel = "* "+workspaceLabel;
- }
- tabSelect.append(''+workspaceLabel+' ');
- });
- if (flowCount > 0) {
- tabSelect.on('change',function() {
- var newScope = $(this).val();
- if (newScope === '') {
- // global scope - everyone can use it
- $("#node-config-dialog-scope-warning").hide();
- } else if (!nodeUserFlows[newScope] || flowCount > 1) {
- // a user will loose access to it
- $("#node-config-dialog-scope-warning").show();
- } else {
- $("#node-config-dialog-scope-warning").hide();
- }
+ var nodeUserFlows = {};
+ editing_config_node.users.forEach(function(n) {
+ nodeUserFlows[n.z] = true;
});
- }
- tabSelect.i18n();
+ var flowCount = Object.keys(nodeUserFlows).length;
+ var tabSelect = $("#node-config-dialog-scope").empty();
+ tabSelect.off("change");
+ tabSelect.append(' ');
+ tabSelect.append(' ');
+ RED.nodes.eachWorkspace(function(ws) {
+ var workspaceLabel = ws.label;
+ if (nodeUserFlows[ws.id]) {
+ workspaceLabel = "* "+workspaceLabel;
+ }
+ tabSelect.append(''+workspaceLabel+' ');
+ });
+ tabSelect.append(' ');
+ RED.nodes.eachSubflow(function(ws) {
+ var workspaceLabel = ws.name;
+ if (nodeUserFlows[ws.id]) {
+ workspaceLabel = "* "+workspaceLabel;
+ }
+ tabSelect.append(''+workspaceLabel+' ');
+ });
+ if (flowCount > 0) {
+ tabSelect.on('change',function() {
+ var newScope = $(this).val();
+ if (newScope === '') {
+ // global scope - everyone can use it
+ $("#node-config-dialog-scope-warning").hide();
+ } else if (!nodeUserFlows[newScope] || flowCount > 1) {
+ // a user will loose access to it
+ $("#node-config-dialog-scope-warning").show();
+ } else {
+ $("#node-config-dialog-scope-warning").hide();
+ }
+ });
+ }
+ tabSelect.i18n();
- dialogForm.i18n();
- if (node_def.hasUsers !== false) {
- $("#node-config-dialog-user-count").find("span").html(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
- }
+ dialogForm.i18n();
+ if (node_def.hasUsers !== false) {
+ $("#node-config-dialog-user-count").find("span").html(RED._("editor.nodesUse", {count:editing_config_node.users.length})).parent().show();
+ }
+ done();
+ });
},
close: function() {
RED.workspaces.refresh();
diff --git a/editor/js/ui/tray.js b/editor/js/ui/tray.js
index 8ba3d4e97..397a0b154 100644
--- a/editor/js/ui/tray.js
+++ b/editor/js/ui/tray.js
@@ -104,85 +104,70 @@ RED.tray = (function() {
}
});
- if (options.open) {
- options.open(el);
- }
+ function finishBuild() {
+ $("#header-shade").show();
+ $("#editor-shade").show();
+ $("#palette-shade").show();
+ $(".sidebar-shade").show();
- $("#header-shade").show();
- $("#editor-shade").show();
- $("#palette-shade").show();
- $(".sidebar-shade").show();
+ tray.preferredWidth = Math.max(el.width(),500);
+ body.css({"minWidth":tray.preferredWidth-40});
- tray.preferredWidth = Math.max(el.width(),500);
- body.css({"minWidth":tray.preferredWidth-40});
-
- if (options.width) {
- if (options.width > $("#editor-stack").position().left-8) {
- options.width = $("#editor-stack").position().left-8;
+ if (options.width) {
+ if (options.width > $("#editor-stack").position().left-8) {
+ options.width = $("#editor-stack").position().left-8;
+ }
+ el.width(options.width);
+ } else {
+ el.width(tray.preferredWidth);
}
- el.width(options.width);
- } else {
- el.width(tray.preferredWidth);
- }
- tray.width = el.width();
- if (tray.width > $("#editor-stack").position().left-8) {
- tray.width = Math.max(0/*tray.preferredWidth*/,$("#editor-stack").position().left-8);
- el.width(tray.width);
- }
+ tray.width = el.width();
+ if (tray.width > $("#editor-stack").position().left-8) {
+ tray.width = Math.max(0/*tray.preferredWidth*/,$("#editor-stack").position().left-8);
+ el.width(tray.width);
+ }
- // tray.body.parent().width(Math.min($("#editor-stack").position().left-8,tray.width));
+ // tray.body.parent().width(Math.min($("#editor-stack").position().left-8,tray.width));
- el.css({
- right: -(el.width()+10)+"px",
- transition: "right 0.25s ease"
- });
- $("#workspace").scrollLeft(0);
- handleWindowResize();
- openingTray = true;
- setTimeout(function() {
+ el.css({
+ right: -(el.width()+10)+"px",
+ transition: "right 0.25s ease"
+ });
+ $("#workspace").scrollLeft(0);
+ handleWindowResize();
+ openingTray = true;
setTimeout(function() {
- if (!options.width) {
- el.width(Math.min(tray.preferredWidth,$("#editor-stack").position().left-8));
- }
- if (options.resize) {
- options.resize({width:el.width()});
- }
- if (options.show) {
- options.show();
- }
setTimeout(function() {
- // Delay resetting the flag, so we don't close prematurely
- openingTray = false;
- },200);
- body.find(":focusable:first").focus();
-
- },150);
- el.css({right:0});
- },0);
-
- // growButton.click(function(e) {
- // e.preventDefault();
- // tray.lastWidth = tray.width;
- // tray.width = $("#editor-stack").position().left-8;
- // el.width(tray.width);
- // if (options.resize) {
- // options.resize({width:tray.width});
- // }
- // });
- // shrinkButton.click(function(e) {
- // e.preventDefault();
- // if (tray.lastWidth && tray.width > tray.lastWidth) {
- // tray.width = tray.lastWidth;
- // } else if (tray.width > tray.preferredWidth) {
- // tray.width = tray.preferredWidth;
- // }
- // el.width(tray.width);
- // if (options.resize) {
- // options.resize({width:tray.width});
- // }
- // });
+ if (!options.width) {
+ el.width(Math.min(tray.preferredWidth,$("#editor-stack").position().left-8));
+ }
+ if (options.resize) {
+ options.resize({width:el.width()});
+ }
+ if (options.show) {
+ options.show();
+ }
+ setTimeout(function() {
+ // Delay resetting the flag, so we don't close prematurely
+ openingTray = false;
+ },200);
+ body.find(":focusable:first").focus();
+ },150);
+ el.css({right:0});
+ },0);
+ }
+ if (options.open) {
+ if (options.open.length === 1) {
+ options.open(el);
+ finishBuild();
+ } else {
+ options.open(el,finishBuild);
+ }
+ } else {
+ finishBuild();
+ }
}
function handleWindowResize() {
From a625eeeac87dbaef69744fda67cf0a412daa8a77 Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Wed, 22 Feb 2017 20:19:44 +0000
Subject: [PATCH 20/25] move csv fixes to master
to fix #1142 in master
---
nodes/core/parsers/70-CSV.js | 29 +++++++++++++++++++++++---
test/nodes/core/parsers/70-CSV_spec.js | 24 ++++++++++++++++-----
2 files changed, 45 insertions(+), 8 deletions(-)
diff --git a/nodes/core/parsers/70-CSV.js b/nodes/core/parsers/70-CSV.js
index f02a8d080..fa1ece00f 100644
--- a/nodes/core/parsers/70-CSV.js
+++ b/nodes/core/parsers/70-CSV.js
@@ -28,6 +28,7 @@ module.exports = function(RED) {
this.hdrin = n.hdrin || false;
this.hdrout = n.hdrout || false;
this.goodtmpl = true;
+ var tmpwarn = true;
var node = this;
// pass in an array of column names to be trimed, de-quoted and retrimed
@@ -71,7 +72,27 @@ module.exports = function(RED) {
}
else {
if ((node.template.length === 1) && (node.template[0] === '')) {
- node.warn(RED._("csv.errors.obj_csv"));
+ if (tmpwarn === true) { // just warn about missing template once
+ node.warn(RED._("csv.errors.obj_csv"));
+ tmpwarn = false;
+ }
+ ou = "";
+ for (var p in msg.payload[0]) {
+ if (msg.payload[0].hasOwnProperty(p)) {
+ if (typeof msg.payload[0][p] !== "object") {
+ var q = msg.payload[0][p];
+ if (q.indexOf(node.quo) !== -1) { // add double quotes if any quotes
+ q = q.replace(/"/g, '""');
+ ou += node.quo + q + node.quo + node.sep;
+ }
+ else if (q.indexOf(node.sep) !== -1) { // add quotes if any "commas"
+ ou += node.quo + q + node.quo + node.sep;
+ }
+ else { ou += q + node.sep; } // otherwise just add
+ }
+ }
+ }
+ ou = ou.slice(0,-1) + node.ret;
}
else {
for (var t=0; t < node.template.length; t++) {
@@ -112,7 +133,7 @@ module.exports = function(RED) {
var first = true; // is this the first line
var line = msg.payload;
var tmp = "";
- var reg = new RegExp("^[-]?[0-9.]*[\.]?[0-9]*$");
+ var reg = /^[-]?[0-9]*\.?[0-9]+$/;
// For now we are just going to assume that any \r or \n means an end of line...
// got to be a weird csv that has singleton \r \n in it for another reason...
@@ -129,7 +150,9 @@ module.exports = function(RED) {
else {
if (line[i] === node.quo) { // if it's a quote toggle inside or outside
f = !f;
- if (line[i-1] === node.quo) { k[j] += '\"'; } // if it's a quotequote then it's actually a quote
+ if (line[i-1] === node.quo) {
+ if (f === false) { k[j] += '\"'; }
+ } // if it's a quotequote then it's actually a quote
//if ((line[i-1] !== node.sep) && (line[i+1] !== node.sep)) { k[j] += line[i]; }
}
else if ((line[i] === node.sep) && f) { // if it is the end of the line then finish
diff --git a/test/nodes/core/parsers/70-CSV_spec.js b/test/nodes/core/parsers/70-CSV_spec.js
index 5c7f2b3dd..98a842e30 100644
--- a/test/nodes/core/parsers/70-CSV_spec.js
+++ b/test/nodes/core/parsers/70-CSV_spec.js
@@ -119,7 +119,7 @@ describe('CSV node', function() {
msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: 4, e: -5, f: 'ab"cd', g: 'with,a,comma' });
done();
});
- var testString = '"1","-2","+3","04","-05",ab""cd,"with,a,comma"'+String.fromCharCode(10);
+ var testString = '"1","-2","+3","04","-05","ab""cd","with,a,comma"'+String.fromCharCode(10);
n1.emit("input", {payload:testString});
});
});
@@ -132,12 +132,11 @@ describe('CSV node', function() {
var n2 = helper.getNode("n2");
n2.on("input", function(msg) {
//console.log(msg);
- msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: 4, e: -5, f: 'ab"cd', g: 'with,a,comma' });
+ msg.should.have.property('payload', { a: "with,an", b: "odd,number", c: "ofquotes" });
+ //msg.should.have.property('payload', { a: 1, b: -2, c: '+3', d: 4, e: -5, f: 'ab"cd', g: 'with,a,comma' });
done();
});
- var testString = '"with,a"n,odd",num"ber,of"quotes'+String.fromCharCode(10);
- n1.emit("input", {payload:testString});
- testString = '"1","-2","+3","04","-05",ab""cd,"with,a,comma"'+String.fromCharCode(10);
+ var testString = '"with,a"n,odd","num"ber","of"qu"ot"es"'+String.fromCharCode(10);
n1.emit("input", {payload:testString});
});
});
@@ -179,6 +178,21 @@ describe('CSV node', function() {
n1.emit("input", {payload:testString});
});
});
+
+ it('should handle numbers in strings but not IP addresses', function(done) {
+ var flow = [ { id:"n1", type:"csv", temp:"a,b,c,d,e", wires:[["n2"]] },
+ {id:"n2", type:"helper"} ];
+ helper.load(csvNode, flow, function() {
+ var n1 = helper.getNode("n1");
+ var n2 = helper.getNode("n2");
+ n2.on("input", function(msg) {
+ msg.should.have.property('payload', { a: "a", b: "127.0.0.1", c: 56.7, d: -32.8, e: "+76.22C" });
+ done();
+ });
+ var testString = "a,127.0.0.1,56.7,-32.8,+76.22C";
+ n1.emit("input", {payload:testString});
+ });
+ });
});
describe('json object to csv', function() {
From ee0bd49918db1becdb0b166c8e43340c6b06402b Mon Sep 17 00:00:00 2001
From: cinhcet
Date: Wed, 22 Feb 2017 23:22:06 +0100
Subject: [PATCH 21/25] exec node returns 0 on the third output if command
ended without error. (#1160)
* exec node returns 0 on the third output if command ended without error.
Otherwise, the status of the node is updated and the error code is send through the third output.
* info text updated and the second output returns only something if stderr is not empty
* proper stderror handling
* proper handling of stderr
---
nodes/core/core/75-exec.html | 5 ++++-
nodes/core/core/75-exec.js | 12 ++++++++----
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/nodes/core/core/75-exec.html b/nodes/core/core/75-exec.html
index 0f3a11c59..6aa423fb4 100644
--- a/nodes/core/core/75-exec.html
+++ b/nodes/core/core/75-exec.html
@@ -47,10 +47,13 @@
Calls out to a system command.
Provides 3 outputs: stdout, stderr, and return code.
By default uses the exec
system call which calls the command, then gets a callback
- on completion, returning the complete result in one message, along with any errors.
+ on completion, returning stdout as the payload to the first, the error code as the third
+ and, if available, stderr to the second output. If no error occurred, a zero is returned on the third output.
Optionally can use spawn
instead, which returns the output from stdout and stderr
as the command runs (usually one line at a time). On completion it then returns a return code
(on the 3rd output).
+ The exec
method spawns a subshell and therefore can be used for more complicated
+ commands involving pipes. However, it waits for completion of the whole command before returing anything.
The optional append gets added to the command after msg.payload
- so you can do
things like pipe the result to another command.
Commands or parameters with spaces should be enclosed in quotes - "This is a single parameter"
diff --git a/nodes/core/core/75-exec.js b/nodes/core/core/75-exec.js
index 546a3f130..0847957a4 100644
--- a/nodes/core/core/75-exec.js
+++ b/nodes/core/core/75-exec.js
@@ -102,15 +102,19 @@ module.exports = function(RED) {
child = exec(cl, {encoding: 'binary', maxBuffer:10000000}, function (error, stdout, stderr) {
msg.payload = new Buffer(stdout,"binary");
if (isUtf8(msg.payload)) { msg.payload = msg.payload.toString(); }
- var msg2 = {payload:stderr};
- var msg3 = null;
+ var msg2 = null;
+ if(stderr) {
+ msg2 = {payload: stderr};
+ }
+ var msg3 = {payload:0};
+ node.status({});
//console.log('[exec] stdout: ' + stdout);
//console.log('[exec] stderr: ' + stderr);
if (error !== null) {
- msg3 = {payload:error};
+ msg3 = {payload:error.code};
+ node.status({fill:"red",shape:"dot",text:"error: "+error.code});
//console.log('[exec] error: ' + error);
}
- node.status({});
node.send([msg,msg2,msg3]);
if (child.tout) { clearTimeout(child.tout); }
delete node.activeProcesses[child.pid];
From 8b31a918a4ef352f4b36086592844d181ad9cddc Mon Sep 17 00:00:00 2001
From: Dave Conway-Jones
Date: Mon, 27 Feb 2017 19:22:02 +0000
Subject: [PATCH 22/25] Fix Pi GPIO debounce
To close #1139
---
nodes/core/hardware/36-rpi-gpio.html | 3 ---
nodes/core/hardware/36-rpi-gpio.js | 11 ++++++++---
nodes/core/hardware/nrgpio.py | 6 +++---
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/nodes/core/hardware/36-rpi-gpio.html b/nodes/core/hardware/36-rpi-gpio.html
index 627129364..37c63fafd 100644
--- a/nodes/core/hardware/36-rpi-gpio.html
+++ b/nodes/core/hardware/36-rpi-gpio.html
@@ -218,7 +218,6 @@
var pinsInUse = {};
RED.nodes.registerType('rpi-gpio out',{
category: 'Raspberry Pi',
- label: 'Raspberry Pi',
color:"#c6dbef",
defaults: {
name: { value:"" },
@@ -351,7 +350,6 @@