]> BookStack Code Mirror - bookstack/blob - resources/js/markdown/codemirror.js
Connected md editor settings to logic for functionality
[bookstack] / resources / js / markdown / codemirror.js
1 import {provide as provideShortcuts} from "./shortcuts";
2 import {debounce} from "../services/util";
3 import Clipboard from "../services/clipboard";
4
5 /**
6  * Initiate the codemirror instance for the markdown editor.
7  * @param {MarkdownEditor} editor
8  * @returns {Promise<void>}
9  */
10 export async function init(editor) {
11     const Code = await window.importVersioned('code');
12     const cm = Code.markdownEditor(editor.config.inputEl);
13
14     // Will force to remain as ltr for now due to issues when HTML is in editor.
15     cm.setOption('direction', 'ltr');
16     // Register shortcuts
17     cm.setOption('extraKeys', provideShortcuts(editor, Code.getMetaKey()));
18
19
20     // Register codemirror events
21
22     // Update data on content change
23     cm.on('change', (instance, changeObj) => editor.actions.updateAndRender());
24
25     // Handle scroll to sync display view
26     const onScrollDebounced = debounce(editor.actions.syncDisplayPosition.bind(editor.actions), 100, false);
27     let syncActive = editor.settings.get('scrollSync');
28     editor.settings.onChange('scrollSync', val => syncActive = val);
29     cm.on('scroll', instance => {
30         if (syncActive) {
31             onScrollDebounced(instance);
32         }
33     });
34
35     // Handle image paste
36     cm.on('paste', (cm, event) => {
37         const clipboard = new Clipboard(event.clipboardData || event.dataTransfer);
38
39         // Don't handle the event ourselves if no items exist of contains table-looking data
40         if (!clipboard.hasItems() || clipboard.containsTabularData()) {
41             return;
42         }
43
44         const images = clipboard.getImages();
45         for (const image of images) {
46             editor.actions.uploadImage(image);
47         }
48     });
49
50     // Handle image & content drag n drop
51     cm.on('drop', (cm, event) => {
52
53         const templateId = event.dataTransfer.getData('bookstack/template');
54         if (templateId) {
55             event.preventDefault();
56             editor.actions.insertTemplate(templateId, event.pageX, event.pageY);
57         }
58
59         const clipboard = new Clipboard(event.dataTransfer);
60         const clipboardImages = clipboard.getImages();
61         if (clipboardImages.length > 0) {
62             event.stopPropagation();
63             event.preventDefault();
64             editor.actions.insertClipboardImages(clipboardImages);
65         }
66
67     });
68
69     return cm;
70 }