@atlaskit/editor-plugin-table 7.2.1 → 7.2.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 (124) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/nodeviews/TableComponent.js +11 -7
  3. package/dist/cjs/pm-plugins/drag-and-drop/commands-with-analytics.js +3 -19
  4. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +11 -25
  5. package/dist/cjs/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +13 -3
  6. package/dist/cjs/ui/TableFloatingColumnControls/index.js +7 -3
  7. package/dist/cjs/utils/drag-menu.js +37 -23
  8. package/dist/cjs/utils/merged-cells.js +66 -1
  9. package/dist/es2019/nodeviews/TableComponent.js +9 -5
  10. package/dist/es2019/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
  11. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -21
  12. package/dist/es2019/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +10 -2
  13. package/dist/es2019/ui/TableFloatingColumnControls/index.js +7 -3
  14. package/dist/es2019/utils/drag-menu.js +38 -14
  15. package/dist/es2019/utils/merged-cells.js +73 -0
  16. package/dist/esm/nodeviews/TableComponent.js +11 -7
  17. package/dist/esm/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
  18. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +7 -21
  19. package/dist/esm/ui/TableFloatingColumnControls/ColumnDropTargets/index.js +10 -2
  20. package/dist/esm/ui/TableFloatingColumnControls/index.js +7 -3
  21. package/dist/esm/utils/drag-menu.js +36 -22
  22. package/dist/esm/utils/merged-cells.js +65 -0
  23. package/dist/types/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  24. package/dist/types/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -0
  25. package/dist/types/ui/TableFloatingColumnControls/index.d.ts +1 -0
  26. package/dist/types/utils/drag-menu.d.ts +4 -1
  27. package/dist/types/utils/merged-cells.d.ts +2 -0
  28. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnControls/index.d.ts +2 -1
  29. package/dist/types-ts4.5/ui/TableFloatingColumnControls/ColumnDropTargets/index.d.ts +2 -0
  30. package/dist/types-ts4.5/ui/TableFloatingColumnControls/index.d.ts +1 -0
  31. package/dist/types-ts4.5/utils/drag-menu.d.ts +4 -1
  32. package/dist/types-ts4.5/utils/merged-cells.d.ts +2 -0
  33. package/package.json +9 -16
  34. package/src/nodeviews/TableComponent.tsx +1 -0
  35. package/src/pm-plugins/drag-and-drop/commands-with-analytics.ts +11 -32
  36. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +6 -27
  37. package/src/ui/TableFloatingColumnControls/ColumnDropTargets/index.tsx +12 -1
  38. package/src/ui/TableFloatingColumnControls/index.tsx +5 -0
  39. package/src/utils/drag-menu.ts +94 -20
  40. package/src/utils/merged-cells.ts +78 -0
  41. package/tsconfig.dev.json +0 -69
  42. package/tsconfig.json +2 -871
  43. package/examples/99-testing.tsx +0 -140
  44. package/examples/config.jsonc +0 -14
  45. package/src/__tests__/unit/analytics.ts +0 -888
  46. package/src/__tests__/unit/collab.ts +0 -93
  47. package/src/__tests__/unit/commands/go-to-next-cell.ts +0 -173
  48. package/src/__tests__/unit/commands/insert.ts +0 -137
  49. package/src/__tests__/unit/commands/misc.ts +0 -185
  50. package/src/__tests__/unit/commands/sort.ts +0 -128
  51. package/src/__tests__/unit/commands.ts +0 -745
  52. package/src/__tests__/unit/copy-button.ts +0 -22
  53. package/src/__tests__/unit/copy-paste.ts +0 -677
  54. package/src/__tests__/unit/event-handlers/index.ts +0 -125
  55. package/src/__tests__/unit/event-handlers.ts +0 -296
  56. package/src/__tests__/unit/fix-tables.ts +0 -164
  57. package/src/__tests__/unit/get-toolbar-config.ts +0 -127
  58. package/src/__tests__/unit/handlers.ts +0 -98
  59. package/src/__tests__/unit/hover-selection.ts +0 -230
  60. package/src/__tests__/unit/index-with-fake-timers.ts +0 -111
  61. package/src/__tests__/unit/index.ts +0 -912
  62. package/src/__tests__/unit/layout.ts +0 -146
  63. package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +0 -162
  64. package/src/__tests__/unit/nodeviews/TableComponent.tsx +0 -280
  65. package/src/__tests__/unit/nodeviews/TableContainer.tsx +0 -525
  66. package/src/__tests__/unit/nodeviews/cell.ts +0 -132
  67. package/src/__tests__/unit/nodeviews/table.ts +0 -129
  68. package/src/__tests__/unit/pm-plugins/analytics.ts +0 -327
  69. package/src/__tests__/unit/pm-plugins/decorations/column-controls.ts +0 -94
  70. package/src/__tests__/unit/pm-plugins/decorations/column-resizing.ts +0 -176
  71. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +0 -211
  72. package/src/__tests__/unit/pm-plugins/main.ts +0 -214
  73. package/src/__tests__/unit/pm-plugins/safari-delete-composition-text-issue-workaround.ts +0 -101
  74. package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +0 -562
  75. package/src/__tests__/unit/pm-plugins/table-local-id.ts +0 -507
  76. package/src/__tests__/unit/pm-plugins/table-resizing/colgroup.ts +0 -269
  77. package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +0 -192
  78. package/src/__tests__/unit/pm-plugins/table-resizing/utils/resize-state.ts +0 -33
  79. package/src/__tests__/unit/pm-plugins/table-width.ts +0 -292
  80. package/src/__tests__/unit/sort-column.ts +0 -399
  81. package/src/__tests__/unit/toolbar.ts +0 -512
  82. package/src/__tests__/unit/transforms/delete-columns.ts +0 -597
  83. package/src/__tests__/unit/transforms/delete-rows.ts +0 -620
  84. package/src/__tests__/unit/transforms/merging.ts +0 -392
  85. package/src/__tests__/unit/ui/ContextualMenu.tsx +0 -71
  86. package/src/__tests__/unit/ui/CornerControls.tsx +0 -99
  87. package/src/__tests__/unit/ui/DeleteButton.tsx +0 -38
  88. package/src/__tests__/unit/ui/FixedButton.tsx +0 -217
  89. package/src/__tests__/unit/ui/FloatingContextualButton.tsx +0 -123
  90. package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +0 -68
  91. package/src/__tests__/unit/ui/FloatingDeleteButton.tsx +0 -178
  92. package/src/__tests__/unit/ui/FloatingDragMenu.tsx +0 -511
  93. package/src/__tests__/unit/ui/FloatingInsertButton.tsx +0 -322
  94. package/src/__tests__/unit/ui/NumberColumn.tsx +0 -146
  95. package/src/__tests__/unit/ui/RowControls.tsx +0 -294
  96. package/src/__tests__/unit/ui/RowDragControls.tsx +0 -129
  97. package/src/__tests__/unit/ui/TableFloatingColumnControls.tsx +0 -189
  98. package/src/__tests__/unit/ui/TableFloatingControls.tsx +0 -118
  99. package/src/__tests__/unit/undo-redo.ts +0 -220
  100. package/src/__tests__/unit/utils/analytics.ts +0 -98
  101. package/src/__tests__/unit/utils/collapse.ts +0 -57
  102. package/src/__tests__/unit/utils/column-controls.ts +0 -205
  103. package/src/__tests__/unit/utils/dom.ts +0 -180
  104. package/src/__tests__/unit/utils/merged-cells.ts +0 -156
  105. package/src/__tests__/unit/utils/nodes.ts +0 -79
  106. package/src/__tests__/unit/utils/row-controls.ts +0 -195
  107. package/src/__tests__/unit/utils/table.ts +0 -96
  108. package/src/__tests__/unit/utils.ts +0 -670
  109. package/src/__tests__/visual-regression/__fixtures__/sticky-header-with-horizontal-scroll.json +0 -5228
  110. package/src/__tests__/visual-regression/__fixtures__/table-with-100-numbered-list-items.json +0 -20272
  111. package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-column-menu-item-should-remove-the-table-column-on-click-1-snap.png +0 -3
  112. package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-column-menu-item-visual-hints-should-be-added-to-the-table-column-on-hover-1-snap.png +0 -3
  113. package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-should-remove-the-table-row-on-click-1-snap.png +0 -3
  114. package/src/__tests__/visual-regression/__image_snapshots__/cell-options-menu-ts-table-cell-options-menu-delete-row-menu-item-visual-hints-should-be-added-to-the-table-row-on-hover-1-snap.png +0 -3
  115. package/src/__tests__/visual-regression/__image_snapshots__/copy-button-ts-floating-toolbar-copy-button-table-target-node-displays-blue-border-when-copy-button-is-hovered-1-snap.png +0 -3
  116. package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-1-snap.png +0 -3
  117. package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-2-snap.png +0 -3
  118. package/src/__tests__/visual-regression/__image_snapshots__/index-ts-snapshot-test-table-numbered-list-should-not-overflow-table-cell-when-there-are-more-than-100-ordered-list-items-3-snap.png +0 -3
  119. package/src/__tests__/visual-regression/__image_snapshots__/sticky-header-ts-snapshot-test-table-sticky-header-should-align-with-table-cell-when-active-1-snap.png +0 -3
  120. package/src/__tests__/visual-regression/__image_snapshots__/sticky-header-ts-snapshot-test-table-sticky-header-should-align-with-table-cell-when-active-2-snap.png +0 -3
  121. package/src/__tests__/visual-regression/cell-options-menu.ts +0 -101
  122. package/src/__tests__/visual-regression/copy-button.ts +0 -181
  123. package/src/__tests__/visual-regression/index.ts +0 -62
  124. package/src/__tests__/visual-regression/sticky-header.ts +0 -61
