]> BookStack Code Mirror - bookstack/commitdiff
Added image paste and drop to markdown editor
authorDan Brown <redacted>
Fri, 2 Sep 2016 20:18:48 +0000 (21:18 +0100)
committerDan Brown <redacted>
Fri, 2 Sep 2016 20:18:48 +0000 (21:18 +0100)
Only currently tested in chrome.
Closes #128

resources/assets/js/directives.js
resources/assets/js/pages/page-form.js

index fc7b88259eccb92b17e4a2305abe75d96bd66027..286854832d75a2730a85c49b94976596ad4e7e7f 100644 (file)
@@ -370,6 +370,83 @@ module.exports = function (ngApp, events) {
                     });
                 });
 
+                // Upload and insert image on paste
+                function editorPaste(e) {
+                    e = e.originalEvent;
+                    if (!e.clipboardData) return
+                    var items = e.clipboardData.items;
+                    if (!items) return;
+                    for (var i = 0; i < items.length; i++) {
+                        uploadImage(items[i].getAsFile());
+                    }
+                }
+
+                input.on('paste', editorPaste);
+
+                // Handle image drop, Uploads images to BookStack.
+                function handleImageDrop(event) {
+                    event.stopPropagation();
+                    event.preventDefault();
+                    let files = event.originalEvent.dataTransfer.files;
+                    for (let i = 0; i < files.length; i++) {
+                        uploadImage(files[i]);
+                    }
+                }
+
+                input.on('drop', handleImageDrop);
+
+                // Handle image upload and add image into markdown content
+                function uploadImage(file) {
+                    if (file.type.indexOf('image') !== 0) return;
+                    var formData = new FormData();
+                    var ext = 'png';
+                    var xhr = new XMLHttpRequest();
+
+                    if (file.name) {
+                        var fileNameMatches = file.name.match(/\.(.+)$/);
+                        if (fileNameMatches) {
+                            ext = fileNameMatches[1];
+                        }
+                    }
+
+                    // Insert image into markdown
+                    let id = "image-" + Math.random().toString(16).slice(2);
+                    let selectStart = input[0].selectionStart;
+                    let selectEnd = input[0].selectionEnd;
+                    let content = input[0].value;
+                    let selectText = content.substring(selectStart, selectEnd);
+                    let placeholderImage = `/loading.gif#upload${id}`;
+                    let innerContent = ((selectEnd > selectStart) ? `![${selectText}]` : '![]') + `(${placeholderImage})`;
+                    input[0].value = content.substring(0, selectStart) +  innerContent + content.substring(selectEnd);
+
+                    input.focus();
+                    input[0].selectionStart = selectStart;
+                    input[0].selectionEnd = selectStart;
+
+                    let remoteFilename = "image-" + Date.now() + "." + ext;
+                    formData.append('file', file, remoteFilename);
+                    formData.append('_token', document.querySelector('meta[name="token"]').getAttribute('content'));
+
+                    xhr.open('POST', window.baseUrl('/images/gallery/upload'));
+                    xhr.onload = function () {
+                        let selectStart = input[0].selectionStart;
+                        if (xhr.status === 200 || xhr.status === 201) {
+                            var result = JSON.parse(xhr.responseText);
+                            input[0].value = input[0].value.replace(placeholderImage, result.url);
+                            input.change();
+                        } else {
+                            console.log('An error occurred uploading the image');
+                            console.log(xhr.responseText);
+                            input[0].value = input[0].value.replace(innerContent, '');
+                            input.change();
+                        }
+                        input.focus();
+                        input[0].selectionStart = selectStart;
+                        input[0].selectionEnd = selectStart;
+                    };
+                    xhr.send(formData);
+                }
+
             }
         }
     }]);
index 86678a1bada517ce3156569b1bf57f5a5ba223f2..15fcdbb8e6cacb5479d97eb58da35b61b94a9648 100644 (file)
@@ -1,6 +1,6 @@
 "use strict";
 
-function editorPaste(e) {
+function editorPaste(e, editor) {
     if (!e.clipboardData) return
     var items = e.clipboardData.items;
     if (!items) return;
@@ -32,7 +32,7 @@ function editorPaste(e) {
                     var result = JSON.parse(xhr.responseText);
                     editor.dom.setAttrib(id, 'src', result.url);
                 } else {
-                    console.log('An error occured uploading the image');
+                    console.log('An error occurred uploading the image');
                     console.log(xhr.responseText);
                     editor.dom.remove(id);
                 }
@@ -181,6 +181,8 @@ var mceOptions = module.exports = {
         });
 
         // Paste image-uploads
-        editor.on('paste', editorPaste);
+        editor.on('paste', function(event) {
+            editorPaste(event, editor);
+        });
     }
 };
\ No newline at end of file