quill-table-up 2.0.1 → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.umd.js +1 -1
  5. package/dist/index.umd.js.map +1 -1
  6. package/dist/table-creator.css +1 -1
  7. package/package.json +9 -14
  8. package/src/__tests__/e2e/custom-creator.test.ts +44 -0
  9. package/src/__tests__/e2e/table-align.test.ts +39 -0
  10. package/src/__tests__/e2e/table-resize.test.ts +152 -0
  11. package/src/__tests__/e2e/table-scrollbar.test.ts +31 -0
  12. package/src/__tests__/e2e/table-selection.test.ts +83 -0
  13. package/src/__tests__/e2e/utils.ts +6 -0
  14. package/src/__tests__/unit/table-insert-blot.test.ts +464 -0
  15. package/src/__tests__/unit/table-insert-remove-merge.test.ts +1270 -0
  16. package/src/__tests__/unit/table-redo-undo.test.ts +909 -0
  17. package/src/__tests__/unit/utils.test-d.ts +49 -0
  18. package/src/__tests__/unit/utils.test.ts +715 -0
  19. package/src/__tests__/unit/utils.ts +216 -0
  20. package/src/__tests__/unit/vitest.d.ts +12 -0
  21. package/src/formats/container-format.ts +52 -0
  22. package/src/formats/index.ts +10 -0
  23. package/src/formats/overrides/block.ts +93 -0
  24. package/src/formats/overrides/blockquote.ts +8 -0
  25. package/src/formats/overrides/code.ts +8 -0
  26. package/src/formats/overrides/header.ts +8 -0
  27. package/src/formats/overrides/index.ts +6 -0
  28. package/src/formats/overrides/list.ts +10 -0
  29. package/src/formats/overrides/scroll.ts +51 -0
  30. package/src/formats/table-body-format.ts +92 -0
  31. package/src/formats/table-cell-format.ts +139 -0
  32. package/src/formats/table-cell-inner-format.ts +251 -0
  33. package/src/formats/table-col-format.ts +174 -0
  34. package/src/formats/table-colgroup-format.ts +133 -0
  35. package/src/formats/table-main-format.ts +143 -0
  36. package/src/formats/table-row-format.ts +147 -0
  37. package/src/formats/table-wrapper-format.ts +55 -0
  38. package/src/formats/utils.ts +3 -0
  39. package/src/index.ts +1157 -0
  40. package/src/modules/index.ts +5 -0
  41. package/src/modules/table-align.ts +116 -0
  42. package/src/modules/table-menu/constants.ts +140 -0
  43. package/src/modules/table-menu/index.ts +3 -0
  44. package/src/modules/table-menu/table-menu-common.ts +249 -0
  45. package/src/modules/table-menu/table-menu-contextmenu.ts +94 -0
  46. package/src/modules/table-menu/table-menu-select.ts +28 -0
  47. package/src/modules/table-resize/index.ts +5 -0
  48. package/src/modules/table-resize/table-resize-box.ts +293 -0
  49. package/src/modules/table-resize/table-resize-common.ts +343 -0
  50. package/src/modules/table-resize/table-resize-line.ts +163 -0
  51. package/src/modules/table-resize/table-resize-scale.ts +154 -0
  52. package/src/modules/table-resize/utils.ts +3 -0
  53. package/src/modules/table-scrollbar.ts +255 -0
  54. package/src/modules/table-selection.ts +262 -0
  55. package/src/style/button.less +45 -0
  56. package/src/style/color-picker.less +134 -0
  57. package/src/style/dialog.less +53 -0
  58. package/src/style/functions.less +9 -0
  59. package/src/style/index.less +89 -0
  60. package/src/style/input.less +64 -0
  61. package/src/style/select-box.less +51 -0
  62. package/src/style/table-creator.less +68 -0
  63. package/src/style/table-menu.less +122 -0
  64. package/src/style/table-resize-scale.less +31 -0
  65. package/src/style/table-resize.less +183 -0
  66. package/src/style/table-scrollbar.less +49 -0
  67. package/src/style/table-selection.less +15 -0
  68. package/src/style/tooltip.less +19 -0
  69. package/src/style/variables.less +1 -0
  70. package/src/svg/background.svg +1 -0
  71. package/src/svg/border.svg +1 -0
  72. package/src/svg/color.svg +1 -0
  73. package/src/svg/insert-bottom.svg +1 -0
  74. package/src/svg/insert-left.svg +1 -0
  75. package/src/svg/insert-right.svg +1 -0
  76. package/src/svg/insert-top.svg +1 -0
  77. package/src/svg/merge-cell.svg +1 -0
  78. package/src/svg/remove-column.svg +1 -0
  79. package/src/svg/remove-row.svg +1 -0
  80. package/src/svg/remove-table.svg +1 -0
  81. package/src/svg/split-cell.svg +1 -0
  82. package/src/types.d.ts +4 -0
  83. package/src/utils/bem.ts +23 -0
  84. package/src/utils/color.ts +109 -0
  85. package/src/utils/components/button.ts +22 -0
  86. package/src/utils/components/color-picker.ts +236 -0
  87. package/src/utils/components/dialog.ts +41 -0
  88. package/src/utils/components/index.ts +6 -0
  89. package/src/utils/components/input.ts +74 -0
  90. package/src/utils/components/table/creator.ts +86 -0
  91. package/src/utils/components/table/index.ts +2 -0
  92. package/src/utils/components/table/select-box.ts +83 -0
  93. package/src/utils/components/tooltip.ts +186 -0
  94. package/src/utils/constants.ts +99 -0
  95. package/src/utils/index.ts +7 -0
  96. package/src/utils/is.ts +6 -0
  97. package/src/utils/position.ts +21 -0
  98. package/src/utils/types.ts +131 -0
  99. package/src/utils/utils.ts +139 -0