@@ -1,745 +0,0 @@
1
- import { uuid } from '@atlaskit/adf-schema';
2
- import { defaultSchema } from '@atlaskit/adf-schema/schema-default';
3
- import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
4
- import type { DocBuilder } from '@atlaskit/editor-common/types';
5
- // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
6
- import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
7
- import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
8
- import { decorationsPlugin } from '@atlaskit/editor-plugin-decorations';
9
- import { featureFlagsPlugin } from '@atlaskit/editor-plugin-feature-flags';
10
- import { gridPlugin } from '@atlaskit/editor-plugin-grid';
11
- import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
12
- import { selectionPlugin } from '@atlaskit/editor-plugin-selection';
13
- import { widthPlugin } from '@atlaskit/editor-plugin-width';
14
- import { Fragment, Slice } from '@atlaskit/editor-prosemirror/model';
15
- import { TextSelection } from '@atlaskit/editor-prosemirror/state';
16
- import { findParentNodeOfType } from '@atlaskit/editor-prosemirror/utils';
17
- import type { EditorView } from '@atlaskit/editor-prosemirror/view';
18
- import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
19
- import { isRowSelected } from '@atlaskit/editor-tables/utils';
20
- // eslint-disable-next-line import/no-extraneous-dependencies
21
- import type { LightEditorPlugin } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
22
- // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
23
- import {
24
- createProsemirrorEditorFactory,
25
- Preset,
26
- } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
27
- // eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
28
- import {
29
- doc,
30
- p,
31
- panelNote,
32
- table,
33
- td,
34
- tdCursor,
35
- tdEmpty,
36
- th,
37
- thCursor,
38
- tr,
39
- } from '@atlaskit/editor-test-helpers/doc-builder';
40
-
41
- import {
42
- addBoldInEmptyHeaderCells,
43
- selectColumn,
44
- selectRow,
45
- setEditorFocus,
46
- setMultipleCellAttrs,
47
- setTableRef,
48
- toggleContextualMenu,
49
- toggleHeaderColumn,
50
- toggleHeaderRow,
51
- transformSliceToAddTableHeaders,
52
- } from '../../commands';
53
- import { splitCell } from '../../commands/split-cell';
54
- import { handleCut } from '../../event-handlers';
55
- import tablePlugin from '../../plugin';
56
- import { getPluginState } from '../../pm-plugins/plugin-factory';
57
- import { pluginKey } from '../../pm-plugins/plugin-key';
58
-
59
- const TABLE_LOCAL_ID = 'test-table-local-id';
60
-
61
- describe('table plugin: actions', () => {
62
- beforeAll(() => {
63
- uuid.setStatic(TABLE_LOCAL_ID);
64
- });
65
-
66
- afterAll(() => {
67
- uuid.setStatic(false);
68
- });
69
-
70
- const createEditor = createProsemirrorEditorFactory();
71
- const editor = (doc: DocBuilder) =>
72
- createEditor({
73
- doc,
74
- attachTo: document.body,
75
- preset: new Preset<LightEditorPlugin>()
76
- .add([featureFlagsPlugin, {}])
77
- .add([analyticsPlugin, {}])
78
- .add(contentInsertionPlugin)
79
- .add(decorationsPlugin)
80
- .add(widthPlugin)
81
- .add(guidelinePlugin)
82
- .add(gridPlugin)
83
- .add(selectionPlugin)
84
- .add(tablePlugin),
85
- pluginKey,
86
- });
87
-
88
- describe('transformSliceToAddTableHeaders', () => {
89
- const textNode = defaultSchema.text('hello', undefined);
90
- const paragraphNode = defaultSchema.nodes.paragraph.createChecked(
91
- undefined,
92
- defaultSchema.text('within paragraph', [
93
- defaultSchema.marks.strong.create(),
94
- ]),
95
- undefined,
96
- );
97
- const ruleNode = defaultSchema.nodes.rule.createChecked();
98
-
99
- const tableBody = tr(
100
- td({ colwidth: [300] })(p('r4')),
101
- td()(p('r5')),
102
- td()(panelNote(p('r6'))),
103
- );
104
-
105
- it('handles an empty fragment', () => {
106
- const slice = new Slice(Fragment.from(undefined), 0, 0);
107
- expect(
108
- transformSliceToAddTableHeaders(slice, defaultSchema).eq(slice),
109
- ).toBe(true);
110
- });
111
-
112
- it('does nothing to a text fragment', () => {
113
- const slice = new Slice(Fragment.from(textNode), 0, 0);
114
- expect(
115
- transformSliceToAddTableHeaders(slice, defaultSchema).eq(slice),
116
- ).toBe(true);
117
- });
118
-
119
- it('does nothing to fragment with multiple non-table nodes', () => {
120
- const slice = new Slice(
121
- Fragment.from([textNode, ruleNode, paragraphNode]),
122
- 1,
123
- 0,
124
- );
125
-
126
- expect(
127
- transformSliceToAddTableHeaders(slice, defaultSchema).eq(slice),
128
- ).toBe(true);
129
- });
130
-
131
- it('transforms only the table within the slice', () => {
132
- const preTable = table({
133
- isNumberColumnEnabled: true,
134
- localId: TABLE_LOCAL_ID,
135
- })(
136
- tr(
137
- td()(p('r1')),
138
- th({ colspan: 2 })(p('r2')),
139
- td()(panelNote(p('r3'))),
140
- ),
141
-
142
- tableBody,
143
- );
144
-
145
- const postTable = table({
146
- isNumberColumnEnabled: true,
147
- localId: TABLE_LOCAL_ID,
148
- })(
149
- tr(
150
- th()(p('r1')),
151
- th({ colspan: 2 })(p('r2')),
152
- th()(panelNote(p('r3'))),
153
- ),
154
-
155
- tableBody,
156
- );
157
-
158
- const preSlice = new Slice(
159
- Fragment.from([textNode, preTable(defaultSchema), paragraphNode]),
160
- 1,
161
- 0,
162
- );
163
-
164
- const postSlice = new Slice(
165
- Fragment.from([textNode, postTable(defaultSchema), paragraphNode]),
166
- 1,
167
- 0,
168
- );
169
-
170
- expect(
171
- transformSliceToAddTableHeaders(preSlice, defaultSchema).eq(postSlice),
172
- ).toBe(true);
173
- });
174
-
175
- it('transforms any table within the slice', () => {
176
- const preTableA = table({
177
- isNumberColumnEnabled: true,
178
- localId: TABLE_LOCAL_ID,
179
- })(
180
- tr(
181
- td()(p('r1')),
182
- th({ colspan: 2 })(p('r2')),
183
- td()(panelNote(p('r3'))),
184
- ),
185
-
186
- tableBody,
187
- );
188
-
189
- const postTableA = table({
190
- isNumberColumnEnabled: true,
191
- localId: TABLE_LOCAL_ID,
192
- })(
193
- tr(
194
- th()(p('r1')),
195
- th({ colspan: 2 })(p('r2')),
196
- th()(panelNote(p('r3'))),
197
- ),
198
-
199
- tableBody,
200
- );
201
-
202
- const preTableB = table({
203
- isNumberColumnEnabled: true,
204
- localId: TABLE_LOCAL_ID,
205
- })(
206
- tr(td()(p('b1')), th()(p('b2')), th()(p('b3'))),
207
-
208
- tableBody,
209
- );
210
-
211
- const postTableB = table({
212
- isNumberColumnEnabled: true,
213
- localId: TABLE_LOCAL_ID,
214
- })(
215
- tr(th()(p('b1')), th()(p('b2')), th()(p('b3'))),
216
-
217
- tableBody,
218
- );
219
-
220
- const preSlice = new Slice(
221
- Fragment.from([
222
- textNode,
223
- preTableA(defaultSchema),
224
- paragraphNode,
225
- preTableB(defaultSchema),
226
- ]),
227
- 1,
228
- 0,
229
- );
230
-
231
- const postSlice = new Slice(
232
- Fragment.from([
233
- textNode,
234
- postTableA(defaultSchema),
235
- paragraphNode,
236
- postTableB(defaultSchema),
237
- ]),
238
- 1,
239
- 0,
240
- );
241
-
242
- expect(
243
- transformSliceToAddTableHeaders(preSlice, defaultSchema).eq(postSlice),
244
- ).toBe(true);
245
- });
246
- });
247
-
248
- describe('#setMultipleCellAttrs', () => {
249
- it('should set selected cell attributes', () => {
250
- const { editorView } = editor(
251
- doc(
252
- p('text'),
253
- table()(
254
- tr(td()(p('c1')), td()(p('c2'))),
255
- tr(td()(p('c3')), td()(p('c4'))),
256
- ),
257
- ),
258
- );
259
- const { state, dispatch } = editorView;
260
- selectColumn(0)(state, dispatch);
261
- setMultipleCellAttrs({ background: 'purple' }, 0)(
262
- editorView.state,
263
- dispatch,
264
- );
265
- expect(editorView.state.doc).toEqualDocument(
266
- doc(
267
- p('text'),
268
- table({ localId: TABLE_LOCAL_ID })(
269
- tr(td({ background: 'purple' })(p('c1')), td()(p('c2'))),
270
- tr(td({ background: 'purple' })(p('c3')), td()(p('c4'))),
271
- ),
272
- ),
273
- );
274
- });
275
- });
276
-
277
- describe('#toggleContextualMenu', () => {
278
- it('should update isContextualMenuOpen in plugin state', () => {
279
- const { editorView } = editor(
280
- doc(p('text'), table()(tr(tdEmpty, tdEmpty))),
281
- );
282
- const { state, dispatch } = editorView;
283
- toggleContextualMenu()(state, dispatch);
284
- const { isContextualMenuOpen } = getPluginState(editorView.state);
285
- expect(isContextualMenuOpen).toBe(true);
286
- });
287
- });
288
-
289
- describe('#setEditorFocus', () => {
290
- it('should update editorHasFocus in plugin state', () => {
291
- const { editorView } = editor(
292
- doc(p('text'), table()(tr(tdEmpty, tdEmpty))),
293
- );
294
- const { state, dispatch } = editorView;
295
- setEditorFocus(true)(state, dispatch);
296
- const { editorHasFocus } = getPluginState(editorView.state);
297
- expect(editorHasFocus).toBe(true);
298
- });
299
- });
300
-
301
- describe('#setTableRef', () => {
302
- it('should update tableRef and tableNode in plugin state', () => {
303
- const { editorView } = editor(doc(table()(tr(tdCursor, tdEmpty))));
304
- const { state, dispatch } = editorView;
305
- const tableRef = document.querySelector(
306
- '.ProseMirror table',
307
- ) as HTMLTableElement;
308
- setEditorFocus(true)(state, dispatch);
309
- setTableRef(tableRef)(editorView.state, dispatch);
310
- const pluginState = getPluginState(editorView.state);
311
- expect(pluginState.tableRef).toEqual(tableRef);
312
- expect(pluginState.tableNode).toEqual(editorView.state.doc.firstChild!);
313
- });
314
- });
315
-
316
- describe('#selectRow', () => {
317
- it('should select a row and set targetCellPosition to point to the first cell', () => {
318
- const { editorView } = editor(doc(table()(tr(tdEmpty), tr(tdEmpty))));
319
- const { state, dispatch } = editorView;
320
- selectRow(1)(state, dispatch);
321
- const pluginState = getPluginState(editorView.state);
322
- expect(pluginState.targetCellPosition).toEqual(8);
323
- expect(isRowSelected(1)(editorView.state.selection));
324
- });
325
- });
326
-
327
- describe('#handleCut', () => {
328
- const editorAnalyticsAPIFake: EditorAnalyticsAPI = {
329
- attachAnalyticsEvent: jest.fn().mockReturnValue(() => jest.fn()),
330
- fireAnalyticsEvent: jest.fn(),
331
- };
332
-
333
- describe('when the entire table is selected', () => {
334
- it('should remove the table', () => {
335
- const { editorView, refs } = editor(
336
- doc(
337
- table()(
338
- tr(
339
- td()(p('{from}a1')),
340
- td()(p('a2')),
341
- td()(p('a3')),
342
- td()(p('{cursorPos}a4')),
343
- ),
344
- tr(
345
- td()(p('b1')),
346
- td()(p('b2')),
347
- td()(p('b3')),
348
- td()(p('{to}b4')),
349
- ),
350
- ),
351
- ),
352
- );
353
- const { state, dispatch } = editorView;
354
- const sel = new CellSelection(
355
- state.doc.resolve(refs.from - 2),
356
- state.doc.resolve(refs.to - 2),
357
- );
358
- dispatch(state.tr.setSelection(sel as any));
359
- const oldState = editorView.state;
360
- dispatch(
361
- oldState.tr.setSelection(
362
- new TextSelection(oldState.doc.resolve(refs.cursorPos)),
363
- ),
364
- );
365
- const newTr = handleCut(
366
- oldState.tr,
367
- oldState,
368
- editorView.state,
369
- editorAnalyticsAPIFake,
370
- );
371
- expect(
372
- editorAnalyticsAPIFake.attachAnalyticsEvent,
373
- ).toHaveBeenCalledWith({
374
- action: 'cut',
375
- actionSubject: 'table',
376
- actionSubjectId: null,
377
- attributes: {
378
- horizontalCells: 4,
379
- totalCells: 8,
380
- totalColumnCount: 4,
381
- totalRowCount: 2,
382
- verticalCells: 2,
383
- },
384
- eventType: 'track',
385
- });
386
- expect(newTr.doc).toEqualDocument(doc(p('')));
387
- });
388
- });
389
-
390
- describe('when selected columns are cut', () => {
391
- it('should remove those columns', () => {
392
- const { editorView, refs } = editor(
393
- doc(
394
- table()(
395
- tr(
396
- td()(p('a1')),
397
- td()(p('{from}a2')),
398
- td()(p('a3')),
399
- td()(p('{cursorPos}a4')),
400
- ),
401
- tr(
402
- td()(p('b1')),
403
- td()(p('b2')),
404
- td()(p('{to}b3')),
405
- td()(p('b4')),
406
- ),
407
- ),
408
- ),
409
- );
410
- const { state, dispatch } = editorView;
411
- // selecting 2 and 3 columns
412
- const sel = new CellSelection(
413
- state.doc.resolve(refs.from - 2),
414
- state.doc.resolve(refs.to - 2),
415
- );
416
- dispatch(state.tr.setSelection(sel as any));
417
- const oldState = editorView.state;
418
- // re-setting selection to a text selection
419
- // this is what happens when we let PM handle cut so that it saves content to a clipboard
420
- dispatch(
421
- oldState.tr.setSelection(
422
- new TextSelection(oldState.doc.resolve(refs.cursorPos)),
423
- ),
424
- );
425
- const newTr = handleCut(
426
- oldState.tr,
427
- oldState,
428
- editorView.state,
429
- editorAnalyticsAPIFake,
430
- );
431
- expect(
432
- editorAnalyticsAPIFake.attachAnalyticsEvent,
433
- ).toHaveBeenCalledWith({
434
- action: 'cut',
435
- actionSubject: 'table',
436
- actionSubjectId: null,
437
- attributes: {
438
- horizontalCells: 4,
439
- totalCells: 8,
440
- totalColumnCount: 4,
441
- totalRowCount: 2,
442
- verticalCells: 2,
443
- },
444
- eventType: 'track',
445
- });
446
- expect(newTr.doc).toEqualDocument(
447
- doc(
448
- table({ localId: TABLE_LOCAL_ID })(
449
- tr(td()(p('a1')), td()(p('a4'))),
450
- tr(td()(p('b1')), td()(p('b4'))),
451
- ),
452
- ),
453
- );
454
- });
455
- });
456
-
457
- describe('when selected rows are cut', () => {
458
- it('should remove those rows', () => {
459
- const { editorView, refs } = editor(
460
- doc(
461
- table()(
462
- tr(td()(p('a1')), td()(p('a2')), td()(p('a3'))),
463
- tr(td()(p('{from}b1')), td()(p('b2')), td()(p('b3'))),
464
- tr(td()(p('c1')), td()(p('c2')), td()(p('{to}c3'))),
465
- tr(td()(p('{cursorPos}d1')), td()(p('d2')), td()(p('d3'))),
466
- ),
467
- ),
468
- );
469
- const { state, dispatch } = editorView;
470
- // selecting 2 and 3 rows
471
- const sel = new CellSelection(
472
- state.doc.resolve(refs.from - 2),
473
- state.doc.resolve(refs.to - 2),
474
- );
475
- dispatch(state.tr.setSelection(sel as any));
476
- const oldState = editorView.state;
477
- // re-setting selection to a text selection
478
- // this is what happens when we let PM handle cut so that it saves content to a clipboard
479
- dispatch(
480
- oldState.tr.setSelection(
481
- new TextSelection(oldState.doc.resolve(refs.cursorPos)),
482
- ),
483
- );
484
- const newTr = handleCut(
485
- oldState.tr,
486
- oldState,
487
- editorView.state,
488
- editorAnalyticsAPIFake,
489
- );
490
- expect(
491
- editorAnalyticsAPIFake.attachAnalyticsEvent,
492
- ).toHaveBeenCalledWith({
493
- action: 'cut',
494
- actionSubject: 'table',
495
- actionSubjectId: null,
496
- attributes: {
497
- horizontalCells: 4,
498
- totalCells: 8,
499
- totalColumnCount: 4,
500
- totalRowCount: 2,
501
- verticalCells: 2,
502
- },
503
- eventType: 'track',
504
- });
505
- expect(newTr.doc).toEqualDocument(
506
- doc(
507
- table({ localId: TABLE_LOCAL_ID })(
508
- tr(td()(p('a1')), td()(p('a2')), td()(p('a3'))),
509
- tr(td()(p('d1')), td()(p('d2')), td()(p('d3'))),
510
- ),
511
- ),
512
- );
513
- });
514
- });
515
- });
516
-
517
- describe('#toggleHeaderColumn', () => {
518
- let editorView: EditorView;
519
- const tableDoc = doc(
520
- table({ localId: TABLE_LOCAL_ID })(
521
- tr(td()(p('c1')), td()(p('c2'))),
522
- tr(td({ rowspan: 2 })(p('c3')), td()(p('c4'))),
523
- tr(td()(p('c6'))),
524
- tr(td()(p('c7')), td()(p('c8'))),
525
- ),
526
- );
527
- beforeEach(() => {
528
- ({ editorView } = editor(tableDoc));
529
- const { state, dispatch } = editorView;
530
- toggleHeaderColumn(state, dispatch);
531
- });
532
-
533
- it('should convert all cells including rowspans to table headers', () => {
534
- expect(editorView.state.doc).toEqualDocument(
535
- doc(
536
- table({ localId: TABLE_LOCAL_ID })(
537
- tr(th()(p('c1')), td()(p('c2'))),
538
- tr(th({ rowspan: 2 })(p('c3')), td()(p('c4'))),
539
- tr(td()(p('c6'))),
540
- tr(th()(p('c7')), td()(p('c8'))),
541
- ),
542
- ),
543
- );
544
- });
545
-
546
- it('should isHeaderColumnEnabled be true', () => {
547
- const tableState = getPluginState(editorView.state);
548
-
549
- expect(tableState.isHeaderColumnEnabled).toBe(true);
550
- });
551
- describe('Toggle header columns again', () => {
552
- beforeEach(() => {
553
- const { state, dispatch } = editorView;
554
- toggleHeaderColumn(state, dispatch);
555
- });
556
-
557
- it('should convert all cells including rowspan back to the original document', () => {
558
- expect(editorView.state.doc).toEqualDocument(tableDoc);
559
- });
560
-
561
- it('should isHeaderColumnEnabled be false', () => {
562
- const tableState = getPluginState(editorView.state);
563
- expect(tableState.isHeaderColumnEnabled).toBe(false);
564
- });
565
- });
566
- });
567
-
568
- describe('#toggleHeaderRow', () => {
569
- let editorView: EditorView;
570
- const tableDoc = doc(
571
- table({ localId: TABLE_LOCAL_ID })(
572
- tr(th()(p('c1')), th()(p('c2'))),
573
- tr(td({ rowspan: 2 })(p('c3')), td()(p('c4'))),
574
- tr(td()(p('c6'))),
575
- tr(td()(p('c7')), td()(p('c8'))),
576
- ),
577
- );
578
- beforeEach(() => {
579
- ({ editorView } = editor(tableDoc));
580
- const { state, dispatch } = editorView;
581
- toggleHeaderRow(state, dispatch);
582
- });
583
-
584
- it('should convert all rows including to table normal', () => {
585
- expect(editorView.state.doc).toEqualDocument(
586
- doc(
587
- table({ localId: TABLE_LOCAL_ID })(
588
- tr(td()(p('c1')), td()(p('c2'))),
589
- tr(td({ rowspan: 2 })(p('c3')), td()(p('c4'))),
590
- tr(td()(p('c6'))),
591
- tr(td()(p('c7')), td()(p('c8'))),
592
- ),
593
- ),
594
- );
595
- });
596
-
597
- it('should isHeaderRowEnabled be false', () => {
598
- const tableState = getPluginState(editorView.state);
599
- expect(tableState.isHeaderRowEnabled).toBe(false);
600
- });
601
-
602
- describe('Toggle header rows again', () => {
603
- beforeEach(() => {
604
- const { state, dispatch } = editorView;
605
- toggleHeaderRow(state, dispatch);
606
- });
607
-
608
- it('should convert all rows back to the original document', () => {
609
- expect(editorView.state.doc).toEqualDocument(tableDoc);
610
- });
611
-
612
- it('should isHeaderRowEnabled be false', () => {
613
- const tableState = getPluginState(editorView.state);
614
- expect(tableState.isHeaderRowEnabled).toBe(true);
615
- });
616
- });
617
- });
618
-
619
- describe('#toggleBoldOnHeaderCells', () => {
620
- describe('when there is no cursor', () => {
621
- it('should not add a strong mark on storedMarks', function () {
622
- const { editorView } = editor(
623
- doc(table()(tr(th()(p('{<}foo bar{>}'))), tr(td()(p(''))))),
624
- );
625
-
626
- const { state, dispatch } = editorView;
627
-
628
- const tableCellHeader = findParentNodeOfType(
629
- state.schema.nodes.tableHeader,
630
- )(state.selection);
631
-
632
- addBoldInEmptyHeaderCells(tableCellHeader!)(state, dispatch);
633
-
634
- const result = editorView.state.storedMarks || [];
635
- expect(result).toEqual([]);
636
- });
637
- });
638
- describe('when the cursor is on table header cell', () => {
639
- describe('and the cell is empty', () => {
640
- describe('and the user removed the strong mark', () => {
641
- it('should not add strong mark on storedMarks', () => {
642
- const { editorView } = editor(
643
- doc(table()(tr(thCursor), tr(td()(p(''))))),
644
- );
645
- const { state, dispatch } = editorView;
646
-
647
- const tableCellHeader = findParentNodeOfType(
648
- state.schema.nodes.tableHeader,
649
- )(state.selection);
650
-
651
- editorView.state.storedMarks = [];
652
- addBoldInEmptyHeaderCells(tableCellHeader!)(state, dispatch);
653
-
654
- const result = editorView.state.storedMarks || [];
655
- expect(result).toEqual([]);
656
- });
657
- });
658
- });
659
-
660
- describe('and the cell is not empty', () => {
661
- it('should not add strong mark on storedMarks', () => {
662
- const { editorView } = editor(
663
- doc(table()(tr(th()(p('Rato{<>}'))), tr(td()(p('Rato'))))),
664
- );
665
- const { state, dispatch } = editorView;
666
- expect(editorView.state.storedMarks).toBeNull();
667
-
668
- const tableCellHeader = findParentNodeOfType(
669
- state.schema.nodes.tableHeader,
670
- )(state.selection);
671
-
672
- addBoldInEmptyHeaderCells(tableCellHeader!)(state, dispatch);
673
- expect(editorView.state.storedMarks).toBeNull();
674
- });
675
- });
676
- });
677
- });
678
-
679
- describe('#splitCell', () => {
680
- /**
681
- * | th | th | th |
682
- * ---- ----
683
- * | td | | td |
684
- *
685
- * If header row is enabled should split into:
686
- *
687
- * | th | th | th |
688
- * ---- ---- ----
689
- * | th | td | td |
690
- */
691
- it('should keep right column header and cells after split', () => {
692
- const { editorView } = editor(
693
- doc(
694
- table()(
695
- tr(th()(p('')), th({ rowspan: 2 })(p('foo{<>}')), th()(p(''))),
696
- tr(td()(p('')), td()(p(''))),
697
- ),
698
- ),
699
- );
700
-
701
- splitCell(editorView.state, editorView.dispatch);
702
-
703
- expect(editorView.state.doc).toEqualDocument(
704
- doc(
705
- table({ localId: TABLE_LOCAL_ID })(
706
- tr(th()(p('')), th()(p('foo')), th()(p(''))),
707
- tr(td()(p('')), td()(p('')), td()(p(''))),
708
- ),
709
- ),
710
- );
711
- });
712
-
713
- /**
714
- * | th | th | th |
715
- * | th | td |
716
- *
717
- * If header column is enabled should split into:
718
- *
719
- * | th | th | th |
720
- * | th | td | td |
721
- */
722
- it('should keep right row header and cells after split', () => {
723
- const { editorView } = editor(
724
- doc(
725
- table()(
726
- tr(th()(p('')), th()(p('')), th()(p(''))),
727
- tr(td({ colspan: 2 })(p('foo{<>}')), td()(p(''))),
728
- ),
729
- ),
730
- );
731
- toggleHeaderColumn(editorView.state, editorView.dispatch); // Activate header columns first
732
-
733
- splitCell(editorView.state, editorView.dispatch);
734
-
735
- expect(editorView.state.doc).toEqualDocument(
736
- doc(
737
- table({ localId: TABLE_LOCAL_ID })(
738
- tr(th()(p('')), th()(p('')), th()(p(''))),
739
- tr(th()(p('foo')), td()(p('')), td()(p(''))),
740
- ),
741
- ),
742
- );
743
- });
744
- });
745
- });