]> BookStack Code Mirror - bookstack/commitdiff
Integrated the markdown editor with the image manager
authorDan Brown <redacted>
Tue, 29 Mar 2016 17:25:54 +0000 (18:25 +0100)
committerDan Brown <redacted>
Tue, 29 Mar 2016 17:25:54 +0000 (18:25 +0100)
resources/assets/js/directives.js
resources/assets/sass/_forms.scss
resources/views/pages/form.blade.php

index 316e5dcb4e4b7c822c18d78b9e8668d6fcd490df..de87950dc6662fa55dfdc88a17e51b655fd21885 100644 (file)
@@ -1,6 +1,6 @@
 "use strict";
 var DropZone = require('dropzone');
-var markdown = require( "marked" );
+var markdown = require('marked');
 
 var toggleSwitchTemplate = require('./components/toggle-switch.html');
 var imagePickerTemplate = require('./components/image-picker.html');
@@ -201,9 +201,9 @@ module.exports = function (ngApp, events) {
                 tinymce.init(scope.tinymce);
             }
         }
-    }])
+    }]);
 
-    ngApp.directive('markdownEditor', ['$timeout', function($timeout) {
+    ngApp.directive('markdownInput', ['$timeout', function($timeout) {
         return {
             restrict: 'A',
             scope: {
@@ -231,6 +231,50 @@ module.exports = function (ngApp, events) {
                     scope.mdChange(markdown(value));
                 });
 
+            }
+        }
+    }]);
+
+    ngApp.directive('markdownEditor', ['$timeout', function($timeout) {
+        return {
+            restrict: 'A',
+            link: function (scope, element, attrs) {
+
+                // Elements
+                var input = element.find('textarea[markdown-input]');
+                var insertImage = element.find('button[data-action="insertImage"]');
+
+                var currentCaretPos = 0;
+
+                input.blur((event) => {
+                    currentCaretPos = input[0].selectionStart;
+                });
+
+                // Insert image shortcut
+                input.keydown((event) => {
+                    if (event.which === 73 && event.ctrlKey && event.shiftKey) {
+                        event.preventDefault();
+                        var caretPos = input[0].selectionStart;
+                        var currentContent = input.val();
+                        var mdImageText = "![](http://)";
+                        input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
+                        input.focus();
+                        input[0].selectionStart = caretPos + ("![](".length);
+                        input[0].selectionEnd = caretPos + ('![](http://'.length);
+                    }
+                });
+
+                // Insert image from image manager
+                insertImage.click((event) => {
+                    window.ImageManager.showExternal((image) => {
+                        var caretPos = currentCaretPos;
+                        var currentContent = input.val();
+                        var mdImageText = "![" + image.name + "](" + image.url + ")";
+                        input.val(currentContent.substring(0, caretPos) + mdImageText + currentContent.substring(caretPos));
+                        input.change();
+                    });
+                });
+
             }
         }
     }])
index 5351f06e7ec4607192a3504752f909373a8a0d0f..4da0c39ad5d73121b8e3426745a347ba3354f03f 100644 (file)
     max-height: 100%;
     flex: 1;
     border: 0;
+    width: 100%;
     &:focus {
       outline: 0;
     }
   }
   .markdown-display, .markdown-editor-wrap {
     flex: 1;
-    padding-top: 28px;
     position: relative;
-    border: 1px solid #DDD;
-    &:before {
-      display: block;
-      position: absolute;
-      top: 0;
-      left: 0;
-      width: 100%;
-      padding: $-xs $-m;
-      font-family: 'Roboto Mono';
-      font-size: 11px;
-      line-height: 1;
-      border-bottom: 1px solid #DDD;
-      background-color: #EEE;
-    }
   }
   .markdown-editor-wrap {
     display: flex;
-    &:before {
-      content: 'Editor';
-    }
+    flex-direction: column;
+    border: 1px solid #DDD;
   }
   .markdown-display {
-    padding: 0 $-m;
-    padding-top: 28px;
+    padding: 0 $-m 0;
     margin-left: -1px;
-    &:before {
-      content: 'Preview';
-    }
+    overflow-y: scroll;
+  }
+}
+.editor-toolbar {
+  width: 100%;
+  padding: $-xs $-m;
+  font-family: 'Roboto Mono';
+  font-size: 11px;
+  line-height: 1.6;
+  border-bottom: 1px solid #DDD;
+  background-color: #EEE;
+  flex: none;
+  &:after {
+    content: '';
+    display: block;
+    clear: both;
   }
 }
 
+
 label {
   display: block;
   line-height: 1.4em;
index 2118d23b2b29321bf4328efeb5d975d6fce824b1..6b16cb87065b73b9cb4830e732cb03327c69b6d3 100644 (file)
         @endif
 
         @if(config('app.editor') === 'markdown')
-            <div id="markdown-editor" class="flex-fill flex">
+            <div id="markdown-editor" markdown-editor class="flex-fill flex">
 
                 <div class="markdown-editor-wrap">
-                    <textarea markdown-editor md-change="editorChange" md-model="editContent"  name="markdown" rows="5"
+                    <div class="editor-toolbar">
+                        <span class="float left">Editor</span>
+                        <div class="float right buttons">
+                            <button class="text-button" type="button" data-action="insertImage"><i class="zmdi zmdi-image"></i>Insert Image</button>
+                        </div>
+                    </div>
+                    <textarea markdown-input md-change="editorChange" md-model="editContent"  name="markdown" rows="5"
                               @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>
                 </div>
 
-                <div class="markdown-display page-content" ng-bind-html="displayContent"></div>
+                <div class="markdown-editor-wrap">
+                    <div class="editor-toolbar">
+                        <div class="">Preview</div>
+                    </div>
+                    <div class="markdown-display page-content" ng-bind-html="displayContent"></div>
+                </div>
+
             </div>
 
             <input type="hidden" name="html" ng-value="displayContent">
Morty Proxy This is a proxified and sanitized view of the page, visit original site.