@@ -7,8 +7,11 @@ import { Markdown } from './../../extensions/index.js'
77import { createMarkdownSerializer } from './../../extensions/Markdown.js'
88import { CodeBlock } from '@tiptap/extension-code-block'
99import { Blockquote } from '@tiptap/extension-blockquote'
10+ import { ListItem } from '@tiptap/extension-list-item'
1011import Image from './../../nodes/Image.js'
1112import ImageInline from './../../nodes/ImageInline.js'
13+ import OrderedList from './../../nodes/OrderedList.js'
14+ import Table from './../../nodes/Table.js'
1215import TaskList from './../../nodes/TaskList.js'
1316import TaskItem from './../../nodes/TaskItem.js'
1417import { Italic , Strong , Underline , Link } from './../../marks/index.js'
@@ -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
@@ -41,6 +45,7 @@ describe('Markdown extension integrated in the editor', () => {
4145 const editor = createCustomEditor ( '<p><u>Test</u></p>' , [ Markdown , Underline ] )
4246 const serializer = createMarkdownSerializer ( editor . schema )
4347 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '__Test__' )
48+ editor . destroy ( )
4449 } )
4550
4651 it ( 'serializes nodes according to their spec' , ( ) => {
@@ -50,6 +55,7 @@ describe('Markdown extension integrated in the editor', () => {
5055 )
5156 const serializer = createMarkdownSerializer ( editor . schema )
5257 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '\n- [ ] Hello' )
58+ editor . destroy ( )
5359 } )
5460
5561 it ( 'serializes images with the default prosemirror way' , ( ) => {
@@ -59,6 +65,7 @@ describe('Markdown extension integrated in the editor', () => {
5965 )
6066 const serializer = createMarkdownSerializer ( editor . schema )
6167 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( '' )
68+ editor . destroy ( )
6269 } )
6370
6471 it ( 'serializes block images with the default prosemirror way' , ( ) => {
@@ -79,13 +86,14 @@ describe('Markdown extension integrated in the editor', () => {
7986 expect ( serializer . serialize ( editor . state . doc ) ) . toBe ( 'inline image  inside text' )
8087 } )
8188
82- it ( 'copies task lists to plaintext like markdown ' , ( ) => {
89+ it ( 'copies markdown syntax for task list if selected together with a paragraph ' , ( ) => {
8390 const editor = createCustomEditor (
8491 '<p><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></p>' ,
8592 [ Markdown , TaskList , TaskItem ] ,
8693 )
8794 const text = copyEditorContent ( editor )
8895 expect ( text ) . toBe ( '\n- [ ] Hello' )
96+ editor . destroy ( )
8997 } )
9098
9199 it ( 'copies code block content to plaintext according to their spec' , ( ) => {
@@ -95,15 +103,47 @@ describe('Markdown extension integrated in the editor', () => {
95103 )
96104 const text = copyEditorContent ( editor )
97105 expect ( text ) . toBe ( 'Hello' )
106+ editor . destroy ( )
98107 } )
99108
100- it ( 'copies nested task list nodes to markdown like syntax ' , ( ) => {
109+ it ( 'copies just the content of a single list item ' , ( ) => {
101110 const editor = createCustomEditor (
102- '<blockquote><p><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></blockquote>' ,
111+ '<p>paragraph1</p><ol><li><p>first</p></li></ol><p>paragraph2</p>' ,
112+ [ Markdown , ListItem , OrderedList ] ,
113+ )
114+ const text = copyEditorContent ( editor , editor . schema . nodes . orderedList )
115+ expect ( text ) . toBe ( 'first' )
116+ editor . destroy ( )
117+ } )
118+
119+ it ( 'copies markdown syntax for multiple list items' , ( ) => {
120+ const editor = createCustomEditor (
121+ '<p>paragraph1</p><ol><li><p>first</p></li><li><p>second</p></li></ol><p>paragraph2</p>' ,
122+ [ Markdown , ListItem , OrderedList ] ,
123+ )
124+ const text = copyEditorContent ( editor , editor . schema . nodes . orderedList )
125+ expect ( text ) . toBe ( '1. first\n2. second' )
126+ editor . destroy ( )
127+ } )
128+
129+ it ( 'copies just the content of a single nested task list item' , ( ) => {
130+ const editor = createCustomEditor (
131+ '<blockquote><ul class="contains-task-list"><li><input type="checkbox">Hello</li></ul></blockquote>' ,
103132 [ Markdown , Blockquote , TaskList , TaskItem ] ,
104133 )
105134 const text = copyEditorContent ( editor )
106- expect ( text ) . toBe ( '\n- [ ] Hello' )
135+ expect ( text ) . toBe ( 'Hello' )
136+ editor . destroy ( )
137+ } )
138+
139+ it ( 'copies markdown syntax for multiple nested task list items' , ( ) => {
140+ const editor = createCustomEditor (
141+ '<blockquote><ul class="contains-task-list"><li><input type="checkbox">Hello</li><li><input type="checkbox">World</li></ul></blockquote>' ,
142+ [ Markdown , Blockquote , TaskList , TaskItem ] ,
143+ )
144+ const text = copyEditorContent ( editor )
145+ expect ( text ) . toBe ( '- [ ] Hello\n- [ ] World' )
146+ editor . destroy ( )
107147 } )
108148
109149 it ( 'copies address from blockquote to markdown' , ( ) => {
@@ -113,6 +153,7 @@ describe('Markdown extension integrated in the editor', () => {
113153 )
114154 const text = copyEditorContent ( editor )
115155 expect ( text ) . toBe ( 'Hermannsreute 44A' )
156+ editor . destroy ( )
116157 } )
117158
118159 it ( 'copy version number without escape character' , ( ) => {
@@ -122,6 +163,27 @@ describe('Markdown extension integrated in the editor', () => {
122163 )
123164 const text = copyEditorContent ( editor )
124165 expect ( text ) . toBe ( 'Hello\n\n28.0.4' )
166+ editor . destroy ( )
167+ } )
168+
169+ it ( 'copies just content for table cell' , ( ) => {
170+ const editor = createCustomEditor (
171+ '<p>paragraph</p><table><tr><th>headercell</th></tr><tr><td>contentcell</td></tr></table>' ,
172+ [ Markdown , Table ] ,
173+ )
174+ const text = copyEditorContent ( editor , editor . schema . nodes . tableCell )
175+ expect ( text ) . toBe ( 'contentcell' )
176+ editor . destroy ( )
177+ } )
178+
179+ it ( 'copies markdown syntax for full table' , ( ) => {
180+ const editor = createCustomEditor (
181+ '<p>paragraph</p><table><tr><th>headercell</th></tr><tr><td>contentcell</td></tr></table>' ,
182+ [ Markdown , Table ] ,
183+ )
184+ const text = copyEditorContent ( editor , editor . schema . nodes . table )
185+ expect ( text ) . toBe ( '| headercell |\n|-------------|\n| contentcell |\n' )
186+ editor . destroy ( )
125187 } )
126188
127189 it ( 'strips bold, italic, and other marks from paragraph' , ( ) => {
@@ -131,6 +193,7 @@ describe('Markdown extension integrated in the editor', () => {
131193 )
132194 const text = copyEditorContent ( editor )
133195 expect ( text ) . toBe ( 'Hello\n\nlonely world' )
196+ editor . destroy ( )
134197 } )
135198
136199 it ( 'strips href and link formatting from email address' , ( ) => {
@@ -140,12 +203,22 @@ describe('Markdown extension integrated in the editor', () => {
140203 )
141204 const text = copyEditorContent ( editor )
142205 expect ( text ) . toBe ( 'Hello\n\nexample@example.com' )
206+ editor . destroy ( )
143207 } )
144208
145209} )
146210
147- const copyEditorContent = ( editor ) => {
148- editor . commands . selectAll ( )
211+ const copyEditorContent = ( editor , nodeType = null ) => {
212+ if ( nodeType ) {
213+ editor . state . doc . descendants ( ( node , pos ) => {
214+ if ( node . type === nodeType ) {
215+ editor . commands . setNodeSelection ( pos )
216+ }
217+ } )
218+ } else {
219+ editor . commands . selectAll ( )
220+ }
221+
149222 const slice = editor . state . selection . content ( )
150223 const { text } = editor . view . serializeForClipboard ( slice )
151224 return text
0 commit comments