2023-04-19 05:20:02 +08:00
|
|
|
import {Component} from './component';
|
2018-01-21 04:40:21 +08:00
|
|
|
|
2022-11-16 21:04:22 +08:00
|
|
|
export class MarkdownEditor extends Component {
|
2017-09-23 19:24:06 +08:00
|
|
|
|
2020-07-06 04:18:17 +08:00
|
|
|
setup() {
|
|
|
|
this.elem = this.$el;
|
2019-03-09 05:32:31 +08:00
|
|
|
|
2020-07-06 04:18:17 +08:00
|
|
|
this.pageId = this.$opts.pageId;
|
|
|
|
this.textDirection = this.$opts.textDirection;
|
2020-11-22 01:52:49 +08:00
|
|
|
this.imageUploadErrorText = this.$opts.imageUploadErrorText;
|
2021-05-27 01:23:27 +08:00
|
|
|
this.serverUploadLimitText = this.$opts.serverUploadLimitText;
|
2019-03-09 05:32:31 +08:00
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
this.display = this.$refs.display;
|
|
|
|
this.input = this.$refs.input;
|
2022-11-28 22:08:20 +08:00
|
|
|
this.divider = this.$refs.divider;
|
|
|
|
this.displayWrap = this.$refs.displayWrap;
|
|
|
|
|
2023-04-19 05:20:02 +08:00
|
|
|
const {settingContainer} = this.$refs;
|
2022-11-28 22:08:20 +08:00
|
|
|
const settingInputs = settingContainer.querySelectorAll('input[type="checkbox"]');
|
2017-09-23 19:24:06 +08:00
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
this.editor = null;
|
2024-04-08 21:41:51 +08:00
|
|
|
window.importVersioned('markdown').then(markdown => {
|
|
|
|
return markdown.init({
|
|
|
|
pageId: this.pageId,
|
|
|
|
container: this.elem,
|
|
|
|
displayEl: this.display,
|
|
|
|
inputEl: this.input,
|
|
|
|
drawioUrl: this.getDrawioUrl(),
|
|
|
|
settingInputs: Array.from(settingInputs),
|
|
|
|
text: {
|
|
|
|
serverUploadLimit: this.serverUploadLimitText,
|
|
|
|
imageUploadError: this.imageUploadErrorText,
|
|
|
|
},
|
|
|
|
});
|
2022-11-27 00:43:28 +08:00
|
|
|
}).then(editor => {
|
|
|
|
this.editor = editor;
|
|
|
|
this.setupListeners();
|
|
|
|
this.emitEditorEvents();
|
|
|
|
this.scrollToTextIfNeeded();
|
|
|
|
this.editor.actions.updateAndRender();
|
2022-02-08 19:10:01 +08:00
|
|
|
});
|
2022-11-27 00:43:28 +08:00
|
|
|
}
|
2017-09-23 19:24:06 +08:00
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
emitEditorEvents() {
|
2020-07-06 04:18:17 +08:00
|
|
|
window.$events.emitPublic(this.elem, 'editor-markdown::setup', {
|
2022-11-27 00:43:28 +08:00
|
|
|
markdownIt: this.editor.markdown.getRenderer(),
|
2019-10-17 01:01:35 +08:00
|
|
|
displayEl: this.display,
|
2023-04-14 21:08:40 +08:00
|
|
|
cmEditorView: this.editor.cm,
|
2019-10-17 01:01:35 +08:00
|
|
|
});
|
2017-09-23 19:24:06 +08:00
|
|
|
}
|
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
setupListeners() {
|
2017-09-23 19:24:06 +08:00
|
|
|
// Button actions
|
|
|
|
this.elem.addEventListener('click', event => {
|
2023-04-19 05:20:02 +08:00
|
|
|
const button = event.target.closest('button[data-action]');
|
2017-09-23 19:24:06 +08:00
|
|
|
if (button === null) return;
|
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
const action = button.getAttribute('data-action');
|
2023-04-11 18:48:58 +08:00
|
|
|
if (action === 'insertImage') this.editor.actions.showImageInsert();
|
2022-11-27 00:43:28 +08:00
|
|
|
if (action === 'insertLink') this.editor.actions.showLinkSelector();
|
2019-04-20 20:12:35 +08:00
|
|
|
if (action === 'insertDrawing' && (event.ctrlKey || event.metaKey)) {
|
2022-11-27 00:43:28 +08:00
|
|
|
this.editor.actions.showImageManager();
|
2018-05-27 21:33:50 +08:00
|
|
|
return;
|
|
|
|
}
|
2022-11-27 00:43:28 +08:00
|
|
|
if (action === 'insertDrawing') this.editor.actions.startDrawing();
|
|
|
|
if (action === 'fullscreen') this.editor.actions.fullScreen();
|
2017-09-23 19:24:06 +08:00
|
|
|
});
|
|
|
|
|
2019-04-14 19:04:20 +08:00
|
|
|
// Mobile section toggling
|
|
|
|
this.elem.addEventListener('click', event => {
|
|
|
|
const toolbarLabel = event.target.closest('.editor-toolbar-label');
|
|
|
|
if (!toolbarLabel) return;
|
|
|
|
|
|
|
|
const currentActiveSections = this.elem.querySelectorAll('.markdown-editor-wrap');
|
2022-11-27 00:43:28 +08:00
|
|
|
for (const activeElem of currentActiveSections) {
|
2019-04-14 19:04:20 +08:00
|
|
|
activeElem.classList.remove('active');
|
|
|
|
}
|
|
|
|
|
|
|
|
toolbarLabel.closest('.markdown-editor-wrap').classList.add('active');
|
|
|
|
});
|
|
|
|
|
2022-11-28 22:08:20 +08:00
|
|
|
this.handleDividerDrag();
|
|
|
|
}
|
2022-11-28 20:12:36 +08:00
|
|
|
|
2022-11-28 22:08:20 +08:00
|
|
|
handleDividerDrag() {
|
2023-04-19 22:20:04 +08:00
|
|
|
this.divider.addEventListener('pointerdown', () => {
|
2022-11-28 22:08:20 +08:00
|
|
|
const wrapRect = this.elem.getBoundingClientRect();
|
2023-04-19 05:20:02 +08:00
|
|
|
const moveListener = event => {
|
2022-11-28 22:08:20 +08:00
|
|
|
const xRel = event.pageX - wrapRect.left;
|
|
|
|
const xPct = Math.min(Math.max(20, Math.floor((xRel / wrapRect.width) * 100)), 80);
|
2023-04-19 05:20:02 +08:00
|
|
|
this.displayWrap.style.flexBasis = `${100 - xPct}%`;
|
2022-11-28 22:08:20 +08:00
|
|
|
this.editor.settings.set('editorWidth', xPct);
|
|
|
|
};
|
2023-04-19 22:20:04 +08:00
|
|
|
const upListener = () => {
|
2022-11-28 22:08:20 +08:00
|
|
|
window.removeEventListener('pointermove', moveListener);
|
|
|
|
window.removeEventListener('pointerup', upListener);
|
|
|
|
this.display.style.pointerEvents = null;
|
|
|
|
document.body.style.userSelect = null;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.display.style.pointerEvents = 'none';
|
|
|
|
document.body.style.userSelect = 'none';
|
|
|
|
window.addEventListener('pointermove', moveListener);
|
|
|
|
window.addEventListener('pointerup', upListener);
|
|
|
|
});
|
|
|
|
const widthSetting = this.editor.settings.get('editorWidth');
|
|
|
|
if (widthSetting) {
|
2023-04-19 05:20:02 +08:00
|
|
|
this.displayWrap.style.flexBasis = `${100 - widthSetting}%`;
|
2022-11-28 20:12:36 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
scrollToTextIfNeeded() {
|
2019-09-01 17:51:52 +08:00
|
|
|
const queryParams = (new URL(window.location)).searchParams;
|
|
|
|
const scrollText = queryParams.get('content-text');
|
|
|
|
if (scrollText) {
|
2022-11-27 00:43:28 +08:00
|
|
|
this.editor.actions.scrollToText(scrollText);
|
2017-09-23 19:24:06 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
/**
|
|
|
|
* Get the URL for the configured drawio instance.
|
|
|
|
* @returns {String}
|
|
|
|
*/
|
2020-04-06 00:27:16 +08:00
|
|
|
getDrawioUrl() {
|
2022-11-27 00:43:28 +08:00
|
|
|
const drawioAttrEl = document.querySelector('[drawio-url]');
|
|
|
|
if (!drawioAttrEl) {
|
|
|
|
return '';
|
2019-03-09 05:32:31 +08:00
|
|
|
}
|
|
|
|
|
2022-11-27 00:43:28 +08:00
|
|
|
return drawioAttrEl.getAttribute('drawio-url') || '';
|
2018-01-21 04:40:21 +08:00
|
|
|
}
|
|
|
|
|
2023-02-23 20:30:27 +08:00
|
|
|
/**
|
|
|
|
* Get the content of this editor.
|
|
|
|
* Used by the parent page editor component.
|
|
|
|
* @return {{html: String, markdown: String}}
|
|
|
|
*/
|
|
|
|
getContent() {
|
|
|
|
return this.editor.actions.getContent();
|
|
|
|
}
|
|
|
|
|
2017-09-23 19:24:06 +08:00
|
|
|
}
|