1 import {Component} from './component';
2 import {init as initEditor} from '../markdown/editor';
4 export class MarkdownEditor extends Component {
9 this.pageId = this.$opts.pageId;
10 this.textDirection = this.$opts.textDirection;
11 this.imageUploadErrorText = this.$opts.imageUploadErrorText;
12 this.serverUploadLimitText = this.$opts.serverUploadLimitText;
14 this.display = this.$refs.display;
15 this.input = this.$refs.input;
16 this.divider = this.$refs.divider;
17 this.displayWrap = this.$refs.displayWrap;
19 const {settingContainer} = this.$refs;
20 const settingInputs = settingContainer.querySelectorAll('input[type="checkbox"]');
26 displayEl: this.display,
28 drawioUrl: this.getDrawioUrl(),
29 settingInputs: Array.from(settingInputs),
31 serverUploadLimit: this.serverUploadLimitText,
32 imageUploadError: this.imageUploadErrorText,
36 this.setupListeners();
37 this.emitEditorEvents();
38 this.scrollToTextIfNeeded();
39 this.editor.actions.updateAndRender();
44 window.$events.emitPublic(this.elem, 'editor-markdown::setup', {
45 markdownIt: this.editor.markdown.getRenderer(),
46 displayEl: this.display,
47 cmEditorView: this.editor.cm,
53 this.elem.addEventListener('click', event => {
54 const button = event.target.closest('button[data-action]');
55 if (button === null) return;
57 const action = button.getAttribute('data-action');
58 if (action === 'insertImage') this.editor.actions.showImageInsert();
59 if (action === 'insertLink') this.editor.actions.showLinkSelector();
60 if (action === 'insertDrawing' && (event.ctrlKey || event.metaKey)) {
61 this.editor.actions.showImageManager();
64 if (action === 'insertDrawing') this.editor.actions.startDrawing();
65 if (action === 'fullscreen') this.editor.actions.fullScreen();
68 // Mobile section toggling
69 this.elem.addEventListener('click', event => {
70 const toolbarLabel = event.target.closest('.editor-toolbar-label');
71 if (!toolbarLabel) return;
73 const currentActiveSections = this.elem.querySelectorAll('.markdown-editor-wrap');
74 for (const activeElem of currentActiveSections) {
75 activeElem.classList.remove('active');
78 toolbarLabel.closest('.markdown-editor-wrap').classList.add('active');
81 this.handleDividerDrag();
85 this.divider.addEventListener('pointerdown', () => {
86 const wrapRect = this.elem.getBoundingClientRect();
87 const moveListener = event => {
88 const xRel = event.pageX - wrapRect.left;
89 const xPct = Math.min(Math.max(20, Math.floor((xRel / wrapRect.width) * 100)), 80);
90 this.displayWrap.style.flexBasis = `${100 - xPct}%`;
91 this.editor.settings.set('editorWidth', xPct);
93 const upListener = () => {
94 window.removeEventListener('pointermove', moveListener);
95 window.removeEventListener('pointerup', upListener);
96 this.display.style.pointerEvents = null;
97 document.body.style.userSelect = null;
100 this.display.style.pointerEvents = 'none';
101 document.body.style.userSelect = 'none';
102 window.addEventListener('pointermove', moveListener);
103 window.addEventListener('pointerup', upListener);
105 const widthSetting = this.editor.settings.get('editorWidth');
107 this.displayWrap.style.flexBasis = `${100 - widthSetting}%`;
111 scrollToTextIfNeeded() {
112 const queryParams = (new URL(window.location)).searchParams;
113 const scrollText = queryParams.get('content-text');
115 this.editor.actions.scrollToText(scrollText);
120 * Get the URL for the configured drawio instance.
124 const drawioAttrEl = document.querySelector('[drawio-url]');
129 return drawioAttrEl.getAttribute('drawio-url') || '';
133 * Get the content of this editor.
134 * Used by the parent page editor component.
135 * @return {{html: String, markdown: String}}
138 return this.editor.actions.getContent();