Compare commits

...

47 Commits

Author SHA1 Message Date
Nick O'Leary
526b3fda91 Include rewired nodes when calculating Modified Flows stop list 2024-06-10 16:56:49 +01:00
Nick O'Leary
61b12f6bbe Merge pull request #3743 from bonanitech/fix-build-script
Ensure all CSS variables are in the output file
2024-05-30 13:43:25 +01:00
Nick O'Leary
d71b22412b Merge pull request #4734 from GogoVega/fix-sidebar-config
Fix the Sidebar Config is not refreshed after a deploy
2024-05-30 13:40:12 +01:00
Nick O'Leary
e408c6b376 Merge pull request #4729 from GogoVega/fix-4728
Fix checkboxes are not updated when calling `typedInput("value", "")`
2024-05-30 10:32:27 +01:00
GogoVega
bf30c24e8e Fix the Sidebar Config is not refreshed after a deploy 2024-05-29 20:44:49 +02:00
GogoVega
6c14ed0ef5 Revert and fix an undefined value returned instead of a false value 2024-05-28 22:08:42 +02:00
Nick O'Leary
6d41ecdae0 Merge pull request #4716 from corentin-sodebo-voile/master
Fix panning with middle mouse button on windows 10/11
2024-05-28 10:28:57 +01:00
Nick O'Leary
3f89bc2733 Merge pull request #4727 from kazuhitoyokoi/master-addjpn
Add Japanese translation for sidebar tooltip
2024-05-28 09:49:35 +01:00
Nick O'Leary
87a25df162 Merge pull request #4730 from GogoVega/translate-multiple-option-label
Translate the number of items selected in the options list
2024-05-28 09:49:03 +01:00
GogoVega
341f43610a Translate the number of items selected in the options list 2024-05-27 19:56:51 +02:00
GogoVega
67cdf3ef96 Fix checkboxes are not updated when calling typedInput("value", "") 2024-05-27 18:59:25 +02:00
Kazuhito Yokoi
cd98f448e9 Add Japanese translation for sidebar tooltip 2024-05-26 23:34:32 +09:00
corentin-sodebo-voile
fac79fd068 Fix panning with middle mouse button on windows 10/11
Without preventDefault, when you try to drag the canvas with middle mouse button on Windows (e.g. in Chrome), the cursor change to a "scroll cursor" and the canvas scrolls endlessly instead of being dragged accurately.
2024-05-23 15:30:13 +02:00
Nick O'Leary
da97c5d558 Merge pull request #4715 from GogoVega/fix-validateNodeEditorProperty
Fix a checkbox should return a Boolean value and not the string `on`
2024-05-23 13:43:55 +01:00
Nick O'Leary
ae7b9fe62e Merge pull request #4714 from GogoVega/fix-4712
Deleting a grouped node should update the group
2024-05-23 13:43:26 +01:00
GogoVega
e52c2911da Fix a checkbox must return a boolean value and not on 2024-05-23 10:57:51 +02:00
Nick O'Leary
07a29ff779 Merge pull request #4711 from GogoVega/change-config-node-cursor
Change the Config Node cursor to `pointer`
2024-05-22 17:02:05 +01:00
Nick O'Leary
1b4a8ebe83 Merge branch 'master' into fix-4712 2024-05-22 17:01:29 +01:00
GogoVega
abf2eacf18 Revert and fix without using RED.group.removeFromGroup 2024-05-21 19:48:21 +02:00
Gauthier Dandele
f808f4e2e8 Apply suggestions from code review
Co-authored-by: Nick O'Leary <nick.oleary@gmail.com>
2024-05-21 19:01:57 +02:00
Nick O'Leary
ca33d6b799 Merge pull request #4713 from GogoVega/add-missing-sidebar-tooltips
Add missing tooltips to Sidebar
2024-05-21 17:15:52 +01:00
Nick O'Leary
940740f15d Merge pull request #4710 from node-red/4704-node-edit-history
Allow nodes to return additional history entries in onEditSave
2024-05-21 17:10:23 +01:00
GogoVega
51208fcd0c Fix indexOf returns -1 2024-05-21 16:06:15 +02:00
GogoVega
707152d82f Deleting a grouped node should update the group 2024-05-21 15:07:26 +02:00
GogoVega
5538f6dd8a Add missing tooltips to Sidebar 2024-05-21 12:58:29 +02:00
GogoVega
d601e2caa4 Change the config node cursor to pointer 2024-05-21 11:37:01 +02:00
Nick O'Leary
46fdf56c79 Allow nodes to return additional history entries in onEditSave 2024-05-20 16:41:44 +01:00
Nick O'Leary
f55ee6e665 Merge pull request #4685 from node-red/4683-preserve-full-error-obj
Pass full error object in Function node and copy over cause property
2024-05-13 15:25:02 +01:00
Nick O'Leary
03648dc7e8 Update tests for changed function node low-level output 2024-05-09 17:25:47 +01:00
Nick O'Leary
66a667fe58 Pass full error object in Function node and copy over cause property
Fixes #4683
2024-05-09 16:48:51 +01:00
Nick O'Leary
1bb3a0eca5 Merge pull request #4534 from patlux/master
Replacing vm.createScript in favour of vm.Script
2024-05-09 15:19:45 +01:00
Nick O'Leary
08927dfb55 Merge pull request #4684 from node-red/4363-autoLogin-redirect-loop
Avoid login loops when autoLogin enabled but login fails
2024-05-08 15:48:21 +01:00
Nick O'Leary
b27483de9c Avoid login loops when autoLogin enabled but login fails
Fixes #4363
2024-05-08 15:09:51 +01:00
Nick O'Leary
211d420fb2 Merge pull request #4667 from node-red/fix-subflow-property-undo
Fix undo of subflow env property edits
2024-04-23 23:45:46 +02:00
Nick O'Leary
b8ca4665c1 Merge pull request #4660 from JoshuaCWebDeveloper/patch-1
Fix three error typos in monaco.js
2024-04-23 23:45:16 +02:00
Nick O'Leary
960af87fb0 Ensure subflow change state is cleared after deploy 2024-04-23 21:17:35 +02:00
Nick O'Leary
de7339ae97 Fix undo of subflow env property edits 2024-04-23 20:39:14 +02:00
Stephen McLaughlin
0995af62b6 Merge pull request #4664 from ZJvandeWeg/patch-3
docs: Add closing paragraph tag
2024-04-20 13:54:37 +01:00
Zeger-Jan van de Weg
c2e03a40b4 docs: Add closing paragraph tag
Minor change that only improves xpath parsing.
2024-04-20 14:20:59 +02:00
Joshua Carter
c855050bcf Fix three error typos in monaco.js 2024-04-15 08:09:26 -07:00
Patrick Wozniak
28907082f1 fix usage of vm.Script() 2024-01-21 02:16:00 +01:00
Patrick Wozniak
f83174c40a fix use of vm.Script by adding new 2024-01-21 01:23:07 +01:00
Patrick Wozniak
ec062d008f replace vm.createScript in favor of vm.Script 2024-01-21 01:13:00 +01:00
Patrick Wozniak
a587655a5a adding pollyfill for vm.createScript
adds support for bun.sh
2024-01-21 01:00:02 +01:00
Mauricio Bonani
3e6f0acf79 Refactor code 2023-10-03 15:42:33 -04:00
Mauricio Bonani
7f93d943d7 Merge remote-tracking branch 'upstream/master' into fix-build-script 2023-10-03 09:04:40 -04:00
Mauricio Bonani
12543d2c2a Ensure all CSS variables are in the output file 2022-07-06 19:06:11 -04:00
19 changed files with 149 additions and 116 deletions

