]> BookStack Code Mirror - bookstack/blob - resources/js/code/views.js
JS Events: Added CM pre/post init events
[bookstack] / resources / js / code / views.js
1 import {Compartment, EditorState} from '@codemirror/state';
2 import {EditorView} from '@codemirror/view';
3 import {getLanguageExtension} from './languages';
4
5 const viewLangCompartments = new WeakMap();
6
7 /**
8  * Create a new editor view.
9  *
10  * @param {String} usageType
11  * @param {{parent: Element, doc: String, extensions: Array}} config
12  * @returns {EditorView}
13  */
14 export function createView(usageType, config) {
15     const langCompartment = new Compartment();
16     config.extensions.push(langCompartment.of([]));
17
18     const commonEventData = {
19         usage: usageType,
20         editorViewConfig: config,
21         libEditorView: EditorView,
22         libEditorState: EditorState,
23         libCompartment: Compartment,
24     };
25
26     // Emit a pre-init public event so the user can tweak the config before instance creation
27     window.$events.emitPublic(config.parent, 'library-cm6::pre-init', commonEventData);
28
29     const ev = new EditorView(config);
30     viewLangCompartments.set(ev, langCompartment);
31
32     // Emit a post-init public event so the user can gain a reference to the EditorView
33     window.$events.emitPublic(config.parent, 'library-cm6::post-init', {editorView: ev, ...commonEventData});
34
35     return ev;
36 }
37
38 /**
39  * Set the language mode of an EditorView.
40  *
41  * @param {EditorView} ev
42  * @param {string} modeSuggestion
43  * @param {string} content
44  */
45 export async function updateViewLanguage(ev, modeSuggestion, content) {
46     const compartment = viewLangCompartments.get(ev);
47     const language = await getLanguageExtension(modeSuggestion, content);
48
49     ev.dispatch({
50         effects: compartment.reconfigure(language || []),
51     });
52 }