@@ -0,0 +1,1270 @@
1
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
2
+ import TableUp, { TableCellInnerFormat, TableSelection } from '../..';
3
+ import { createQuillWithTableModule, createTable, createTaleColHTML } from './utils';
4
+
5
+ beforeEach(() => {
6
+ vi.useFakeTimers();
7
+ });
8
+ afterEach(() => {
9
+ vi.useRealTimers();
10
+ });
11
+
12
+ describe('merge and split cell', () => {
13
+ it('merge cells', async () => {
14
+ const quill = createQuillWithTableModule(`<p><br></p>`);
15
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
16
+ tableModule.insertTable(3, 3);
17
+ await vi.runAllTimersAsync();
18
+ const table = quill.root.querySelector('table')!;
19
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
20
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
21
+ tableModule.tableSelection.selectedTds = [tds[3], tds[4], tds[6], tds[7]];
22
+ tableModule.mergeCells();
23
+ await vi.runAllTimersAsync();
24
+ expect(quill.root).toEqualHTML(
25
+ `
26
+ <p><br></p>
27
+ <div>
28
+ <table cellpadding="0" cellspacing="0" data-full="true">
29
+ <colgroup data-full="true">
30
+ ${new Array(3).fill(0).map(() => `<col width="${1 / 3 * 100}%" data-full="true" />`).join('\n')}
31
+ </colgroup>
32
+ <tbody>
33
+ <tr>
34
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
35
+ </tr>
36
+ <tr>
37
+ <td rowspan="2" colspan="2">
38
+ <div>
39
+ <p><br></p>
40
+ <p><br></p>
41
+ <p><br></p>
42
+ <p><br></p>
43
+ </div>
44
+ </td>
45
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
46
+ </tr>
47
+ <tr>
48
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
49
+ </tr>
50
+ </tbody>
51
+ </table>
52
+ </div>
53
+ <p><br></p>
54
+ `,
55
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
56
+ );
57
+ });
58
+
59
+ it('merge cells and clear rowspan or colspan', async () => {
60
+ const quill = createQuillWithTableModule(`<p><br></p>`);
61
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
62
+ tableModule.insertTable(2, 5);
63
+ await vi.runAllTimersAsync();
64
+ const table = quill.root.querySelector('table')!;
65
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
66
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
67
+ tableModule.tableSelection.selectedTds = [tds[1], tds[2], tds[3], tds[6], tds[7], tds[8]];
68
+ tableModule.mergeCells();
69
+ await vi.runAllTimersAsync();
70
+ expect(quill.root).toEqualHTML(
71
+ `
72
+ <p><br></p>
73
+ <div>
74
+ <table cellpadding="0" cellspacing="0" data-full="true">
75
+ <colgroup data-full="true">
76
+ <col width="20%" data-full="true" />
77
+ <col width="60%" data-full="true" />
78
+ <col width="20%" data-full="true" />
79
+ </colgroup>
80
+ <tbody>
81
+ <tr>
82
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
83
+ <td rowspan="2" colspan="1">
84
+ <div>
85
+ <p><br></p>
86
+ <p><br></p>
87
+ <p><br></p>
88
+ <p><br></p>
89
+ <p><br></p>
90
+ <p><br></p>
91
+ </div>
92
+ </td>
93
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
94
+ </tr>
95
+ <tr>
96
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
97
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
98
+ </tr>
99
+ </tbody>
100
+ </table>
101
+ </div>
102
+ <p><br></p>
103
+ `,
104
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
105
+ );
106
+ });
107
+
108
+ it('merge cells across rowspan and colspan', async () => {
109
+ const quill = createQuillWithTableModule(`<p><br></p>`);
110
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
111
+ tableModule.insertTable(6, 7);
112
+ await vi.runAllTimersAsync();
113
+ const table = quill.root.querySelector('table')!;
114
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
115
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
116
+ tableModule.tableSelection.selectedTds = [tds[7], tds[8], tds[9], tds[14], tds[15], tds[16], tds[21], tds[22], tds[23]];
117
+ tableModule.mergeCells();
118
+ await vi.runAllTimersAsync();
119
+ tableModule.tableSelection.selectedTds = [tds[25], tds[26], tds[27], tds[32], tds[33], tds[34], tds[39], tds[40], tds[41]];
120
+ tableModule.mergeCells();
121
+ await vi.runAllTimersAsync();
122
+ tableModule.tableSelection.selectedTds = [tds[3], tds[4], tds[5], tds[10], tds[11], tds[12], tds[17], tds[18], tds[19]];
123
+ tableModule.mergeCells();
124
+ await vi.runAllTimersAsync();
125
+ expect(quill.root).toEqualHTML(
126
+ `
127
+ <p><br></p>
128
+ <div>
129
+ <table cellpadding="0" cellspacing="0" data-full="true">
130
+ <colgroup data-full="true">
131
+ ${new Array(4).fill(0).map(() => `<col width="${1 / 7 * 100}%" data-full="true" />`).join('\n')}
132
+ <col width="${2 / 7 * 100}%" data-full="true" />
133
+ <col width="${1 / 7 * 100}%" data-full="true" />
134
+ </colgroup>
135
+ <tbody>
136
+ <tr>
137
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
138
+ <td rowspan="3" colspan="2">
139
+ <div>
140
+ ${new Array(9).fill(0).map(() => `<p><br></p>`).join('\n')}
141
+ </div>
142
+ </td>
143
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
144
+ </tr>
145
+ <tr>
146
+ <td rowspan="3" colspan="3">
147
+ <div>
148
+ ${new Array(9).fill(0).map(() => `<p><br></p>`).join('\n')}
149
+ </div>
150
+ </td>
151
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
152
+ </tr>
153
+ <tr>
154
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
155
+ </tr>
156
+ <tr>
157
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
158
+ <td rowspan="3" colspan="2">
159
+ <div>
160
+ ${new Array(9).fill(0).map(() => `<p><br></p>`).join('\n')}
161
+ </div>
162
+ </td>
163
+ </tr>
164
+ ${
165
+ new Array(2).fill(0).map(() => `
166
+ <tr>
167
+ ${new Array(4).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
168
+ </tr>
169
+ `).join('\n')
170
+ }
171
+ </tbody>
172
+ </table>
173
+ </div>
174
+ <p><br></p>
175
+ `,
176
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
177
+ );
178
+ });
179
+
180
+ it('split cell', async () => {
181
+ const quill = createQuillWithTableModule(`<p><br></p>`);
182
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
183
+ tableModule.insertTable(3, 3);
184
+ await vi.runAllTimersAsync();
185
+ const table = quill.root.querySelector('table')!;
186
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
187
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
188
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[3], tds[4]];
189
+ tableModule.mergeCells();
190
+ await vi.runAllTimersAsync();
191
+ tableModule.tableSelection.selectedTds = [tds[0]];
192
+ tableModule.splitCell();
193
+ await vi.runAllTimersAsync();
194
+ expect(quill.root).toEqualHTML(
195
+ `
196
+ <p><br></p>
197
+ <div>
198
+ <table cellpadding="0" cellspacing="0" data-full="true">
199
+ <colgroup data-full="true">
200
+ ${new Array(3).fill(0).map(() => `<col width="${1 / 3 * 100}%" data-full="true" />`).join('\n')}
201
+ </colgroup>
202
+ <tbody>
203
+ <tr>
204
+ <td rowspan="1" colspan="1">
205
+ <div>
206
+ <p><br></p>
207
+ <p><br></p>
208
+ <p><br></p>
209
+ <p><br></p>
210
+ </div>
211
+ </td>
212
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
213
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
214
+ </tr>
215
+ ${
216
+ new Array(2).fill(0).map(() => `
217
+ <tr>
218
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
219
+ </tr>
220
+ `).join('\n')
221
+ }
222
+ </tbody>
223
+ </table>
224
+ </div>
225
+ <p><br></p>
226
+ `,
227
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
228
+ );
229
+ });
230
+
231
+ it('merge cells should sort correct colId', async () => {
232
+ const quill = await createTable(5, 5);
233
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
234
+ const table = quill.root.querySelector('table')!;
235
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
236
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
237
+ tableModule.tableSelection.selectedTds = [tds[6], tds[7], tds[11], tds[12]];
238
+ tableModule.mergeCells();
239
+ await vi.runAllTimersAsync();
240
+ tableModule.tableSelection.selectedTds = [tds[5], tds[6], tds[10], tds[15], tds[16], tds[17], tds[20], tds[21], tds[22]];
241
+ tableModule.mergeCells();
242
+ await vi.runAllTimersAsync();
243
+ expect(quill.root).toEqualHTML(
244
+ `
245
+ <p><br></p>
246
+ <div>
247
+ <table cellpadding="0" cellspacing="0" data-full="true">
248
+ ${createTaleColHTML(5)}
249
+ <tbody>
250
+ <tr data-row-id="1">
251
+ ${
252
+ new Array(5).fill(0).map((_, j) => `<td rowspan="1" colspan="1" data-row-id="1" data-col-id="${j + 1}">
253
+ <div data-rowspan="1" data-colspan="1" data-row-id="1" data-col-id="${j + 1}"><p>${j + 1}</p></div>
254
+ </td>`).join('\n')
255
+ }
256
+ </tr>
257
+ <tr data-row-id="2">
258
+ <td rowspan="4" colspan="3" data-row-id="2" data-col-id="1">
259
+ <div data-rowspan="4" data-colspan="3" data-row-id="2" data-col-id="1">
260
+ <p>6</p>
261
+ <p>7</p>
262
+ <p>8</p>
263
+ <p>12</p>
264
+ <p>13</p>
265
+ <p>11</p>
266
+ <p>16</p>
267
+ <p>17</p>
268
+ <p>18</p>
269
+ <p>21</p>
270
+ <p>22</p>
271
+ <p>23</p>
272
+ </div>
273
+ </td>
274
+ <td rowspan="1" colspan="1" data-row-id="2" data-col-id="4">
275
+ <div data-rowspan="1" data-colspan="1" data-row-id="2" data-col-id="4"><p>9</p></div>
276
+ </td>
277
+ <td rowspan="1" colspan="1" data-row-id="2" data-col-id="5">
278
+ <div data-rowspan="1" data-colspan="1" data-row-id="2" data-col-id="5"><p>10</p></div>
279
+ </td>
280
+ </tr>
281
+ <tr data-row-id="3">
282
+ <td rowspan="1" colspan="1" data-row-id="3" data-col-id="4">
283
+ <div data-rowspan="1" data-colspan="1" data-row-id="3" data-col-id="4"><p>14</p></div>
284
+ </td>
285
+ <td rowspan="1" colspan="1" data-row-id="3" data-col-id="5">
286
+ <div data-rowspan="1" data-colspan="1" data-row-id="3" data-col-id="5"><p>15</p></div>
287
+ </td>
288
+ </tr>
289
+ <tr data-row-id="4">
290
+ <td rowspan="1" colspan="1" data-row-id="4" data-col-id="4">
291
+ <div data-rowspan="1" data-colspan="1" data-row-id="4" data-col-id="4"><p>19</p></div>
292
+ </td>
293
+ <td rowspan="1" colspan="1" data-row-id="4" data-col-id="5">
294
+ <div data-rowspan="1" data-colspan="1" data-row-id="4" data-col-id="5"><p>20</p></div>
295
+ </td>
296
+ </tr>
297
+ <tr data-row-id="5">
298
+ <td rowspan="1" colspan="1" data-row-id="5" data-col-id="4">
299
+ <div data-rowspan="1" data-colspan="1" data-row-id="5" data-col-id="4"><p>24</p></div>
300
+ </td>
301
+ <td rowspan="1" colspan="1" data-row-id="5" data-col-id="5">
302
+ <div data-rowspan="1" data-colspan="1" data-row-id="5" data-col-id="5"><p>25</p></div>
303
+ </td>
304
+ </tr>
305
+ </tbody>
306
+ </table>
307
+ </div>
308
+ <p><br></p>
309
+ `,
310
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'contenteditable'] },
311
+ );
312
+ });
313
+ });
314
+
315
+ describe('remove column from table', () => {
316
+ it('remove column', async () => {
317
+ const quill = createQuillWithTableModule(`<p><br></p>`);
318
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
319
+ tableModule.insertTable(3, 3);
320
+ await vi.runAllTimersAsync();
321
+ const table = quill.root.querySelector('table')!;
322
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
323
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
324
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[3], tds[4]];
325
+ tableModule.removeCol();
326
+ await vi.runAllTimersAsync();
327
+ expect(quill.root).toEqualHTML(
328
+ `
329
+ <p><br></p>
330
+ <div>
331
+ <table cellpadding="0" cellspacing="0" data-full="true">
332
+ <colgroup data-full="true">
333
+ <col width="${1 / 3 * 100 * 3}%" data-full="true" />
334
+ </colgroup>
335
+ <tbody>
336
+ ${
337
+ new Array(3).fill(0).map(() => `
338
+ <tr>
339
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
340
+ </tr>
341
+ `).join('\n')
342
+ }
343
+ </tbody>
344
+ </table>
345
+ </div>
346
+ <p><br></p>
347
+ `,
348
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
349
+ );
350
+ });
351
+
352
+ it('remove column in not full table', async () => {
353
+ const quill = await createTable(1, 3, { full: false });
354
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
355
+ await vi.runAllTimersAsync();
356
+ const table = quill.root.querySelector('table')!;
357
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
358
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
359
+ tableModule.tableSelection.selectedTds = [tds[0]];
360
+ tableModule.removeCol();
361
+ await vi.runAllTimersAsync();
362
+ expect(quill.root).toEqualHTML(
363
+ `
364
+ <p><br></p>
365
+ <div>
366
+ <table cellpadding="0" cellspacing="0" style="margin-right: auto; width: 200px;">
367
+ <colgroup>
368
+ <col width="100px" />
369
+ <col width="100px" />
370
+ </colgroup>
371
+ <tbody>
372
+ <tr>
373
+ <td rowspan="1" colspan="1"><div><p>2</p></div></td>
374
+ <td rowspan="1" colspan="1"><div><p>3</p></div></td>
375
+ </tr>
376
+ </tbody>
377
+ </table>
378
+ </div>
379
+ <p><br></p>
380
+ `,
381
+ { ignoreAttrs: ['class', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
382
+ );
383
+ });
384
+
385
+ it('remove column. remove colspan start cell and rowspan cell', async () => {
386
+ const quill = createQuillWithTableModule(`<p><br></p>`);
387
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
388
+ tableModule.insertTable(4, 4);
389
+ await vi.runAllTimersAsync();
390
+ const table = quill.root.querySelector('table')!;
391
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
392
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
393
+ tableModule.tableSelection.selectedTds = [tds[4], tds[5], tds[6], tds[8], tds[9], tds[10]];
394
+ tableModule.mergeCells();
395
+ await vi.runAllTimersAsync();
396
+ tableModule.tableSelection.selectedTds = [tds[13], tds[14], tds[15]];
397
+ tableModule.mergeCells();
398
+ await vi.runAllTimersAsync();
399
+ tableModule.tableSelection.selectedTds = [tds[1], tds[2]];
400
+ tableModule.removeCol();
401
+ await vi.runAllTimersAsync();
402
+ expect(quill.root).toEqualHTML(
403
+ `
404
+ <p><br></p>
405
+ <div>
406
+ <table cellpadding="0" cellspacing="0" data-full="true">
407
+ <colgroup data-full="true">
408
+ <col width="25%" data-full="true" />
409
+ <col width="75%" data-full="true" />
410
+ </colgroup>
411
+ <tbody>
412
+ <tr>
413
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
414
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
415
+ </tr>
416
+ <tr>
417
+ <td rowspan="2" colspan="1">
418
+ <div>
419
+ <p><br></p>
420
+ <p><br></p>
421
+ <p><br></p>
422
+ <p><br></p>
423
+ <p><br></p>
424
+ <p><br></p>
425
+ </div>
426
+ </td>
427
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
428
+ </tr>
429
+ <tr>
430
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
431
+ </tr>
432
+ <tr>
433
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
434
+ <td rowspan="1" colspan="1">
435
+ <div>
436
+ <p><br></p>
437
+ <p><br></p>
438
+ <p><br></p>
439
+ </div>
440
+ </td>
441
+ </tr>
442
+ </tbody>
443
+ </table>
444
+ </div>
445
+ <p><br></p>
446
+ `,
447
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
448
+ );
449
+ });
450
+ });
451
+
452
+ describe('remove row from table', () => {
453
+ it('remove row', async () => {
454
+ const quill = createQuillWithTableModule(`<p><br></p>`);
455
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
456
+ tableModule.insertTable(3, 3);
457
+ await vi.runAllTimersAsync();
458
+ const table = quill.root.querySelector('table')!;
459
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
460
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
461
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[3], tds[4], tds[5]];
462
+ tableModule.removeRow();
463
+ await vi.runAllTimersAsync();
464
+ expect(quill.root).toEqualHTML(
465
+ `
466
+ <p><br></p>
467
+ <div>
468
+ <table cellpadding="0" cellspacing="0" data-full="true">
469
+ <colgroup data-full="true">
470
+ ${new Array(3).fill(0).map(() => `<col width="${1 / 3 * 100}%" data-full="true" />`).join('\n')}
471
+ </colgroup>
472
+ <tbody>
473
+ <tr>
474
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
475
+ </tr>
476
+ </tbody>
477
+ </table>
478
+ </div>
479
+ <p><br></p>
480
+ `,
481
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
482
+ );
483
+ });
484
+
485
+ it('remove row. remove rowspan cell at start index', async () => {
486
+ const quill = createQuillWithTableModule(`<p><br></p>`);
487
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
488
+ tableModule.insertTable(3, 3);
489
+ await vi.runAllTimersAsync();
490
+ const table = quill.root.querySelector('table')!;
491
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
492
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
493
+ tableModule.tableSelection.selectedTds = [tds[1], tds[2], tds[4], tds[5]];
494
+ tableModule.mergeCells();
495
+ await vi.runAllTimersAsync();
496
+ tableModule.tableSelection.selectedTds = [tds[0]];
497
+ tableModule.removeRow();
498
+ await vi.runAllTimersAsync();
499
+ expect(quill.root).toEqualHTML(
500
+ `
501
+ <p><br></p>
502
+ <div>
503
+ <table cellpadding="0" cellspacing="0" data-full="true">
504
+ <colgroup data-full="true">
505
+ ${new Array(3).fill(0).map(() => `<col width="${1 / 3 * 100}%" data-full="true" />`).join('\n')}
506
+ </colgroup>
507
+ <tbody>
508
+ <tr>
509
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
510
+ <td rowspan="1" colspan="2"><div><p><br></p></div></td>
511
+ </tr>
512
+ <tr>
513
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
514
+ </tr>
515
+ </tbody>
516
+ </table>
517
+ </div>
518
+ <p><br></p>
519
+ `,
520
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
521
+ );
522
+ });
523
+ });
524
+
525
+ describe('insert column into table', () => {
526
+ it('render insert', async () => {
527
+ const quill = createQuillWithTableModule(`<p><br></p>`);
528
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
529
+ tableModule.insertTable(4, 4);
530
+ await vi.runAllTimersAsync();
531
+ expect(quill.root).toEqualHTML(
532
+ `
533
+ <p><br></p>
534
+ <div>
535
+ <table cellpadding="0" cellspacing="0" data-full="true">
536
+ <colgroup data-full="true">
537
+ ${new Array(4).fill(0).map(() => `<col width="${100 / 4}%" data-full="true" />`).join('\n')}
538
+ </colgroup>
539
+ <tbody>
540
+ ${
541
+ new Array(4).fill(0).map(() => `
542
+ <tr>
543
+ ${new Array(4).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
544
+ </tr>
545
+ `).join('\n')
546
+ }
547
+ </tbody>
548
+ </table>
549
+ </div>
550
+ <p><br></p>
551
+ `,
552
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
553
+ );
554
+ });
555
+
556
+ it('insert column left', async () => {
557
+ const quill = createQuillWithTableModule(`<p><br></p>`);
558
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
559
+ tableModule.insertTable(2, 2);
560
+ await vi.runAllTimersAsync();
561
+ const table = quill.root.querySelector('table')!;
562
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
563
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
564
+ tableModule.tableSelection.selectedTds = [tds[0]];
565
+ tableModule.appendCol(false);
566
+ await vi.runAllTimersAsync();
567
+ expect(quill.root).toEqualHTML(
568
+ `
569
+ <p><br></p>
570
+ <div>
571
+ <table cellpadding="0" cellspacing="0" data-full="true">
572
+ <colgroup data-full="true">
573
+ <col width="6%" data-full="true" />
574
+ <col width="44%" data-full="true" />
575
+ <col width="50%" data-full="true" />
576
+ </colgroup>
577
+ <tbody>
578
+ ${
579
+ new Array(2).fill(0).map(() => `
580
+ <tr>
581
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
582
+ </tr>
583
+ `).join('\n')
584
+ }
585
+ </tbody>
586
+ </table>
587
+ </div>
588
+ <p><br></p>
589
+ `,
590
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
591
+ );
592
+ });
593
+
594
+ it('insert column left and index is inside colspan cell', async () => {
595
+ const quill = createQuillWithTableModule(`<p><br></p>`);
596
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
597
+ tableModule.insertTable(2, 2);
598
+ await vi.runAllTimersAsync();
599
+ const table = quill.root.querySelector('table')!;
600
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
601
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
602
+ tableModule.tableSelection.selectedTds = [tds[2], tds[3]];
603
+ tableModule.mergeCells();
604
+ await vi.runAllTimersAsync();
605
+ tableModule.tableSelection.selectedTds = [tds[1]];
606
+ tableModule.appendCol(false);
607
+ await vi.runAllTimersAsync();
608
+ expect(quill.root).toEqualHTML(
609
+ `
610
+ <p><br></p>
611
+ <div>
612
+ <table cellpadding="0" cellspacing="0" data-full="true">
613
+ <colgroup data-full="true">
614
+ <col width="44%" data-full="true" />
615
+ <col width="6%" data-full="true" />
616
+ <col width="50%" data-full="true" />
617
+ </colgroup>
618
+ <tbody>
619
+ <tr>
620
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
621
+ </tr>
622
+ <tr>
623
+ <td rowspan="1" colspan="3">
624
+ <div>
625
+ <p><br></p>
626
+ <p><br></p>
627
+ </div>
628
+ </td>
629
+ </tr>
630
+ </tbody>
631
+ </table>
632
+ </div>
633
+ <p><br></p>
634
+ `,
635
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
636
+ );
637
+ });
638
+
639
+ it('insert column right', async () => {
640
+ const quill = createQuillWithTableModule(`<p><br></p>`);
641
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
642
+ tableModule.insertTable(2, 2);
643
+ await vi.runAllTimersAsync();
644
+ const table = quill.root.querySelector('table')!;
645
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
646
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
647
+ tableModule.tableSelection.selectedTds = [tds[1]];
648
+ tableModule.appendCol(true);
649
+ await vi.runAllTimersAsync();
650
+ expect(quill.root).toEqualHTML(
651
+ `
652
+ <p><br></p>
653
+ <div>
654
+ <table cellpadding="0" cellspacing="0" data-full="true">
655
+ <colgroup data-full="true">
656
+ <col width="44%" data-full="true" />
657
+ <col width="50%" data-full="true" />
658
+ <col width="6%" data-full="true" />
659
+ </colgroup>
660
+ <tbody>
661
+ ${
662
+ new Array(2).fill(0).map(() => `
663
+ <tr>
664
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
665
+ </tr>
666
+ `).join('\n')
667
+ }
668
+ </tbody>
669
+ </table>
670
+ </div>
671
+ <p><br></p>
672
+ `,
673
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
674
+ );
675
+ });
676
+
677
+ it('insert column right and index is inside colspan cell', async () => {
678
+ const quill = createQuillWithTableModule(`<p><br></p>`);
679
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
680
+ tableModule.insertTable(2, 2);
681
+ await vi.runAllTimersAsync();
682
+ const table = quill.root.querySelector('table')!;
683
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
684
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
685
+ tableModule.tableSelection.selectedTds = [tds[2], tds[3]];
686
+ tableModule.mergeCells();
687
+ await vi.runAllTimersAsync();
688
+ tableModule.tableSelection.selectedTds = [tds[0]];
689
+ tableModule.appendCol(true);
690
+ await vi.runAllTimersAsync();
691
+ expect(quill.root).toEqualHTML(
692
+ `
693
+ <p><br></p>
694
+ <div>
695
+ <table cellpadding="0" cellspacing="0" data-full="true">
696
+ <colgroup data-full="true">
697
+ <col width="44%" data-full="true" />
698
+ <col width="6%" data-full="true" />
699
+ <col width="50%" data-full="true" />
700
+ </colgroup>
701
+ <tbody>
702
+ <tr>
703
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
704
+ </tr>
705
+ <tr>
706
+ <td rowspan="1" colspan="3">
707
+ <div>
708
+ <p><br></p>
709
+ <p><br></p>
710
+ </div>
711
+ </td>
712
+ </tr>
713
+ </tbody>
714
+ </table>
715
+ </div>
716
+ <p><br></p>
717
+ `,
718
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
719
+ );
720
+ });
721
+
722
+ it('insert column with colspan cell', async () => {
723
+ const quill = createQuillWithTableModule(`<p><br></p>`);
724
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
725
+ tableModule.insertTable(2, 2);
726
+ await vi.runAllTimersAsync();
727
+ const table = quill.root.querySelector('table')!;
728
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
729
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
730
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1]];
731
+ tableModule.mergeCells();
732
+ await vi.runAllTimersAsync();
733
+ tableModule.tableSelection.selectedTds = [tds[0]];
734
+ tableModule.appendCol(true);
735
+ await vi.runAllTimersAsync();
736
+ expect(quill.root).toEqualHTML(
737
+ `
738
+ <p><br></p>
739
+ <div>
740
+ <table cellpadding="0" cellspacing="0" data-full="true">
741
+ <colgroup data-full="true">
742
+ <col width="44%" data-full="true" />
743
+ <col width="50%" data-full="true" />
744
+ <col width="6%" data-full="true" />
745
+ </colgroup>
746
+ <tbody>
747
+ <tr>
748
+ <td rowspan="1" colspan="2">
749
+ <div>
750
+ <p><br></p>
751
+ <p><br></p>
752
+ </div>
753
+ </td>
754
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
755
+ </tr>
756
+ <tr>
757
+ ${new Array(3).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
758
+ </tr>
759
+ </tbody>
760
+ </table>
761
+ </div>
762
+ <p><br></p>
763
+ `,
764
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
765
+ );
766
+ });
767
+
768
+ it('insert column with mutiple rowspan', async () => {
769
+ const quill = createQuillWithTableModule(`<p><br></p>`);
770
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
771
+ tableModule.insertTable(6, 3);
772
+ await vi.runAllTimersAsync();
773
+ const table = quill.root.querySelector('table')!;
774
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
775
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
776
+ tableModule.tableSelection.selectedTds = [tds[3], tds[4], tds[5], tds[6], tds[7], tds[8], tds[9], tds[10], tds[11]];
777
+ tableModule.mergeCells();
778
+ await vi.runAllTimersAsync();
779
+ tableModule.tableSelection.selectedTds = [tds[12], tds[13], tds[15], tds[16]];
780
+ tableModule.mergeCells();
781
+ await vi.runAllTimersAsync();
782
+ tableModule.tableSelection.selectedTds = [tds[0]];
783
+ tableModule.appendCol(true);
784
+ await vi.runAllTimersAsync();
785
+ expect(quill.root).toEqualHTML(
786
+ `
787
+ <p><br></p>
788
+ <div>
789
+ <table cellpadding="0" cellspacing="0" data-full="true">
790
+ <colgroup data-full="true">
791
+ <col width="${1 / 3 * 100 - 6}%" data-full="true" />
792
+ <col width="6%" data-full="true" />
793
+ <col width="${1 / 3 * 100}%" data-full="true" />
794
+ <col width="${1 / 3 * 100}%" data-full="true" />
795
+ </colgroup>
796
+ <tbody>
797
+ <tr>
798
+ ${new Array(4).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
799
+ </tr>
800
+ <tr>
801
+ <td rowspan="1" colspan="4">
802
+ <div>
803
+ <p><br></p>
804
+ <p><br></p>
805
+ <p><br></p>
806
+ <p><br></p>
807
+ <p><br></p>
808
+ <p><br></p>
809
+ <p><br></p>
810
+ <p><br></p>
811
+ <p><br></p>
812
+ </div>
813
+ </td>
814
+ </tr>
815
+ <tr>
816
+ <td rowspan="2" colspan="3">
817
+ <div>
818
+ <p><br></p>
819
+ <p><br></p>
820
+ <p><br></p>
821
+ <p><br></p>
822
+ </div>
823
+ </td>
824
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
825
+ </tr>
826
+ <tr>
827
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
828
+ </tr>
829
+ </tbody>
830
+ </table>
831
+ </div>
832
+ <p><br></p>
833
+ `,
834
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
835
+ );
836
+ });
837
+
838
+ it('insert column. `tr.insertCell` should find correct index and skip index', async () => {
839
+ const quill = createQuillWithTableModule(`<p><br></p>`);
840
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
841
+ tableModule.insertTable(4, 5);
842
+ await vi.runAllTimersAsync();
843
+ const table = quill.root.querySelector('table')!;
844
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
845
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
846
+ tableModule.tableSelection.selectedTds = [tds[2], tds[3], tds[4], tds[7], tds[8], tds[9], tds[12], tds[13], tds[14]];
847
+ tableModule.mergeCells();
848
+ await vi.runAllTimersAsync();
849
+ tableModule.tableSelection.selectedTds = [tds[1]];
850
+ tableModule.appendCol(true);
851
+ await vi.runAllTimersAsync();
852
+ expect(quill.root).toEqualHTML(
853
+ `
854
+ <p><br></p>
855
+ <div>
856
+ <table cellpadding="0" cellspacing="0" data-full="true">
857
+ <colgroup data-full="true">
858
+ <col width="14%" data-full="true" />
859
+ <col width="20%" data-full="true" />
860
+ <col width="6%" data-full="true" />
861
+ <col width="20%" data-full="true" />
862
+ <col width="20%" data-full="true" />
863
+ <col width="20%" data-full="true" />
864
+ </colgroup>
865
+ <tbody>
866
+ <tr>
867
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
868
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
869
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
870
+ <td rowspan="3" colspan="3">
871
+ <div>
872
+ <p><br></p>
873
+ <p><br></p>
874
+ <p><br></p>
875
+ <p><br></p>
876
+ <p><br></p>
877
+ <p><br></p>
878
+ <p><br></p>
879
+ <p><br></p>
880
+ <p><br></p>
881
+ </div>
882
+ </td>
883
+ </tr>
884
+ <tr>
885
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
886
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
887
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
888
+ </tr>
889
+ <tr>
890
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
891
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
892
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
893
+ </tr>
894
+ <tr>
895
+ ${new Array(6).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
896
+ </tr>
897
+ </tbody>
898
+ </table>
899
+ </div>
900
+ <p><br></p>
901
+ `,
902
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
903
+ );
904
+ });
905
+ });
906
+
907
+ describe('insert row into table', () => {
908
+ it('insert row top', async () => {
909
+ const quill = createQuillWithTableModule(`<p><br></p>`);
910
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
911
+ tableModule.insertTable(2, 2);
912
+ await vi.runAllTimersAsync();
913
+ const table = quill.root.querySelector('table')!;
914
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
915
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
916
+ tableModule.tableSelection.selectedTds = [tds[0]];
917
+ tableModule.appendRow(false);
918
+ await vi.runAllTimersAsync();
919
+ expect(quill.root).toEqualHTML(
920
+ `
921
+ <p><br></p>
922
+ <div>
923
+ <table cellpadding="0" cellspacing="0" data-full="true">
924
+ <colgroup data-full="true">
925
+ <col width="50%" data-full="true" />
926
+ <col width="50%" data-full="true" />
927
+ </colgroup>
928
+ <tbody>
929
+ ${
930
+ new Array(3).fill(0).map(() => `
931
+ <tr>
932
+ ${new Array(2).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
933
+ </tr>
934
+ `).join('\n')
935
+ }
936
+ </tbody>
937
+ </table>
938
+ </div>
939
+ <p><br></p>
940
+ `,
941
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
942
+ );
943
+ });
944
+
945
+ it('insert row top and index is inside rowspan cell', async () => {
946
+ const quill = createQuillWithTableModule(`<p><br></p>`);
947
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
948
+ tableModule.insertTable(3, 5);
949
+ await vi.runAllTimersAsync();
950
+ const table = quill.root.querySelector('table')!;
951
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
952
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
953
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[5], tds[6], tds[7]];
954
+ tableModule.mergeCells();
955
+ await vi.runAllTimersAsync();
956
+ tableModule.tableSelection.selectedTds = [tds[9], tds[14]];
957
+ tableModule.mergeCells();
958
+ await vi.runAllTimersAsync();
959
+ tableModule.tableSelection.selectedTds = [tds[8]];
960
+ tableModule.appendRow(false);
961
+ await vi.runAllTimersAsync();
962
+ expect(quill.root).toEqualHTML(
963
+ `
964
+ <p><br></p>
965
+ <div>
966
+ <table cellpadding="0" cellspacing="0" data-full="true">
967
+ <colgroup data-full="true">
968
+ ${new Array(5).fill(0).map(() => `<col width="20%" data-full="true" />`).join('\n')}
969
+ </colgroup>
970
+ <tbody>
971
+ <tr>
972
+ <td rowspan="3" colspan="3">
973
+ <div>
974
+ <p><br></p>
975
+ <p><br></p>
976
+ <p><br></p>
977
+ <p><br></p>
978
+ <p><br></p>
979
+ <p><br></p>
980
+ </div>
981
+ </td>
982
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
983
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
984
+ </tr>
985
+ <tr>
986
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
987
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
988
+ </tr>
989
+ <tr>
990
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
991
+ <td rowspan="2" colspan="1">
992
+ <div>
993
+ <p><br></p>
994
+ <p><br></p>
995
+ </div>
996
+ </td>
997
+ </tr>
998
+ <tr>
999
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1000
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1001
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1002
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1003
+ </tr>
1004
+ </tbody>
1005
+ </table>
1006
+ </div>
1007
+ <p><br></p>
1008
+ `,
1009
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1010
+ );
1011
+ });
1012
+
1013
+ it('insert row bottom', async () => {
1014
+ const quill = createQuillWithTableModule(`<p><br></p>`);
1015
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
1016
+ tableModule.insertTable(2, 2);
1017
+ await vi.runAllTimersAsync();
1018
+ const table = quill.root.querySelector('table')!;
1019
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1020
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
1021
+ tableModule.tableSelection.selectedTds = [tds[2]];
1022
+ tableModule.appendRow(true);
1023
+ await vi.runAllTimersAsync();
1024
+ expect(quill.root).toEqualHTML(
1025
+ `
1026
+ <p><br></p>
1027
+ <div>
1028
+ <table cellpadding="0" cellspacing="0" data-full="true">
1029
+ <colgroup data-full="true">
1030
+ <col width="50%" data-full="true" />
1031
+ <col width="50%" data-full="true" />
1032
+ </colgroup>
1033
+ <tbody>
1034
+ ${
1035
+ new Array(3).fill(0).map(() => `
1036
+ <tr>
1037
+ ${new Array(2).fill(0).map(() => `<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
1038
+ </tr>
1039
+ `).join('\n')
1040
+ }
1041
+ </tbody>
1042
+ </table>
1043
+ </div>
1044
+ <p><br></p>
1045
+ `,
1046
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1047
+ );
1048
+ });
1049
+
1050
+ it('insert row bottom and index is inside rowspan cell', async () => {
1051
+ const quill = createQuillWithTableModule(`<p><br></p>`);
1052
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
1053
+ tableModule.insertTable(2, 5);
1054
+ await vi.runAllTimersAsync();
1055
+ const table = quill.root.querySelector('table')!;
1056
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1057
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
1058
+ tableModule.tableSelection.selectedTds = [tds[1], tds[2], tds[3], tds[6], tds[7], tds[8]];
1059
+ tableModule.mergeCells();
1060
+ await vi.runAllTimersAsync();
1061
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1062
+ tableModule.tableSelection.selectedTds = [tds[0]];
1063
+ tableModule.appendRow(true);
1064
+ await vi.runAllTimersAsync();
1065
+ expect(quill.root).toEqualHTML(
1066
+ `
1067
+ <p><br></p>
1068
+ <div>
1069
+ <table cellpadding="0" cellspacing="0" data-full="true">
1070
+ <colgroup data-full="true">
1071
+ <col width="20%" data-full="true" />
1072
+ <col width="60%" data-full="true" />
1073
+ <col width="20%" data-full="true" />
1074
+ </colgroup>
1075
+ <tbody>
1076
+ <tr>
1077
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1078
+ <td rowspan="3" colspan="1">
1079
+ <div>
1080
+ <p><br></p>
1081
+ <p><br></p>
1082
+ <p><br></p>
1083
+ <p><br></p>
1084
+ <p><br></p>
1085
+ <p><br></p>
1086
+ </div>
1087
+ </td>
1088
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1089
+ </tr>
1090
+ <tr>
1091
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1092
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1093
+ </tr>
1094
+ <tr>
1095
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1096
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1097
+ </tr>
1098
+ </tbody>
1099
+ </table>
1100
+ </div>
1101
+ <p><br></p>
1102
+ `,
1103
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1104
+ );
1105
+ });
1106
+ });
1107
+
1108
+ describe('unusual delete', () => {
1109
+ it('delete head from outside table to inside', async () => {
1110
+ const quill = createQuillWithTableModule(`<p><br></p>`);
1111
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
1112
+ tableModule.insertTable(5, 5);
1113
+ await vi.runAllTimersAsync();
1114
+ const table = quill.root.querySelector('table')!;
1115
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1116
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
1117
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[5], tds[6], tds[7], tds[10], tds[11], tds[12]];
1118
+ tableModule.mergeCells();
1119
+ await vi.runAllTimersAsync();
1120
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1121
+ tableModule.tableSelection.selectedTds = [tds[4], tds[9], tds[14], tds[19]];
1122
+ tableModule.mergeCells();
1123
+ await vi.runAllTimersAsync();
1124
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1125
+ tableModule.tableSelection.selectedTds = [tds[17], tds[18], tds[22], tds[23]];
1126
+ tableModule.mergeCells();
1127
+ await vi.runAllTimersAsync();
1128
+ quill.deleteText(0, 16);
1129
+ await vi.runAllTimersAsync();
1130
+ expect(quill.root).toEqualHTML(
1131
+ `<p><br></p>`,
1132
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1133
+ );
1134
+ });
1135
+
1136
+ it('delete tail from inside table to outside', async () => {
1137
+ const quill = createQuillWithTableModule(`<p><br></p>`);
1138
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
1139
+ tableModule.insertTable(5, 5);
1140
+ await vi.runAllTimersAsync();
1141
+ const table = quill.root.querySelector('table')!;
1142
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1143
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
1144
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[5], tds[6], tds[7], tds[10], tds[11], tds[12]];
1145
+ tableModule.mergeCells();
1146
+ await vi.runAllTimersAsync();
1147
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1148
+ tableModule.tableSelection.selectedTds = [tds[4], tds[9], tds[14], tds[19]];
1149
+ tableModule.mergeCells();
1150
+ await vi.runAllTimersAsync();
1151
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1152
+ tableModule.tableSelection.selectedTds = [tds[17], tds[18], tds[22], tds[23]];
1153
+ tableModule.mergeCells();
1154
+ await vi.runAllTimersAsync();
1155
+ quill.deleteText(18, 8);
1156
+ await vi.runAllTimersAsync();
1157
+ expect(quill.root).toEqualHTML(
1158
+ `
1159
+ <p><br></p>
1160
+ <div>
1161
+ <table cellpadding="0" cellspacing="0" data-full="true">
1162
+ <colgroup data-full="true">
1163
+ ${new Array(5).fill(`<col width="20%" data-full="true" />`).join('\n')}
1164
+ </colgroup>
1165
+ <tbody>
1166
+ <tr>
1167
+ <td rowspan="3" colspan="3">
1168
+ <div>
1169
+ <p><br></p>
1170
+ <p><br></p>
1171
+ <p><br></p>
1172
+ <p><br></p>
1173
+ <p><br></p>
1174
+ <p><br></p>
1175
+ <p><br></p>
1176
+ <p><br></p>
1177
+ <p><br></p>
1178
+ </div>
1179
+ </td>
1180
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1181
+ <td rowspan="3" colspan="1">
1182
+ <div>
1183
+ <p><br></p>
1184
+ <p><br></p>
1185
+ </div>
1186
+ </td>
1187
+ </tr>
1188
+ <tr>
1189
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1190
+ </tr>
1191
+ <tr>
1192
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1193
+ </tr>
1194
+ </tbody>
1195
+ </table>
1196
+ </div>
1197
+ <p><br></p>
1198
+ `,
1199
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1200
+ );
1201
+ });
1202
+
1203
+ it('delete table inside cell', async () => {
1204
+ const quill = createQuillWithTableModule(`<p><br></p>`);
1205
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
1206
+ tableModule.insertTable(5, 5);
1207
+ await vi.runAllTimersAsync();
1208
+ const table = quill.root.querySelector('table')!;
1209
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1210
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
1211
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[5], tds[6], tds[7], tds[10], tds[11], tds[12]];
1212
+ tableModule.mergeCells();
1213
+ await vi.runAllTimersAsync();
1214
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1215
+ tableModule.tableSelection.selectedTds = [tds[4], tds[9], tds[14], tds[19]];
1216
+ tableModule.mergeCells();
1217
+ await vi.runAllTimersAsync();
1218
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
1219
+ tableModule.tableSelection.selectedTds = [tds[17], tds[18], tds[22], tds[23]];
1220
+ tableModule.mergeCells();
1221
+ await vi.runAllTimersAsync();
1222
+ quill.deleteText(21, 3);
1223
+ await vi.runAllTimersAsync();
1224
+ expect(quill.root).toEqualHTML(
1225
+ `
1226
+ <p><br></p>
1227
+ <div>
1228
+ <table cellpadding="0" cellspacing="0" data-full="true">
1229
+ <colgroup data-full="true">
1230
+ ${new Array(5).fill(`<col width="20%" data-full="true" />`).join('\n')}
1231
+ </colgroup>
1232
+ <tbody>
1233
+ <tr>
1234
+ <td rowspan="3" colspan="3">
1235
+ <div>
1236
+ <p><br></p>
1237
+ <p><br></p>
1238
+ <p><br></p>
1239
+ <p><br></p>
1240
+ <p><br></p>
1241
+ <p><br></p>
1242
+ <p><br></p>
1243
+ <p><br></p>
1244
+ <p><br></p>
1245
+ </div>
1246
+ </td>
1247
+ <td rowspan="1" colspan="1"><div><p><br></p></div></td>
1248
+ <td rowspan="4" colspan="1">
1249
+ <div>
1250
+ <p><br></p>
1251
+ <p><br></p>
1252
+ <p><br></p>
1253
+ <p><br></p>
1254
+ </div>
1255
+ </td>
1256
+ </tr>
1257
+ <tr><td rowspan="1" colspan="1"><div><p><br></p></div></td></tr>
1258
+ <tr><td rowspan="1" colspan="1"><div><p><br></p></div></td></tr>
1259
+ <tr>
1260
+ ${new Array(4).fill(`<td rowspan="1" colspan="1"><div><p><br></p></div></td>`).join('\n')}
1261
+ </tr>
1262
+ </tbody>
1263
+ </table>
1264
+ </div>
1265
+ <p><br></p>
1266
+ `,
1267
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'data-row-id', 'data-col-id', 'data-rowspan', 'data-colspan', 'contenteditable'] },
1268
+ );
1269
+ });
1270
+ });