View File

@@ -205,9 +205,10 @@ function genericStrategy(adminApp,strategy) {
passport.use(new strategy.strategy(options, verify)); passport.use(new strategy.strategy(options, verify));
adminApp.get('/auth/strategy', adminApp.get('/auth/strategy',
passport.authenticate(strategy.name, {session:false, passport.authenticate(strategy.name, {
session:false,
failureMessage: true, failureMessage: true,
failureRedirect: settings.httpAdminRoot failureRedirect: settings.httpAdminRoot + '?session_message=Login Failed'
}), }),
completeGenerateStrategyAuth, completeGenerateStrategyAuth,
handleStrategyError handleStrategyError
@@ -221,7 +222,7 @@ function genericStrategy(adminApp,strategy) {
passport.authenticate(strategy.name, { passport.authenticate(strategy.name, {
session:false, session:false,
failureMessage: true, failureMessage: true,
failureRedirect: settings.httpAdminRoot failureRedirect: settings.httpAdminRoot + '?session_message=Login Failed'
}), }),
completeGenerateStrategyAuth, completeGenerateStrategyAuth,
handleStrategyError handleStrategyError

View File

@@ -719,6 +719,7 @@
"nodeHelp": "Node Help", "nodeHelp": "Node Help",
"showHelp": "Show help", "showHelp": "Show help",
"showInOutline": "Show in outline", "showInOutline": "Show in outline",
"hideTopics": "Hide topics",
"showTopics": "Show topics", "showTopics": "Show topics",
"noHelp": "No help topic selected", "noHelp": "No help topic selected",
"changeLog": "Change Log" "changeLog": "Change Log"
@@ -914,6 +915,8 @@
} }
}, },
"typedInput": { "typedInput": {
"selected": "__count__ selected",
"selected_plural": "__count__ selected",
"type": { "type": {
"str": "string", "str": "string",
"num": "number", "num": "number",

View File

@@ -719,6 +719,7 @@
"nodeHelp": "Aide sur les noeuds", "nodeHelp": "Aide sur les noeuds",
"showHelp": "Afficher l'aide", "showHelp": "Afficher l'aide",
"showInOutline": "Afficher dans les grandes lignes", "showInOutline": "Afficher dans les grandes lignes",
"hideTopics": "Masquer les sujets",
"showTopics": "Afficher les sujets", "showTopics": "Afficher les sujets",
"noHelp": "Aucune rubrique d'aide sélectionnée", "noHelp": "Aucune rubrique d'aide sélectionnée",
"changeLog": "Journal des modifications" "changeLog": "Journal des modifications"
@@ -914,6 +915,8 @@
} }
}, },
"typedInput": { "typedInput": {
"selected": "__count__ sélectionnée",
"selected_plural": "__count__ sélectionnées",
"type": { "type": {
"str": "chaîne de caractères", "str": "chaîne de caractères",
"num": "nombre", "num": "nombre",

View File

@@ -719,6 +719,7 @@
"nodeHelp": "ノードヘルプ", "nodeHelp": "ノードヘルプ",
"showHelp": "ヘルプを表示", "showHelp": "ヘルプを表示",
"showInOutline": "アウトラインに表示", "showInOutline": "アウトラインに表示",
"hideTopics": "トピックを非表示",
"showTopics": "トピックを表示", "showTopics": "トピックを表示",
"noHelp": "ヘルプのトピックが未選択", "noHelp": "ヘルプのトピックが未選択",
"changeLog": "更新履歴" "changeLog": "更新履歴"

View File

@@ -736,10 +736,10 @@
var selected = {}; var selected = {};
this.value().split(",").forEach(function(f) { this.value().split(",").forEach(function(f) {
selected[f] = true; selected[f] = true;
}) });
menu.find('input[type="checkbox"]').each(function() { menu.find('input[type="checkbox"]').each(function() {
$(this).prop("checked",selected[$(this).data('value')]) $(this).prop("checked", selected[$(this).data('value')] || false);
}) });
} }
@@ -830,7 +830,7 @@
this.input.trigger('change',[this.propertyType,this.value()]); this.input.trigger('change',[this.propertyType,this.value()]);
} }
} else { } else {
this.optionSelectLabel.text(o.length+" selected"); this.optionSelectLabel.text(RED._("typedInput.selected", { count: o.length }));
} }
} }
}, },

