@atlaskit/editor-plugin-table 0.2.2 → 0.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.
- package/CHANGELOG.md +20 -0
- package/dist/cjs/plugins/table/commands/hover.js +2 -1
- package/dist/cjs/plugins/table/event-handlers.js +5 -12
- package/dist/cjs/plugins/table/index.js +3 -1
- package/dist/cjs/plugins/table/nodeviews/TableComponent.js +15 -5
- package/dist/cjs/plugins/table/pm-plugins/default-table-selection.js +1 -2
- package/dist/cjs/plugins/table/pm-plugins/main.js +2 -2
- package/dist/cjs/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +42 -8
- package/dist/cjs/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
- package/dist/cjs/plugins/table/toolbar.js +42 -10
- package/dist/cjs/plugins/table/ui/FloatingContextualButton/index.js +7 -1
- package/dist/cjs/plugins/table/ui/FloatingContextualButton/styles.js +34 -6
- package/dist/cjs/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
- package/dist/cjs/plugins/table/ui/common-styles.js +1 -1
- package/dist/cjs/plugins/table/ui/consts.js +4 -4
- package/dist/cjs/plugins/table/ui/ui-styles.js +5 -5
- package/dist/cjs/version.json +1 -1
- package/dist/es2019/plugins/table/commands/hover.js +2 -1
- package/dist/es2019/plugins/table/event-handlers.js +5 -11
- package/dist/es2019/plugins/table/index.js +1 -1
- package/dist/es2019/plugins/table/nodeviews/TableComponent.js +12 -1
- package/dist/es2019/plugins/table/pm-plugins/default-table-selection.js +1 -2
- package/dist/es2019/plugins/table/pm-plugins/main.js +2 -2
- package/dist/es2019/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +31 -4
- package/dist/es2019/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
- package/dist/es2019/plugins/table/toolbar.js +43 -12
- package/dist/es2019/plugins/table/ui/FloatingContextualButton/index.js +6 -2
- package/dist/es2019/plugins/table/ui/FloatingContextualButton/styles.js +47 -8
- package/dist/es2019/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
- package/dist/es2019/plugins/table/ui/common-styles.js +9 -9
- package/dist/es2019/plugins/table/ui/consts.js +5 -5
- package/dist/es2019/plugins/table/ui/ui-styles.js +5 -5
- package/dist/es2019/version.json +1 -1
- package/dist/esm/plugins/table/commands/hover.js +2 -1
- package/dist/esm/plugins/table/event-handlers.js +5 -12
- package/dist/esm/plugins/table/index.js +3 -1
- package/dist/esm/plugins/table/nodeviews/TableComponent.js +17 -6
- package/dist/esm/plugins/table/pm-plugins/default-table-selection.js +1 -2
- package/dist/esm/plugins/table/pm-plugins/main.js +2 -2
- package/dist/esm/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.js +43 -8
- package/dist/esm/plugins/table/pm-plugins/table-resizing/utils/resize-logic.js +1 -1
- package/dist/esm/plugins/table/toolbar.js +43 -12
- package/dist/esm/plugins/table/ui/FloatingContextualButton/index.js +8 -2
- package/dist/esm/plugins/table/ui/FloatingContextualButton/styles.js +28 -5
- package/dist/esm/plugins/table/ui/FloatingContextualMenu/ContextualMenu.js +4 -1
- package/dist/esm/plugins/table/ui/common-styles.js +1 -1
- package/dist/esm/plugins/table/ui/consts.js +5 -5
- package/dist/esm/plugins/table/ui/ui-styles.js +5 -5
- package/dist/esm/version.json +1 -1
- package/dist/types/plugins/table/event-handlers.d.ts +2 -2
- package/dist/types/plugins/table/pm-plugins/default-table-selection.d.ts +0 -1
- package/dist/types/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.d.ts +8 -0
- package/dist/types/plugins/table/toolbar.d.ts +3 -2
- package/dist/types/plugins/table/ui/FloatingContextualButton/styles.d.ts +3 -1
- package/dist/types/plugins/table/ui/consts.d.ts +2 -2
- package/package.json +4 -4
- package/src/__tests__/integration/__snapshots__/floating-toolbar.ts.snap +321 -0
- package/src/__tests__/integration/delete-last-column-in-full-width.ts +6 -5
- package/src/__tests__/integration/floating-toolbar.ts +169 -0
- package/src/__tests__/unit/get-toolbar-config.ts +1 -0
- package/src/__tests__/unit/nodeviews/TableComponent.tsx +146 -4
- package/src/__tests__/unit/pm-plugins/table-resizing/event-handlers.ts +82 -31
- package/src/__tests__/unit/toolbar.ts +165 -4
- 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 +2 -2
- package/src/plugins/table/commands/hover.ts +1 -0
- package/src/plugins/table/event-handlers.ts +3 -16
- package/src/plugins/table/index.tsx +1 -0
- package/src/plugins/table/nodeviews/TableComponent.tsx +10 -2
- package/src/plugins/table/nodeviews/tableCell.tsx +1 -1
- package/src/plugins/table/pm-plugins/default-table-selection.ts +0 -1
- package/src/plugins/table/pm-plugins/main.ts +26 -28
- package/src/plugins/table/pm-plugins/sticky-headers/nodeviews/tableRow.ts +44 -9
- package/src/plugins/table/pm-plugins/table-resizing/utils/resize-logic.ts +1 -1
- package/src/plugins/table/toolbar.tsx +60 -13
- package/src/plugins/table/ui/FloatingContextualButton/index.tsx +12 -2
- package/src/plugins/table/ui/FloatingContextualButton/styles.ts +51 -7
- package/src/plugins/table/ui/FloatingContextualMenu/ContextualMenu.tsx +3 -0
- package/src/plugins/table/ui/common-styles.ts +24 -9
- package/src/plugins/table/ui/consts.ts +7 -5
- package/src/plugins/table/ui/ui-styles.ts +20 -5
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import {
|
|
2
|
+
animationFrame,
|
|
3
|
+
editable,
|
|
4
|
+
fullpage,
|
|
5
|
+
getDocFromElement,
|
|
6
|
+
} from '@atlaskit/editor-test-helpers/integration/helpers';
|
|
7
|
+
import {
|
|
8
|
+
clickFirstCell,
|
|
9
|
+
multiCellTableSelectionBottomRightToMiddleTopCell,
|
|
10
|
+
tableSelectors,
|
|
11
|
+
} from '@atlaskit/editor-test-helpers/page-objects/table';
|
|
12
|
+
import {
|
|
13
|
+
goToEditorTestingWDExample,
|
|
14
|
+
mountEditor,
|
|
15
|
+
} from '@atlaskit/editor-test-helpers/testing-example-page';
|
|
16
|
+
import { BrowserTestCase } from '@atlaskit/webdriver-runner/runner';
|
|
17
|
+
import { TableCssClassName } from '../../plugins/table/types';
|
|
18
|
+
import basicTable from './__fixtures__/basic-table';
|
|
19
|
+
|
|
20
|
+
BrowserTestCase(
|
|
21
|
+
'should floating toolbar context menu sit above other context menu layers',
|
|
22
|
+
{ skip: [] },
|
|
23
|
+
async (client: any) => {
|
|
24
|
+
const page = await goToEditorTestingWDExample(
|
|
25
|
+
client,
|
|
26
|
+
'editor-plugin-table',
|
|
27
|
+
);
|
|
28
|
+
await mountEditor(page, {
|
|
29
|
+
appearance: fullpage.appearance,
|
|
30
|
+
allowTables: {
|
|
31
|
+
advanced: true,
|
|
32
|
+
allowColumnSorting: true,
|
|
33
|
+
allowDistributeColumns: true,
|
|
34
|
+
allowCellOptionsInFloatingToolbar: true,
|
|
35
|
+
},
|
|
36
|
+
defaultValue: basicTable,
|
|
37
|
+
});
|
|
38
|
+
const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
|
|
39
|
+
// Select the all cells under column 2 and 3
|
|
40
|
+
await multiCellTableSelectionBottomRightToMiddleTopCell(page);
|
|
41
|
+
// Table floating toolbar should appear, then click on "Cell Options", which brings up another context menu
|
|
42
|
+
const cellOptionsMenuItem = await (
|
|
43
|
+
await page.$(tableFloatingToolbarContextMenuSelector)
|
|
44
|
+
).$(`button=${tableSelectors.cellOptionsFloatingToolbarText}`);
|
|
45
|
+
await cellOptionsMenuItem.waitForClickable();
|
|
46
|
+
await cellOptionsMenuItem.click();
|
|
47
|
+
// Get the z-index style value of the delete icon popup
|
|
48
|
+
const popupZIndex = await page.evaluate(() => {
|
|
49
|
+
const popupSelector = 'div[aria-label="Popup"][data-editor-popup=true]';
|
|
50
|
+
const deleteIconSelector = 'button.pm-table-controls__delete-button';
|
|
51
|
+
return +(
|
|
52
|
+
(
|
|
53
|
+
document
|
|
54
|
+
?.querySelector(`${popupSelector} ${deleteIconSelector}`)
|
|
55
|
+
?.closest(popupSelector) as HTMLElement | null
|
|
56
|
+
)?.style.zIndex || 0
|
|
57
|
+
);
|
|
58
|
+
});
|
|
59
|
+
// Get the z-index style value of the table floating toolbar context menu
|
|
60
|
+
const floatingTablePopupZIndex = await page.evaluate(() => {
|
|
61
|
+
const floatingTablePopupSelector =
|
|
62
|
+
'div[aria-label="Table floating controls"][data-editor-popup=true]';
|
|
63
|
+
return +(
|
|
64
|
+
(
|
|
65
|
+
document?.querySelector(
|
|
66
|
+
floatingTablePopupSelector,
|
|
67
|
+
) as HTMLElement | null
|
|
68
|
+
)?.style.zIndex || 0
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
// Floating toolbar context menu should sit above the popup
|
|
72
|
+
expect(floatingTablePopupZIndex).toBeGreaterThan(popupZIndex);
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
BrowserTestCase(
|
|
77
|
+
'should show hover indicators on delete columns menu option',
|
|
78
|
+
{ skip: ['safari'] }, // The test does not pass on CI but works on physical browser
|
|
79
|
+
async (client: any, testName: string) => {
|
|
80
|
+
const page = await goToEditorTestingWDExample(
|
|
81
|
+
client,
|
|
82
|
+
'editor-plugin-table',
|
|
83
|
+
);
|
|
84
|
+
await mountEditor(page, {
|
|
85
|
+
appearance: fullpage.appearance,
|
|
86
|
+
allowTables: {
|
|
87
|
+
advanced: true,
|
|
88
|
+
allowColumnSorting: true,
|
|
89
|
+
allowDistributeColumns: true,
|
|
90
|
+
allowCellOptionsInFloatingToolbar: true,
|
|
91
|
+
},
|
|
92
|
+
defaultValue: basicTable,
|
|
93
|
+
});
|
|
94
|
+
const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
|
|
95
|
+
|
|
96
|
+
// First click on the cell
|
|
97
|
+
await clickFirstCell(page);
|
|
98
|
+
|
|
99
|
+
// Table floating toolbar should appear, then click on "Cell Options", which brings up another context menu
|
|
100
|
+
const cellOptionsMenuItem = await (
|
|
101
|
+
await page.$(tableFloatingToolbarContextMenuSelector)
|
|
102
|
+
).$(`button=${tableSelectors.cellOptionsFloatingToolbarText}`);
|
|
103
|
+
await cellOptionsMenuItem.waitForClickable();
|
|
104
|
+
await cellOptionsMenuItem.click();
|
|
105
|
+
|
|
106
|
+
// Hover on the "Delete column" menu option on the context menu
|
|
107
|
+
const deleteColumnMenuItem = await (
|
|
108
|
+
await page.$(tableFloatingToolbarContextMenuSelector)
|
|
109
|
+
).$(`button=${tableSelectors.removeColumnText}`);
|
|
110
|
+
await deleteColumnMenuItem.moveTo();
|
|
111
|
+
await animationFrame(page);
|
|
112
|
+
|
|
113
|
+
// Check the first column cells should have the hover indicators appear
|
|
114
|
+
const hoverCells = await page.$$(
|
|
115
|
+
`tbody tr th.${TableCssClassName.HOVERED_CELL}.${TableCssClassName.HOVERED_COLUMN}, tbody tr td.${TableCssClassName.HOVERED_CELL}.${TableCssClassName.HOVERED_COLUMN}`,
|
|
116
|
+
);
|
|
117
|
+
expect(hoverCells.length).toBe(3);
|
|
118
|
+
|
|
119
|
+
const doc = await page.$eval(editable, getDocFromElement);
|
|
120
|
+
expect(doc).toMatchCustomDocSnapshot(testName);
|
|
121
|
+
},
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
BrowserTestCase(
|
|
125
|
+
'should show hover indicators on delete rows menu option',
|
|
126
|
+
{ skip: ['safari'] }, // The test does not pass on CI but works on physical browser
|
|
127
|
+
async (client: any, testName: string) => {
|
|
128
|
+
const page = await goToEditorTestingWDExample(
|
|
129
|
+
client,
|
|
130
|
+
'editor-plugin-table',
|
|
131
|
+
);
|
|
132
|
+
await mountEditor(page, {
|
|
133
|
+
appearance: fullpage.appearance,
|
|
134
|
+
allowTables: {
|
|
135
|
+
allowColumnSorting: true,
|
|
136
|
+
allowDistributeColumns: true,
|
|
137
|
+
allowCellOptionsInFloatingToolbar: true,
|
|
138
|
+
},
|
|
139
|
+
defaultValue: basicTable,
|
|
140
|
+
});
|
|
141
|
+
const tableFloatingToolbarContextMenuSelector = `div[aria-label="Table floating controls"][data-editor-popup=true]`;
|
|
142
|
+
|
|
143
|
+
// First click on the cell
|
|
144
|
+
await clickFirstCell(page);
|
|
145
|
+
|
|
146
|
+
// Table floating toolbar should appear, then click on "Cell Options", which brings up another context menu
|
|
147
|
+
const cellOptionsMenuItem = await (
|
|
148
|
+
await page.$(tableFloatingToolbarContextMenuSelector)
|
|
149
|
+
).$(`button=${tableSelectors.cellOptionsFloatingToolbarText}`);
|
|
150
|
+
await cellOptionsMenuItem.waitForClickable();
|
|
151
|
+
await cellOptionsMenuItem.click();
|
|
152
|
+
|
|
153
|
+
// Hover on the "Delete row" menu option on the context menu
|
|
154
|
+
const deleteRowMenuItem = await (
|
|
155
|
+
await page.$(tableFloatingToolbarContextMenuSelector)
|
|
156
|
+
).$(`button=${tableSelectors.removeRowText}`);
|
|
157
|
+
await deleteRowMenuItem.moveTo();
|
|
158
|
+
await animationFrame(page);
|
|
159
|
+
|
|
160
|
+
// Check the first row cells should have the hover indicators appear (second row from the top)
|
|
161
|
+
const hoverCells = await page.$$(
|
|
162
|
+
`tbody tr:nth-child(2) td.${TableCssClassName.HOVERED_CELL}.${TableCssClassName.HOVERED_ROW}`,
|
|
163
|
+
);
|
|
164
|
+
expect(hoverCells.length).toBe(3);
|
|
165
|
+
|
|
166
|
+
const doc = await page.$eval(editable, getDocFromElement);
|
|
167
|
+
expect(doc).toMatchCustomDocSnapshot(testName);
|
|
168
|
+
},
|
|
169
|
+
);
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { replaceRaf } from 'raf-stub';
|
|
3
|
+
import { TextSelection } from 'prosemirror-state';
|
|
4
|
+
|
|
5
|
+
import { Command } from '@atlaskit/editor-common/types';
|
|
3
6
|
import { render } from '@testing-library/react';
|
|
4
7
|
import { createEditorFactory } from '@atlaskit/editor-test-helpers/create-editor';
|
|
8
|
+
import { selectTableClosestToPos } from '@atlaskit/editor-tables/src/utils/select-nodes';
|
|
5
9
|
import tablePlugin from '../../../plugins/table-plugin';
|
|
6
10
|
import {
|
|
7
11
|
doc,
|
|
@@ -12,8 +16,13 @@ import {
|
|
|
12
16
|
tdEmpty,
|
|
13
17
|
tdCursor,
|
|
14
18
|
DocBuilder,
|
|
19
|
+
thEmpty,
|
|
15
20
|
} from '@atlaskit/editor-test-helpers/doc-builder';
|
|
16
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
findTable,
|
|
23
|
+
findTableClosestToPos,
|
|
24
|
+
selectTable,
|
|
25
|
+
} from '@atlaskit/editor-tables/utils';
|
|
17
26
|
import {
|
|
18
27
|
TableCssClassName as ClassName,
|
|
19
28
|
TablePluginState,
|
|
@@ -22,7 +31,11 @@ import TableComponent from '../../../plugins/table/nodeviews/TableComponent';
|
|
|
22
31
|
|
|
23
32
|
import { pluginKey } from '../../../plugins/table/pm-plugins/plugin-key';
|
|
24
33
|
import type { EventDispatcher } from '@atlaskit/editor-common/event-dispatcher';
|
|
25
|
-
import
|
|
34
|
+
import * as commands from '../../../plugins/table/commands';
|
|
35
|
+
import {
|
|
36
|
+
toggleNumberColumn,
|
|
37
|
+
hoverTable,
|
|
38
|
+
} from '../../../plugins/table/commands';
|
|
26
39
|
|
|
27
40
|
jest.mock('../../../plugins/table/utils/nodes', () =>
|
|
28
41
|
Object.assign({}, jest.requireActual('../../../plugins/table/utils/nodes'), {
|
|
@@ -30,6 +43,12 @@ jest.mock('../../../plugins/table/utils/nodes', () =>
|
|
|
30
43
|
}),
|
|
31
44
|
);
|
|
32
45
|
|
|
46
|
+
jest.mock('../../../plugins/table/commands', () =>
|
|
47
|
+
Object.assign({}, jest.requireActual('../../../plugins/table/commands'), {
|
|
48
|
+
clearHoverSelection: jest.fn(),
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
|
|
33
52
|
replaceRaf();
|
|
34
53
|
const requestAnimationFrame = window.requestAnimationFrame as any;
|
|
35
54
|
|
|
@@ -57,8 +76,8 @@ describe('table -> nodeviews -> TableComponent.tsx', () => {
|
|
|
57
76
|
jest.clearAllMocks();
|
|
58
77
|
});
|
|
59
78
|
|
|
60
|
-
describe('when
|
|
61
|
-
it('should add table selected css class', () => {
|
|
79
|
+
describe('when a table is selected', () => {
|
|
80
|
+
it('should add table selected css class to the selected table', () => {
|
|
62
81
|
const { editorView } = editor(
|
|
63
82
|
doc(p('text'), table()(tr(tdEmpty, tdEmpty, tdCursor))),
|
|
64
83
|
{
|
|
@@ -78,6 +97,129 @@ describe('table -> nodeviews -> TableComponent.tsx', () => {
|
|
|
78
97
|
tableContainer!.classList.contains(ClassName.TABLE_SELECTED),
|
|
79
98
|
).toBeTruthy();
|
|
80
99
|
});
|
|
100
|
+
|
|
101
|
+
it('should not clear the editor state hover selection when changing selection to another table', () => {
|
|
102
|
+
const clearHoverSelectionSpy = jest
|
|
103
|
+
.spyOn(commands, 'clearHoverSelection')
|
|
104
|
+
.mockImplementation(() => (() => {}) as any as Command);
|
|
105
|
+
|
|
106
|
+
const { editorView } = editor(
|
|
107
|
+
doc(
|
|
108
|
+
p('text'),
|
|
109
|
+
table()(tr(thEmpty, thEmpty, thEmpty)),
|
|
110
|
+
table()(tr(thEmpty, thEmpty, thEmpty)),
|
|
111
|
+
),
|
|
112
|
+
);
|
|
113
|
+
const { state, dispatch } = editorView;
|
|
114
|
+
|
|
115
|
+
const isInDanger = true;
|
|
116
|
+
hoverTable(isInDanger)(state, dispatch);
|
|
117
|
+
|
|
118
|
+
const selectSecondTableTr = selectTableClosestToPos(
|
|
119
|
+
state.tr,
|
|
120
|
+
state.doc.resolve(26),
|
|
121
|
+
);
|
|
122
|
+
dispatch(selectSecondTableTr);
|
|
123
|
+
const secondTable = findTableClosestToPos(state.doc.resolve(26));
|
|
124
|
+
|
|
125
|
+
const selectFirstTableTr = selectTableClosestToPos(
|
|
126
|
+
state.tr,
|
|
127
|
+
state.doc.resolve(8),
|
|
128
|
+
);
|
|
129
|
+
dispatch(selectFirstTableTr);
|
|
130
|
+
const firstTable = findTableClosestToPos(state.doc.resolve(8));
|
|
131
|
+
|
|
132
|
+
const getTableNode = (index: number) => () =>
|
|
133
|
+
index === 1 ? firstTable!.node : secondTable!.node;
|
|
134
|
+
|
|
135
|
+
render(
|
|
136
|
+
<div>
|
|
137
|
+
<TableComponent
|
|
138
|
+
view={editorView}
|
|
139
|
+
eventDispatcher={
|
|
140
|
+
{ on: () => {}, off: () => {} } as any as EventDispatcher
|
|
141
|
+
}
|
|
142
|
+
// @ts-ignore
|
|
143
|
+
containerWidth={{}}
|
|
144
|
+
// @ts-ignore
|
|
145
|
+
getNode={getTableNode(1)}
|
|
146
|
+
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
147
|
+
allowControls
|
|
148
|
+
contentDOM={(wrapper: HTMLElement | null) => {
|
|
149
|
+
const node = editorView.dom.getElementsByTagName('table')[0];
|
|
150
|
+
if (!wrapper?.firstChild) {
|
|
151
|
+
wrapper?.appendChild(node);
|
|
152
|
+
}
|
|
153
|
+
}}
|
|
154
|
+
/>
|
|
155
|
+
<TableComponent
|
|
156
|
+
view={editorView}
|
|
157
|
+
eventDispatcher={
|
|
158
|
+
{ on: () => {}, off: () => {} } as any as EventDispatcher
|
|
159
|
+
}
|
|
160
|
+
// @ts-ignore
|
|
161
|
+
containerWidth={{}}
|
|
162
|
+
// @ts-ignore
|
|
163
|
+
getNode={getTableNode(2)}
|
|
164
|
+
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
165
|
+
allowControls
|
|
166
|
+
contentDOM={(wrapper: HTMLElement | null) => {
|
|
167
|
+
const node = editorView.dom.getElementsByTagName('table')[0];
|
|
168
|
+
if (!wrapper?.firstChild) {
|
|
169
|
+
wrapper?.appendChild(node);
|
|
170
|
+
}
|
|
171
|
+
}}
|
|
172
|
+
/>
|
|
173
|
+
,
|
|
174
|
+
</div>,
|
|
175
|
+
);
|
|
176
|
+
expect(clearHoverSelectionSpy).not.toBeCalled();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
describe('when there are no tables in selection', () => {
|
|
181
|
+
it('clears the editor state hover selection if the editor state is in danger flag is set', () => {
|
|
182
|
+
const clearHoverSelectionSpy = jest
|
|
183
|
+
.spyOn(commands, 'clearHoverSelection')
|
|
184
|
+
.mockImplementation(() => (() => {}) as any as Command);
|
|
185
|
+
|
|
186
|
+
const { editorView } = editor(
|
|
187
|
+
doc(p('text'), table()(tr(thEmpty, thEmpty, thEmpty))),
|
|
188
|
+
);
|
|
189
|
+
const { state, dispatch } = editorView;
|
|
190
|
+
|
|
191
|
+
const isInDanger = true;
|
|
192
|
+
hoverTable(isInDanger)(state, dispatch);
|
|
193
|
+
dispatch(selectTable(state.tr));
|
|
194
|
+
|
|
195
|
+
const tableF = findTable(state.selection);
|
|
196
|
+
const getNode = () => tableF!.node;
|
|
197
|
+
|
|
198
|
+
const newTr = state.tr.setSelection(TextSelection.create(state.doc, 0));
|
|
199
|
+
dispatch(newTr);
|
|
200
|
+
|
|
201
|
+
render(
|
|
202
|
+
<TableComponent
|
|
203
|
+
view={editorView}
|
|
204
|
+
eventDispatcher={
|
|
205
|
+
{ on: () => {}, off: () => {} } as any as EventDispatcher
|
|
206
|
+
}
|
|
207
|
+
// @ts-ignore
|
|
208
|
+
containerWidth={{}}
|
|
209
|
+
// @ts-ignore
|
|
210
|
+
getNode={getNode}
|
|
211
|
+
getEditorFeatureFlags={getEditorFeatureFlags}
|
|
212
|
+
allowControls
|
|
213
|
+
contentDOM={(wrapper: HTMLElement | null) => {
|
|
214
|
+
const node = editorView.dom.getElementsByTagName('table')[0];
|
|
215
|
+
if (!wrapper?.firstChild) {
|
|
216
|
+
wrapper?.appendChild(node);
|
|
217
|
+
}
|
|
218
|
+
}}
|
|
219
|
+
/>,
|
|
220
|
+
);
|
|
221
|
+
expect(clearHoverSelectionSpy).toBeCalledTimes(1);
|
|
222
|
+
});
|
|
81
223
|
});
|
|
82
224
|
|
|
83
225
|
describe('when the numbered column attribute is changed', () => {
|
|
@@ -21,10 +21,12 @@ import {
|
|
|
21
21
|
|
|
22
22
|
import tablePlugin from '../../../../plugins/table';
|
|
23
23
|
import { pluginKey } from '../../../../plugins/table/pm-plugins/plugin-key';
|
|
24
|
-
import { TextSelection, NodeSelection } from 'prosemirror-state';
|
|
24
|
+
import { TextSelection, NodeSelection, EditorState } from 'prosemirror-state';
|
|
25
|
+
import { EditorView } from 'prosemirror-view';
|
|
25
26
|
import panelPlugin from '@atlaskit/editor-core/src/plugins/panel';
|
|
26
27
|
import widthPlugin from '@atlaskit/editor-core/src/plugins/width';
|
|
27
28
|
import type { EditorAnalyticsAPI } from '@atlaskit/editor-common/analytics';
|
|
29
|
+
import { akEditorFullPageMaxWidth } from '@atlaskit/editor-shared-styles/consts';
|
|
28
30
|
|
|
29
31
|
describe('table-resizing/event-handlers', () => {
|
|
30
32
|
const editorAnalyticsAPIFake: EditorAnalyticsAPI = {
|
|
@@ -57,18 +59,7 @@ describe('table-resizing/event-handlers', () => {
|
|
|
57
59
|
doc(table()(tr(td()(p('1')), td()(p('2')), td()(p('3{<>}'))))),
|
|
58
60
|
);
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const mousedownEvent = new MouseEvent('mousedown', {
|
|
63
|
-
clientX: 150,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
view.dom.dispatchEvent(mousedownEvent);
|
|
67
|
-
|
|
68
|
-
const mouseupEvent = new MouseEvent('mouseup', {
|
|
69
|
-
clientX: 250,
|
|
70
|
-
});
|
|
71
|
-
window.dispatchEvent(mouseupEvent);
|
|
62
|
+
resizeColumn(view, 12, 150, 250);
|
|
72
63
|
|
|
73
64
|
expect(editorAnalyticsAPIFake.attachAnalyticsEvent).toHaveBeenCalledWith(
|
|
74
65
|
expect.objectContaining({
|
|
@@ -85,6 +76,50 @@ describe('table-resizing/event-handlers', () => {
|
|
|
85
76
|
);
|
|
86
77
|
});
|
|
87
78
|
|
|
79
|
+
it('should shrink last column until table is no longer overflowing', async () => {
|
|
80
|
+
const { editorView: view } = editor(
|
|
81
|
+
doc(table()(tr(td()(p('1')), td()(p('2')), td()(p('3{<>}'))))),
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Increase column to overflow
|
|
85
|
+
resizeColumn(view, 7, 50, 500);
|
|
86
|
+
|
|
87
|
+
expect(getTotalTableWidth(view.state as EditorState)).toBeGreaterThan(
|
|
88
|
+
akEditorFullPageMaxWidth,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
resizeColumn(view, 12, 3000, 700);
|
|
92
|
+
|
|
93
|
+
// No matter how large we try to resize the result should equal the width (within 1 pt)
|
|
94
|
+
expect(getTotalTableWidth(view.state as EditorState)).toBeLessThanOrEqual(
|
|
95
|
+
akEditorFullPageMaxWidth,
|
|
96
|
+
);
|
|
97
|
+
expect(
|
|
98
|
+
getTotalTableWidth(view.state as EditorState),
|
|
99
|
+
).toBeGreaterThanOrEqual(akEditorFullPageMaxWidth - 1);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('should not resize the last column to grow', async () => {
|
|
103
|
+
const { editorView: view } = editor(
|
|
104
|
+
doc(table()(tr(td()(p('1')), td()(p('2')), td()(p('3{<>}'))))),
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
// Increase column to overflow
|
|
108
|
+
resizeColumn(view, 7, 50, 500);
|
|
109
|
+
|
|
110
|
+
const overflowingTableWidth = getTotalTableWidth(
|
|
111
|
+
view.state as EditorState,
|
|
112
|
+
);
|
|
113
|
+
expect(overflowingTableWidth).toBeGreaterThan(akEditorFullPageMaxWidth);
|
|
114
|
+
|
|
115
|
+
resizeColumn(view, 12, 400, 3000);
|
|
116
|
+
|
|
117
|
+
// Width should be unchanged
|
|
118
|
+
expect(getTotalTableWidth(view.state as EditorState)).toBe(
|
|
119
|
+
overflowingTableWidth,
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
|
|
88
123
|
it('should restore text selection after replacing the table', async () => {
|
|
89
124
|
const { editorView: view } = editor(
|
|
90
125
|
doc(table()(tr(td()(p('1')), td()(p('2')), td()(p('3{<>}'))))),
|
|
@@ -94,15 +129,7 @@ describe('table-resizing/event-handlers', () => {
|
|
|
94
129
|
expect(currentSelection instanceof TextSelection).toBeTruthy();
|
|
95
130
|
expect(currentSelection.$cursor.pos).toBe(15);
|
|
96
131
|
|
|
97
|
-
|
|
98
|
-
const mousedownEvent = new MouseEvent('mousedown', {
|
|
99
|
-
clientX: 150,
|
|
100
|
-
});
|
|
101
|
-
view.dom.dispatchEvent(mousedownEvent);
|
|
102
|
-
const mouseupEvent = new MouseEvent('mouseup', {
|
|
103
|
-
clientX: 250,
|
|
104
|
-
});
|
|
105
|
-
window.dispatchEvent(mouseupEvent);
|
|
132
|
+
resizeColumn(view, 12, 150, 250);
|
|
106
133
|
|
|
107
134
|
expect(currentSelection instanceof TextSelection).toBeTruthy();
|
|
108
135
|
expect(currentSelection.$cursor.pos).toBe(15);
|
|
@@ -118,17 +145,41 @@ describe('table-resizing/event-handlers', () => {
|
|
|
118
145
|
view.dispatch(_tr);
|
|
119
146
|
expect(view.state.tr.selection.node.type.name).toBe('panel');
|
|
120
147
|
|
|
121
|
-
|
|
122
|
-
const mousedownEvent = new MouseEvent('mousedown', {
|
|
123
|
-
clientX: 150,
|
|
124
|
-
});
|
|
125
|
-
view.dom.dispatchEvent(mousedownEvent);
|
|
126
|
-
const mouseupEvent = new MouseEvent('mouseup', {
|
|
127
|
-
clientX: 250,
|
|
128
|
-
});
|
|
129
|
-
window.dispatchEvent(mouseupEvent);
|
|
148
|
+
resizeColumn(view, 13, 150, 250);
|
|
130
149
|
|
|
131
150
|
expect(view.state.tr.selection.node.type.name).toBe('panel');
|
|
132
151
|
});
|
|
133
152
|
});
|
|
134
153
|
});
|
|
154
|
+
|
|
155
|
+
function getTotalTableWidth(state: EditorState) {
|
|
156
|
+
let totalWidth = 0;
|
|
157
|
+
state.doc.descendants((node) => {
|
|
158
|
+
if (node.type.name === 'tableCell') {
|
|
159
|
+
totalWidth += node.attrs.colwidth[0];
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
return true;
|
|
163
|
+
});
|
|
164
|
+
return totalWidth;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function resizeColumn(
|
|
168
|
+
view: EditorView,
|
|
169
|
+
pos: number,
|
|
170
|
+
start: number,
|
|
171
|
+
end: number,
|
|
172
|
+
) {
|
|
173
|
+
setResizeHandlePos(pos)(view.state, view.dispatch);
|
|
174
|
+
|
|
175
|
+
const firstmousedownEvent = new MouseEvent('mousedown', {
|
|
176
|
+
clientX: start,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
view.dom.dispatchEvent(firstmousedownEvent);
|
|
180
|
+
|
|
181
|
+
const firstmouseupEvent = new MouseEvent('mouseup', {
|
|
182
|
+
clientX: end,
|
|
183
|
+
});
|
|
184
|
+
window.dispatchEvent(firstmouseupEvent);
|
|
185
|
+
}
|