Add markdown-preview to expandable editor for ndoe descriptions

This commit is contained in:
Nick O'Leary 2018-09-21 17:21:04 +01:00
parent 8edf399631
commit 80a15089b4
No known key found for this signature in database
GPG Key ID: 4F2157149161A6C9
6 changed files with 172 additions and 42 deletions

View File

@ -23,53 +23,74 @@ RED.panels = (function() {
if (children.length !== 2) {
throw new Error("Container must have exactly two children");
}
var vertical = (!options.dir || options.dir === "vertical");
container.addClass("red-ui-panels");
if (!vertical) {
container.addClass("red-ui-panels-horizontal");
}
var separator = $('<div class="red-ui-panels-separator"></div>').insertAfter(children[0]);
var startPosition;
var panelHeights = [];
var modifiedHeights = false;
var panelSizes = [];
var modifiedSizes = false;
var panelRatio;
separator.draggable({
axis: "y",
axis: vertical?"y":"x",
containment: container,
scroll: false,
start:function(event,ui) {
var height = container.height();
startPosition = ui.position.top;
panelHeights = [$(children[0]).height(),$(children[1]).height()];
startPosition = vertical?ui.position.top:ui.position.left;
panelSizes = [
vertical?$(children[0]).height():$(children[0]).width(),
vertical?$(children[1]).height():$(children[1]).width()
];
},
drag: function(event,ui) {
var height = container.height();
var delta = ui.position.top-startPosition;
var newHeights = [panelHeights[0]+delta,panelHeights[1]-delta];
$(children[0]).height(newHeights[0]);
$(children[1]).height(newHeights[1]);
if (options.resize) {
options.resize(newHeights[0],newHeights[1]);
var size = vertical?container.height():container.width();
var delta = (vertical?ui.position.top:ui.position.left)-startPosition;
var newSizes = [panelSizes[0]+delta,panelSizes[1]-delta];
if (vertical) {
$(children[0]).height(newSizes[0]);
$(children[1]).height(newSizes[1]);
ui.position.top -= delta;
} else {
$(children[0]).width(newSizes[0]);
$(children[1]).width(newSizes[1]);
ui.position.left -= delta;
}
ui.position.top -= delta;
panelRatio = newHeights[0]/height;
if (options.resize) {
options.resize(newSizes[0],newSizes[1]);
}
panelRatio = newSizes[0]/size;
},
stop:function(event,ui) {
modifiedHeights = true;
modifiedSizes = true;
}
});
return {
resize: function(height) {
var panelHeights = [$(children[0]).height(),$(children[1]).height()];
container.height(height);
if (modifiedHeights) {
var topPanelHeight = panelRatio*height;
var bottomPanelHeight = height - topPanelHeight - 48;
panelHeights = [topPanelHeight,bottomPanelHeight];
$(children[0]).height(panelHeights[0]);
$(children[1]).height(panelHeights[1]);
resize: function(size) {
var panelSizes = [$(children[0]).height(),$(children[1]).height()];
if (vertical) {
container.height(size);
} else {
container.width(size);
}
if (modifiedSizes) {
var topPanelSize = panelRatio*size;
var bottomPanelSize = size - topPanelSize - 48;
panelSizes = [topPanelSize,bottomPanelSize];
if (vertical) {
$(children[0]).height(panelSizes[0]);
$(children[1]).height(panelSizes[1]);
} else {
$(children[0]).width(panelSizes[0]);
$(children[1]).width(panelSizes[1]);
}
}
if (options.resize) {
options.resize(panelHeights[0],panelHeights[1]);
options.resize(panelSizes[0],panelSizes[1]);
}
}
}

View File

@ -884,7 +884,9 @@ RED.editor = (function() {
function buildDescriptionForm(container,node) {
var dialogForm = $('<form class="dialog-form form-horizontal" autocomplete="off"></form>').appendTo(container);
$('<div style="height: 100%;" class="node-text-editor" id="node-info-input-info-editor" ></div>').appendTo(dialogForm);
var row = $('<div class="form-row node-text-editor-row" style="position:relative; padding-top: 4px; height: 100%"></div>').appendTo(dialogForm);
$('<div style="position: absolute; right:0; bottom:100%;"><button id="node-info-input-info-expand" class="editor-button editor-button-small"><i class="fa fa-expand"></i></button></div>').appendTo(row);
$('<div style="height: 100%;" class="node-text-editor" id="node-info-input-info-editor" ></div>').appendTo(row);
var nodeInfoEditor = RED.editor.createEditor({
id: "node-info-input-info-editor",
mode: 'ace/mode/markdown',
@ -893,6 +895,23 @@ RED.editor = (function() {
if (node.info) {
nodeInfoEditor.getSession().setValue(node.info, -1);
}
$('#node-info-input-info-expand').click(function(e) {
e.preventDefault();
var value = nodeInfoEditor.getValue();
RED.editor.editMarkdown({
value: value,
width: "Infinity",
cursor: nodeInfoEditor.getCursorPosition(),
complete: function(v,cursor) {
nodeInfoEditor.setValue(v, -1);
nodeInfoEditor.gotoLine(cursor.row+1,cursor.column,false);
setTimeout(function() {
nodeInfoEditor.focus();
},300);
}
})
});
return nodeInfoEditor;
}

View File

@ -16,7 +16,34 @@
RED.editor.types._expression = (function() {
var template = '<script type="text/x-red" data-template-name="_expression"><div id="node-input-expression-panels"><div id="node-input-expression-panel-expr" class="red-ui-panel"><div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-expression-legacy"><i class="fa fa-exclamation-circle"></i> <span data-i18n="expressionEditor.compatMode"></span></span><button id="node-input-expression-reformat" class="editor-button editor-button-small"><span data-i18n="expressionEditor.format"></span></button></div><div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-expression"></div></div></div><div id="node-input-expression-panel-info" class="red-ui-panel"><div class="form-row"><ul id="node-input-expression-tabs"></ul><div id="node-input-expression-tab-help" class="node-input-expression-tab-content hide"><div><select id="node-input-expression-func"></select><button id="node-input-expression-func-insert" class="editor-button" data-i18n="expressionEditor.insert"></button></div><div id="node-input-expression-help"></div></div><div id="node-input-expression-tab-test" class="node-input-expression-tab-content hide"><div><span style="display: inline-block; width: calc(50% - 5px);"><span data-i18n="expressionEditor.data"></span><button style="float: right; margin-right: 5px;" id="node-input-example-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></span><span style="display: inline-block; width: calc(50% - 5px);" data-i18n="expressionEditor.result"></span></div><div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-data"></div><div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-result"></div></div></div></div></div></script>';
var template = '<script type="text/x-red" data-template-name="_expression">'+
'<div id="node-input-expression-panels">'+
'<div id="node-input-expression-panel-expr" class="red-ui-panel">'+
'<div class="form-row" style="margin-bottom: 3px; text-align: right;"><span class="node-input-expression-legacy"><i class="fa fa-exclamation-circle"></i> <span data-i18n="expressionEditor.compatMode"></span></span><button id="node-input-expression-reformat" class="editor-button editor-button-small"><span data-i18n="expressionEditor.format"></span></button></div>'+
'<div class="form-row node-text-editor-row"><div class="node-text-editor" id="node-input-expression"></div></div>'+
'</div>'+
'<div id="node-input-expression-panel-info" class="red-ui-panel">'+
'<div class="form-row">'+
'<ul id="node-input-expression-tabs"></ul>'+
'<div id="node-input-expression-tab-help" class="node-input-expression-tab-content hide">'+
'<div>'+
'<select id="node-input-expression-func"></select>'+
'<button id="node-input-expression-func-insert" class="editor-button" data-i18n="expressionEditor.insert"></button>'+
'</div>'+
'<div id="node-input-expression-help"></div>'+
'</div>'+
'<div id="node-input-expression-tab-test" class="node-input-expression-tab-content hide">'+
'<div>'+
'<span style="display: inline-block; width: calc(50% - 5px);"><span data-i18n="expressionEditor.data"></span><button style="float: right; margin-right: 5px;" id="node-input-example-reformat" class="editor-button editor-button-small"><span data-i18n="jsonEditor.format"></span></button></span>'+
'<span style="display: inline-block; width: calc(50% - 5px);" data-i18n="expressionEditor.result"></span>'+
'</div>'+
'<div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-data"></div>'+
'<div style="display: inline-block; width: calc(50% - 5px);" class="node-text-editor" id="node-input-expression-test-result"></div>'+
'</div>'+
'</div>'+
'</div>'+
'</div>'+
'</script>';
var expressionTestCache = {};
return {

View File

@ -16,7 +16,18 @@
RED.editor.types._markdown = (function() {
var template = '<script type="text/x-red" data-template-name="_markdown"><div class="form-row" id="node-input-markdown-title" style="margin-bottom: 3px; text-align: right;"></div><div class="form-row node-text-editor-row"><div style="height: 200px;min-height: 150px;" class="node-text-editor" id="node-input-markdown"></div></div></script>';
var template = '<script type="text/x-red" data-template-name="_markdown">'+
'<div id="node-input-markdown-panels">'+
'<div id="node-input-markdown-panel-editor" class="red-ui-panel">'+
'<div class="node-text-editor" style="height: calc(100% - 20px)" id="node-input-markdown"></div>'+
'</div>'+
'<div class="red-ui-panel">'+
'<div id="node-input-markdown-panel-preview" style="padding: 20px;" class="node-help"></div>'+
'</div>'+
'</script>';
var panels;
return {
init: function() {
@ -31,7 +42,7 @@ RED.editor.types._markdown = (function() {
var trayOptions = {
title: options.title,
width: "inherit",
width: options.width||Infinity,
buttons: [
{
id: "node-dialog-cancel",
@ -45,34 +56,55 @@ RED.editor.types._markdown = (function() {
text: RED._("common.label.done"),
class: "primary",
click: function() {
onComplete(expressionEditor.getValue());
onComplete(expressionEditor.getValue(),expressionEditor.getCursorPosition());
RED.tray.close();
}
}
],
resize: function(dimensions) {
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<rows.size();i++) {
height -= $(rows[i]).outerHeight(true);
var width = $("#dialog-form").width();
if (panels) {
panels.resize(width);
}
height -= (parseInt($("#dialog-form").css("marginTop"))+parseInt($("#dialog-form").css("marginBottom")));
$(".node-text-editor").css("height",height+"px");
expressionEditor.resize();
},
open: function(tray) {
var trayBody = tray.find('.editor-tray-body');
trayBody.addClass("node-input-markdown-editor")
var dialogForm = RED.editor.buildEditForm(tray.find('.editor-tray-body'),'dialog-form',type,'editor');
expressionEditor = RED.editor.createEditor({
id: 'node-input-markdown',
value: value,
mode:"ace/mode/markdown"
});
var changeTimer;
expressionEditor.getSession().on("change", function() {
clearTimeout(changeTimer);
changeTimer = setTimeout(function() {
var currentScrollTop = $("#node-input-markdown-panel-preview").scrollTop();
$("#node-input-markdown-panel-preview").html(marked(expressionEditor.getValue()));
$("#node-input-markdown-panel-preview").scrollTop(currentScrollTop);
},200);
})
if (options.header) {
options.header.appendTo(tray.find('#node-input-markdown-title'));
}
if (value) {
$("#node-input-markdown-panel-preview").html(marked(expressionEditor.getValue()));
}
panels = RED.panels.create({
id:"node-input-markdown-panels",
dir: "horizontal",
resize: function(p1Width,p2Width) {
expressionEditor.resize();
}
});
if (options.cursor) {
expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);
}
dialogForm.i18n();
},
close: function() {

View File

@ -56,6 +56,7 @@
}
.editor-tray-content {
overflow: auto;
position: relative;
}
.editor-tray-header {
@include disable-selection;
@ -312,7 +313,18 @@
float: none;
text-align: right;
}
.node-input-markdown-editor #dialog-form {
margin: 0;
height: 100%;
.red-ui-panel {
&:first-child {
padding: 20px 20px 0;
}
&:last-child {
padding-bottom: 20px;
}
}
}
#clipboard-hidden {
position: absolute;
top: -3000px;

View File

@ -17,7 +17,7 @@
.red-ui-panels {
position: relative;
overflow: hidden;
& > div {
// border: 1px solid red;
box-sizing: border-box;
@ -38,3 +38,22 @@
overflow: auto;
height: calc(50% - 4px);
}
.red-ui-panels.red-ui-panels-horizontal {
height: 100%;
.red-ui-panel {
display: inline-block;
height: 100%;
width: calc(50% - 4px);
}
.red-ui-panels-separator {
border-top: none;
border-bottom: none;
border-left: 1px solid $secondary-border-color;
border-right: 1px solid $secondary-border-color;
height: 100%;
width: 7px;
display: inline-block;
cursor: ew-resize;
}
}