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

Add RED.editor.registerTypeEditor for custom type editors

This commit is contained in:
Nick O'Leary 2018-12-10 22:20:56 +00:00
parent d47ac84d2e
commit ea4d65ceee
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
8 changed files with 155 additions and 125 deletions

View File

@ -445,7 +445,17 @@ module.exports = function(grunt) {
destination: 'docs', destination: 'docs',
configure: './jsdoc.json' configure: './jsdoc.json'
} }
},
editor: {
src: [
'packages/node_modules/@node-red/editor-client/src/js'
],
options: {
destination: 'packages/node_modules/@node-red/editor-client/docs',
configure: './jsdoc.json'
}
} }
}, },
jsdoc2md: { jsdoc2md: {
runtimeAPI: { runtimeAPI: {

View File

@ -1304,7 +1304,7 @@ RED.text.format = (function() {
} }
return { return {
/** /*!
* Returns the HTML representation of a given structured text * Returns the HTML representation of a given structured text
* @param text - the structured text * @param text - the structured text
* @param type - could be one of filepath, url, email * @param type - could be one of filepath, url, email
@ -1315,7 +1315,7 @@ RED.text.format = (function() {
getHtml: function (text, type, args, isRtl, locale) { getHtml: function (text, type, args, isRtl, locale) {
return getHandler(type).format(text, args, isRtl, true, locale); return getHandler(type).format(text, args, isRtl, true, locale);
}, },
/** /*!
* Handle Structured text correct display for a given HTML element. * Handle Structured text correct display for a given HTML element.
* @param element - the element : should be of type div contenteditable=true * @param element - the element : should be of type div contenteditable=true
* @param type - could be one of filepath, url, email * @param type - could be one of filepath, url, email

View File

@ -13,6 +13,10 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
/**
* @namespace RED.editor
*/
RED.editor = (function() { RED.editor = (function() {
@ -21,6 +25,8 @@ RED.editor = (function() {
var editing_config_node = null; var editing_config_node = null;
var subflowEditor; var subflowEditor;
var customEditTypes = {};
var editTrayWidthCache = {}; var editTrayWidthCache = {};
function getCredentialsURL(nodeType, nodeID) { function getCredentialsURL(nodeType, nodeID) {
@ -2137,7 +2143,7 @@ RED.editor = (function() {
} }
function showTypeEditor(type, options) { function showTypeEditor(type, options) {
if (RED.editor.types.hasOwnProperty(type)) { if (customEditTypes.hasOwnProperty(type)) {
if (editStack.length > 0) { if (editStack.length > 0) {
options.parent = editStack[editStack.length-1].id; options.parent = editStack[editStack.length-1].id;
} }
@ -2146,12 +2152,99 @@ RED.editor = (function() {
options.onclose = function() { options.onclose = function() {
editStack.pop(); editStack.pop();
} }
RED.editor.types[type].show(options); customEditTypes[type].show(options);
} else { } else {
console.log("Unknown type editor:",type); console.log("Unknown type editor:",type);
} }
} }
function createEditor(options) {
var el = options.element || $("#"+options.id)[0];
var toolbarRow = $("<div>").appendTo(el);
el = $("<div>").appendTo(el).addClass("node-text-editor-container")[0];
var editor = ace.edit(el);
editor.setTheme("ace/theme/tomorrow");
var session = editor.getSession();
session.on("changeAnnotation", function () {
var annotations = session.getAnnotations() || [];
var i = annotations.length;
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, esversion:6, sub:true, asi:true, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("node-text-editor-container-toolbar");
editor.toolbar = customEditTypes['_markdown'].buildToolbar(toolbarRow,editor);
if (options.expandable !== false) {
var expandButton = $('<button class="editor-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
expandButton.click(function(e) {
e.preventDefault();
var value = editor.getValue();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: editor.getCursorPosition(),
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button class="node-text-editor-help editor-button editor-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
}
return editor;
}
return { return {
init: function() { init: function() {
@ -2164,14 +2257,7 @@ RED.editor = (function() {
$("#node-dialog-cancel").click(); $("#node-dialog-cancel").click();
$("#node-config-dialog-cancel").click(); $("#node-config-dialog-cancel").click();
}); });
for (var type in RED.editor.types) {
if (RED.editor.types.hasOwnProperty(type)) {
RED.editor.types[type].init();
}
}
}, },
types: {},
edit: showEditDialog, edit: showEditDialog,
editConfig: showEditConfigNodeDialog, editConfig: showEditConfigNodeDialog,
editSubflow: showEditSubflowDialog, editSubflow: showEditSubflowDialog,
@ -2184,93 +2270,32 @@ RED.editor = (function() {
validateNode: validateNode, validateNode: validateNode,
updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo updateNodeProperties: updateNodeProperties, // TODO: only exposed for edit-undo
/**
* Show a type editor.
* @param {string} type - the type to display
* @param {object} options - options for the editor
* @function
* @memberof RED.editor
*/
showTypeEditor: showTypeEditor,
createEditor: function(options) { /**
var el = options.element || $("#"+options.id)[0]; * Register a type editor.
var toolbarRow = $("<div>").appendTo(el); * @param {string} type - the type name
el = $("<div>").appendTo(el).addClass("node-text-editor-container")[0]; * @param {object} options - the editor definition
var editor = ace.edit(el); * @function
editor.setTheme("ace/theme/tomorrow"); * @memberof RED.editor
var session = editor.getSession(); */
session.on("changeAnnotation", function () { registerTypeEditor: function(type, definition) {
var annotations = session.getAnnotations() || []; customEditTypes[type] = definition;
var i = annotations.length; },
var len = annotations.length;
while (i--) {
if (/doctype first\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
else if (/Unexpected End of file\. Expected/.test(annotations[i].text)) { annotations.splice(i, 1); }
}
if (len > annotations.length) { session.setAnnotations(annotations); }
});
if (options.mode) {
session.setMode(options.mode);
}
if (options.foldStyle) {
session.setFoldStyle(options.foldStyle);
} else {
session.setFoldStyle('markbeginend');
}
if (options.options) {
editor.setOptions(options.options);
} else {
editor.setOptions({
enableBasicAutocompletion:true,
enableSnippets:true,
tooltipFollowsMouse: false
});
}
if (options.readOnly) {
editor.setOption('readOnly',options.readOnly);
editor.container.classList.add("ace_read-only");
}
if (options.hasOwnProperty('lineNumbers')) {
editor.renderer.setOption('showGutter',options.lineNumbers);
}
editor.$blockScrolling = Infinity;
if (options.value) {
session.setValue(options.value,-1);
}
if (options.globals) {
setTimeout(function() {
if (!!session.$worker) {
session.$worker.send("setOptions", [{globals: options.globals, esversion:6, sub:true, asi:true, maxerr:1000}]);
}
},100);
}
if (options.mode === 'ace/mode/markdown') {
$(el).addClass("node-text-editor-container-toolbar");
editor.toolbar = RED.editor.types._markdown.buildToolbar(toolbarRow,editor);
if (options.expandable !== false) {
var expandButton = $('<button class="editor-button" style="float: right;"><i class="fa fa-expand"></i></button>').appendTo(editor.toolbar);
expandButton.click(function(e) { /**
e.preventDefault(); * Create a editor ui component
var value = editor.getValue(); * @param {object} options - the editor options
RED.editor.editMarkdown({ * @function
value: value, * @memberof RED.editor
width: "Infinity", */
cursor: editor.getCursorPosition(), createEditor: createEditor
complete: function(v,cursor) {
editor.setValue(v, -1);
editor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
editor.focus();
},300);
}
})
});
}
var helpButton = $('<button class="node-text-editor-help editor-button editor-button-small"><i class="fa fa-question"></i></button>').appendTo($(el).parent());
RED.popover.create({
target: helpButton,
trigger: 'click',
size: "small",
direction: "left",
content: RED._("markdownEditor.format"),
autoClose: 50
});
}
return editor;
}
} }
})(); })();

View File

@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.editor.types._buffer = (function() { (function() {
var template = '<script type="text/x-red" data-template-name="_buffer"><div id="node-input-buffer-panels"><div id="node-input-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-buffer-type"><i class="fa fa-exclamation-circle"></i> <span id="node-input-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="node-input-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></span></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-buffer-str"></div></div></div><div id="node-input-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px"><div class="node-text-editor" id="node-input-buffer-bin"></div></div></div></div></script>'; var template = '<script type="text/x-red" data-template-name="_buffer"><div id="node-input-buffer-panels"><div id="node-input-buffer-panel-str" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-buffer-type"><i class="fa fa-exclamation-circle"></i> <span id="node-input-buffer-type-string" data-i18n="bufferEditor.modeString"></span><span id="node-input-buffer-type-array" data-i18n="bufferEditor.modeArray"></span></span></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-buffer-str"></div></div></div><div id="node-input-buffer-panel-bin" class="red-ui-panel"><div class="form-row node-text-editor-row" style="margin-top: 10px"><div class="node-text-editor" id="node-input-buffer-bin"></div></div></div></div></script>';
@ -45,10 +44,7 @@ RED.editor.types._buffer = (function() {
} }
return { var definition = {
init: function() {
$(template).appendTo(document.body);
},
show: function(options) { show: function(options) {
var value = options.value; var value = options.value;
var onComplete = options.complete; var onComplete = options.complete;
@ -206,4 +202,7 @@ RED.editor.types._buffer = (function() {
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }
} }
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_buffer", definition);
})(); })();

View File

@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.editor.types._expression = (function() { (function() {
var template = '<script type="text/x-red" data-template-name="_expression">'+ var template = '<script type="text/x-red" data-template-name="_expression">'+
@ -46,10 +46,7 @@ RED.editor.types._expression = (function() {
'</script>'; '</script>';
var expressionTestCache = {}; var expressionTestCache = {};
return { var definition = {
init: function() {
$(template).appendTo(document.body);
},
show: function(options) { show: function(options) {
var expressionTestCacheId = options.parent||"_"; var expressionTestCacheId = options.parent||"_";
var value = options.value; var value = options.value;
@ -349,4 +346,6 @@ RED.editor.types._expression = (function() {
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }
} }
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_expression", definition);
})(); })();

View File

@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.editor.types._js = (function() { (function() {
var template = '<script type="text/x-red" data-template-name="_js"><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-js"></div></div></script>'; var template = '<script type="text/x-red" data-template-name="_js"><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-js"></div></div></script>';
return { var definition = {
init: function() {
$(template).appendTo(document.body);
},
show: function(options) { show: function(options) {
var value = options.value; var value = options.value;
var onComplete = options.complete; var onComplete = options.complete;
@ -99,4 +96,7 @@ RED.editor.types._js = (function() {
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }
} }
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_js", definition);
})(); })();

View File

@ -13,15 +13,12 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.editor.types._json = (function() { (function() {
var template = '<script type="text/x-red" data-template-name="_json"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button id="node-input-json-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div></div></script>'; var template = '<script type="text/x-red" data-template-name="_json"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><button id="node-input-json-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-json"></div></div></script>';
return { var definition = {
init: function() {
$(template).appendTo(document.body);
},
show: function(options) { show: function(options) {
var value = options.value; var value = options.value;
var onComplete = options.complete; var onComplete = options.complete;
@ -115,4 +112,6 @@ RED.editor.types._json = (function() {
RED.tray.show(trayOptions); RED.tray.show(trayOptions);
} }
} }
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_json", definition);
})(); })();

View File

@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
**/ **/
RED.editor.types._markdown = (function() { (function() {
var toolbarTemplate = '<div style="margin-bottom: 5px">'+ var toolbarTemplate = '<div style="margin-bottom: 5px">'+
'<span class="button-group">'+ '<span class="button-group">'+
@ -66,10 +65,7 @@ RED.editor.types._markdown = (function() {
'hr': { before:"\n---\n\n", tooltip: "Horizontal rule" } 'hr': { before:"\n---\n\n", tooltip: "Horizontal rule" }
} }
return { var definition = {
init: function() {
$(template).appendTo(document.body);
},
show: function(options) { show: function(options) {
var value = options.value; var value = options.value;
var onComplete = options.complete; var onComplete = options.complete;
@ -212,4 +208,6 @@ RED.editor.types._markdown = (function() {
return toolbar; return toolbar;
} }
} }
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_markdown", definition);
})(); })();