From f10d3dc978a045852c456537ab2fd17d6f90c075 Mon Sep 17 00:00:00 2001
From: Elizabeth Danzberger
Date: Tue, 9 Apr 2024 19:37:09 +0000
Subject: [PATCH] fix: copy-paste markdown/raw text inconsistencies (#5487)
* fix: traverse through nodes in order to determine the correct copy-paste behavior
---------
Signed-off-by: Elizabeth Danzberger
Signed-off-by: Max
Co-authored-by: Max
---
src/extensions/Markdown.js | 12 ++++++++-
src/tests/extensions/Markdown.spec.js | 36 +++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 1 deletion(-)
diff --git a/src/extensions/Markdown.js b/src/extensions/Markdown.js
index ba1b097003d..6070a6465fa 100644
--- a/src/extensions/Markdown.js
+++ b/src/extensions/Markdown.js
@@ -108,7 +108,17 @@ const Markdown = Extension.create({
return parser.parseSlice(dom, { preserveWhitespace: true, context: $context })
},
clipboardTextSerializer: (slice) => {
- return createMarkdownSerializer(this.editor.schema).serialize(slice.content)
+ const traverseNodes = (slice) => {
+ if (slice.content.childCount > 1) {
+ return createMarkdownSerializer(this.editor.schema).serialize(slice.content)
+ } else if (slice.isLeaf) {
+ return slice.textContent
+ } else {
+ return traverseNodes(slice.content.firstChild)
+ }
+ }
+
+ return traverseNodes(slice)
},
transformPastedHTML,
},
diff --git a/src/tests/extensions/Markdown.spec.js b/src/tests/extensions/Markdown.spec.js
index bde2e828245..a1bcc081b6d 100644
--- a/src/tests/extensions/Markdown.spec.js
+++ b/src/tests/extensions/Markdown.spec.js
@@ -1,5 +1,7 @@
import { Markdown } from './../../extensions/index.js'
import { createMarkdownSerializer } from './../../extensions/Markdown.js'
+import CodeBlock from '@tiptap/extension-code-block'
+import Blockquote from '@tiptap/extension-blockquote'
import Image from './../../nodes/Image.js'
import ImageInline from './../../nodes/ImageInline.js'
import TaskList from './../../nodes/TaskList.js'
@@ -7,6 +9,7 @@ import TaskItem from './../../nodes/TaskItem.js'
import Underline from './../../marks/Underline.js'
import TiptapImage from '@tiptap/extension-image'
import { getExtensionField } from '@tiptap/core'
+import { __serializeForClipboard as serializeForClipboard } from '@tiptap/pm/view'
import { createCustomEditor } from '../helpers.js'
describe('Markdown extension unit', () => {
@@ -77,4 +80,37 @@ describe('Markdown extension integrated in the editor', () => {
expect(serializer.serialize(editor.state.doc)).toBe('inline image ![Hello](test) inside text')
})
+ it('copies task lists to plaintext like markdown', () => {
+ const editor = createCustomEditor({
+ content: '
',
+ extensions: [Markdown, TaskList, TaskItem],
+ })
+ editor.commands.selectAll()
+ const slice = editor.state.selection.content()
+ const { text } = serializeForClipboard(editor.view, slice)
+ expect(text).toBe('\n- [ ] Hello')
+ })
+
+ it('copies code block content to plaintext according to their spec', () => {
+ const editor = createCustomEditor({
+ content: 'Hello
',
+ extensions: [Markdown, CodeBlock],
+ })
+ editor.commands.selectAll()
+ const slice = editor.state.selection.content()
+ const { text } = serializeForClipboard(editor.view, slice)
+ expect(text).toBe('Hello')
+ })
+
+ it('copies nested task list nodes to markdown like syntax', () => {
+ const editor = createCustomEditor({
+ content: '
',
+ extensions: [Markdown, Blockquote, TaskList, TaskItem],
+ })
+ editor.commands.selectAll()
+ const slice = editor.state.selection.content()
+ const { text } = serializeForClipboard(editor.view, slice)
+ expect(text).toBe('\n- [ ] Hello')
+ })
+
})