@atlaskit/editor-plugin-table 7.2.2 → 7.3.0

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 (149) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/cjs/commands/column-resize.js +115 -45
  3. package/dist/cjs/commands/go-to-next-cell.js +7 -11
  4. package/dist/cjs/commands/misc.js +3 -2
  5. package/dist/cjs/commands/selection.js +3 -3
  6. package/dist/cjs/event-handlers.js +38 -25
  7. package/dist/cjs/pm-plugins/drag-and-drop/commands-with-analytics.js +3 -19
  8. package/dist/cjs/pm-plugins/keymap.js +1 -0
  9. package/dist/cjs/pm-plugins/main.js +43 -9
  10. package/dist/cjs/pm-plugins/table-resizing/event-handlers.js +37 -7
  11. package/dist/cjs/pm-plugins/table-resizing/plugin.js +20 -6
  12. package/dist/cjs/reducer.js +5 -2
  13. package/dist/cjs/utils/drag-menu.js +37 -23
  14. package/dist/cjs/utils/merged-cells.js +66 -1
  15. package/dist/es2019/commands/column-resize.js +100 -35
  16. package/dist/es2019/commands/go-to-next-cell.js +7 -9
  17. package/dist/es2019/commands/misc.js +3 -2
  18. package/dist/es2019/commands/selection.js +5 -5
  19. package/dist/es2019/event-handlers.js +17 -3
  20. package/dist/es2019/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
  21. package/dist/es2019/pm-plugins/keymap.js +3 -2
  22. package/dist/es2019/pm-plugins/main.js +41 -5
  23. package/dist/es2019/pm-plugins/table-resizing/event-handlers.js +37 -4
  24. package/dist/es2019/pm-plugins/table-resizing/plugin.js +16 -1
  25. package/dist/es2019/reducer.js +5 -2
  26. package/dist/es2019/utils/drag-menu.js +38 -14
  27. package/dist/es2019/utils/merged-cells.js +73 -0
  28. package/dist/esm/commands/column-resize.js +105 -35
  29. package/dist/esm/commands/go-to-next-cell.js +7 -11
  30. package/dist/esm/commands/misc.js +3 -2
  31. package/dist/esm/commands/selection.js +5 -5
  32. package/dist/esm/event-handlers.js +38 -25
  33. package/dist/esm/pm-plugins/drag-and-drop/commands-with-analytics.js +4 -20
  34. package/dist/esm/pm-plugins/keymap.js +3 -2
  35. package/dist/esm/pm-plugins/main.js +38 -4
  36. package/dist/esm/pm-plugins/table-resizing/event-handlers.js +34 -4
  37. package/dist/esm/pm-plugins/table-resizing/plugin.js +15 -1
  38. package/dist/esm/reducer.js +5 -2
  39. package/dist/esm/utils/drag-menu.js +36 -22
  40. package/dist/esm/utils/merged-cells.js +65 -0
  41. package/dist/types/commands/column-resize.d.ts +2 -0
  42. package/dist/types/commands/misc.d.ts +1 -1
  43. package/dist/types/types.d.ts +16 -0
  44. package/dist/types/utils/drag-menu.d.ts +4 -1
  45. package/dist/types/utils/merged-cells.d.ts +2 -0
  46. package/dist/types-ts4.5/commands/column-resize.d.ts +2 -0
  47. package/dist/types-ts4.5/commands/misc.d.ts +1 -1
  48. package/dist/types-ts4.5/types.d.ts +16 -0
  49. package/dist/types-ts4.5/utils/drag-menu.d.ts +4 -1
  50. package/dist/types-ts4.5/utils/merged-cells.d.ts +2 -0
  51. package/package.json +10 -17
  52. package/src/commands/column-resize.ts +155 -40
  53. package/src/commands/go-to-next-cell.ts +6 -15
  54. package/src/commands/misc.ts +2 -0
  55. package/src/commands/selection.ts +5 -5
  56. package/src/event-handlers.ts +21 -4
  57. package/src/pm-plugins/drag-and-drop/commands-with-analytics.ts +11 -32
  58. package/src/pm-plugins/keymap.ts +3 -0
  59. package/src/pm-plugins/main.ts +47 -2
  60. package/src/pm-plugins/table-resizing/event-handlers.ts +33 -5
  61. package/src/pm-plugins/table-resizing/plugin.ts +18 -1
  62. package/src/reducer.ts +5 -2
  63. package/src/types.ts +16 -0
  64. package/src/utils/drag-menu.ts +94 -20
  65. package/src/utils/merged-cells.ts +78 -0
  66. package/tsconfig.dev.json +0 -69
  67. package/tsconfig.json +2 -877
  68. package/examples/99-testing.tsx +0 -140
  69. package/examples/config.jsonc +0 -14
  70. package/src/__tests__/unit/analytics.ts +0 -888
  71. package/src/__tests__/unit/collab.ts +0 -93
  72. package/src/__tests__/unit/commands/go-to-next-cell.ts +0 -173
  73. package/src/__tests__/unit/commands/insert.ts +0 -137
  74. package/src/__tests__/unit/commands/misc.ts +0 -185
  75. package/src/__tests__/unit/commands/sort.ts +0 -128
  76. package/src/__tests__/unit/commands.ts +0 -745
  77. package/src/__tests__/unit/copy-button.ts +0 -22
  78. package/src/__tests__/unit/copy-paste.ts +0 -677
  79. package/src/__tests__/unit/event-handlers/index.ts +0 -125
  80. package/src/__tests__/unit/event-handlers.ts +0 -296
  81. package/src/__tests__/unit/fix-tables.ts +0 -164
  82. package/src/__tests__/unit/get-toolbar-config.ts +0 -127
  83. package/src/__tests__/unit/handlers.ts +0 -98
  84. package/src/__tests__/unit/hover-selection.ts +0 -230
  85. package/src/__tests__/unit/index-with-fake-timers.ts +0 -111
  86. package/src/__tests__/unit/index.ts +0 -912
  87. package/src/__tests__/unit/layout.ts +0 -146
  88. package/src/__tests__/unit/nodeviews/OverflowShadowsObserver.ts +0 -162
  89. package/src/__tests__/unit/nodeviews/TableComponent.tsx +0 -280
  90. package/src/__tests__/unit/nodeviews/TableContainer.tsx +0 -525
  91. package/src/__tests__/unit/nodeviews/cell.ts +0 -132
  92. package/src/__tests__/unit/nodeviews/table.ts +0 -129
  93. package/src/__tests__/unit/pm-plugins/analytics.ts +0 -327
  94. package/src/__tests__/unit/pm-plugins/decorations/column-controls.ts +0 -94
  95. package/src/__tests__/unit/pm-plugins/decorations/column-resizing.ts +0 -176
  96. package/src/__tests__/unit/pm-plugins/decorations/plugin.ts +0 -211
  97. package/src/__tests__/unit/pm-plugins/main.ts +0 -214
  98. package/src/__tests__/unit/pm-plugins/safari-delete-composition-text-issue-workaround.ts +0 -101
  99. package/src/__tests__/unit/pm-plugins/sticky-headers/tableRow.tsx +0 -562
  100. package/src/__tests__/unit/pm-plugins/table-local-id.ts +0 -507
  101. package/src/__tests__/unit/pm-plugins/table-resizing/colgroup.ts +0 -269
  102. package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +0 -192
  103. package/src/__tests__/unit/pm-plugins/table-resizing/utils/resize-state.ts +0 -33
  104. package/src/__tests__/unit/pm-plugins/table-width.ts +0 -292
  105. package/src/__tests__/unit/sort-column.ts +0 -399
  106. package/src/__tests__/unit/toolbar.ts +0 -512
  107. package/src/__tests__/unit/transforms/delete-columns.ts +0 -597
  108. package/src/__tests__/unit/transforms/delete-rows.ts +0 -620
  109. package/src/__tests__/unit/transforms/merging.ts +0 -392
  110. package/src/__tests__/unit/ui/ContextualMenu.tsx +0 -71
  111. package/src/__tests__/unit/ui/CornerControls.tsx +0 -99
  112. package/src/__tests__/unit/ui/DeleteButton.tsx +0 -38
  113. package/src/__tests__/unit/ui/FixedButton.tsx +0 -217
  114. package/src/__tests__/unit/ui/FloatingContextualButton.tsx +0 -123
  115. package/src/__tests__/unit/ui/FloatingContextualMenu.tsx +0 -68
  116. package/src/__tests__/unit/ui/FloatingDeleteButton.tsx +0 -178
  117. package/src/__tests__/unit/ui/FloatingDragMenu.tsx +0 -511
  118. package/src/__tests__/unit/ui/FloatingInsertButton.tsx +0 -322
  119. package/src/__tests__/unit/ui/NumberColumn.tsx +0 -146
  120. package/src/__tests__/unit/ui/RowControls.tsx +0 -294
  121. package/src/__tests__/unit/ui/RowDragControls.tsx +0 -129
  122. package/src/__tests__/unit/ui/TableFloatingColumnControls.tsx +0 -189
  123. package/src/__tests__/unit/ui/TableFloatingControls.tsx +0 -118
  124. package/src/__tests__/unit/undo-redo.ts +0 -220
  125. package/src/__tests__/unit/utils/analytics.ts +0 -98
  126. package/src/__tests__/unit/utils/collapse.ts +0 -57
  127. package/src/__tests__/unit/utils/column-controls.ts +0 -205
  128. package/src/__tests__/unit/utils/dom.ts +0 -180
  129. package/src/__tests__/unit/utils/merged-cells.ts +0 -156
  130. package/src/__tests__/unit/utils/nodes.ts +0 -79
  131. package/src/__tests__/unit/utils/row-controls.ts +0 -195
  132. package/src/__tests__/unit/utils/table.ts +0 -96
  133. package/src/__tests__/unit/utils.ts +0 -670
  134. package/src/__tests__/visual-regression/__fixtures__/sticky-header-with-horizontal-scroll.json +0 -5228
  135. package/src/__tests__/visual-regression/__fixtures__/table-with-100-numbered-list-items.json +0 -20272
  136. 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
  137. 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
  138. 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
  139. 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
  140. 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
  141. 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
  142. 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
  143. 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
  144. 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
  145. 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
  146. package/src/__tests__/visual-regression/cell-options-menu.ts +0 -101
  147. package/src/__tests__/visual-regression/copy-button.ts +0 -181
  148. package/src/__tests__/visual-regression/index.ts +0 -62
  149. 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
- });