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,715 @@
1
+ import Quill from 'quill';
2
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
+ import TableUp, { updateTableConstants } from '../..';
4
+ import { TableBodyFormat, TableCellFormat, TableCellInnerFormat, TableColFormat, TableMainFormat, TableRowFormat, TableWrapperFormat } from '../../formats';
5
+ import { TableSelection } from '../../modules';
6
+ import { blotName, findParentBlot, findParentBlots } from '../../utils';
7
+ import { createTable, createTableHTML, createTaleColHTML, datasetFull, getColWidthStyle, normalizeHTML } from './utils';
8
+
9
+ beforeEach(() => {
10
+ vi.useFakeTimers();
11
+ });
12
+ afterEach(() => {
13
+ vi.useRealTimers();
14
+ });
15
+
16
+ const createOverridesTable = (html: string, options = true, moduleOptions = {}, register = {}) => {
17
+ updateTableConstants({
18
+ blotName: {
19
+ tableCol: 'a-col',
20
+ tableCell: 'a-cell',
21
+ tableCellInner: 'a-cell-inner',
22
+ },
23
+ });
24
+
25
+ // rename `colId` to `column`
26
+ class TableColFormatOverride extends TableColFormat {
27
+ static create(value: any) {
28
+ const { colId, column } = value;
29
+ const node = super.create(value);
30
+ node.dataset.colId = column || colId;
31
+ node.setAttribute('contenteditable', 'false');
32
+ return node;
33
+ }
34
+
35
+ static value(domNode: HTMLElement) {
36
+ const value = super.value(domNode);
37
+ value.column = value.colId;
38
+ delete value.colId;
39
+ return value;
40
+ }
41
+ }
42
+ // rename `rowId` to `row`, `colId` to `cell`
43
+ class TableCellFormatOverride extends TableCellFormat {
44
+ static allowDataAttrs = new Set(['table-id', 'row', 'cell']);
45
+ static create(value: any) {
46
+ const node = super.create(value);
47
+ let { rowId, colId, row, cell } = value;
48
+ row = row || rowId;
49
+ cell = cell || colId;
50
+ node.dataset.row = row;
51
+ node.dataset.cell = cell;
52
+ node.removeAttribute('data-row-id');
53
+ node.removeAttribute('data-col-id');
54
+ return node;
55
+ }
56
+
57
+ static formats(domNode: HTMLElement) {
58
+ const value = super.formats(domNode);
59
+ const { row, cell } = domNode.dataset;
60
+ value.row = row;
61
+ value.cell = cell;
62
+ delete value.rowId;
63
+ delete value.colId;
64
+ return value;
65
+ }
66
+
67
+ get rowId() {
68
+ return this.domNode.dataset.row!;
69
+ }
70
+
71
+ get colId() {
72
+ return this.domNode.dataset.cell!;
73
+ }
74
+ }
75
+ class TableCellInnerFormatOverride extends TableCellInnerFormat {
76
+ static allowDataAttrs = new Set(['table-id', 'row', 'cell', 'rowspan', 'colspan']);
77
+ static create(value: any) {
78
+ const node = super.create(value);
79
+ let { rowId, colId, row, cell } = value;
80
+ row = row || rowId;
81
+ cell = cell || colId;
82
+ node.dataset.row = row;
83
+ node.dataset.cell = cell;
84
+ node.removeAttribute('data-row-id');
85
+ node.removeAttribute('data-col-id');
86
+ return node;
87
+ }
88
+
89
+ static formats(domNode: HTMLElement) {
90
+ const value = super.formats(domNode);
91
+ const { row, cell } = domNode.dataset;
92
+ value.row = row;
93
+ value.cell = cell;
94
+ delete value.rowId;
95
+ delete value.colId;
96
+ return value;
97
+ }
98
+
99
+ get rowId() {
100
+ return this.domNode.dataset.row!;
101
+ }
102
+
103
+ set rowId(value) {
104
+ this.setFormatValue('row', value);
105
+ }
106
+
107
+ get colId() {
108
+ return this.domNode.dataset.cell!;
109
+ }
110
+
111
+ set colId(value) {
112
+ this.setFormatValue('cell', value);
113
+ }
114
+ }
115
+ class TableUpOverride extends TableUp {
116
+ static register(): void {
117
+ super.register();
118
+ Quill.register({
119
+ 'formats/a-col': TableColFormatOverride,
120
+ 'formats/a-cell': TableCellFormatOverride,
121
+ 'formats/a-cell-inner': TableCellInnerFormatOverride,
122
+ }, true);
123
+ }
124
+ }
125
+ Quill.register({
126
+ 'modules/tableUpOverride': TableUpOverride,
127
+ ...register,
128
+ }, true);
129
+ const container = document.body.appendChild(document.createElement('div'));
130
+ container.innerHTML = normalizeHTML(html);
131
+ const quill = new Quill(container, {
132
+ modules: {
133
+ tableUpOverride: options,
134
+ history: {
135
+ delay: 0,
136
+ },
137
+ ...moduleOptions,
138
+ },
139
+ });
140
+ return quill;
141
+ };
142
+
143
+ describe('test utils', () => {
144
+ it('test findParentBlot', async () => {
145
+ const quill = await createTable(1, 1);
146
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
147
+ const tableCellBlot = findParentBlot(tds[0], blotName.tableCell);
148
+ expect(tableCellBlot).toBeInstanceOf(TableCellFormat);
149
+ const tableRowBlot = findParentBlot(tds[0], blotName.tableRow);
150
+ expect(tableRowBlot).toBeInstanceOf(TableRowFormat);
151
+ const tableBodyBlot = findParentBlot(tds[0], blotName.tableBody);
152
+ expect(tableBodyBlot).toBeInstanceOf(TableBodyFormat);
153
+ const tableMainBlot = findParentBlot(tds[0], blotName.tableMain);
154
+ expect(tableMainBlot).toBeInstanceOf(TableMainFormat);
155
+ const tableWrapperBlot = findParentBlot(tds[0], blotName.tableWrapper);
156
+ expect(tableWrapperBlot).toBeInstanceOf(TableWrapperFormat);
157
+ expect(() => findParentBlot(tds[0], 'scroll')).toThrowError(`${blotName.tableCellInner} must be a child of scroll`);
158
+ });
159
+
160
+ it('test findParentBlots', async () => {
161
+ const quill = await createTable(1, 1);
162
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
163
+ const [tableCellBlot, tableRowBlot, tableBodyBlot, tableMainBlot, tableWrapperBlot] = findParentBlots(
164
+ tds[0],
165
+ [
166
+ blotName.tableCell,
167
+ blotName.tableRow,
168
+ blotName.tableBody,
169
+ blotName.tableMain,
170
+ blotName.tableWrapper,
171
+ ] as const,
172
+ );
173
+ expect(tableCellBlot).toBeInstanceOf(TableCellFormat);
174
+ expect(tableRowBlot).toBeInstanceOf(TableRowFormat);
175
+ expect(tableBodyBlot).toBeInstanceOf(TableBodyFormat);
176
+ expect(tableMainBlot).toBeInstanceOf(TableMainFormat);
177
+ expect(tableWrapperBlot).toBeInstanceOf(TableWrapperFormat);
178
+ });
179
+ });
180
+
181
+ // this test need be last. it's effect `blotName`
182
+ describe('test override format', () => {
183
+ it('should change blotName', async () => {
184
+ updateTableConstants({
185
+ blotName: {
186
+ tableCol: 'a-col',
187
+ tableCellInner: 'a-cell-inner',
188
+ },
189
+ });
190
+ const quill = await createTable(2, 2);
191
+ expect(quill.getContents()).toMatchObject({
192
+ ops: [
193
+ {
194
+ insert: '\n',
195
+ },
196
+ {
197
+ insert: {
198
+ 'a-col': {
199
+ tableId: '1',
200
+ colId: '1',
201
+ full: true,
202
+ width: 50,
203
+ },
204
+ },
205
+ },
206
+ {
207
+ insert: {
208
+ 'a-col': {
209
+ tableId: '1',
210
+ colId: '2',
211
+ full: true,
212
+ width: 50,
213
+ },
214
+ },
215
+ },
216
+ {
217
+ insert: '1',
218
+ },
219
+ {
220
+ attributes: {
221
+ 'a-cell-inner': {
222
+ tableId: '1',
223
+ colId: '1',
224
+ rowId: '1',
225
+ rowspan: 1,
226
+ colspan: 1,
227
+ },
228
+ },
229
+ insert: '\n',
230
+ },
231
+ {
232
+ insert: '2',
233
+ },
234
+ {
235
+ attributes: {
236
+ 'a-cell-inner': {
237
+ tableId: '1',
238
+ colId: '2',
239
+ rowId: '1',
240
+ rowspan: 1,
241
+ colspan: 1,
242
+ },
243
+ },
244
+ insert: '\n',
245
+ },
246
+ {
247
+ insert: '3',
248
+ },
249
+ {
250
+ attributes: {
251
+ 'a-cell-inner': {
252
+ tableId: '1',
253
+ colId: '1',
254
+ rowId: '2',
255
+ rowspan: 1,
256
+ colspan: 1,
257
+ },
258
+ },
259
+ insert: '\n',
260
+ },
261
+ {
262
+ insert: '4',
263
+ },
264
+ {
265
+ attributes: {
266
+ 'a-cell-inner': {
267
+ tableId: '1',
268
+ colId: '2',
269
+ rowId: '2',
270
+ rowspan: 1,
271
+ colspan: 1,
272
+ },
273
+ },
274
+ insert: '\n',
275
+ },
276
+ {
277
+ insert: '\n',
278
+ },
279
+ ],
280
+ });
281
+ expect(quill.root).toEqualHTML(
282
+ `
283
+ <p><br></p>
284
+ ${createTableHTML(2, 2)}
285
+ <p><br></p>
286
+ `,
287
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'contenteditable'] },
288
+ );
289
+ const tableModule = quill.getModule(TableUp.moduleName) as TableUp;
290
+ const table = quill.root.querySelector('table')!;
291
+ tableModule.tableSelection = new TableSelection(tableModule, table, quill);
292
+ const tds = quill.scroll.descendants(TableCellInnerFormat, 0);
293
+ tableModule.tableSelection.selectedTds = [tds[0], tds[1], tds[2], tds[3]];
294
+ tableModule.mergeCells();
295
+ await vi.runAllTimersAsync();
296
+ expect(quill.getContents()).toMatchObject({
297
+ ops: [
298
+ {
299
+ insert: '\n',
300
+ },
301
+ {
302
+ insert: {
303
+ 'a-col': {
304
+ tableId: '1',
305
+ colId: '1',
306
+ full: true,
307
+ width: 100,
308
+ },
309
+ },
310
+ },
311
+ {
312
+ insert: '1',
313
+ },
314
+ {
315
+ attributes: {
316
+ 'a-cell-inner': {
317
+ tableId: '1',
318
+ colId: '1',
319
+ rowId: '1',
320
+ rowspan: 1,
321
+ colspan: 1,
322
+ },
323
+ },
324
+ insert: '\n',
325
+ },
326
+ {
327
+ insert: '2',
328
+ },
329
+ {
330
+ attributes: {
331
+ 'a-cell-inner': {
332
+ tableId: '1',
333
+ colId: '1',
334
+ rowId: '1',
335
+ rowspan: 1,
336
+ colspan: 1,
337
+ },
338
+ },
339
+ insert: '\n',
340
+ },
341
+ {
342
+ insert: '3',
343
+ },
344
+ {
345
+ attributes: {
346
+ 'a-cell-inner': {
347
+ tableId: '1',
348
+ colId: '1',
349
+ rowId: '1',
350
+ rowspan: 1,
351
+ colspan: 1,
352
+ },
353
+ },
354
+ insert: '\n',
355
+ },
356
+ {
357
+ insert: '4',
358
+ },
359
+ {
360
+ attributes: {
361
+ 'a-cell-inner': {
362
+ tableId: '1',
363
+ colId: '1',
364
+ rowId: '1',
365
+ rowspan: 1,
366
+ colspan: 1,
367
+ },
368
+ },
369
+ insert: '\n',
370
+ },
371
+ {
372
+ insert: '\n',
373
+ },
374
+ ],
375
+ });
376
+ expect(quill.root).toEqualHTML(
377
+ `
378
+ <p><br></p>
379
+ <div>
380
+ <table cellpadding="0" cellspacing="0" data-full="true">
381
+ ${createTaleColHTML(1)}
382
+ <tbody>
383
+ <tr data-row-id="1">
384
+ <td rowspan="1" colspan="1" data-row-id="1" data-col-id="1">
385
+ <div data-rowspan="1" data-colspan="1" data-row-id="1" data-col-id="1">
386
+ <p>1</p>
387
+ <p>2</p>
388
+ <p>3</p>
389
+ <p>4</p>
390
+ </div>
391
+ </td>
392
+ </tr>
393
+ </tbody>
394
+ </table>
395
+ </div>
396
+ <p><br></p>
397
+ `,
398
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'contenteditable'] },
399
+ );
400
+ });
401
+
402
+ it('should change format name in delta', async () => {
403
+ const quill = createOverridesTable(`<p><br></p>`);
404
+ quill.setContents([
405
+ { insert: '\n' },
406
+ {
407
+ insert: {
408
+ 'a-col': { tableId: '1', column: '1', full: true, width: 50 },
409
+ },
410
+ },
411
+ {
412
+ insert: {
413
+ 'a-col': { tableId: '1', column: '2', full: true, width: 50 },
414
+ },
415
+ },
416
+ {
417
+ attributes: {
418
+ 'a-cell-inner': { tableId: '1', row: '1', cell: '1', rowspan: 1, colspan: 1 },
419
+ },
420
+ insert: '\n',
421
+ },
422
+ {
423
+ attributes: {
424
+ 'a-cell-inner': { tableId: '1', row: '1', cell: '2', rowspan: 1, colspan: 1 },
425
+ },
426
+ insert: '\n',
427
+ },
428
+ {
429
+ attributes: {
430
+ 'a-cell-inner': { tableId: '1', row: '2', cell: '1', rowspan: 1, colspan: 1 },
431
+ },
432
+ insert: '\n',
433
+ },
434
+ {
435
+ attributes: {
436
+ 'a-cell-inner': { tableId: '1', row: '2', cell: '2', rowspan: 1, colspan: 1 },
437
+ },
438
+ insert: '\n',
439
+ },
440
+ { insert: '\n' },
441
+ ]);
442
+ await vi.runAllTimersAsync();
443
+ expect(quill.getContents()).toMatchObject({
444
+ ops: [
445
+ {
446
+ insert: '\n',
447
+ },
448
+ {
449
+ insert: {
450
+ 'a-col': {
451
+ tableId: '1',
452
+ column: '1',
453
+ full: true,
454
+ width: 50,
455
+ },
456
+ },
457
+ },
458
+ {
459
+ insert: {
460
+ 'a-col': {
461
+ tableId: '1',
462
+ column: '2',
463
+ full: true,
464
+ width: 50,
465
+ },
466
+ },
467
+ },
468
+ {
469
+ attributes: {
470
+ 'a-cell-inner': {
471
+ tableId: '1',
472
+ cell: '1',
473
+ row: '1',
474
+ rowspan: 1,
475
+ colspan: 1,
476
+ },
477
+ },
478
+ insert: '\n',
479
+ },
480
+ {
481
+ attributes: {
482
+ 'a-cell-inner': {
483
+ tableId: '1',
484
+ cell: '2',
485
+ row: '1',
486
+ rowspan: 1,
487
+ colspan: 1,
488
+ },
489
+ },
490
+ insert: '\n',
491
+ },
492
+ {
493
+ attributes: {
494
+ 'a-cell-inner': {
495
+ tableId: '1',
496
+ cell: '1',
497
+ row: '2',
498
+ rowspan: 1,
499
+ colspan: 1,
500
+ },
501
+ },
502
+ insert: '\n',
503
+ },
504
+ {
505
+ attributes: {
506
+ 'a-cell-inner': {
507
+ tableId: '1',
508
+ cell: '2',
509
+ row: '2',
510
+ rowspan: 1,
511
+ colspan: 1,
512
+ },
513
+ },
514
+ insert: '\n',
515
+ },
516
+ {
517
+ insert: '\n',
518
+ },
519
+ ],
520
+ });
521
+ const colWidth = getColWidthStyle({ full: true, colNum: 2 });
522
+ expect(quill.root).toEqualHTML(
523
+ `
524
+ <p><br></p>
525
+ <div>
526
+ <table cellpadding="0" cellspacing="0"${datasetFull(true)}>
527
+ <colgroup${datasetFull(true)}>
528
+ ${new Array(2).fill(0).map((_, i) => `<col ${colWidth} data-col-id="${i + 1}"${datasetFull(true)} />`).join('\n')}
529
+ </colgroup>
530
+ <tbody>
531
+ ${
532
+ new Array(2).fill(0).map((_, i) => `
533
+ <tr data-row-id="${i + 1}">
534
+ ${
535
+ new Array(2).fill(0).map((_, j) => `<td rowspan="1" colspan="1" data-row="${i + 1}" data-cell="${j + 1}">
536
+ <div data-rowspan="1" data-colspan="1" data-row="${i + 1}" data-cell="${j + 1}">
537
+ <p>
538
+ <br>
539
+ </p>
540
+ </div>
541
+ </td>`).join('\n')
542
+ }
543
+ </tr>
544
+ `).join('\n')
545
+ }
546
+ </tbody>
547
+ </table>
548
+ </div>
549
+ <p><br></p>
550
+ `,
551
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'contenteditable'] },
552
+ );
553
+ });
554
+
555
+ it('should change format name in delta with contents', async () => {
556
+ const quill = createOverridesTable(`<p><br></p>`);
557
+ quill.setContents([
558
+ { insert: '\n' },
559
+ {
560
+ insert: {
561
+ 'a-col': { tableId: '1', column: '1', full: true, width: 50 },
562
+ },
563
+ },
564
+ {
565
+ insert: {
566
+ 'a-col': { tableId: '1', column: '2', full: true, width: 50 },
567
+ },
568
+ },
569
+ { insert: '1' },
570
+ {
571
+ attributes: {
572
+ 'a-cell-inner': { tableId: '1', row: '1', cell: '1', rowspan: 1, colspan: 1 },
573
+ },
574
+ insert: '\n',
575
+ },
576
+ { insert: '2' },
577
+ {
578
+ attributes: {
579
+ 'a-cell-inner': { tableId: '1', row: '1', cell: '2', rowspan: 1, colspan: 1 },
580
+ },
581
+ insert: '\n',
582
+ },
583
+ { insert: '3' },
584
+ {
585
+ attributes: {
586
+ 'a-cell-inner': { tableId: '1', row: '2', cell: '1', rowspan: 1, colspan: 1 },
587
+ },
588
+ insert: '\n',
589
+ },
590
+ { insert: '4' },
591
+ {
592
+ attributes: {
593
+ 'a-cell-inner': { tableId: '1', row: '2', cell: '2', rowspan: 1, colspan: 1 },
594
+ },
595
+ insert: '\n',
596
+ },
597
+ { insert: '\n' },
598
+ ]);
599
+ await vi.runAllTimersAsync();
600
+ expect(quill.getContents()).toMatchObject({
601
+ ops: [
602
+ {
603
+ insert: '\n',
604
+ },
605
+ {
606
+ insert: {
607
+ 'a-col': {
608
+ tableId: '1',
609
+ column: '1',
610
+ full: true,
611
+ width: 50,
612
+ },
613
+ },
614
+ },
615
+ {
616
+ insert: {
617
+ 'a-col': {
618
+ tableId: '1',
619
+ column: '2',
620
+ full: true,
621
+ width: 50,
622
+ },
623
+ },
624
+ },
625
+ { insert: '1' },
626
+ {
627
+ attributes: {
628
+ 'a-cell-inner': {
629
+ tableId: '1',
630
+ cell: '1',
631
+ row: '1',
632
+ rowspan: 1,
633
+ colspan: 1,
634
+ },
635
+ },
636
+ insert: '\n',
637
+ },
638
+ { insert: '2' },
639
+ {
640
+ attributes: {
641
+ 'a-cell-inner': {
642
+ tableId: '1',
643
+ cell: '2',
644
+ row: '1',
645
+ rowspan: 1,
646
+ colspan: 1,
647
+ },
648
+ },
649
+ insert: '\n',
650
+ },
651
+ { insert: '3' },
652
+ {
653
+ attributes: {
654
+ 'a-cell-inner': {
655
+ tableId: '1',
656
+ cell: '1',
657
+ row: '2',
658
+ rowspan: 1,
659
+ colspan: 1,
660
+ },
661
+ },
662
+ insert: '\n',
663
+ },
664
+ { insert: '4' },
665
+ {
666
+ attributes: {
667
+ 'a-cell-inner': {
668
+ tableId: '1',
669
+ cell: '2',
670
+ row: '2',
671
+ rowspan: 1,
672
+ colspan: 1,
673
+ },
674
+ },
675
+ insert: '\n',
676
+ },
677
+ {
678
+ insert: '\n',
679
+ },
680
+ ],
681
+ });
682
+ const colWidth = getColWidthStyle({ full: true, colNum: 2 });
683
+ expect(quill.root).toEqualHTML(
684
+ `
685
+ <p><br></p>
686
+ <div>
687
+ <table cellpadding="0" cellspacing="0"${datasetFull(true)}>
688
+ <colgroup${datasetFull(true)}>
689
+ ${new Array(2).fill(0).map((_, i) => `<col ${colWidth} data-col-id="${i + 1}"${datasetFull(true)} />`).join('\n')}
690
+ </colgroup>
691
+ <tbody>
692
+ ${
693
+ new Array(2).fill(0).map((_, i) => `
694
+ <tr data-row-id="${i + 1}">
695
+ ${
696
+ new Array(2).fill(0).map((_, j) => `<td rowspan="1" colspan="1" data-row="${i + 1}" data-cell="${j + 1}">
697
+ <div data-rowspan="1" data-colspan="1" data-row="${i + 1}" data-cell="${j + 1}">
698
+ <p>
699
+ ${i * 2 + j + 1}
700
+ </p>
701
+ </div>
702
+ </td>`).join('\n')
703
+ }
704
+ </tr>
705
+ `).join('\n')
706
+ }
707
+ </tbody>
708
+ </table>
709
+ </div>
710
+ <p><br></p>
711
+ `,
712
+ { ignoreAttrs: ['class', 'style', 'data-table-id', 'contenteditable'] },
713
+ );
714
+ });
715
+ });