Showing
3 changed files
with
81 additions
and
27 deletions
| 1 | "use strict"; | 1 | "use strict"; |
| 2 | var DropZone = require('dropzone'); | 2 | var DropZone = require('dropzone'); |
| 3 | -var markdown = require( "marked" ); | 3 | +var markdown = require('marked'); |
| 4 | 4 | ||
| 5 | var toggleSwitchTemplate = require('./components/toggle-switch.html'); | 5 | var toggleSwitchTemplate = require('./components/toggle-switch.html'); |
| 6 | var imagePickerTemplate = require('./components/image-picker.html'); | 6 | var imagePickerTemplate = require('./components/image-picker.html'); |
| ... | @@ -201,9 +201,9 @@ module.exports = function (ngApp, events) { | ... | @@ -201,9 +201,9 @@ module.exports = function (ngApp, events) { |
| 201 | tinymce.init(scope.tinymce); | 201 | tinymce.init(scope.tinymce); |
| 202 | } | 202 | } |
| 203 | } | 203 | } |
| 204 | - }]) | 204 | + }]); |
| 205 | 205 | ||
| 206 | - ngApp.directive('markdownEditor', ['$timeout', function($timeout) { | 206 | + ngApp.directive('markdownInput', ['$timeout', function($timeout) { |
| 207 | return { | 207 | return { |
| 208 | restrict: 'A', | 208 | restrict: 'A', |
| 209 | scope: { | 209 | scope: { |
| ... | @@ -233,6 +233,50 @@ module.exports = function (ngApp, events) { | ... | @@ -233,6 +233,50 @@ module.exports = function (ngApp, events) { |
| 233 | 233 | ||
| 234 | } | 234 | } |
| 235 | } | 235 | } |
| 236 | + }]); | ||
| 237 | + | ||
| 238 | + ngApp.directive('markdownEditor', ['$timeout', function($timeout) { | ||
| 239 | + return { | ||
| 240 | + restrict: 'A', | ||
| 241 | + link: function (scope, element, attrs) { | ||
| 242 | + | ||
| 243 | + // Elements | ||
| 244 | + var input = element.find('textarea[markdown-input]'); | ||
| 245 | + var insertImage = element.find('button[data-action="insertImage"]'); | ||
| 246 | + | ||
| 247 | + var currentCaretPos = 0; | ||
| 248 | + | ||
| 249 | + input.blur((event) => { | ||
| 250 | + currentCaretPos = input[0].selectionStart; | ||
| 251 | + }); | ||
| 252 | + | ||
| 253 | + // Insert image shortcut | ||
| 254 | + input.keydown((event) => { | ||
| 255 | + if (event.which === 73 && event.ctrlKey && event.shiftKey) { | ||
| 256 | + event.preventDefault(); | ||
| 257 | + var caretPos = input[0].selectionStart; | ||
| 258 | + var currentContent = input.val(); | ||
| 259 | + var mdImageText = ""; | ||
| 260 | + input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos)); | ||
| 261 | + input.focus(); | ||
| 262 | + input[0].selectionStart = caretPos + ("; | ||
| 263 | + input[0].selectionEnd = caretPos + ('; | ||
| 264 | + } | ||
| 265 | + }); | ||
| 266 | + | ||
| 267 | + // Insert image from image manager | ||
| 268 | + insertImage.click((event) => { | ||
| 269 | + window.ImageManager.showExternal((image) => { | ||
| 270 | + var caretPos = currentCaretPos; | ||
| 271 | + var currentContent = input.val(); | ||
| 272 | + var mdImageText = ""; | ||
| 273 | + input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos)); | ||
| 274 | + input.change(); | ||
| 275 | + }); | ||
| 276 | + }); | ||
| 277 | + | ||
| 278 | + } | ||
| 279 | + } | ||
| 236 | }]) | 280 | }]) |
| 237 | 281 | ||
| 238 | }; | 282 | }; |
| ... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
| ... | @@ -39,45 +39,43 @@ | ... | @@ -39,45 +39,43 @@ |
| 39 | max-height: 100%; | 39 | max-height: 100%; |
| 40 | flex: 1; | 40 | flex: 1; |
| 41 | border: 0; | 41 | border: 0; |
| 42 | + width: 100%; | ||
| 42 | &:focus { | 43 | &:focus { |
| 43 | outline: 0; | 44 | outline: 0; |
| 44 | } | 45 | } |
| 45 | } | 46 | } |
| 46 | .markdown-display, .markdown-editor-wrap { | 47 | .markdown-display, .markdown-editor-wrap { |
| 47 | flex: 1; | 48 | flex: 1; |
| 48 | - padding-top: 28px; | ||
| 49 | position: relative; | 49 | position: relative; |
| 50 | - border: 1px solid #DDD; | ||
| 51 | - &:before { | ||
| 52 | - display: block; | ||
| 53 | - position: absolute; | ||
| 54 | - top: 0; | ||
| 55 | - left: 0; | ||
| 56 | - width: 100%; | ||
| 57 | - padding: $-xs $-m; | ||
| 58 | - font-family: 'Roboto Mono'; | ||
| 59 | - font-size: 11px; | ||
| 60 | - line-height: 1; | ||
| 61 | - border-bottom: 1px solid #DDD; | ||
| 62 | - background-color: #EEE; | ||
| 63 | - } | ||
| 64 | } | 50 | } |
| 65 | .markdown-editor-wrap { | 51 | .markdown-editor-wrap { |
| 66 | display: flex; | 52 | display: flex; |
| 67 | - &:before { | 53 | + flex-direction: column; |
| 68 | - content: 'Editor'; | 54 | + border: 1px solid #DDD; |
| 69 | - } | ||
| 70 | } | 55 | } |
| 71 | .markdown-display { | 56 | .markdown-display { |
| 72 | - padding: 0 $-m; | 57 | + padding: 0 $-m 0; |
| 73 | - padding-top: 28px; | ||
| 74 | margin-left: -1px; | 58 | margin-left: -1px; |
| 75 | - &:before { | 59 | + overflow-y: scroll; |
| 76 | - content: 'Preview'; | ||
| 77 | } | 60 | } |
| 61 | +} | ||
| 62 | +.editor-toolbar { | ||
| 63 | + width: 100%; | ||
| 64 | + padding: $-xs $-m; | ||
| 65 | + font-family: 'Roboto Mono'; | ||
| 66 | + font-size: 11px; | ||
| 67 | + line-height: 1.6; | ||
| 68 | + border-bottom: 1px solid #DDD; | ||
| 69 | + background-color: #EEE; | ||
| 70 | + flex: none; | ||
| 71 | + &:after { | ||
| 72 | + content: ''; | ||
| 73 | + display: block; | ||
| 74 | + clear: both; | ||
| 78 | } | 75 | } |
| 79 | } | 76 | } |
| 80 | 77 | ||
| 78 | + | ||
| 81 | label { | 79 | label { |
| 82 | display: block; | 80 | display: block; |
| 83 | line-height: 1.4em; | 81 | line-height: 1.4em; | ... | ... |
| ... | @@ -51,16 +51,28 @@ | ... | @@ -51,16 +51,28 @@ |
| 51 | @endif | 51 | @endif |
| 52 | 52 | ||
| 53 | @if(config('app.editor') === 'markdown') | 53 | @if(config('app.editor') === 'markdown') |
| 54 | - <div id="markdown-editor" class="flex-fill flex"> | 54 | + <div id="markdown-editor" markdown-editor class="flex-fill flex"> |
| 55 | 55 | ||
| 56 | <div class="markdown-editor-wrap"> | 56 | <div class="markdown-editor-wrap"> |
| 57 | - <textarea markdown-editor md-change="editorChange" md-model="editContent" name="markdown" rows="5" | 57 | + <div class="editor-toolbar"> |
| 58 | + <span class="float left">Editor</span> | ||
| 59 | + <div class="float right buttons"> | ||
| 60 | + <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>Insert Image</button> | ||
| 61 | + </div> | ||
| 62 | + </div> | ||
| 63 | + <textarea markdown-input md-change="editorChange" md-model="editContent" name="markdown" rows="5" | ||
| 58 | @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea> | 64 | @if($errors->has('markdown')) class="neg" @endif>@if(isset($model) || old('markdown')){{htmlspecialchars( old('markdown') ? old('markdown') : ($model->markdown === '' ? $model->html : $model->markdown))}}@endif</textarea> |
| 59 | </div> | 65 | </div> |
| 60 | 66 | ||
| 67 | + <div class="markdown-editor-wrap"> | ||
| 68 | + <div class="editor-toolbar"> | ||
| 69 | + <div class="">Preview</div> | ||
| 70 | + </div> | ||
| 61 | <div class="markdown-display page-content" ng-bind-html="displayContent"></div> | 71 | <div class="markdown-display page-content" ng-bind-html="displayContent"></div> |
| 62 | </div> | 72 | </div> |
| 63 | 73 | ||
| 74 | + </div> | ||
| 75 | + | ||
| 64 | <input type="hidden" name="html" ng-value="displayContent"> | 76 | <input type="hidden" name="html" ng-value="displayContent"> |
| 65 | 77 | ||
| 66 | @if($errors->has('markdown')) | 78 | @if($errors->has('markdown')) | ... | ... |
-
Please register or sign in to post a comment