View File

@@ -612,7 +612,10 @@ RED.deploy = (function() {
} }
}); });
RED.nodes.eachSubflow(function (subflow) { RED.nodes.eachSubflow(function (subflow) {
if (subflow.changed) {
subflow.changed = false; subflow.changed = false;
RED.events.emit("subflows:change", subflow);
}
}); });
RED.nodes.eachWorkspace(function (ws) { RED.nodes.eachWorkspace(function (ws) {
if (ws.changed || ws.added) { if (ws.changed || ws.added) {
@@ -628,6 +631,7 @@ RED.deploy = (function() {
// Once deployed, cannot undo back to a clean state // Once deployed, cannot undo back to a clean state
RED.history.markAllDirty(); RED.history.markAllDirty();
RED.view.redraw(); RED.view.redraw();
RED.sidebar.config.refresh();
RED.events.emit("deploy"); RED.events.emit("deploy");
}).fail(function (xhr, textStatus, err) { }).fail(function (xhr, textStatus, err) {
RED.nodes.dirty(true); RED.nodes.dirty(true);

View File

@@ -248,6 +248,8 @@ RED.editor = (function() {
var value = input.val(); var value = input.val();
if (defaults[property].hasOwnProperty("format") && defaults[property].format !== "" && input[0].nodeName === "DIV") { if (defaults[property].hasOwnProperty("format") && defaults[property].format !== "" && input[0].nodeName === "DIV") {
value = input.text(); value = input.text();
} else if (input.attr("type") === "checkbox") {
value = input.prop("checked");
} }
var valid = validateNodeProperty(node, defaults, property,value); var valid = validateNodeProperty(node, defaults, property,value);
if (((typeof valid) === "string") || !valid) { if (((typeof valid) === "string") || !valid) {
@@ -741,9 +743,16 @@ RED.editor = (function() {
} }
try { try {
var rc = editing_node._def.oneditsave.call(editing_node); const rc = editing_node._def.oneditsave.call(editing_node);
if (rc === true) { if (rc === true) {
editState.changed = true; editState.changed = true;
} else if (typeof rc === 'object' && rc !== null ) {
if (rc.changed === true) {
editState.changed = true
}
if (Array.isArray(rc.history) && rc.history.length > 0) {
editState.history = rc.history
}
} }
} catch(err) { } catch(err) {
console.warn("oneditsave",editing_node.id,editing_node.type,err.toString()); console.warn("oneditsave",editing_node.id,editing_node.type,err.toString());
@@ -914,6 +923,17 @@ RED.editor = (function() {
dirty: startDirty dirty: startDirty
} }
if (editing_node.g) {
const group = RED.nodes.group(editing_node.g);
// Don't use RED.group.removeFromGroup as that emits
// a change event on the node - but we're deleting it
const index = group?.nodes.indexOf(editing_node) ?? -1;
if (index > -1) {
group.nodes.splice(index, 1);
RED.group.markDirty(group);
}
}
RED.nodes.dirty(true); RED.nodes.dirty(true);
RED.view.redraw(true); RED.view.redraw(true);
RED.history.push(historyEvent); RED.history.push(historyEvent);
@@ -1015,7 +1035,7 @@ RED.editor = (function() {
} }
}); });
} }
var historyEvent = { let historyEvent = {
t:'edit', t:'edit',
node:editing_node, node:editing_node,
changes:editState.changes, changes:editState.changes,
@@ -1031,6 +1051,15 @@ RED.editor = (function() {
instances:subflowInstances instances:subflowInstances
} }
} }
if (editState.history) {
historyEvent = {
t: 'multi',
events: [ historyEvent, ...editState.history ],
dirty: wasDirty
}
}
RED.history.push(historyEvent); RED.history.push(historyEvent);
} }
editing_node.dirty = true; editing_node.dirty = true;
@@ -1623,8 +1652,8 @@ RED.editor = (function() {
} }
if (!isSameObj(old_env, new_env)) { if (!isSameObj(old_env, new_env)) {
editing_node.env = new_env;
editState.changes.env = editing_node.env; editState.changes.env = editing_node.env;
editing_node.env = new_env;
editState.changed = true; editState.changed = true;
} }

View File

@@ -514,7 +514,7 @@ RED.editor.codeEditor.monaco = (function() {
_monaco.languages.json.jsonDefaults.setDiagnosticsOptions(diagnosticOptions); _monaco.languages.json.jsonDefaults.setDiagnosticsOptions(diagnosticOptions);
if(modeConfiguration) { _monaco.languages.json.jsonDefaults.setModeConfiguration(modeConfiguration); } if(modeConfiguration) { _monaco.languages.json.jsonDefaults.setModeConfiguration(modeConfiguration); }
} catch (error) { } catch (error) {
console.warn("monaco - Error setting up json options", err) console.warn("monaco - Error setting up json options", error)
} }
} }
@@ -526,7 +526,7 @@ RED.editor.codeEditor.monaco = (function() {
if(htmlDefaults) { _monaco.languages.html.htmlDefaults.setOptions(htmlDefaults); } if(htmlDefaults) { _monaco.languages.html.htmlDefaults.setOptions(htmlDefaults); }
if(handlebarDefaults) { _monaco.languages.html.handlebarDefaults.setOptions(handlebarDefaults); } if(handlebarDefaults) { _monaco.languages.html.handlebarDefaults.setOptions(handlebarDefaults); }
} catch (error) { } catch (error) {
console.warn("monaco - Error setting up html options", err) console.warn("monaco - Error setting up html options", error)
} }
} }
@@ -546,7 +546,7 @@ RED.editor.codeEditor.monaco = (function() {
if(lessDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(lessDefaults_modeConfiguration); } if(lessDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(lessDefaults_modeConfiguration); }
if(scssDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(scssDefaults_modeConfiguration); } if(scssDefaults_modeConfiguration) { _monaco.languages.css.cssDefaults.setDiagnosticsOptions(scssDefaults_modeConfiguration); }
} catch (error) { } catch (error) {
console.warn("monaco - Error setting up CSS/SCSS/LESS options", err) console.warn("monaco - Error setting up CSS/SCSS/LESS options", error)
} }
} }

