]> BookStack Code Mirror - bookstack/blobdiff - resources/js/markdown/codemirror.ts
Merge pull request #5731 from BookStackApp/lexical_jul25
[bookstack] / resources / js / markdown / codemirror.ts
index 1b54c58196b4372fa27ded2b70098bb088c4aa0a..1ae018477047619219f651031cff82f5419f6a8d 100644 (file)
@@ -1,78 +1,48 @@
-import {provideKeyBindings} from './shortcuts';
-import {debounce} from '../services/util';
-import {Clipboard} from '../services/clipboard';
-import {EditorView, ViewUpdate} from "@codemirror/view";
-import {MarkdownEditor} from "./index.mjs";
+import {EditorView, KeyBinding, ViewUpdate} from "@codemirror/view";
 import {CodeModule} from "../global";
+import {MarkdownEditorEventMap} from "./dom-handlers";
+import {MarkdownEditorShortcutMap} from "./shortcuts";
 
 /**
- * Initiate the codemirror instance for the MarkDown editor.
+ * Convert editor shortcuts to CodeMirror keybinding format.
  */
-export function init(editor: MarkdownEditor, Code: CodeModule): EditorView {
-    function onViewUpdate(v: ViewUpdate) {
-        if (v.docChanged) {
-            editor.actions.updateAndRender();
-        }
-    }
+export function shortcutsToKeyBindings(shortcuts: MarkdownEditorShortcutMap): KeyBinding[] {
+    const keyBindings = [];
 
-    const onScrollDebounced = debounce(editor.actions.syncDisplayPosition.bind(editor.actions), 100, false);
-    let syncActive = editor.settings.get('scrollSync');
-    editor.settings.onChange('scrollSync', val => {
-        syncActive = val;
-    });
-
-    const domEventHandlers = {
-        // Handle scroll to sync display view
-        scroll: (event: Event) => syncActive && onScrollDebounced(event),
-        // Handle image & content drag n drop
-        drop: (event: DragEvent) => {
-            if (!event.dataTransfer) {
-                return;
-            }
-
-            const templateId = event.dataTransfer.getData('bookstack/template');
-            if (templateId) {
-                event.preventDefault();
-                editor.actions.insertTemplate(templateId, event.pageX, event.pageY);
-            }
+    const wrapAction = (action: () => void) => () => {
+        action();
+        return true;
+    };
 
-            const clipboard = new Clipboard(event.dataTransfer);
-            const clipboardImages = clipboard.getImages();
-            if (clipboardImages.length > 0) {
-                event.stopPropagation();
-                event.preventDefault();
-                editor.actions.insertClipboardImages(clipboardImages, event.pageX, event.pageY);
-            }
-        },
-        // Handle dragover event to allow as drop-target in chrome
-        dragover: (event: DragEvent) => {
-            event.preventDefault();
-        },
-        // Handle image paste
-        paste: (event: ClipboardEvent) => {
-            if (!event.clipboardData) {
-                return;
-            }
+    for (const [shortcut, action] of Object.entries(shortcuts)) {
+        keyBindings.push({key: shortcut, run: wrapAction(action), preventDefault: true});
+    }
 
-            const clipboard = new Clipboard(event.clipboardData);
+    return keyBindings;
+}
 
-            // Don't handle the event ourselves if no items exist of contains table-looking data
-            if (!clipboard.hasItems() || clipboard.containsTabularData()) {
-                return;
-            }
+/**
+ * Initiate the codemirror instance for the Markdown editor.
+ */
+export async function init(
+    input: HTMLTextAreaElement,
+    shortcuts: MarkdownEditorShortcutMap,
+    domEventHandlers: MarkdownEditorEventMap,
+    onChange: () => void
+): Promise<EditorView> {
+    const Code = await window.importVersioned('code') as CodeModule;
 
-            const images = clipboard.getImages();
-            for (const image of images) {
-                editor.actions.uploadImage(image);
-            }
-        },
-    };
+    function onViewUpdate(v: ViewUpdate) {
+        if (v.docChanged) {
+            onChange();
+        }
+    }
 
     const cm = Code.markdownEditor(
-        editor.config.inputEl,
+        input,
         onViewUpdate,
         domEventHandlers,
-        provideKeyBindings(editor),
+        shortcutsToKeyBindings(shortcuts),
     );
 
     // Add editor view to the window for easy access/debugging.