@@ -7,14 +7,17 @@ import { getExtensionField } from '@tiptap/core'
77import { Blockquote } from '@tiptap/extension-blockquote'
88import { CodeBlock } from '@tiptap/extension-code-block'
99import TiptapImage from '@tiptap/extension-image'
10+ import { ListItem } from '@tiptap/extension-list-item'
11+ import { Markdown } from '../../extensions/index.js'
12+ import { createMarkdownSerializer } from '../../extensions/Markdown.js'
13+ import { Italic , Link , Strong , Underline } from '../../marks/index.js'
14+ import Image from '../../nodes/Image.js'
15+ import OrderedList from '../../nodes/OrderedList.js'
16+ import Table from '../../nodes/Table.js'
17+ import TaskItem from '../../nodes/TaskItem.js'
18+ import TaskList from '../../nodes/TaskList.js'
1019import createCustomEditor from '../testHelpers/createCustomEditor.ts'
11- import { Markdown } from './../../extensions/index.js'
12- import { createMarkdownSerializer } from './../../extensions/Markdown.js'
13- import { Italic , Link , Strong , Underline } from './../../marks/index.js'
14- import Image from './../../nodes/Image.js'
1520import ImageInline from './../../nodes/ImageInline.js'
16- import TaskItem from './../../nodes/TaskItem.js'
17- import TaskList from './../../nodes/TaskList.js'
1821
1922describe ( 'Markdown extension unit' , ( ) => {
2023 it ( 'has a config' , ( ) => {
@@ -33,6 +36,7 @@ describe('Markdown extension unit', () => {
3336 expect ( underline ) . toEqual ( Underline . config . toMarkdown )
3437 const listItem = serializer . serializer . nodes . listItem
3538 expect ( typeof listItem ) . toBe ( 'function' )
39+ editor . destroy ( )
3640 } )
3741} )
3842
@@ -44,6 +48,7 @@ describe('Markdown extension integrated in the editor', () => {
4448 ] )
4549 const serializer = createMarkdownSerializer ( editor . schema )
4650 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '__Test__' )
51+ editor . destroy ( )
4752 } )
4853
4954 it ( 'serializes nodes according to their spec' , ( ) => {
@@ -53,6 +58,7 @@ describe('Markdown extension integrated in the editor', () => {
5358 )
5459 const serializer = createMarkdownSerializer ( editor . schema )
5560 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '\n- [ ] Hello' )
61+ editor . destroy ( )
5662 } )
5763
5864 it ( 'serializes images with the default prosemirror way' , ( ) => {
@@ -62,6 +68,7 @@ describe('Markdown extension integrated in the editor', () => {
6268 ] )
6369 const serializer = createMarkdownSerializer ( editor . schema )
6470 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '' )
71+ editor . destroy ( )
6572 } )
6673
6774 it ( 'serializes block images with the default prosemirror way' , ( ) => {
@@ -73,6 +80,7 @@ describe('Markdown extension integrated in the editor', () => {
7380 expect ( serializer . serialize ( editor . state . doc ) ) . toBe (
7481 '\n\nhello' ,
7582 )
83+ editor . destroy ( )
7684 } )
7785
7886 it ( 'serializes inline images with the default prosemirror way' , ( ) => {
@@ -84,33 +92,67 @@ describe('Markdown extension integrated in the editor', () => {
8492 expect ( serializer . serialize ( editor . state . doc ) ) . toBe (
8593 'inline image  inside text' ,
8694 )
95+ editor . destroy ( )
8796 } )
8897
89- it ( 'copies task lists to plaintext like markdown ' , ( ) => {
98+ it ( 'copies markdown syntax for task list if selected together with a paragraph ' , ( ) => {
9099 const editor = createCustomEditor (
91100 '<p><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></p>' ,
92101 [ Markdown , TaskList , TaskItem ] ,
93102 )
94103 const text = copyEditorContent ( editor )
95104 expect ( text ) . toBe ( '\n- [ ] Hello' )
105+ editor . destroy ( )
96106 } )
97107
98- it ( 'copies code block content to plaintext according to their spec ' , ( ) => {
108+ it ( 'copies just the content of a block node ' , ( ) => {
99109 const editor = createCustomEditor ( '<pre><code>Hello</code></pre>' , [
100110 Markdown ,
101111 CodeBlock ,
102112 ] )
103113 const text = copyEditorContent ( editor )
104114 expect ( text ) . toBe ( 'Hello' )
115+ editor . destroy ( )
105116 } )
106117
107- it ( 'copies nested task list nodes to markdown like syntax ' , ( ) => {
118+ it ( 'copies just the content of a single list item ' , ( ) => {
108119 const editor = createCustomEditor (
109- '<blockquote><p><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></blockquote>' ,
120+ '<p>paragraph1</p><ol><li><p>first</p></li></ol><p>paragraph2</p>' ,
121+ [ Markdown , ListItem , OrderedList ] ,
122+ )
123+ const text = copyEditorContent ( editor , editor . schema . nodes . orderedList )
124+ expect ( text ) . toBe ( 'first' )
125+ editor . destroy ( )
126+ } )
127+
128+ it ( 'copies markdown syntax for multiple list items' , ( ) => {
129+ const editor = createCustomEditor (
130+ '<p>paragraph1</p><ol><li><p>first</p></li><li><p>second</p></li></ol><p>paragraph2</p>' ,
131+ [ Markdown , ListItem , OrderedList ] ,
132+ )
133+ const text = copyEditorContent ( editor , editor . schema . nodes . orderedList )
134+ expect ( text ) . toBe ( '1. first\n2. second' )
135+ editor . destroy ( )
136+ } )
137+
138+ it ( 'copies just the content of a single nested task list item' , ( ) => {
139+ const editor = createCustomEditor (
140+ '<blockquote><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></blockquote>' ,
110141 [ Markdown , Blockquote , TaskList , TaskItem ] ,
111142 )
112143 const text = copyEditorContent ( editor )
113- expect ( text ) . toBe ( '\n- [ ] Hello' )
144+ expect ( text ) . toBe ( 'Hello' )
145+ editor . destroy ( )
146+ } )
147+
148+ it ( 'copies markdown syntax for multiple nested task list items' , ( ) => {
149+ const editor = createCustomEditor (
150+ '<blockquote><ul class="contains-task-list"><li><input type="checkbox">Hello</li><li><input type="checkbox">World</li></ul></blockquote>' ,
151+ [ Markdown , Blockquote , TaskList , TaskItem ] ,
152+ )
153+ const text = copyEditorContent ( editor )
154+ expect ( text ) . toBe ( '- [ ] Hello\n- [ ] World' )
155+ editor . destroy ( )
114156 } )
115157
116158 it ( 'copies address from blockquote to markdown' , ( ) => {
@@ -120,12 +162,34 @@ describe('Markdown extension integrated in the editor', () => {
120162 )
121163 const text = copyEditorContent ( editor )
122164 expect ( text ) . toBe ( 'Hermannsreute 44A' )
165+ editor . destroy ( )
123166 } )
124167
125- it ( 'copy version number without escape character' , ( ) => {
168+ it ( 'copies version number without escape character' , ( ) => {
126169 const editor = createCustomEditor ( '<p>Hello</p><p>28.0.4</p>' , [ Markdown ] )
127170 const text = copyEditorContent ( editor )
128171 expect ( text ) . toBe ( 'Hello\n\n28.0.4' )
172+ editor . destroy ( )
173+ } )
174+
175+ it ( 'copies just content for table cell' , ( ) => {
176+ const editor = createCustomEditor (
177+ '<p>paragraph</p><table><tr><th>headercell</th></tr><tr><td>contentcell</td></tr></table>' ,
178+ [ Markdown , Table ] ,
179+ )
180+ const text = copyEditorContent ( editor , editor . schema . nodes . tableCell )
181+ expect ( text ) . toBe ( 'contentcell' )
182+ editor . destroy ( )
183+ } )
184+
185+ it ( 'copies markdown syntax for full table' , ( ) => {
186+ const editor = createCustomEditor (
187+ '<p>paragraph</p><table><tr><th>headercell</th></tr><tr><td>contentcell</td></tr></table>' ,
188+ [ Markdown , Table ] ,
189+ )
190+ const text = copyEditorContent ( editor , editor . schema . nodes . table )
191+ expect ( text ) . toBe ( '| headercell |\n|-------------|\n| contentcell |\n' )
192+ editor . destroy ( )
129193 } )
130194
131195 it ( 'strips bold, italic, and other marks from paragraph' , ( ) => {
@@ -135,6 +199,7 @@ describe('Markdown extension integrated in the editor', () => {
135199 )
136200 const text = copyEditorContent ( editor )
137201 expect ( text ) . toBe ( 'Hello\n\nlonely world' )
202+ editor . destroy ( )
138203 } )
139204
140205 it ( 'strips href and link formatting from email address' , ( ) => {
@@ -144,11 +209,21 @@ describe('Markdown extension integrated in the editor', () => {
144209 )
145210 const text = copyEditorContent ( editor )
146211 expect ( text ) . toBe ( 'Hello\n\nexample@example.com' )
212+ editor . destroy ( )
147213 } )
148214} )
149215
150- const copyEditorContent = ( editor ) => {
151- editor . commands . selectAll ( )
216+ const copyEditorContent = ( editor , nodeType = null ) => {
217+ if ( nodeType ) {
218+ editor . state . doc . descendants ( ( node , pos ) => {
219+ if ( node . type === nodeType ) {
220+ editor . commands . setNodeSelection ( pos )
221+ }
222+ } )
223+ } else {
224+ editor . commands . selectAll ( )
225+ }
226+
152227 const slice = editor . state . selection . content ( )
153228 const { text } = editor . view . serializeForClipboard ( slice )
154229 return text
0 commit comments