X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ec07793cda66d319bf716ef3dcbbe2fe19f0c355..HEAD:/resources/js/markdown/codemirror.ts diff --git a/resources/js/markdown/codemirror.ts b/resources/js/markdown/codemirror.ts index 1b54c5819..1ae018477 100644 --- a/resources/js/markdown/codemirror.ts +++ b/resources/js/markdown/codemirror.ts @@ -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 { + 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.