feat: convert pasted markdown to html so that it is correctly rendered (#3041)
Resolves https://community.vikunja.io/t/markdown-as-first-class-citizen/2975/4 Reviewed-on: https://kolaente.dev/vikunja/vikunja/pulls/3041 Co-authored-by: kolaente <k@knt.li> Co-committed-by: kolaente <k@knt.li>
This commit is contained in:
parent
021d71b90e
commit
f52a321acf
|
|
@ -93,6 +93,7 @@
|
|||
"is-touch-device": "1.0.1",
|
||||
"klona": "2.0.6",
|
||||
"lowlight": "3.3.0",
|
||||
"marked": "^15.0.6",
|
||||
"pinia": "2.3.1",
|
||||
"register-service-worker": "1.7.2",
|
||||
"sortablejs": "1.15.6",
|
||||
|
|
|
|||
|
|
@ -148,6 +148,9 @@ importers:
|
|||
lowlight:
|
||||
specifier: 3.3.0
|
||||
version: 3.3.0
|
||||
marked:
|
||||
specifier: ^15.0.6
|
||||
version: 15.0.6
|
||||
pinia:
|
||||
specifier: 2.3.1
|
||||
version: 2.3.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||
|
|
@ -4754,6 +4757,11 @@ packages:
|
|||
resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
|
||||
hasBin: true
|
||||
|
||||
marked@15.0.6:
|
||||
resolution: {integrity: sha512-Y07CUOE+HQXbVDCGl3LXggqJDbXDP2pArc2C1N1RRMN0ONiShoSsIInMd5Gsxupe7fKLpgimTV+HOJ9r7bA+pg==}
|
||||
engines: {node: '>= 18'}
|
||||
hasBin: true
|
||||
|
||||
mdn-data@2.0.28:
|
||||
resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==}
|
||||
|
||||
|
|
@ -11719,6 +11727,8 @@ snapshots:
|
|||
punycode.js: 2.3.1
|
||||
uc.micro: 2.1.0
|
||||
|
||||
marked@15.0.6: {}
|
||||
|
||||
mdn-data@2.0.28: {}
|
||||
|
||||
mdn-data@2.0.30: {}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,8 @@ import EditorToolbar from './EditorToolbar.vue'
|
|||
import StarterKit from '@tiptap/starter-kit'
|
||||
import {Extension, mergeAttributes} from '@tiptap/core'
|
||||
import {BubbleMenu, EditorContent, type Extensions, useEditor} from '@tiptap/vue-3'
|
||||
import {Plugin, PluginKey} from '@tiptap/pm/state'
|
||||
import {marked} from 'marked'
|
||||
|
||||
import Link from '@tiptap/extension-link'
|
||||
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
|
||||
|
|
@ -327,6 +329,32 @@ const additionalLinkProtocols = [
|
|||
'notion',
|
||||
]
|
||||
|
||||
const MarkdownPasteHandler = Extension.create({
|
||||
name: 'markdownPasteHandler',
|
||||
|
||||
addProseMirrorPlugins() {
|
||||
return [
|
||||
new Plugin({
|
||||
key: new PluginKey('markdownPasteHandler'),
|
||||
props: {
|
||||
handlePaste: (view, event) => {
|
||||
const text = event.clipboardData?.getData('text/plain')
|
||||
if (!text) return false
|
||||
|
||||
const html = marked.parse(text)
|
||||
|
||||
// It is fine to paste the content without sanitizing because it will be sanitized later by TipTap
|
||||
this.editor.commands.insertContent(html)
|
||||
// https://github.com/ueberdosis/tiptap/discussions/4118#discussioncomment-8931999
|
||||
return true
|
||||
},
|
||||
},
|
||||
}),
|
||||
]
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
const extensions : Extensions = [
|
||||
// Starterkit:
|
||||
StarterKit.configure({
|
||||
|
|
@ -418,6 +446,8 @@ const extensions : Extensions = [
|
|||
Commands.configure({
|
||||
suggestion: suggestionSetup(t),
|
||||
}),
|
||||
|
||||
MarkdownPasteHandler,
|
||||
]
|
||||
|
||||
// Add a custom extension for the Escape key
|
||||
|
|
|
|||
Loading…
Reference in New Issue