X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/e00d88f45dc6f3ab8855aa10f8d9200f923f1bf5..refs/pull/3853/head:/resources/js/components/markdown-editor.js diff --git a/resources/js/components/markdown-editor.js b/resources/js/components/markdown-editor.js index 21cf37bb4..b9567d864 100644 --- a/resources/js/components/markdown-editor.js +++ b/resources/js/components/markdown-editor.js @@ -4,8 +4,9 @@ import Clipboard from "../services/clipboard"; import {debounce} from "../services/util"; import {patchDomFromHtmlString} from "../services/vdom"; import DrawIO from "../services/drawio"; +import {Component} from "./component"; -class MarkdownEditor { +export class MarkdownEditor extends Component { setup() { this.elem = this.$el; @@ -211,13 +212,15 @@ class MarkdownEditor { extraKeys[`${metaKey}-3`] = cm => {replaceLineStart('####');}; extraKeys[`${metaKey}-4`] = cm => {replaceLineStart('#####');}; extraKeys[`${metaKey}-5`] = cm => {replaceLineStart('');}; - extraKeys[`${metaKey}-d`] = cm => {replaceLineStart('');}; + extraKeys[`${metaKey}-D`] = cm => {replaceLineStart('');}; extraKeys[`${metaKey}-6`] = cm => {replaceLineStart('>');}; - extraKeys[`${metaKey}-q`] = cm => {replaceLineStart('>');}; + extraKeys[`${metaKey}-Q`] = cm => {replaceLineStart('>');}; extraKeys[`${metaKey}-7`] = cm => {wrapSelection('\n```\n', '\n```');}; extraKeys[`${metaKey}-8`] = cm => {wrapSelection('`', '`');}; extraKeys[`Shift-${metaKey}-E`] = cm => {wrapSelection('`', '`');}; extraKeys[`${metaKey}-9`] = cm => {wrapSelection('

', '

');}; + extraKeys[`${metaKey}-P`] = cm => {replaceLineStart('-')} + extraKeys[`${metaKey}-O`] = cm => {replaceLineStartForOrderedList()} cm.setOption('extraKeys', extraKeys); // Update data on content change @@ -366,6 +369,19 @@ class MarkdownEditor { cm.setSelections([selections]); } + function replaceLineStartForOrderedList() { + const cursor = cm.getCursor(); + const prevLineContent = cm.getLine(cursor.line - 1) || ''; + const listMatch = prevLineContent.match(/^(\s*)(\d)([).])\s/) || []; + + const number = (Number(listMatch[2]) || 0) + 1; + const whiteSpace = listMatch[1] || ''; + const listMark = listMatch[3] || '.' + + const prefix = `${whiteSpace}${number}${listMark}`; + return replaceLineStart(prefix); + } + // Handle image upload and add image into markdown content function uploadImage(file) { if (file === null || file.type.indexOf('image') !== 0) return; @@ -415,7 +431,9 @@ class MarkdownEditor { actionInsertImage() { const cursorPos = this.cm.getCursor('from'); - window.ImageManager.show(image => { + /** @type {ImageManager} **/ + const imageManager = window.$components.first('image-manager'); + imageManager.show(image => { const imageUrl = image.thumbs.display || image.url; let selectedText = this.cm.getSelection(); let newText = "[![" + (selectedText || image.name) + "](" + imageUrl + ")](" + image.url + ")"; @@ -427,7 +445,9 @@ class MarkdownEditor { actionShowImageManager() { const cursorPos = this.cm.getCursor('from'); - window.ImageManager.show(image => { + /** @type {ImageManager} **/ + const imageManager = window.$components.first('image-manager'); + imageManager.show(image => { this.insertDrawing(image, cursorPos); }, 'drawio'); } @@ -435,7 +455,9 @@ class MarkdownEditor { // Show the popup link selector and insert a link when finished actionShowLinkSelector() { const cursorPos = this.cm.getCursor('from'); - window.EntitySelectorPopup.show(entity => { + /** @type {EntitySelectorPopup} **/ + const selector = window.$components.first('entity-selector-popup'); + selector.show(entity => { let selectedText = this.cm.getSelection() || entity.name; let newText = `[${selectedText}](${entity.link})`; this.cm.focus(); @@ -604,5 +626,3 @@ class MarkdownEditor { }); } } - -export default MarkdownEditor ;