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',
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: {
runtimeAPI: {

View File

@ -1242,7 +1242,7 @@ RED.text.format = (function() {
element.dispatchEvent(event);
return;
}
var range = selection.getRangeAt(0);
var tempRange = range.cloneRange(), startNode, startOffset;
startNode = range.startContainer;
@ -1304,7 +1304,7 @@ RED.text.format = (function() {
}
return {
/**
/*!
* Returns the HTML representation of a given structured text
* @param text - the structured text
* @param type - could be one of filepath, url, email
@ -1315,7 +1315,7 @@ RED.text.format = (function() {
getHtml: function (text, type, args, isRtl, locale) {
return getHandler(type).format(text, args, isRtl, true, locale);
},
/**
/*!
* Handle Structured text correct display for a given HTML element.
* @param element - the element : should be of type div contenteditable=true
* @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
* limitations under the License.
**/
/**
* @namespace RED.editor
*/
RED.editor = (function() {
@ -21,6 +25,8 @@ RED.editor = (function() {
var editing_config_node = null;
var subflowEditor;
var customEditTypes = {};
var editTrayWidthCache = {};
function getCredentialsURL(nodeType, nodeID) {
@ -2137,7 +2143,7 @@ RED.editor = (function() {
}
function showTypeEditor(type, options) {
if (RED.editor.types.hasOwnProperty(type)) {
if (customEditTypes.hasOwnProperty(type)) {
if (editStack.length > 0) {
options.parent = editStack[editStack.length-1].id;
}
@ -2146,12 +2152,99 @@ RED.editor = (function() {
options.onclose = function() {
editStack.pop();
}
RED.editor.types[type].show(options);
customEditTypes[type].show(options);
} else {
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 {
init: function() {
@ -2164,14 +2257,7 @@ RED.editor = (function() {
$("#node-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,
editConfig: showEditConfigNodeDialog,
editSubflow: showEditSubflowDialog,
@ -2184,93 +2270,32 @@ RED.editor = (function() {
validateNode: validateNode,
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];
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 = 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);
/**
* Register a type editor.
* @param {string} type - the type name
* @param {object} options - the editor definition
* @function
* @memberof RED.editor
*/
registerTypeEditor: function(type, definition) {
customEditTypes[type] = definition;
},
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;
}
/**
* Create a editor ui component
* @param {object} options - the editor options
* @function
* @memberof RED.editor
*/
createEditor: createEditor
}
})();

View File

@ -13,8 +13,7 @@
* See the License for the specific language governing permissions and
* 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>';
@ -45,10 +44,7 @@ RED.editor.types._buffer = (function() {
}
return {
init: function() {
$(template).appendTo(document.body);
},
var definition = {
show: function(options) {
var value = options.value;
var onComplete = options.complete;
@ -206,4 +202,7 @@ RED.editor.types._buffer = (function() {
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
* limitations under the License.
**/
RED.editor.types._expression = (function() {
(function() {
var template = '<script type="text/x-red" data-template-name="_expression">'+
@ -46,10 +46,7 @@ RED.editor.types._expression = (function() {
'</script>';
var expressionTestCache = {};
return {
init: function() {
$(template).appendTo(document.body);
},
var definition = {
show: function(options) {
var expressionTestCacheId = options.parent||"_";
var value = options.value;
@ -349,4 +346,6 @@ RED.editor.types._expression = (function() {
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
* 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>';
return {
init: function() {
$(template).appendTo(document.body);
},
var definition = {
show: function(options) {
var value = options.value;
var onComplete = options.complete;
@ -99,4 +96,7 @@ RED.editor.types._js = (function() {
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
* 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>';
return {
init: function() {
$(template).appendTo(document.body);
},
var definition = {
show: function(options) {
var value = options.value;
var onComplete = options.complete;
@ -115,4 +112,6 @@ RED.editor.types._json = (function() {
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
* limitations under the License.
**/
RED.editor.types._markdown = (function() {
(function() {
var toolbarTemplate = '<div style="margin-bottom: 5px">'+
'<span class="button-group">'+
@ -66,10 +65,7 @@ RED.editor.types._markdown = (function() {
'hr': { before:"\n---\n\n", tooltip: "Horizontal rule" }
}
return {
init: function() {
$(template).appendTo(document.body);
},
var definition = {
show: function(options) {
var value = options.value;
var onComplete = options.complete;
@ -212,4 +208,6 @@ RED.editor.types._markdown = (function() {
return toolbar;
}
}
$(template).appendTo(document.body);
RED.editor.registerTypeEditor("_markdown", definition);
})();