X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/ec3713bc743d56d2aeea5fe6890f8843dce63127..refs/pull/4828/head:/resources/js/components/markdown-editor.js diff --git a/resources/js/components/markdown-editor.js b/resources/js/components/markdown-editor.js index 373fedf48..fa06807a5 100644 --- a/resources/js/components/markdown-editor.js +++ b/resources/js/components/markdown-editor.js @@ -1,6 +1,5 @@ -import {debounce} from "../services/util"; -import {Component} from "./component"; -import {init as initEditor} from "../markdown/editor"; +import {Component} from './component'; +import {init as initEditor} from '../markdown/editor'; export class MarkdownEditor extends Component { @@ -14,7 +13,11 @@ export class MarkdownEditor extends Component { this.display = this.$refs.display; this.input = this.$refs.input; - this.settingContainer = this.$refs.settingContainer; + this.divider = this.$refs.divider; + this.displayWrap = this.$refs.displayWrap; + + const {settingContainer} = this.$refs; + const settingInputs = settingContainer.querySelectorAll('input[type="checkbox"]'); this.editor = null; initEditor({ @@ -23,11 +26,11 @@ export class MarkdownEditor extends Component { displayEl: this.display, inputEl: this.input, drawioUrl: this.getDrawioUrl(), + settingInputs: Array.from(settingInputs), text: { serverUploadLimit: this.serverUploadLimitText, imageUploadError: this.imageUploadErrorText, }, - settings: this.loadSettings(), }).then(editor => { this.editor = editor; this.setupListeners(); @@ -41,19 +44,18 @@ export class MarkdownEditor extends Component { window.$events.emitPublic(this.elem, 'editor-markdown::setup', { markdownIt: this.editor.markdown.getRenderer(), displayEl: this.display, - codeMirrorInstance: this.editor.cm, + cmEditorView: this.editor.cm, }); } setupListeners() { - // Button actions this.elem.addEventListener('click', event => { - let button = event.target.closest('button[data-action]'); + const button = event.target.closest('button[data-action]'); if (button === null) return; const action = button.getAttribute('data-action'); - if (action === 'insertImage') this.editor.actions.insertImage(); + if (action === 'insertImage') this.editor.actions.showImageInsert(); if (action === 'insertLink') this.editor.actions.showLinkSelector(); if (action === 'insertDrawing' && (event.ctrlKey || event.metaKey)) { this.editor.actions.showImageManager(); @@ -76,30 +78,34 @@ export class MarkdownEditor extends Component { toolbarLabel.closest('.markdown-editor-wrap').classList.add('active'); }); - // Setting changes - this.settingContainer.addEventListener('change', e => { - const actualInput = e.target.parentNode.querySelector('input[type="hidden"]'); - const name = actualInput.getAttribute('name'); - const value = actualInput.getAttribute('value'); - window.$http.patch('/preferences/update-boolean', {name, value}); - this.editor.settings.set(name, value === 'true'); - }); - - // Refresh CodeMirror on container resize - const resizeDebounced = debounce(() => this.editor.cm.refresh(), 100, false); - const observer = new ResizeObserver(resizeDebounced); - observer.observe(this.elem); + this.handleDividerDrag(); } - loadSettings() { - const settings = {}; - const inputs = this.settingContainer.querySelectorAll('input[type="hidden"]'); - - for (const input of inputs) { - settings[input.getAttribute('name')] = input.value === 'true'; + handleDividerDrag() { + this.divider.addEventListener('pointerdown', () => { + const wrapRect = this.elem.getBoundingClientRect(); + const moveListener = event => { + const xRel = event.pageX - wrapRect.left; + const xPct = Math.min(Math.max(20, Math.floor((xRel / wrapRect.width) * 100)), 80); + this.displayWrap.style.flexBasis = `${100 - xPct}%`; + this.editor.settings.set('editorWidth', xPct); + }; + const upListener = () => { + 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) { + this.displayWrap.style.flexBasis = `${100 - widthSetting}%`; } - - return settings; } scrollToTextIfNeeded() { @@ -123,4 +129,13 @@ export class MarkdownEditor extends Component { return drawioAttrEl.getAttribute('drawio-url') || ''; } + /** + * Get the content of this editor. + * Used by the parent page editor component. + * @return {{html: String, markdown: String}} + */ + getContent() { + return this.editor.actions.getContent(); + } + }