1 import {debounce} from "../services/util";
2 import {Component} from "./component";
3 import {init as initEditor} from "../markdown/editor";
5 export class MarkdownEditor extends Component {
10 this.pageId = this.$opts.pageId;
11 this.textDirection = this.$opts.textDirection;
12 this.imageUploadErrorText = this.$opts.imageUploadErrorText;
13 this.serverUploadLimitText = this.$opts.serverUploadLimitText;
15 this.display = this.$refs.display;
16 this.input = this.$refs.input;
17 this.settingContainer = this.$refs.settingContainer;
23 displayEl: this.display,
25 drawioUrl: this.getDrawioUrl(),
27 serverUploadLimit: this.serverUploadLimitText,
28 imageUploadError: this.imageUploadErrorText,
32 this.setupListeners();
33 this.emitEditorEvents();
34 this.scrollToTextIfNeeded();
35 this.editor.actions.updateAndRender();
40 window.$events.emitPublic(this.elem, 'editor-markdown::setup', {
41 markdownIt: this.editor.markdown.getRenderer(),
42 displayEl: this.display,
43 codeMirrorInstance: this.editor.cm,
50 this.elem.addEventListener('click', event => {
51 let button = event.target.closest('button[data-action]');
52 if (button === null) return;
54 const action = button.getAttribute('data-action');
55 if (action === 'insertImage') this.editor.actions.insertImage();
56 if (action === 'insertLink') this.editor.actions.showLinkSelector();
57 if (action === 'insertDrawing' && (event.ctrlKey || event.metaKey)) {
58 this.editor.actions.showImageManager();
61 if (action === 'insertDrawing') this.editor.actions.startDrawing();
62 if (action === 'fullscreen') this.editor.actions.fullScreen();
65 // Mobile section toggling
66 this.elem.addEventListener('click', event => {
67 const toolbarLabel = event.target.closest('.editor-toolbar-label');
68 if (!toolbarLabel) return;
70 const currentActiveSections = this.elem.querySelectorAll('.markdown-editor-wrap');
71 for (const activeElem of currentActiveSections) {
72 activeElem.classList.remove('active');
75 toolbarLabel.closest('.markdown-editor-wrap').classList.add('active');
79 this.settingContainer.addEventListener('change', e => {
80 const actualInput = e.target.parentNode.querySelector('input[type="hidden"]');
81 const name = actualInput.getAttribute('name');
82 const value = actualInput.getAttribute('value');
83 window.$http.patch('/preferences/update-boolean', {name, value});
84 // TODO - Update state locally
87 // Refresh CodeMirror on container resize
88 const resizeDebounced = debounce(() => this.editor.cm.refresh(), 100, false);
89 const observer = new ResizeObserver(resizeDebounced);
90 observer.observe(this.elem);
93 scrollToTextIfNeeded() {
94 const queryParams = (new URL(window.location)).searchParams;
95 const scrollText = queryParams.get('content-text');
97 this.editor.actions.scrollToText(scrollText);
102 * Get the URL for the configured drawio instance.
106 const drawioAttrEl = document.querySelector('[drawio-url]');
111 return drawioAttrEl.getAttribute('drawio-url') || '';