', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
+ iconClass: "fa fa-file-text-o",
+ onchange: function() {
+ subflowEditor.focus();
+ }
+ };
+ editorTabs.addTab(descriptionTab);
+ subflowEditor = buildDescriptionForm(descriptionTab.content,editing_node);
+
+ var appearanceTab = {
+ id: "editor-tab-appearance",
+ label: "Appearance",
+ name: "Appearance",
+ content: $('
', {class:"editor-tray-content"}).appendTo(editorContent).hide(),
+ iconClass: "fa fa-object-group",
+ onchange: function() {
+ refreshLabelForm(this.content,editing_node);
+ }
+ };
+ buildAppearanceForm(appearanceTab.content,editing_node);
+ editorTabs.addTab(appearanceTab);
+
+
+
+
$("#subflow-input-name").val(subflow.name);
RED.text.bidi.prepareInput($("#subflow-input-name"));
@@ -1836,10 +2021,7 @@ RED.editor = (function() {
}
})
-
$("#subflow-input-category").val(subflow.category||"subflows");
-
- subflowEditor.getSession().setValue(subflow.info||"",-1);
var userCount = 0;
var subflowType = "subflow:"+editing_node.id;
@@ -1850,8 +2032,8 @@ RED.editor = (function() {
});
$("#subflow-dialog-user-count").text(RED._("subflow.subflowInstances", {count:userCount})).show();
- buildLabelForm(portLabels.content,subflow);
trayBody.i18n();
+ finishedBuilding = true;
},
close: function() {
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
@@ -1860,6 +2042,7 @@ RED.editor = (function() {
RED.sidebar.info.refresh(editing_node);
RED.workspaces.refresh();
subflowEditor.destroy();
+ subflowEditor = null;
editStack.pop();
editing_node = null;
},
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/search.js b/packages/node_modules/@node-red/editor-client/src/js/ui/search.js
index f13281807..837f6831e 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/search.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/search.js
@@ -118,6 +118,7 @@ RED.search = (function() {
}
}
}
+
function ensureSelectedIsVisible() {
var selectedEntry = searchResults.find("li.selected");
if (selectedEntry.length === 1) {
@@ -143,6 +144,7 @@ RED.search = (function() {
search($(this).val());
}
});
+
searchInput.on('keydown',function(evt) {
var children;
if (results.length > 0) {
@@ -229,12 +231,13 @@ RED.search = (function() {
});
}
+
function reveal(node) {
hide();
RED.view.reveal(node.id);
}
- function show() {
+ function show(v) {
if (disabled) {
return;
}
@@ -250,11 +253,13 @@ RED.search = (function() {
createDialog();
}
dialog.slideDown(300);
+ searchInput.searchBox('value',v)
RED.events.emit("search:open");
visible = true;
}
searchInput.focus();
}
+
function hide() {
if (visible) {
RED.keyboard.remove("escape");
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
index a7bfd47b1..7eaa9627d 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/subflow.js
@@ -21,8 +21,6 @@ RED.subflow = (function() {
var _subflowTemplateEditTemplate = '';
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
index 00caea6cd..438fbe359 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-config.js
@@ -140,7 +140,8 @@ RED.sidebar.config = (function() {
var entry = $('
').appendTo(list);
$('
').text(label).appendTo(entry);
if (node._def.hasUsers !== false) {
- var iconContainer = $('
',{class:"palette_icon_container palette_icon_container_right"}).text(node.users.length).appendTo(entry);
+ var iconContainer = $('
',{class:"palette_icon_container palette_icon_container_right"}).appendTo(entry);
+ var butt = $('
').click(function(e) { e.preventDefault(); RED.search.show(node.id); }).text(node.users.length).appendTo(iconContainer);
if (node.users.length === 0) {
entry.addClass("config_node_unused");
}
@@ -161,7 +162,6 @@ RED.sidebar.config = (function() {
});
RED.view.redraw();
});
-
entry.on('mouseout',function(e) {
RED.nodes.eachNode(function(node) {
if(node.highlighted) {
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
index 7802f6e1a..287df1130 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tab-info.js
@@ -277,6 +277,10 @@ RED.sidebar.info = (function() {
// TODO: help
infoText = infoText + marked(textInfo);
}
+ if (node.info) {
+ infoSection.title.text(RED._("sidebar.info.nodeHelp"));
+ infoText = marked(node.info || "") || ('
' + RED._("sidebar.info.none") + '');
+ }
if (infoText) {
setInfoText(infoText);
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js b/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js
index 3c6a78a6b..2fdbb2ac8 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/tray.js
@@ -232,6 +232,7 @@ RED.tray = (function() {
}
},
+ resize: handleWindowResize,
close: function close(done) {
if (stack.length > 0) {
var tray = stack.pop();
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 b5e4c1f4a..bdfd2088b 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
@@ -826,7 +826,11 @@ RED.utils = (function() {
}
result = nodeColorCache[type];
}
- return result;
+ if (result) {
+ return result;
+ } else {
+ return "#ddd";
+ }
}
function addSpinnerOverlay(container,contain) {
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 a80f7446f..6e6560418 100644
--- 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
@@ -1766,7 +1766,7 @@ RED.view = (function() {
clickTime = now;
dblClickPrimed = (lastClickNode == mousedown_node &&
- d3.event.buttons === 1 &&
+ d3.event.button === 0 &&
!d3.event.shiftKey && !d3.event.metaKey && !d3.event.altKey && !d3.event.ctrlKey);
lastClickNode = mousedown_node;
diff --git a/packages/node_modules/@node-red/nodes/99-sample.html.demo b/packages/node_modules/@node-red/nodes/99-sample.html.demo
index 94e049e31..c7548b032 100644
--- a/packages/node_modules/@node-red/nodes/99-sample.html.demo
+++ b/packages/node_modules/@node-red/nodes/99-sample.html.demo
@@ -67,6 +67,7 @@
},
inputs:1, // set the number of inputs - only 0 or 1
outputs:1, // set the number of outputs - 0 to n
+ color: "#ddd", // set icon color
// set the icon (held in icons dir below where you save the node)
icon: "myicon.png", // saved in icons/myicon.png
label: function() { // sets the default label contents
diff --git a/packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py b/packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py
index 0cde0e4df..7908ca117 100755
--- a/packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py
+++ b/packages/node_modules/@node-red/nodes/core/hardware/nrgpio.py
@@ -21,7 +21,12 @@ import os
import subprocess
from time import sleep
-bounce = 25;
+try:
+ raw_input # Python 2
+except NameError:
+ raw_input = input # Python 3
+
+bounce = 25
if len(sys.argv) > 2:
cmd = sys.argv[1].lower()
@@ -198,7 +203,7 @@ if len(sys.argv) > 2:
elif cmd == "kbd": # catch keyboard button events
try:
while not os.path.isdir("/dev/input/by-path"):
- time.sleep(10)
+ sleep(10)
infile = subprocess.check_output("ls /dev/input/by-path/ | grep -m 1 'kbd'", shell=True).strip()
infile_path = "/dev/input/by-path/" + infile
EVENT_SIZE = struct.calcsize('llHHI')
diff --git a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
index 4ddb1d3b9..28d67d077 100644
--- a/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
+++ b/packages/node_modules/@node-red/nodes/core/io/21-httprequest.js
@@ -83,6 +83,7 @@ module.exports = function(RED) {
opts.headers = {};
opts.encoding = null; // Force NodeJs to return a Buffer (instead of a string)
opts.maxRedirects = 21;
+ opts.jar = request.jar();
var ctSet = "Content-Type"; // set default camel case
var clSet = "Content-Length";
if (msg.headers) {
@@ -112,28 +113,42 @@ module.exports = function(RED) {
}
if (msg.hasOwnProperty('followRedirects')) {
opts.followRedirect = msg.followRedirects;
+ }
+ if (!opts.hasOwnProperty('followRedirect') || opts.followRedirect) {
+ opts.followRedirect = function(res) {
+ if (this.headers.cookie) {
+ delete this.headers.cookie;
+ }
+ return true;
+ };
+ }
+ if (opts.headers.hasOwnProperty('cookie')) {
+ var cookies = cookie.parse(opts.headers.cookie);
+ for (var name in cookies) {
+ if (cookies.hasOwnProperty(name)) {
+ if (cookies[name] === null) {
+ // This case clears a cookie for HTTP In/Response nodes.
+ // Ignore for this node.
+ } else {
+ opts.jar.setCookie(name + '=' + cookies[name], url);
+ }
+ }
}
+ delete opts.headers.cookie;
+ }
if (msg.cookies) {
- var cookies = [];
- if (opts.headers.hasOwnProperty('cookie')) {
- cookies.push(opts.headers.cookie);
- }
-
for (var name in msg.cookies) {
if (msg.cookies.hasOwnProperty(name)) {
if (msg.cookies[name] === null || msg.cookies[name].value === null) {
// This case clears a cookie for HTTP In/Response nodes.
// Ignore for this node.
} else if (typeof msg.cookies[name] === 'object') {
- cookies.push(cookie.serialize(name,msg.cookies[name].value));
+ opts.jar.setCookie(name + '=' + msg.cookies[name].value, url);
} else {
- cookies.push(cookie.serialize(name,msg.cookies[name]));
+ opts.jar.setCookie(name + '=' + msg.cookies[name], url);
}
}
}
- if (cookies.length > 0) {
- opts.headers.cookie = cookies.join("; ");
- }
}
if (this.credentials && this.credentials.user) {
opts.auth = {
diff --git a/packages/node_modules/@node-red/nodes/core/logic/10-switch.js b/packages/node_modules/@node-red/nodes/core/logic/10-switch.js
index 89593047e..1d9c52971 100644
--- a/packages/node_modules/@node-red/nodes/core/logic/10-switch.js
+++ b/packages/node_modules/@node-red/nodes/core/logic/10-switch.js
@@ -92,31 +92,80 @@ module.exports = function(RED) {
}
function getProperty(node,msg) {
- return new Promise((resolve,reject) => {
+ if (node.useAsyncRules) {
+ return new Promise((resolve,reject) => {
+ if (node.propertyType === 'jsonata') {
+ RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
+ if (err) {
+ reject(RED._("switch.errors.invalid-expr",{error:err.message}));
+ } else {
+ resolve(value);
+ }
+ });
+ } else {
+ RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg,(err,value) => {
+ if (err) {
+ resolve(undefined);
+ } else {
+ resolve(value);
+ }
+ });
+ }
+ });
+ } else {
if (node.propertyType === 'jsonata') {
- RED.util.evaluateJSONataExpression(node.property,msg,(err,value) => {
- if (err) {
- reject(RED._("switch.errors.invalid-expr",{error:err.message}));
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateJSONataExpression(node.property,msg);
+ } catch(err) {
+ throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
+ }
} else {
- RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg,(err,value) => {
- if (err) {
- resolve(undefined);
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateNodeProperty(node.property,node.propertyType,node,msg);
+ } catch(err) {
+ return undefined;
+ }
}
- });
+ }
}
function getV1(node,msg,rule,hasParts) {
- return new Promise( (resolve,reject) => {
+ if (node.useAsyncRules) {
+ return new Promise( (resolve,reject) => {
+ if (rule.vt === 'prev') {
+ resolve(node.previousValue);
+ } else if (rule.vt === 'jsonata') {
+ var exp = rule.v;
+ if (rule.t === 'jsonata_exp') {
+ if (hasParts) {
+ exp.assign("I", msg.parts.index);
+ exp.assign("N", msg.parts.count);
+ }
+ }
+ RED.util.evaluateJSONataExpression(exp,msg,(err,value) => {
+ if (err) {
+ reject(RED._("switch.errors.invalid-expr",{error:err.message}));
+ } else {
+ resolve(value);
+ }
+ });
+ } else if (rule.vt === 'json') {
+ resolve("json"); // TODO: ?! invalid case
+ } else if (rule.vt === 'null') {
+ resolve("null");
+ } else {
+ RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg, function(err,value) {
+ if (err) {
+ resolve(undefined);
+ } else {
+ resolve(value);
+ }
+ });
+ }
+ });
+ } else {
if (rule.vt === 'prev') {
- resolve(node.previousValue);
+ return node.previousValue;
} else if (rule.vt === 'jsonata') {
var exp = rule.v;
if (rule.t === 'jsonata_exp') {
@@ -125,83 +174,120 @@ module.exports = function(RED) {
exp.assign("N", msg.parts.count);
}
}
- RED.util.evaluateJSONataExpression(exp,msg,(err,value) => {
- if (err) {
- reject(RED._("switch.errors.invalid-expr",{error:err.message}));
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateJSONataExpression(exp,msg);
+ } catch(err) {
+ throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
+ }
} else if (rule.vt === 'json') {
- resolve("json");
+ return "json"; // TODO: ?! invalid case
} else if (rule.vt === 'null') {
- resolve("null");
+ return "null";
} else {
- RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg, function(err,value) {
- if (err) {
- resolve(undefined);
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateNodeProperty(rule.v,rule.vt,node,msg);
+ } catch(err) {
+ return undefined;
+ }
}
- });
+ }
}
function getV2(node,msg,rule) {
- return new Promise((resolve,reject) => {
+ if (node.useAsyncRules) {
+ return new Promise((resolve,reject) => {
+ var v2 = rule.v2;
+ if (rule.v2t === 'prev') {
+ resolve(node.previousValue);
+ } else if (rule.v2t === 'jsonata') {
+ RED.util.evaluateJSONataExpression(rule.v2,msg,(err,value) => {
+ if (err) {
+ reject(RED._("switch.errors.invalid-expr",{error:err.message}));
+ } else {
+ resolve(value);
+ }
+ });
+ } else if (typeof v2 !== 'undefined') {
+ RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg, function(err,value) {
+ if (err) {
+ resolve(undefined);
+ } else {
+ resolve(value);
+ }
+ });
+ } else {
+ resolve(v2);
+ }
+ })
+ } else {
var v2 = rule.v2;
if (rule.v2t === 'prev') {
- resolve(node.previousValue);
+ return node.previousValue;
} else if (rule.v2t === 'jsonata') {
- RED.util.evaluateJSONataExpression(rule.v2,msg,(err,value) => {
- if (err) {
- reject(RED._("switch.errors.invalid-expr",{error:err.message}));
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateJSONataExpression(rule.v2,msg);
+ } catch(err) {
+ throw new Error(RED._("switch.errors.invalid-expr",{error:err.message}))
+ }
} else if (typeof v2 !== 'undefined') {
- RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg, function(err,value) {
- if (err) {
- resolve(undefined);
- } else {
- resolve(value);
- }
- });
+ try {
+ return RED.util.evaluateNodeProperty(rule.v2,rule.v2t,node,msg);
+ } catch(err) {
+ return undefined;
+ }
} else {
- resolve(v2);
+ return v2;
}
- })
+ }
}
function applyRule(node, msg, property, state) {
- return new Promise((resolve,reject) => {
+ if (node.useAsyncRules) {
+ return new Promise((resolve,reject) => {
- var rule = node.rules[state.currentRule];
- var v1,v2;
+ var rule = node.rules[state.currentRule];
+ var v1,v2;
- getV1(node,msg,rule,state.hasParts).then(value => {
- v1 = value;
- }).then(()=>getV2(node,msg,rule)).then(value => {
- v2 = value;
- }).then(() => {
- if (rule.t == "else") {
- property = state.elseflag;
- state.elseflag = true;
- }
- if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
- state.onward.push(msg);
- state.elseflag = false;
- if (node.checkall == "false") {
- return resolve(false);
+ getV1(node,msg,rule,state.hasParts).then(value => {
+ v1 = value;
+ }).then(()=>getV2(node,msg,rule)).then(value => {
+ v2 = value;
+ }).then(() => {
+ if (rule.t == "else") {
+ property = state.elseflag;
+ state.elseflag = true;
}
- } else {
- state.onward.push(null);
+ if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
+ state.onward.push(msg);
+ state.elseflag = false;
+ if (node.checkall == "false") {
+ return resolve(false);
+ }
+ } else {
+ state.onward.push(null);
+ }
+ resolve(state.currentRule < node.rules.length - 1);
+ });
+ })
+ } else {
+ var rule = node.rules[state.currentRule];
+ var v1 = getV1(node,msg,rule,state.hasParts);
+ var v2 = getV2(node,msg,rule);
+ if (rule.t == "else") {
+ property = state.elseflag;
+ state.elseflag = true;
+ }
+ if (operators[rule.t](property,v1,v2,rule.case,msg.parts)) {
+ state.onward.push(msg);
+ state.elseflag = false;
+ if (node.checkall == "false") {
+ return false;
}
- resolve(state.currentRule < node.rules.length - 1);
- });
- })
+ } else {
+ state.onward.push(null);
+ }
+ return state.currentRule < node.rules.length - 1
+ }
}
function applyRules(node, msg, property,state) {
@@ -215,7 +301,18 @@ module.exports = function(RED) {
msg.parts.hasOwnProperty("index")
}
}
- return applyRule(node,msg,property,state).then(hasMore => {
+ if (node.useAsyncRules) {
+ return applyRule(node,msg,property,state).then(hasMore => {
+ if (hasMore) {
+ state.currentRule++;
+ return applyRules(node,msg,property,state);
+ } else {
+ node.previousValue = property;
+ return state.onward;
+ }
+ });
+ } else {
+ var hasMore = applyRule(node,msg,property,state);
if (hasMore) {
state.currentRule++;
return applyRules(node,msg,property,state);
@@ -223,7 +320,7 @@ module.exports = function(RED) {
node.previousValue = property;
return state.onward;
}
- });
+ }
}
@@ -248,6 +345,14 @@ module.exports = function(RED) {
var valid = true;
var repair = n.repair;
var needsCount = repair;
+ this.useAsyncRules = (
+ this.propertyType === 'flow' ||
+ this.propertyType === 'global' || (
+ this.propertyType === 'jsonata' &&
+ /\$(flow|global)Context/.test(this.property)
+ )
+ );
+
for (var i=0; i
applyRules(node,msg,property))
- .then(onward => {
- if (!repair || !hasParts) {
- node.send(onward);
- }
- else {
- sendGroupMessages(onward, msg);
- }
- }).catch(err => {
- node.warn(err);
- });
+ if (node.useAsyncRules) {
+ return getProperty(node,msg)
+ .then(property => applyRules(node,msg,property))
+ .then(onward => {
+ if (!repair || !hasParts) {
+ node.send(onward);
+ }
+ else {
+ sendGroupMessages(onward, msg);
+ }
+ }).catch(err => {
+ node.warn(err);
+ });
+ } else {
+ try {
+ var property = getProperty(node,msg);
+ var onward = applyRules(node,msg,property);
+ if (!repair || !hasParts) {
+ node.send(onward);
+ } else {
+ sendGroupMessages(onward, msg);
+ }
+ } catch(err) {
+ node.warn(err);
+ }
+ }
}
function clearPending() {
@@ -473,7 +608,11 @@ module.exports = function(RED) {
}
this.on('input', function(msg) {
- processMessageQueue(msg);
+ if (node.useAsyncRules) {
+ processMessageQueue(msg);
+ } else {
+ processMessage(msg,true);
+ }
});
this.on('close', function() {
diff --git a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js
index 2f700cf30..6f63344e3 100644
--- a/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js
+++ b/packages/node_modules/@node-red/runtime/lib/nodes/context/index.js
@@ -15,7 +15,8 @@
**/
var clone = require("clone");
-var log = require("@node-red/util").log; // TODO: separate module
+var log = require("@node-red/util").log;
+var util = require("@node-red/util").util;
var memory = require("./memory");
var settings;
@@ -209,104 +210,131 @@ function createContext(id,seed) {
insertSeedValues = function(keys,values) {
if (!Array.isArray(keys)) {
if (values[0] === undefined) {
- values[0] = seed[keys];
+ values[0] = util.getObjectProperty(seed,keys);
}
} else {
for (var i=0;i