]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/drop-paste-handling.js
Audit Log: Fixed bad reference to linked entity item
[bookstack] / resources / js / wysiwyg / drop-paste-handling.js
index 48c6c625daf26871f525d31378820a67b3c5321f..172ad970f0de8a5e51f495a012b88bf157107b85 100644 (file)
@@ -1,4 +1,4 @@
-import Clipboard from '../services/clipboard';
+import {Clipboard} from '../services/clipboard';
 
 let wrap;
 let draggedContentEditable;
@@ -7,6 +7,25 @@ function hasTextContent(node) {
     return node && !!(node.textContent || node.innerText);
 }
 
+/**
+ * Upload an image file to the server
+ * @param {File} file
+ * @param {int} pageId
+ */
+async function uploadImageFile(file, pageId) {
+    if (file === null || file.type.indexOf('image') !== 0) {
+        throw new Error('Not an image file');
+    }
+
+    const remoteFilename = file.name || `image-${Date.now()}.png`;
+    const formData = new FormData();
+    formData.append('file', file, remoteFilename);
+    formData.append('uploaded_to', pageId);
+
+    const resp = await window.$http.post(window.baseUrl('/images/gallery'), formData);
+    return resp.data;
+}
+
 /**
  * Handle pasting images from clipboard.
  * @param {Editor} editor
@@ -42,37 +61,17 @@ function paste(editor, options, event) {
                 editor.dom.replace(newEl, id);
             }).catch(err => {
                 editor.dom.remove(id);
-                window.$events.emit('error', options.translations.imageUploadErrorText);
-                console.log(err);
+                window.$events.error(err?.data?.message || options.translations.imageUploadErrorText);
+                console.error(err);
             });
         }, 10);
     }
 }
 
-/**
- * Upload an image file to the server
- * @param {File} file
- * @param {int} pageId
- */
-async function uploadImageFile(file, pageId) {
-    if (file === null || file.type.indexOf('image') !== 0) {
-        throw new Error('Not an image file');
-    }
-
-    const remoteFilename = file.name || `image-${Date.now()}.png`;
-    const formData = new FormData();
-    formData.append('file', file, remoteFilename);
-    formData.append('uploaded_to', pageId);
-
-    const resp = await window.$http.post(window.baseUrl('/images/gallery'), formData);
-    return resp.data;
-}
-
 /**
  * @param {Editor} editor
- * @param {WysiwygConfigOptions} options
  */
-function dragStart(editor, options) {
+function dragStart(editor) {
     const node = editor.selection.getNode();
 
     if (node.nodeName === 'IMG') {
@@ -96,7 +95,11 @@ function dragStart(editor, options) {
  */
 function drop(editor, options, event) {
     const {dom} = editor;
-    const rng = tinymce.dom.RangeUtils.getCaretRangeFromPoint(event.clientX, event.clientY, editor.getDoc());
+    const rng = window.tinymce.dom.RangeUtils.getCaretRangeFromPoint(
+        event.clientX,
+        event.clientY,
+        editor.getDoc(),
+    );
 
     // Template insertion
     const templateId = event.dataTransfer && event.dataTransfer.getData('bookstack/template');
@@ -146,12 +149,27 @@ function drop(editor, options, event) {
     wrap = null;
 }
 
+/**
+ * @param {Editor} editor
+ * @param {DragEvent} event
+ */
+function dragOver(editor, event) {
+    // This custom handling essentially emulates the default TinyMCE behaviour while allowing us
+    // to specifically call preventDefault on the event to allow the drop of custom elements.
+    event.preventDefault();
+    editor.focus();
+    const rangeUtils = window.tinymce.dom.RangeUtils;
+    const range = rangeUtils.getCaretRangeFromPoint(event.clientX ?? 0, event.clientY ?? 0, editor.getDoc());
+    editor.selection.setRng(range);
+}
+
 /**
  * @param {Editor} editor
  * @param {WysiwygConfigOptions} options
  */
 export function listenForDragAndPaste(editor, options) {
-    editor.on('dragstart', () => dragStart(editor, options));
+    editor.on('dragover', event => dragOver(editor, event));
+    editor.on('dragstart', () => dragStart(editor));
     editor.on('drop', event => drop(editor, options, event));
     editor.on('paste', event => paste(editor, options, event));
 }