View File

@@ -382,9 +382,11 @@ RED.sidebar.config = (function() {
refreshConfigNodeList(); refreshConfigNodeList();
} }
}); });
RED.popover.tooltip($('#red-ui-sidebar-config-filter-all'), RED._("sidebar.config.showAllConfigNodes")); RED.popover.tooltip($('#red-ui-sidebar-config-filter-all'), RED._("sidebar.config.showAllConfigNodes"));
RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes")); RED.popover.tooltip($('#red-ui-sidebar-config-filter-unused'), RED._("sidebar.config.showAllUnusedConfigNodes"));
RED.popover.tooltip($('#red-ui-sidebar-config-collapse-all'), RED._("palette.actions.collapse-all"));
RED.popover.tooltip($('#red-ui-sidebar-config-expand-all'), RED._("palette.actions.expand-all"));
} }
function flashConfigNode(el) { function flashConfigNode(el) {

View File

@@ -36,7 +36,13 @@ RED.sidebar.help = (function() {
toolbar = $("<div>", {class:"red-ui-sidebar-header red-ui-info-toolbar"}).appendTo(content); toolbar = $("<div>", {class:"red-ui-sidebar-header red-ui-info-toolbar"}).appendTo(content);
$('<span class="button-group"><a id="red-ui-sidebar-help-show-toc" class="red-ui-button red-ui-button-small selected" href="#"><i class="fa fa-list-ul"></i></a></span>').appendTo(toolbar) $('<span class="button-group"><a id="red-ui-sidebar-help-show-toc" class="red-ui-button red-ui-button-small selected" href="#"><i class="fa fa-list-ul"></i></a></span>').appendTo(toolbar)
var showTOCButton = toolbar.find('#red-ui-sidebar-help-show-toc') var showTOCButton = toolbar.find('#red-ui-sidebar-help-show-toc')
RED.popover.tooltip(showTOCButton,RED._("sidebar.help.showTopics")); RED.popover.tooltip(showTOCButton, function () {
if ($(showTOCButton).hasClass('selected')) {
return RED._("sidebar.help.hideTopics");
} else {
return RED._("sidebar.help.showTopics");
}
});
showTOCButton.on("click",function(e) { showTOCButton.on("click",function(e) {
e.preventDefault(); e.preventDefault();
if ($(this).hasClass('selected')) { if ($(this).hasClass('selected')) {

View File

@@ -1190,6 +1190,7 @@ RED.view = (function() {
if (d3.event.button === 1) { if (d3.event.button === 1) {
// Middle Click pan // Middle Click pan
d3.event.preventDefault();
mouse_mode = RED.state.PANNING; mouse_mode = RED.state.PANNING;
mouse_position = [d3.event.pageX,d3.event.pageY] mouse_position = [d3.event.pageX,d3.event.pageY]
scroll_position = [chart.scrollLeft(),chart.scrollTop()]; scroll_position = [chart.scrollLeft(),chart.scrollTop()];

View File

@@ -37,7 +37,6 @@ ul.red-ui-sidebar-node-config-list {
} }
.red-ui-palette-node { .red-ui-palette-node {
// overflow: hidden; // overflow: hidden;
cursor: default;
&.selected { &.selected {
border-color: transparent; border-color: transparent;
box-shadow: 0 0 0 2px var(--red-ui-node-selected-color); box-shadow: 0 0 0 2px var(--red-ui-node-selected-color);

View File

@@ -194,27 +194,46 @@
nodeMap[node.links[i]].new = true; nodeMap[node.links[i]].new = true;
} }
} }
var n;
for (var id in nodeMap) { let editHistories = []
let n;
for (let id in nodeMap) {
if (nodeMap.hasOwnProperty(id)) { if (nodeMap.hasOwnProperty(id)) {
n = RED.nodes.node(id); n = RED.nodes.node(id);
if (n) { if (n) {
editHistories.push({
t:'edit',
node: n,
changes: {
links: [...n.links]
},
changed: n.changed
})
if (nodeMap[id].old && !nodeMap[id].new) { if (nodeMap[id].old && !nodeMap[id].new) {
// Removed id // Removed id
i = n.links.indexOf(node.id); i = n.links.indexOf(node.id);
if (i > -1) { if (i > -1) {
n.links.splice(i,1); n.links.splice(i,1);
n.changed = true
n.dirty = true
} }
} else if (!nodeMap[id].old && nodeMap[id].new) { } else if (!nodeMap[id].old && nodeMap[id].new) {
// Added id // Added id
i = n.links.indexOf(id); i = n.links.indexOf(id);
if (i === -1) { if (i === -1) {
n.links.push(node.id); n.links.push(node.id);
n.changed = true
n.dirty = true
} }
} }
} }
} }
} }
if (editHistories.length > 0) {
return {
history: editHistories
}
}
} }
function onAdd() { function onAdd() {
@@ -254,13 +273,14 @@
onEditPrepare(this,"link out"); onEditPrepare(this,"link out");
}, },
oneditsave: function() { oneditsave: function() {
onEditSave(this); const result = onEditSave(this);
// In case the name has changed, ensure any link call nodes on this // In case the name has changed, ensure any link call nodes on this
// tab are redrawn with the updated name // tab are redrawn with the updated name
var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"}); var localCallNodes = RED.nodes.filterNodes({z:RED.workspaces.active(), type:"link call"});
localCallNodes.forEach(function(node) { localCallNodes.forEach(function(node) {
node.dirty = true; node.dirty = true;
}); });
return result
}, },
onadd: onAdd, onadd: onAdd,
oneditresize: resizeNodeList oneditresize: resizeNodeList
@@ -329,7 +349,7 @@
onEditPrepare(this,"link in"); onEditPrepare(this,"link in");
}, },
oneditsave: function() { oneditsave: function() {
onEditSave(this); return onEditSave(this);
}, },
oneditresize: resizeNodeList oneditresize: resizeNodeList
}); });
@@ -373,7 +393,7 @@
}, },
oneditsave: function() { oneditsave: function() {
onEditSave(this); return onEditSave(this);
}, },
onadd: onAdd, onadd: onAdd,
oneditresize: resizeNodeList oneditresize: resizeNodeList

View File

@@ -374,7 +374,7 @@ module.exports = function(RED) {
iniOpt.breakOnSigint = true; iniOpt.breakOnSigint = true;
} }
} }
node.script = vm.createScript(functionText, createVMOpt(node, "")); node.script = new vm.Script(functionText, createVMOpt(node, ""));
if (node.fin && (node.fin !== "")) { if (node.fin && (node.fin !== "")) {
var finText = `(function () { var finText = `(function () {
var node = { var node = {
@@ -438,10 +438,9 @@ module.exports = function(RED) {
//store the error in msg to be used in flows //store the error in msg to be used in flows
msg.error = err; msg.error = err;
var line = 0;
var errorMessage;
if (stack.length > 0) { if (stack.length > 0) {
let line = 0;
let errorMessage;
while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) { while (line < stack.length && stack[line].indexOf("ReferenceError") !== 0) {
line++; line++;
} }
@@ -455,11 +454,13 @@ module.exports = function(RED) {
errorMessage += " (line "+lineno+", col "+cha+")"; errorMessage += " (line "+lineno+", col "+cha+")";
} }
} }
if (errorMessage) {
err.message = errorMessage
} }
if (!errorMessage) {
errorMessage = err.toString();
} }
done(errorMessage); // Pass the whole error object so any additional properties
// (such as cause) are preserved
done(err);
} }
else if (typeof err === "string") { else if (typeof err === "string") {
done(err); done(err);

View File

@@ -103,7 +103,7 @@
<h4>Automatic mode</h4> <h4>Automatic mode</h4>
<p>Automatic mode uses the <code>parts</code> property of incoming messages to <p>Automatic mode uses the <code>parts</code> property of incoming messages to
determine how the sequence should be joined. This allows it to automatically determine how the sequence should be joined. This allows it to automatically
reverse the action of a <b>split</b> node. reverse the action of a <b>split</b> node.</p>
<h4>Manual mode</h4> <h4>Manual mode</h4>
<p>When configured to join in manual mode, the node is able to join sequences <p>When configured to join in manual mode, the node is able to join sequences

View File

@@ -678,6 +678,9 @@ class Flow {
if (logMessage.hasOwnProperty('stack')) { if (logMessage.hasOwnProperty('stack')) {
errorMessage.error.stack = logMessage.stack; errorMessage.error.stack = logMessage.stack;
} }
if (logMessage.hasOwnProperty('cause')) {
errorMessage.error.cause = logMessage.cause;
}
targetCatchNode.receive(errorMessage); targetCatchNode.receive(errorMessage);
handled = true; handled = true;
}); });

