From bcc7834650e5145066d6cdf0c27687998b5675c2 Mon Sep 17 00:00:00 2001 From: Nick O'Leary <nick.oleary@gmail.com> Date: Fri, 5 Oct 2018 17:56:54 +0100 Subject: [PATCH] Add markdown formatting toolbar --- .../editor-client/src/js/ui/common/panels.js | 40 ++++++--- .../src/js/ui/editors/markdown.js | 83 ++++++++++++++++++- 2 files changed, 110 insertions(+), 13 deletions(-) diff --git a/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js b/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js index 22e415099..3ccaa6b43 100644 --- a/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js +++ b/packages/node_modules/@node-red/editor-client/src/js/ui/common/panels.js @@ -32,8 +32,7 @@ RED.panels = (function() { var startPosition; var panelSizes = []; var modifiedSizes = false; - var panelRatio; - + var panelRatio = 0.5; separator.draggable({ axis: vertical?"y":"x", containment: container, @@ -62,31 +61,47 @@ RED.panels = (function() { if (options.resize) { options.resize(newSizes[0],newSizes[1]); } - panelRatio = newSizes[0]/size; + panelRatio = newSizes[0]/(size-8); }, stop:function(event,ui) { modifiedSizes = true; } }); - return { - resize: function(size) { - var panelSizes = [$(children[0]).height(),$(children[1]).height()]; + var panel = { + ratio: function(ratio) { + panelRatio = ratio; + modifiedSizes = true; + if (ratio === 0 || ratio === 1) { + separator.hide(); + } else { + separator.show(); + } if (vertical) { + panel.resize(container.height()); + } else { + panel.resize(container.width()); + } + }, + resize: function(size) { + var panelSizes; + if (vertical) { + panelSizes = [$(children[0]).height(),$(children[1]).height()]; container.height(size); } else { + panelSizes = [$(children[0]).width(),$(children[1]).width()]; container.width(size); } if (modifiedSizes) { - var topPanelSize = panelRatio*size; - var bottomPanelSize = size - topPanelSize - 48; + var topPanelSize = panelRatio*(size-8); + var bottomPanelSize = size - topPanelSize - 8; panelSizes = [topPanelSize,bottomPanelSize]; if (vertical) { - $(children[0]).height(panelSizes[0]); - $(children[1]).height(panelSizes[1]); + $(children[0]).outerHeight(panelSizes[0]); + $(children[1]).outerHeight(panelSizes[1]); } else { - $(children[0]).width(panelSizes[0]); - $(children[1]).width(panelSizes[1]); + $(children[0]).outerWidth(panelSizes[0]); + $(children[1]).outerWidth(panelSizes[1]); } } if (options.resize) { @@ -94,6 +109,7 @@ RED.panels = (function() { } } } + return panel; } return { 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 161988150..3e34591c0 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 @@ -19,7 +19,29 @@ RED.editor.types._markdown = (function() { 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 id="node-input-markdown-toolbar" style="margin-bottom: 5px">'+ + '<span class="button-group">'+ + '<button class="editor-button" data-style="h1" style="font-size:1.1em; font-weight: bold">h1</button>'+ + '<button class="editor-button" data-style="h2" style="font-size:1.0em; font-weight: bold">h2</button>'+ + '<button class="editor-button" data-style="h3" style="font-size:0.9em; font-weight: bold">h3</button>'+ + '</span>'+ + '<span class="button-group">'+ + '<button class="editor-button" data-style="b"><i class="fa fa-bold"></i></button>'+ + '<button class="editor-button" data-style="i"><i class="fa fa-italic"></i></button>'+ + '<button class="editor-button" data-style="code"><i class="fa fa-code"></i></button>'+ + '</span>'+ + '<span class="button-group">'+ + '<button class="editor-button" data-style="ol"><i class="fa fa-list-ol"></i></button>'+ + '<button class="editor-button" data-style="ul"><i class="fa fa-list-ul"></i></button>'+ + '<button class="editor-button" data-style="bq"><i class="fa fa-quote-left"></i></button>'+ + '<button class="editor-button" data-style="hr"><i class="fa fa-minus"></i></button>'+ + '<button class="editor-button" data-style="link"><i class="fa fa-link"></i></button>'+ + '</span>'+ + '<span class="button-group">'+ + '<button id="node-btn-markdown-preview" class="editor-button toggle single"><i class="fa fa-eye"></i></button>'+ + '</span>'+ + '</div>'+ + '<div class="node-text-editor" style="height: calc(100% - 50px)" 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>'+ @@ -29,6 +51,20 @@ RED.editor.types._markdown = (function() { var panels; + var styleActions = { + 'h1': { newline: true, before:"# ", tooltip:"Heading 1"}, + 'h2': { newline: true, before:"## ", tooltip:"Heading 2"}, + 'h3': { newline: true, before:"### ", tooltip:"Heading 3"}, + 'b': { before:"**", after: "**", tooltip: "Bold" }, + 'i': { before:"_", after: "_", tooltip: "Italic" }, + 'code': { before:"`", after: "`", tooltip: "Code" }, + 'ol': { before:" * ", newline: true, tooltip: "Ordered list" }, + 'ul': { before:" - ", newline: true, tooltip: "Unordered list" }, + 'bq': { before:"> ", newline: true, tooltip: "Quote" }, + 'link': { before:"[", after: "]()", tooltip: "Link"}, + 'hr': { before:"\n---\n\n", tooltip: "Horizontal rule" } + } + return { init: function() { $(template).appendTo(document.body); @@ -100,6 +136,51 @@ RED.editor.types._markdown = (function() { expressionEditor.resize(); } }); + panels.ratio(1); + + $("#node-btn-markdown-preview").click(function(e) { + e.preventDefault(); + if ($(this).hasClass("selected")) { + $(this).removeClass("selected"); + panels.ratio(1); + } else { + $(this).addClass("selected"); + panels.ratio(0.5); + } + }); + + $('#node-input-markdown-toolbar').find('button[data-style]').each(function(el) { + var style = styleActions[$(this).data('style')]; + $(this).click(function(e) { + e.preventDefault(); + var current = expressionEditor.getSelectedText(); + var range = expressionEditor.selection.getRange(); + if (style.newline) { + var offset = 0; + var beforeOffset = ((style.before||"").match(/\n/g)||[]).length; + var afterOffset = ((style.after||"").match(/\n/g)||[]).length; + for (var i = range.start.row; i<= range.end.row+offset; i++) { + if (style.before) { + expressionEditor.session.insert({row:i, column:0},style.before); + offset += beforeOffset; + i += beforeOffset; + } + if (style.after) { + expressionEditor.session.insert({row:i, column:Infinity},style.after); + offset += afterOffset; + i += afterOffset; + } + } + } else { + expressionEditor.session.replace(expressionEditor.selection.getRange(), (style.before||"")+current+(style.after||"")); + } + expressionEditor.focus(); + }); + if (style.tooltip) { + RED.popover.tooltip($(this),style.tooltip); + } + + }) if (options.cursor) { expressionEditor.gotoLine(options.cursor.row+1,options.cursor.column,false);