diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
index f6b93f840..aa05ad695 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/typedInput.js
@@ -198,6 +198,8 @@
}
RED.editor.editJSON({
value: value,
+ stateId: RED.editor.generateViewStateId("typedInput", that, "json"),
+ focus: true,
complete: function(v) {
var value = v;
try {
@@ -220,6 +222,8 @@
var that = this;
RED.editor.editExpression({
value: this.value().replace(/\t/g,"\n"),
+ stateId: RED.editor.generateViewStateId("typedInput", that, "jsonata"),
+ focus: true,
complete: function(v) {
that.value(v.replace(/\n/g,"\t"));
}
@@ -234,6 +238,8 @@
var that = this;
RED.editor.editBuffer({
value: this.value(),
+ stateId: RED.editor.generateViewStateId("typedInput", that, "bin"),
+ focus: true,
complete: function(v) {
that.value(v);
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
index f0f3a073b..89eb08ef8 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editor.js
@@ -868,6 +868,7 @@ RED.editor = (function() {
if (buildingEditDialog) { return }
buildingEditDialog = true;
var editing_node = node;
+ var removeInfoEditorOnClose = false;
var skipInfoRefreshOnClose = false;
var activeEditPanes = [];
@@ -1063,6 +1064,14 @@ RED.editor = (function() {
}
if (!node._def.defaults || !node._def.defaults.hasOwnProperty('info')) {
nodeEditPanes.push('editor-tab-description');
+ removeInfoEditorOnClose = true;
+ if(node.infoEditor) {
+ //As 'editor-tab-description' adds `node.infoEditor` store original & set a
+ //flag to NOT remove this property
+ node.infoEditor__orig = node.infoEditor;
+ delete node.infoEditor;
+ removeInfoEditorOnClose = false;
+ }
}
nodeEditPanes.push("editor-tab-appearance");
@@ -1078,8 +1087,17 @@ RED.editor = (function() {
if (RED.view.state() != RED.state.IMPORT_DRAGGING) {
RED.view.state(RED.state.DEFAULT);
}
- if (editing_node && !skipInfoRefreshOnClose) {
- RED.sidebar.info.refresh(editing_node);
+ if (editing_node) {
+ if (editing_node.infoEditor__orig) {
+ editing_node.infoEditor = editing_node.infoEditor__orig;
+ delete editing_node.infoEditor__orig;
+ }
+ if (removeInfoEditorOnClose) {
+ delete editing_node.infoEditor;
+ }
+ if (!skipInfoRefreshOnClose) {
+ RED.sidebar.info.refresh(editing_node);
+ }
}
RED.workspaces.refresh();
@@ -1939,6 +1957,48 @@ RED.editor = (function() {
}
}
+ /** Genrate a consistent but unique ID for saving and restoring the code editors view state */
+ function generateViewStateId(source, thing, suffix) {
+ try {
+ thing = thing || {};
+ const thingOptions = typeof thing.options === "object" ? thing.options : {};
+ let stateId;
+ if (thing.hasOwnProperty("stateId")) {
+ stateId = thing.stateId
+ } else if (thingOptions.hasOwnProperty("stateId")) {
+ stateId = thing.stateId
+ }
+ if (stateId === false) { return false; }
+ if (!stateId) {
+ let id;
+ const selection = RED.view.selection();
+ if (source === "node" && thing.id) {
+ id = thing.id;
+ } else if (selection.nodes && selection.nodes.length) {
+ id = selection.nodes[0].id;
+ } else {
+ return false; //cant obtain Id.
+ }
+ //Use a string builder to build an ID
+ const sb = [id];
+ //get the index of the el - there may be more than one editor.
+ const el = $(thing.element || thingOptions.element);
+ if(el.length) {
+ sb.push(el.closest(".form-row").index());
+ sb.push(el.index());
+ }
+ if (source == "typedInput") {
+ sb.push(el.closest("li").index());//for when embeded in editable list
+ if (!suffix && thing.propertyType) { suffix = thing.propertyType }
+ }
+ stateId = sb.join("/");
+ }
+ if (stateId && suffix) { stateId += "/" + suffix; };
+ return stateId;
+ } catch (error) {
+ return false;
+ }
+ }
return {
init: function() {
if(window.ace) { window.ace.config.set('basePath', 'vendor/ace'); }
@@ -1955,6 +2015,7 @@ RED.editor = (function() {
});
RED.editor.codeEditor.init();
},
+ generateViewStateId: generateViewStateId,
edit: showEditDialog,
editConfig: showEditConfigNodeDialog,
editFlow: showEditFlowDialog,
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js
index a1e244290..9a9b582d1 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/buffer.js
@@ -47,6 +47,7 @@
var definition = {
show: function(options) {
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_buffer"
if ($("script[data-template-name='"+type+"']").length === 0) {
@@ -60,12 +61,14 @@
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: "inherit",
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if (onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -74,7 +77,8 @@
text: RED._("common.label.done"),
class: "primary",
click: function() {
- onComplete(JSON.stringify(bufferBinValue));
+ bufferStringEditor.saveView();
+ if (onComplete) { onComplete(JSON.stringify(bufferBinValue),null,bufferStringEditor); }
RED.tray.close();
}
}
@@ -86,19 +90,20 @@
}
},
open: function(tray) {
- var trayBody = tray.find('.red-ui-tray-body');
var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor');
-
bufferStringEditor = RED.editor.createEditor({
id: 'red-ui-editor-type-buffer-str',
- value: "",
+ value: value||"",
+ stateId: RED.editor.generateViewStateId("buffer", options, ""),
+ focus: true,
mode:"ace/mode/text"
});
- bufferStringEditor.getSession().setValue(value||"",-1);
bufferBinEditor = RED.editor.createEditor({
id: 'red-ui-editor-type-buffer-bin',
value: "",
+ stateId: false,
+ focus: false,
mode:"ace/mode/text",
readOnly: true
});
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/ace.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/ace.js
index caec3006c..02b65528d 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/ace.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/ace.js
@@ -80,6 +80,9 @@ RED.editor.codeEditor.ace = (function() {
}
},100);
}
+ if (!options.stateId && options.stateId !== false) {
+ options.stateId = RED.editor.generateViewStateId("ace", options, (options.mode || options.title).split("/").pop());
+ }
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("red-ui-editor-text-container-toolbar");
editor.toolbar = RED.editor.customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
@@ -92,11 +95,15 @@ RED.editor.codeEditor.ace = (function() {
RED.editor.editMarkdown({
value: value,
width: "Infinity",
- cursor: editor.getCursorPosition(),
+ stateId: options.stateId,
+ focus: true,
+ cancel: function () {
+ editor.focus();
+ },
complete: function(v,cursor) {
editor.setValue(v, -1);
- editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
+ editor.restoreView();
editor.focus();
},300);
}
@@ -117,11 +124,56 @@ RED.editor.codeEditor.ace = (function() {
editor._destroy = editor.destroy;
editor.destroy = function() {
try {
+ editor.saveView();
+ editor._initState = null;
this._destroy();
} catch (e) { }
$(el).remove();
$(toolbarRow).remove();
}
+ editor.on("blur", function () {
+ editor.focusMemory = false;
+ editor.saveView();
+ })
+ editor.on("focus", function () {
+ if (editor._initState) {
+ editor.restoreView(editor._initState);
+ editor._initState = null;
+ }
+ })
+ editor.getView = function () {
+ var session = editor.getSession();
+ return {
+ selection: session.selection.toJSON(),
+ scrollTop: session.getScrollTop(),
+ scrollLeft: session.getScrollLeft(),
+ options: session.getOptions()
+ }
+ }
+ editor.saveView = function () {
+ if (!options.stateId) { return; } //only possible if created with a unique stateId
+ window._editorStateAce = window._editorStateAce || {};
+ var state = editor.getView();
+ window._editorStateAce[options.stateId] = state;
+ return state;
+ }
+ editor.restoreView = function (state) {
+ if (!options.stateId) { return; } //only possible if created with a unique stateId
+ window._editorStateAce = window._editorStateAce || {};
+ var _state = state || window._editorStateAce[options.stateId];
+ if (!_state) { return; } //no view state available
+ try {
+ var session = editor.getSession();
+ session.setOptions(_state.options);
+ session.selection.fromJSON(_state.selection);
+ session.setScrollTop(_state.scrollTop);
+ session.setScrollLeft(_state.scrollLeft);
+ editor._initState = _state;
+ } catch (error) {
+ delete window._editorStateMonaco[options.stateId];
+ }
+ };
+ editor.restoreView();
editor.type = type;
return editor;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js
index d1a674dd5..701e3da44 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/code-editors/monaco.js
@@ -171,7 +171,7 @@ RED.editor.codeEditor.monaco = (function() {
options = options || {};
window.MonacoEnvironment = window.MonacoEnvironment || {};
- window.MonacoEnvironment.getWorkerUrl = function (moduleId, label) {
+ window.MonacoEnvironment.getWorkerUrl = window.MonacoEnvironment.getWorkerUrl || function (moduleId, label) {
if (label === 'json') { return './vendor/monaco/dist/json.worker.js'; }
if (label === 'css' || label === 'scss') { return './vendor/monaco/dist/css.worker.js'; }
if (label === 'html' || label === 'handlebars') { return './vendor/monaco/dist/html.worker.js'; }
@@ -747,13 +747,25 @@ RED.editor.codeEditor.monaco = (function() {
mode = "html";
break;
case "appcache":
+ case "sh":
+ case "bash":
mode = "shell";
break;
+ case "batchfile":
+ mode = "bat";
+ break;
+ case "protobuf":
+ mode = "proto";
+ break;
//TODO: add other compatability types.
}
return mode;
}
+
+ if(!options.stateId && options.stateId !== false) {
+ options.stateId = RED.editor.generateViewStateId("monaco", options, (options.mode || options.title).split("/").pop());
+ }
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("
").appendTo(el);
el = $("
").appendTo(el).addClass("red-ui-editor-text-container")[0];
@@ -1098,6 +1110,7 @@ RED.editor.codeEditor.monaco = (function() {
try {
var m = this.getModel();
if(m && !m.isDisposed()) {
+ ed._initState = null;
m.dispose();
}
this.setModel(null);
@@ -1243,14 +1256,7 @@ RED.editor.codeEditor.monaco = (function() {
//#endregion "ACE compatability"
//final setup
- if (options.cursor) {
- var row = options.cursor.row || options.cursor.lineNumber;
- var col = options.cursor.column || options.cursor.col;
- ed.gotoLine(row, col);
- }
- if (options.focus) {
- ed.focus();
- }
+ ed.focusMemory = options.focus;
ed._mode = editorOptions.language;
//as models are signleton, consts and let are avialable to other javascript instances
@@ -1262,11 +1268,12 @@ RED.editor.codeEditor.monaco = (function() {
}
ed.onDidBlurEditorWidget(function() {
+ ed.focusMemory = false;
+ ed.saveView();
if(isVisible(el) == false) {
onVisibilityChange(false, 0, el);
}
});
-
ed.onDidFocusEditorWidget(function() {
onVisibilityChange(true, 10, el);
});
@@ -1300,17 +1307,33 @@ RED.editor.codeEditor.monaco = (function() {
}
function onVisibilityChange(visible, delay, element) {
- if(visible) {
- if(ed._mode == "javascript" && ed._tempMode == "text") {
+ delay = delay || 50;
+ if (visible) {
+ if (ed.focusMemory) {
+ setTimeout(function () {
+ if (element.parentElement) { //ensure el is still in DOM
+ ed.focus();
+ }
+ }, 300)
+ }
+ if (ed._initState) {
+ setTimeout(function () {
+ if (element.parentElement) { //ensure el is still in DOM
+ ed.restoreViewState(ed._initState);
+ ed._initState = null;
+ }
+ }, delay);
+ }
+ if (ed._mode == "javascript" && ed._tempMode == "text") {
ed._tempMode = "";
- setTimeout(function() {
- if(element.parentElement) { //ensure el is still in DOM
+ setTimeout(function () {
+ if (element.parentElement) { //ensure el is still in DOM
ed.setMode('javascript', undefined, false);
}
- }, delay || 50);
+ }, delay);
}
- } else if(ed._mode == "javascript" && ed._tempMode != "text") {
- if(element.parentElement) { //ensure el is still in DOM
+ } else if (ed._mode == "javascript" && ed._tempMode != "text") {
+ if (element.parentElement) { //ensure el is still in DOM
ed.setMode('text', undefined, false);
ed._tempMode = "text";
}
@@ -1329,15 +1352,19 @@ RED.editor.codeEditor.monaco = (function() {
expandButton.on("click", function (e) {
e.preventDefault();
var value = ed.getValue();
+ ed.saveView();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
- cursor: ed.getCursorPosition(),
+ stateId: options.stateId,
+ cancel: function () {
+ ed.focus();
+ },
complete: function (v, cursor) {
ed.setValue(v, -1);
- ed.gotoLine(cursor.row + 1, cursor.column, false);
setTimeout(function () {
ed.focus();
+ ed.restoreView();
}, 300);
}
})
@@ -1353,7 +1380,37 @@ RED.editor.codeEditor.monaco = (function() {
autoClose: 50
});
}
-
+ ed.getView = function () {
+ return ed.saveViewState();
+ }
+ ed.saveView = function (debuginfo) {
+ if (!options.stateId) { return; } //only possible if created with a unique stateId
+ window._editorStateMonaco = window._editorStateMonaco || {};
+ var state = ed.getView();
+ window._editorStateMonaco[options.stateId] = state;
+ return state;
+ }
+ ed.restoreView = function (state) {
+ if (!options.stateId) { return; } //only possible if created with a unique stateId
+ window._editorStateMonaco = window._editorStateMonaco || {};
+ var _state = state || window._editorStateMonaco[options.stateId];
+ if (!_state) { return; } //no view state available
+ try {
+ if (ed.type) { //is editor already initialised?
+ ed.restoreViewState(_state);
+ } else {
+ ed._initState = _state;
+ }
+ } catch (error) {
+ delete window._editorStateMonaco[options.stateId];
+ }
+ };
+ ed.restoreView();
+ if (options.cursor && !ed._initState) {
+ var row = options.cursor.row || options.cursor.lineNumber;
+ var col = options.cursor.column || options.cursor.col;
+ ed.gotoLine(row, col);
+ }
ed.type = type;
return ed;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
index 7f8eb4265..80a212a72 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/expression.js
@@ -50,6 +50,7 @@
show: function(options) {
var expressionTestCacheId = options.parent||"_";
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_expression"
if ($("script[data-template-name='"+type+"']").length === 0) {
@@ -63,12 +64,14 @@
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: "inherit",
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if(onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -78,7 +81,8 @@
class: "primary",
click: function() {
$("#red-ui-editor-type-expression-help").text("");
- onComplete(expressionEditor.getValue());
+ expressionEditor.saveView();
+ if (onComplete) { onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition(),expressionEditor); }
RED.tray.close();
}
}
@@ -110,6 +114,8 @@
id: 'red-ui-editor-type-expression',
value: "",
mode:"ace/mode/jsonata",
+ stateId: options.stateId,
+ focus: true,
options: {
enableBasicAutocompletion:true,
enableSnippets:true,
@@ -233,6 +239,8 @@
testDataEditor = RED.editor.createEditor({
id: 'red-ui-editor-type-expression-test-data',
value: expressionTestCache[expressionTestCacheId] || '{\n "payload": "hello world"\n}',
+ stateId: false,
+ focus: false,
mode:"ace/mode/json",
lineNumbers: false
});
@@ -302,6 +310,8 @@
testResultEditor = RED.editor.createEditor({
id: 'red-ui-editor-type-expression-test-result',
value: "",
+ stateId: false,
+ focus: false,
mode:"ace/mode/json",
lineNumbers: false,
readOnly: true
@@ -346,6 +356,9 @@
expressionEditor.destroy();
testDataEditor.destroy();
testResultEditor.destroy();
+ delete expressionEditor;
+ delete testDataEditor;
+ delete testResultEditor;
},
show: function() {}
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js
index 8619455f2..5ab25177f 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/js.js
@@ -21,6 +21,7 @@
var definition = {
show: function(options) {
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_js"
if ($("script[data-template-name='"+type+"']").length === 0) {
@@ -28,16 +29,16 @@
}
RED.view.state(RED.state.EDITING);
var expressionEditor;
- var changeTimer;
-
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: options.width||"inherit",
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if (onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -46,7 +47,8 @@
text: RED._("common.label.done"),
class: "primary",
click: function() {
- onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition());
+ expressionEditor.saveView();
+ if (onComplete) { onComplete(expressionEditor.getValue(), expressionEditor.getCursorPosition(), expressionEditor); }
RED.tray.close();
}
}
@@ -62,11 +64,12 @@
expressionEditor.resize();
},
open: function(tray) {
- var trayBody = tray.find('.red-ui-tray-body');
var dialogForm = RED.editor.buildEditForm(tray.find('.red-ui-tray-body'),'dialog-form',type,'editor');
expressionEditor = RED.editor.createEditor({
id: 'node-input-js',
mode: options.mode || 'ace/mode/javascript',
+ stateId: options.stateId,
+ focus: true,
value: value,
globals: {
msg:true,
@@ -84,19 +87,17 @@
},
extraLibs: options.extraLibs
});
- if (options.cursor) {
+ if (options.cursor && !expressionEditor._initState) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
dialogForm.i18n();
- setTimeout(function() {
- expressionEditor.focus();
- },300);
},
close: function() {
- expressionEditor.destroy();
if (options.onclose) {
options.onclose();
}
+ expressionEditor.destroy();
+ delete expressionEditor;
},
show: function() {}
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js
index 52ab820ac..400e001a1 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/json.js
@@ -434,6 +434,7 @@
var definition = {
show: function(options) {
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_json"
if ($("script[data-template-name='"+type+"']").length === 0) {
@@ -455,15 +456,16 @@
}
}
var rootNode;
-
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: options.width||700,
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if (onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -485,7 +487,8 @@
} else if (activeTab === "json-raw") {
result = expressionEditor.getValue();
}
- if (onComplete) { onComplete(result) }
+ expressionEditor.saveView();
+ if (onComplete) { onComplete(result,null,expressionEditor) };
RED.tray.close();
}
}
@@ -531,10 +534,12 @@
expressionEditor = RED.editor.createEditor({
id: 'node-input-json',
- value: "",
- mode:"ace/mode/json"
+ value: value||"",
+ mode:"ace/mode/json",
+ stateId: options.stateId,
+ focus: true
});
- expressionEditor.getSession().setValue(value||"",-1);
+
if (options.requireValid) {
expressionEditor.getSession().on('change', function() {
clearTimeout(changeTimer);
@@ -598,14 +603,13 @@
content: $("#red-ui-editor-type-json-tab-ui")
});
finishedBuild = true;
-
-
},
close: function() {
if (options.onclose) {
options.onclose();
}
expressionEditor.destroy();
+ delete expressionEditor;
},
show: function() {}
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
index e0f670c59..68f99d07b 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/markdown.js
@@ -54,24 +54,26 @@
var definition = {
show: function(options) {
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_markdown"
if ($("script[data-template-name='"+type+"']").length === 0) {
$(template).appendTo("#red-ui-editor-node-configs");
}
-
RED.view.state(RED.state.EDITING);
var expressionEditor;
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: options.width||Infinity,
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if (onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -80,7 +82,8 @@
text: RED._("common.label.done"),
class: "primary",
click: function() {
- onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition());
+ expressionEditor.saveView();
+ if (onComplete) { onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition(), expressionEditor); }
RED.tray.close();
}
}
@@ -99,6 +102,8 @@
expressionEditor = RED.editor.createEditor({
id: 'red-ui-editor-type-markdown',
value: value,
+ stateId: options.stateId,
+ focus: true,
mode:"ace/mode/markdown",
expandable: false
});
@@ -143,17 +148,18 @@
});
RED.popover.tooltip($("#node-btn-markdown-preview"), RED._("markdownEditor.toggle-preview"));
- if (options.cursor) {
+ if (options.cursor && !expressionEditor._initState) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
dialogForm.i18n();
},
close: function() {
- expressionEditor.destroy();
if (options.onclose) {
options.onclose();
}
+ expressionEditor.destroy();
+ delete expressionEditor;
},
show: function() {}
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js
index b7be32596..35c4b16d0 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/description.js
@@ -8,7 +8,6 @@
create: function(container) {
this.editor = buildDescriptionForm(container,node);
- RED.e = this.editor;
},
resize: function(size) {
this.editor.resize();
@@ -58,11 +57,9 @@
var nodeInfoEditor = RED.editor.createEditor({
id: editorId,
mode: 'ace/mode/markdown',
- value: ""
+ stateId: RED.editor.generateViewStateId("node", node, "nodeinfo",),
+ value: node.info || ""
});
- if (node.info) {
- nodeInfoEditor.getSession().setValue(node.info, -1);
- }
node.infoEditor = nodeInfoEditor;
return nodeInfoEditor;
}
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/flowProperties.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/flowProperties.js
index 2db4d0c85..826814bab 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/flowProperties.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/panes/flowProperties.js
@@ -19,6 +19,7 @@
this.tabflowEditor = RED.editor.createEditor({
id: 'node-input-info',
mode: 'ace/mode/markdown',
+ stateId: options.stateId,
value: ""
});
diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js
index 1824091fe..e64e5e902 100644
--- a/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js
+++ b/packages/node_modules/@node-red/editor-client/src/js/ui/editors/text.js
@@ -21,6 +21,7 @@
var definition = {
show: function(options) {
var value = options.value;
+ var onCancel = options.cancel;
var onComplete = options.complete;
var type = "_text"
if ($("script[data-template-name='"+type+"']").length === 0) {
@@ -28,16 +29,16 @@
}
RED.view.state(RED.state.EDITING);
var expressionEditor;
- var changeTimer;
-
var trayOptions = {
title: options.title,
+ focusElement: options.focusElement,
width: options.width||"inherit",
buttons: [
{
id: "node-dialog-cancel",
text: RED._("common.label.cancel"),
click: function() {
+ if(onCancel) { onCancel() };
RED.tray.close();
}
},
@@ -46,7 +47,8 @@
text: RED._("common.label.done"),
class: "primary",
click: function() {
- onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition());
+ expressionEditor.saveView();
+ if (onComplete) { onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition(),expressionEditor);}
RED.tray.close();
}
}
@@ -55,31 +57,28 @@
var rows = $("#dialog-form>div:not(.node-text-editor-row)");
var editorRow = $("#dialog-form>div.node-text-editor-row");
var height = $("#dialog-form").height();
- // for (var i=0;i README.md'),
value: activeProject.description,
+ stateId: "sidebar.project.editDescription",
complete: function(v) {
container.empty();
var spinner = utils.addSpinnerOverlay(container);
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 1b331fb9a..6d15394bb 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
@@ -169,7 +169,13 @@
raiseTrayZ();
handleWindowResize();//cause call to monaco layout
},200);
- body.find(":focusable:first").trigger("focus");
+ if(!options.hasOwnProperty("focusElement")) {
+ //focusElement is not inside options - default to focusing 1st
+ body.find(":focusable:first").trigger("focus");
+ } else if(!options.focusElement === false) {
+ //focusElement IS specified, focus that instead (if not false)
+ $(options.focusElement).trigger("focus");
+ }
},150);
el.css({right:0});
diff --git a/packages/node_modules/@node-red/nodes/core/function/10-function.html b/packages/node_modules/@node-red/nodes/core/function/10-function.html
index 4091eb22d..6309ae9ad 100644
--- a/packages/node_modules/@node-red/nodes/core/function/10-function.html
+++ b/packages/node_modules/@node-red/nodes/core/function/10-function.html
@@ -413,11 +413,19 @@
$("#func-tabs-content").children().hide();
$("#" + tab.id).show();
let editor = $("#" + tab.id).find('.monaco-editor').first();
- if(editor.length) {
+ if(editor.length) {
if(that.editor.nodered && that.editor.type == "monaco") {
that.editor.nodered.refreshModuleLibs(getLibsList());
}
RED.tray.resize();
+ //auto focus editor on tab switch
+ if (that.initEditor.getDomNode() == editor[0]) {
+ that.initEditor.focus();
+ } else if (that.editor.getDomNode() == editor[0]) {
+ that.editor.focus();
+ } else if (that.finalizeEditor.getDomNode() == editor[0]) {
+ that.finalizeEditor.focus();
+ }
}
}
});
@@ -452,11 +460,13 @@
}
});
- var buildEditor = function(id, value, defaultValue, extraLibs) {
+ var buildEditor = function(id, stateId, focus, value, defaultValue, extraLibs) {
var editor = RED.editor.createEditor({
id: id,
mode: 'ace/mode/nrjavascript',
value: value || defaultValue || "",
+ stateId: stateId,
+ focus: true,
globals: {
msg:true,
context:true,
@@ -476,11 +486,12 @@
if (defaultValue && value === "") {
editor.moveCursorTo(defaultValue.split("\n").length - 1, 0);
}
+ editor.__stateId = stateId;
return editor;
}
- this.initEditor = buildEditor('node-input-init-editor',$("#node-input-initialize").val(),RED._("node-red:function.text.initialize"))
- this.editor = buildEditor('node-input-func-editor',$("#node-input-func").val(), undefined, that.libs || [])
- this.finalizeEditor = buildEditor('node-input-finalize-editor',$("#node-input-finalize").val(),RED._("node-red:function.text.finalize"))
+ this.initEditor = buildEditor('node-input-init-editor', this.id + "/" + "initEditor", false, $("#node-input-initialize").val(), RED._("node-red:function.text.initialize"))
+ this.editor = buildEditor('node-input-func-editor', this.id + "/" + "editor", true, $("#node-input-func").val(), undefined, that.libs || [])
+ this.finalizeEditor = buildEditor('node-input-finalize-editor', this.id + "/" + "finalizeEditor", false, $("#node-input-finalize").val(), RED._("node-red:function.text.finalize"))
RED.library.create({
url:"functions", // where to get the data from
@@ -519,28 +530,33 @@
],
ext:"js"
});
- this.editor.focus();
-
var expandButtonClickHandler = function(editor) {
- return function(e) {
+ return function (e) {
e.preventDefault();
var value = editor.getValue();
+ editor.saveView(`inside function-expandButtonClickHandler ${editor.__stateId}`);
var extraLibs = that.libs || [];
RED.editor.editJavaScript({
value: value,
width: "Infinity",
- cursor: editor.getCursorPosition(),
+ stateId: editor.__stateId,
mode: "ace/mode/nrjavascript",
- complete: function(v,cursor) {
- editor.setValue(v, -1);
- editor.gotoLine(cursor.row+1,cursor.column,false);
- setTimeout(function() {
+ focus: true,
+ cancel: function () {
+ setTimeout(function () {
editor.focus();
- },300);
+ }, 250);
+ },
+ complete: function (v, cursor) {
+ editor.setValue(v, -1);
+ setTimeout(function () {
+ editor.restoreView();
+ editor.focus();
+ }, 250);
},
extraLibs: extraLibs
- })
+ });
}
}
$("#node-init-expand-js").on("click", expandButtonClickHandler(this.initEditor));
diff --git a/packages/node_modules/@node-red/nodes/core/function/80-template.html b/packages/node_modules/@node-red/nodes/core/function/80-template.html
index 9d60d5a94..940487001 100644
--- a/packages/node_modules/@node-red/nodes/core/function/80-template.html
+++ b/packages/node_modules/@node-red/nodes/core/function/80-template.html
@@ -18,7 +18,7 @@
-
+
@@ -75,7 +75,8 @@
return this.name?"node_label_italic":"";
},
oneditprepare: function() {
- var that = this;
+ const that = this;
+ const stateId = RED.editor.generateViewStateId("node", this, "");
if (!this.field) {
this.field = 'payload';
$("#node-input-field").val("payload");
@@ -92,10 +93,10 @@
types: ['msg','flow','global'],
typeField: $("#node-input-fieldType")
});
-
this.editor = RED.editor.createEditor({
id: 'node-input-template-editor',
mode: 'ace/mode/html',
+ stateId: stateId,
value: $("#node-input-template").val()
});
RED.library.create({
@@ -105,7 +106,6 @@
fields:['name','format','output','syntax'],
ext: "txt"
});
- this.editor.focus();
$("#node-input-format").on("change", function() {
var mod = "ace/mode/"+$("#node-input-format").val();
@@ -115,20 +115,22 @@
});
});
RED.popover.tooltip($("#node-template-expand-editor"), RED._("node-red:common.label.expand"));
- $("#node-template-expand-editor").on("click", function(e) {
+ $("#node-template-expand-editor").on("click", function (e) {
e.preventDefault();
- var value = that.editor.getValue();
+ const value = that.editor.getValue();
+ that.editor.saveView();
RED.editor.editText({
mode: $("#node-input-format").val(),
value: value,
+ stateId: stateId,
width: "Infinity",
- cursor: that.editor.getCursorPosition(),
- complete: function(v,cursor) {
+ focus: true,
+ complete: function (v, cursor) {
that.editor.setValue(v, -1);
- that.editor.gotoLine(cursor.row+1,cursor.column,false);
- setTimeout(function() {
+ setTimeout(function () {
+ that.editor.restoreView();
that.editor.focus();
- },300);
+ }, 250);
}
})
})