View File

@@ -462,9 +462,8 @@ function stop(type,diff,muteLog,isDeploy) {
if (type === 'nodes') { if (type === 'nodes') {
stopList = diff.changed.concat(diff.removed); stopList = diff.changed.concat(diff.removed);
} else if (type === 'flows') { } else if (type === 'flows') {
stopList = diff.changed.concat(diff.removed).concat(diff.linked); stopList = diff.changed.concat(diff.removed).concat(diff.linked).concat(diff.rewired);
} }
events.emit("flows:stopping",{config: activeConfig, type: type, diff: diff}) events.emit("flows:stopping",{config: activeConfig, type: type, diff: diff})
// Stop the global flow object last // Stop the global flow object last

View File

@@ -13,7 +13,7 @@
// 4. Edit your settings file to set the theme: // 4. Edit your settings file to set the theme:
// editorTheme: { // editorTheme: {
// page: { // page: {
// css: "/path/to/file/generated/by/this/script" // css: '/path/to/file/generated/by/this/script'
// } // }
// } // }
// //
@@ -22,110 +22,69 @@
const os = require("os"); const os = require('os');
const nopt = require("nopt"); const nopt = require('nopt');
const path = require("path"); const path = require('path');
const fs = require("fs-extra"); const fs = require('fs-extra');
const sass = require("sass"); const sass = require('sass');
const knownOpts = { const knownOpts = {
"help": Boolean, 'help': Boolean,
"long": Boolean, 'long': Boolean,
"in": [path], 'in': [path],
"out": [path] 'out': [path]
}; };
const shortHands = { const shortHands = {
"?":["--help"] '?':['--help']
}; };
nopt.invalidHandler = function(k,v,t) {} nopt.invalidHandler = function(k,v,t) {}
const parsedArgs = nopt(knownOpts,shortHands,process.argv,2) const parsedArgs = nopt(knownOpts,shortHands,process.argv,2)
if (parsedArgs.help) { if (parsedArgs.help) {
console.log("Usage: build-custom-theme [-?] [--in FILE] [--out FILE]"); showUsageAndExit(0)
console.log("");
console.log("Options:");
console.log(" --in FILE Custom colors sass file");
console.log(" --out FILE Where you write the result");
console.log(" --long Do not compress the output");
console.log(" -?, --help Show this help");
console.log("");
process.exit();
} }
if (!parsedArgs.in) {
const ruleRegex = /(\$.*?) *: *(\S[\S\s]*?);/g; console.warn('Missing argument: in')
var match; showUsageAndExit(1)
const customColors = {};
if (parsedArgs.in && fs.existsSync(parsedArgs.in)) {
let customColorsFile = fs.readFileSync(parsedArgs.in,"utf-8");
while((match = ruleRegex.exec(customColorsFile)) !== null) {
customColors[match[1]] = match[2];
} }
}
// Load base colours
let colorsFile = fs.readFileSync(path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/colors.scss"),"utf-8")
let updatedColors = [];
while((match = ruleRegex.exec(colorsFile)) !== null) {
updatedColors.push(match[1]+": "+(customColors[match[1]]||match[2])+";")
}
(async function() { (async function() {
const tmpDir = os.tmpdir(); const tmpDir = os.tmpdir();
const workingDir = await fs.mkdtemp(`${tmpDir}${path.sep}`); const workingDir = await fs.mkdtemp(`${tmpDir}${path.sep}`);
await fs.copy(path.join(__dirname,"../packages/node_modules/@node-red/editor-client/src/sass/"),workingDir)
await fs.writeFile(path.join(workingDir,"colors.scss"),updatedColors.join("\n"))
const result = sass.renderSync({ await fs.copy(path.join(__dirname, '../packages/node_modules/@node-red/editor-client/src/sass/'), workingDir);
outputStyle: "expanded", await fs.copyFile(parsedArgs.in, path.join(workingDir,'colors.scss'));
file: path.join(workingDir,"style-custom-theme.scss"),
});
const css = result.css.toString() const output = sass.compile(
const lines = css.split("\n"); path.join(workingDir, 'style-custom-theme.scss'),
const colorCSS = [] {style: parsedArgs.long === true ? 'expanded' : 'compressed'}
const nonColorCSS = []; );
let inKeyFrameBlock = false; const nrPkg = require('../package.json');
lines.forEach(l => {
if (inKeyFrameBlock) {
nonColorCSS.push(l);
if (/^}/.test(l)) {
inKeyFrameBlock = false;
}
} else if (/^@keyframes/.test(l)) {
nonColorCSS.push(l);
inKeyFrameBlock = true;
} else if (!/^ /.test(l)) {
colorCSS.push(l);
nonColorCSS.push(l);
} else if (/color|border|background|fill|stroke|outline|box-shadow/.test(l)) {
colorCSS.push(l);
} else {
nonColorCSS.push(l);
}
});
const nrPkg = require("../package.json");
const now = new Date().toISOString(); const now = new Date().toISOString();
const header = `/*\n* Theme generated with Node-RED ${nrPkg.version} on ${now}\n*/`;
const header = `/*
* Theme generated with Node-RED ${nrPkg.version} on ${now}
*/`;
var output = sass.renderSync({outputStyle: parsedArgs.long?"expanded":"compressed",data:colorCSS.join("\n")});
if (parsedArgs.out) { if (parsedArgs.out) {
await fs.writeFile(parsedArgs.out, header+'\n'+output.css);
await fs.writeFile(parsedArgs.out,header+"\n"+output.css);
} else { } else {
console.log(header); console.log(header);
console.log(output.css.toString()); console.log(output.css.toString());
} }
await fs.remove(workingDir); await fs.remove(workingDir);
})() })()
function showUsageAndExit (exitCode) {
console.log('');
console.log('Usage: build-custom-theme [-?] [--in FILE] [--out FILE]');
console.log('');
console.log('Options:');
console.log(' --in FILE Custom colors sass file');
console.log(' --out FILE Where you write the result');
console.log(' --long Do not compress the output');
console.log(' -?, --help Show this help');
console.log('');
process.exit(exitCode);
}

View File

@@ -390,7 +390,8 @@ describe('function node', function() {
msg.should.have.property('level', helper.log().ERROR); msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', 'n1'); msg.should.have.property('id', 'n1');
msg.should.have.property('type', 'function'); msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'ReferenceError: retunr is not defined (line 2, col 1)'); msg.should.have.property('msg')
msg.msg.message.should.equal('ReferenceError: retunr is not defined (line 2, col 1)');
done(); done();
} catch(err) { } catch(err) {
done(err); done(err);
@@ -659,7 +660,8 @@ describe('function node', function() {
msg.should.have.property('level', helper.log().ERROR); msg.should.have.property('level', helper.log().ERROR);
msg.should.have.property('id', name); msg.should.have.property('id', name);
msg.should.have.property('type', 'function'); msg.should.have.property('type', 'function');
msg.should.have.property('msg', 'Error: Callback must be a function'); msg.should.have.property('msg')
msg.msg.message.should.equal('Callback must be a function');
done(); done();
} }
catch (e) { catch (e) {