]> BookStack Code Mirror - bookstack/blob - resources/js/markdown/index.mts
Merge pull request #5725 from BookStackApp/md_plaintext
[bookstack] / resources / js / markdown / index.mts
1 import {Markdown} from './markdown';
2 import {Display} from './display';
3 import {Actions} from './actions';
4 import {Settings} from './settings';
5 import {listenToCommonEvents} from './common-events';
6 import {init as initCodemirror} from './codemirror';
7 import {MarkdownEditorInput} from "./inputs/interface";
8 import {CodemirrorInput} from "./inputs/codemirror";
9 import {TextareaInput} from "./inputs/textarea";
10 import {provideShortcutMap} from "./shortcuts";
11 import {getMarkdownDomEventHandlers} from "./dom-handlers";
12
13 export interface MarkdownEditorConfig {
14     pageId: string;
15     container: Element;
16     displayEl: HTMLIFrameElement;
17     inputEl: HTMLTextAreaElement;
18     drawioUrl: string;
19     settingInputs: HTMLInputElement[];
20     text: Record<string, string>;
21 }
22
23 export interface MarkdownEditor {
24     config: MarkdownEditorConfig;
25     display: Display;
26     markdown: Markdown;
27     actions: Actions;
28     input: MarkdownEditorInput;
29     settings: Settings;
30 }
31
32 /**
33  * Initiate a new Markdown editor instance.
34  */
35 export async function init(config: MarkdownEditorConfig): Promise<MarkdownEditor> {
36     const editor: MarkdownEditor = {
37         config,
38         markdown: new Markdown(),
39         settings: new Settings(config.settingInputs),
40     } as MarkdownEditor;
41
42     editor.actions = new Actions(editor);
43     editor.display = new Display(editor);
44
45     const eventHandlers = getMarkdownDomEventHandlers(editor);
46     const shortcuts = provideShortcutMap(editor);
47     const onInputChange = () => editor.actions.updateAndRender();
48
49     const initCodemirrorInput: () => Promise<MarkdownEditorInput> = async () => {
50         const codeMirror = await initCodemirror(config.inputEl, shortcuts, eventHandlers, onInputChange);
51         return new CodemirrorInput(codeMirror);
52     };
53     const initTextAreaInput: () => Promise<MarkdownEditorInput> = async () => {
54         return new TextareaInput(config.inputEl, shortcuts, eventHandlers, onInputChange);
55     };
56
57     const isPlainEditor = Boolean(editor.settings.get('plainEditor'));
58     editor.input = await (isPlainEditor ? initTextAreaInput() : initCodemirrorInput());
59     editor.settings.onChange('plainEditor', async (value) => {
60         const isPlain = Boolean(value);
61         const newInput = await (isPlain ? initTextAreaInput() : initCodemirrorInput());
62         editor.input.teardown();
63         editor.input = newInput;
64     });
65
66     listenToCommonEvents(editor);
67
68     return editor;
69 }
70
71