X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/1ee3e779e4b9b0a92f701a72f21a72c83cb1ce68..refs/pull/2115/head:/resources/js/components/markdown-editor.js diff --git a/resources/js/components/markdown-editor.js b/resources/js/components/markdown-editor.js index c89a7ad8b..cc9a7b859 100644 --- a/resources/js/components/markdown-editor.js +++ b/resources/js/components/markdown-editor.js @@ -1,6 +1,7 @@ import MarkdownIt from "markdown-it"; import mdTasksLists from 'markdown-it-task-lists'; import code from '../services/code'; +import Clipboard from "../services/clipboard"; import {debounce} from "../services/util"; import DrawIO from "../services/drawio"; @@ -30,6 +31,12 @@ class MarkdownEditor { this.displayDoc = this.display.contentDocument; this.init(); }); + + window.$events.emitPublic(elem, 'editor-markdown::setup', { + markdownIt: this.markdown, + displayEl: this.display, + codeMirrorInstance: this.cm, + }); } init() { @@ -69,6 +76,7 @@ class MarkdownEditor { return; } if (action === 'insertDrawing') this.actionStartDrawing(); + if (action === 'fullscreen') this.actionFullScreen(); }); // Mobile section toggling @@ -119,7 +127,13 @@ class MarkdownEditor { loadStylesIntoDisplay() { if (this.displayStylesLoaded) return; - this.displayDoc.documentElement.className = 'markdown-editor-display'; + this.displayDoc.documentElement.classList.add('markdown-editor-display'); + // Set display to be dark mode if parent is + + if (document.documentElement.classList.contains('dark-mode')) { + this.displayDoc.documentElement.style.backgroundColor = '#222'; + this.displayDoc.documentElement.classList.add('dark-mode'); + } this.displayDoc.head.innerHTML = ''; const styles = document.head.querySelectorAll('style,link[rel=stylesheet]'); @@ -209,20 +223,16 @@ class MarkdownEditor { // Handle image paste cm.on('paste', (cm, event) => { - const clipboardItems = event.clipboardData.items; - if (!event.clipboardData || !clipboardItems) return; + const clipboard = new Clipboard(event.clipboardData || event.dataTransfer); - // Don't handle if clipboard includes text content - for (let clipboardItem of clipboardItems) { - if (clipboardItem.type.includes('text/')) { - return; - } + // Don't handle the event ourselves if no items exist of contains table-looking data + if (!clipboard.hasItems() || clipboard.containsTabularData()) { + return; } - for (let clipboardItem of clipboardItems) { - if (clipboardItem.type.includes("image")) { - uploadImage(clipboardItem.getAsFile()); - } + const images = clipboard.getImages(); + for (const image of images) { + uploadImage(image); } }); @@ -240,13 +250,15 @@ class MarkdownEditor { }); } - if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) { + const clipboard = new Clipboard(event.dataTransfer); + if (clipboard.hasItems()) { const cursorPos = cm.coordsChar({left: event.pageX, top: event.pageY}); cm.setCursor(cursorPos); event.stopPropagation(); event.preventDefault(); - for (let i = 0; i < event.dataTransfer.files.length; i++) { - uploadImage(event.dataTransfer.files[i]); + const images = clipboard.getImages(); + for (const image of images) { + uploadImage(image); } } @@ -405,17 +417,23 @@ class MarkdownEditor { }); } + getDrawioUrl() { + const drawioUrlElem = document.querySelector('[drawio-url]'); + return drawioUrlElem ? drawioUrlElem.getAttribute('drawio-url') : false; + } + // Show draw.io if enabled and handle save. actionStartDrawing() { - if (document.querySelector('[drawio-enabled]').getAttribute('drawio-enabled') !== 'true') return; - let cursorPos = this.cm.getCursor('from'); + const url = this.getDrawioUrl(); + if (!url) return; - DrawIO.show(() => { + const cursorPos = this.cm.getCursor('from'); + + DrawIO.show(url,() => { return Promise.resolve(''); }, (pngData) => { - // let id = "image-" + Math.random().toString(16).slice(2); - // let loadingImage = window.baseUrl('/loading.gif'); - let data = { + + const data = { image: pngData, uploaded_to: Number(document.getElementById('page-editor').getAttribute('page-id')) }; @@ -439,15 +457,15 @@ class MarkdownEditor { // Show draw.io if enabled and handle save. actionEditDrawing(imgContainer) { - const drawingDisabled = document.querySelector('[drawio-enabled]').getAttribute('drawio-enabled') !== 'true'; - if (drawingDisabled) { + const drawioUrl = this.getDrawioUrl(); + if (!drawioUrl) { return; } const cursorPos = this.cm.getCursor('from'); const drawingId = imgContainer.getAttribute('drawio-diagram'); - DrawIO.show(() => { + DrawIO.show(drawioUrl, () => { return DrawIO.load(drawingId); }, (pngData) => { @@ -475,6 +493,13 @@ class MarkdownEditor { }); } + // Make the editor full screen + actionFullScreen() { + const alreadyFullscreen = this.elem.classList.contains('fullscreen'); + this.elem.classList.toggle('fullscreen', !alreadyFullscreen); + document.body.classList.toggle('markdown-fullscreen', !alreadyFullscreen); + } + // Scroll to a specified text scrollToText(searchText) { if (!searchText) { @@ -532,6 +557,11 @@ class MarkdownEditor { const prependLineCount = markdown.split('\n').length; this.cm.setCursor(cursorPos.line + prependLineCount, cursorPos.ch); }); + + // Focus on editor + window.$events.listen('editor::focus', () => { + this.cm.focus(); + }); } }