From 20914b5f64e70b1f960513063c90d14039786c6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Mon, 8 Jan 2024 11:13:16 +0100 Subject: [PATCH] fix: Properly copy selection as markdown to the plaintext clipboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using clipboardTextSerializer we can copy the current selection as markdown and don't need the extra keyboard shortcut, which was broken anyways as it always selected the full text Signed-off-by: Julius Härtl --- src/EditorFactory.js | 20 ++------------------ src/components/Editor.vue | 16 +++------------- src/extensions/Markdown.js | 3 +++ src/tests/plaintext.spec.js | 2 +- 4 files changed, 9 insertions(+), 32 deletions(-) diff --git a/src/EditorFactory.js b/src/EditorFactory.js index 1a0c025cfd1..5518ac985dd 100644 --- a/src/EditorFactory.js +++ b/src/EditorFactory.js @@ -80,24 +80,8 @@ const createEditor = ({ language, onCreate, onUpdate = () => {}, extensions, ena }) } -const SerializeException = function(message) { - this.message = message -} - -const serializePlainText = (tiptap) => { - const doc = tiptap.getJSON() - - if (doc.content.length !== 1 || typeof doc.content[0].content === 'undefined' || doc.content[0].content.length !== 1) { - if (doc.content[0].type === 'codeBlock' && typeof doc.content[0].content === 'undefined') { - return '' - } - throw new SerializeException('Failed to serialize document to plain text') - } - const codeBlock = doc.content[0].content[0] - if (codeBlock.type !== 'text') { - throw new SerializeException('Failed to serialize document to plain text') - } - return codeBlock.text +const serializePlainText = (doc) => { + return doc.textContent } export default createEditor diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 8ae2bd523c3..997e2e79ae4 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -112,7 +112,7 @@ import { createEditor, serializePlainText, loadSyntaxHighlight } from './../Edit import { createMarkdownSerializer } from './../extensions/Markdown.js' import markdownit from './../markdownit/index.js' -import { CollaborationCursor, Keymap } from '../extensions/index.js' +import { CollaborationCursor } from '../extensions/index.js' import DocumentStatus from './Editor/DocumentStatus.vue' import isMobile from './../mixins/isMobile.js' import setContent from './../mixins/setContent.js' @@ -372,8 +372,8 @@ export default { filePath: this.relativePath, forceRecreate: this.forceRecreate, serialize: this.isRichEditor - ? () => createMarkdownSerializer(this.$editor.schema).serialize(this.$editor.state.doc) - : () => serializePlainText(this.$editor), + ? (content) => createMarkdownSerializer(this.$editor.schema).serialize(content ?? this.$editor.state.doc) + : (content) => serializePlainText(content ?? this.$editor.state.doc), getDocumentState: () => getDocumentState(this.$ydoc), }) @@ -527,16 +527,6 @@ export default { clientId: this.$ydoc.clientID, }, }), - Keymap.configure({ - 'Shift-Mod-c': ({ editor }) => { - if (!navigator?.clipboard) { - console.error('Clipboard API is not available') - } - - const proseMirrorMarkdown = this.$syncService.serialize(editor.state.doc) - navigator.clipboard.writeText(proseMirrorMarkdown) - }, - }), ], enableRichEditing: this.isRichEditor, }) diff --git a/src/extensions/Markdown.js b/src/extensions/Markdown.js index 9ad6c7c503e..ba1b097003d 100644 --- a/src/extensions/Markdown.js +++ b/src/extensions/Markdown.js @@ -107,6 +107,9 @@ const Markdown = Extension.create({ return parser.parseSlice(dom, { preserveWhitespace: true, context: $context }) }, + clipboardTextSerializer: (slice) => { + return createMarkdownSerializer(this.editor.schema).serialize(slice.content) + }, transformPastedHTML, }, }), diff --git a/src/tests/plaintext.spec.js b/src/tests/plaintext.spec.js index cc7f6024615..fdd68fa0eb4 100644 --- a/src/tests/plaintext.spec.js +++ b/src/tests/plaintext.spec.js @@ -17,7 +17,7 @@ const plaintextThroughEditor = (markdown) => { enableRichEditing: false }) tiptap.commands.setContent(content) - return serializePlainText(tiptap) || 'failed' + return serializePlainText(tiptap.state.doc) || 'failed' } describe('commonmark as plaintext', () => {