@atlaskit/editor-plugin-table 5.5.4 → 5.5.5
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 +7 -0
- package/dist/cjs/plugins/table/pm-plugins/drag-and-drop/plugin.js +1 -3
- package/dist/cjs/plugins/table/ui/FloatingInsertButton/index.js +0 -3
- package/dist/cjs/plugins/table/utils/index.js +6 -0
- package/dist/cjs/plugins/table/utils/merged-cells.js +75 -1
- package/dist/es2019/plugins/table/pm-plugins/drag-and-drop/plugin.js +2 -4
- package/dist/es2019/plugins/table/ui/FloatingInsertButton/index.js +0 -3
- package/dist/es2019/plugins/table/utils/index.js +1 -1
- package/dist/es2019/plugins/table/utils/merged-cells.js +63 -1
- package/dist/esm/plugins/table/pm-plugins/drag-and-drop/plugin.js +2 -4
- package/dist/esm/plugins/table/ui/FloatingInsertButton/index.js +0 -3
- package/dist/esm/plugins/table/utils/index.js +1 -1
- package/dist/esm/plugins/table/utils/merged-cells.js +73 -0
- package/dist/types/plugins/table/utils/index.d.ts +1 -1
- package/dist/types/plugins/table/utils/merged-cells.d.ts +3 -0
- package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/utils/merged-cells.d.ts +3 -0
- package/package.json +1 -1
- package/src/__tests__/unit/ui/FloatingInsertButton.tsx +3 -3
- package/src/__tests__/unit/utils/merged-cells.ts +156 -0
- package/src/plugins/table/pm-plugins/drag-and-drop/plugin.ts +9 -9
- package/src/plugins/table/ui/FloatingInsertButton/index.tsx +0 -3
- package/src/plugins/table/utils/index.ts +5 -1
- package/src/plugins/table/utils/merged-cells.ts +82 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-table
|
|
2
2
|
|
|
3
|
+
## 5.5.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#59951](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/59951) [`a42a17e8af1b`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/a42a17e8af1b) - ED-21106: Remove nonPrivacySafeAttributes from editor operational events
|
|
8
|
+
- [#59453](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/59453) [`e23de3e96559`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e23de3e96559) - Fix drop table row/column next to merged cells
|
|
9
|
+
|
|
3
10
|
## 5.5.4
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -13,7 +13,6 @@ var _cellSelection = require("@atlaskit/editor-tables/cell-selection");
|
|
|
13
13
|
var _utils = require("@atlaskit/editor-tables/utils");
|
|
14
14
|
var _element = require("@atlaskit/pragmatic-drag-and-drop/adapter/element");
|
|
15
15
|
var _utils2 = require("../../utils");
|
|
16
|
-
var _mergedCells = require("../../utils/merged-cells");
|
|
17
16
|
var _pluginFactory = require("../plugin-factory");
|
|
18
17
|
var _pluginKey = require("../plugin-key");
|
|
19
18
|
var _actions = require("./actions");
|
|
@@ -182,8 +181,7 @@ var createPlugin = exports.createPlugin = function createPlugin(dispatch, eventD
|
|
|
182
181
|
}
|
|
183
182
|
|
|
184
183
|
// If the drop target index contains merged cells then we should not allow the drop to occur.
|
|
185
|
-
|
|
186
|
-
if (hasMergedCells(targetAdjustedIndex)(editorView.state.selection)) {
|
|
184
|
+
if ((0, _utils2.hasMergedCellsInBetween)([targetAdjustedIndex - 1, targetAdjustedIndex], sourceType === 'table-row' ? _consts.DropTargetType.ROW : _consts.DropTargetType.COLUMN)(editorView.state.selection)) {
|
|
187
185
|
(0, _commands.clearDropTarget)(tr)(editorView.state, editorView.dispatch);
|
|
188
186
|
return;
|
|
189
187
|
}
|
|
@@ -105,9 +105,6 @@ var FloatingInsertButton = exports.FloatingInsertButton = /*#__PURE__*/function
|
|
|
105
105
|
position: pos,
|
|
106
106
|
docSize: editorView.state.doc.nodeSize,
|
|
107
107
|
error: error === null || error === void 0 ? void 0 : error.toString()
|
|
108
|
-
},
|
|
109
|
-
nonPrivacySafeAttributes: {
|
|
110
|
-
errorStack: error.stack || undefined
|
|
111
108
|
}
|
|
112
109
|
};
|
|
113
110
|
dispatchAnalyticsEvent(payload);
|
|
@@ -213,6 +213,12 @@ Object.defineProperty(exports, "getTableWidth", {
|
|
|
213
213
|
return _nodes.getTableWidth;
|
|
214
214
|
}
|
|
215
215
|
});
|
|
216
|
+
Object.defineProperty(exports, "hasMergedCellsInBetween", {
|
|
217
|
+
enumerable: true,
|
|
218
|
+
get: function get() {
|
|
219
|
+
return _mergedCells.hasMergedCellsInBetween;
|
|
220
|
+
}
|
|
221
|
+
});
|
|
216
222
|
Object.defineProperty(exports, "hasMergedCellsInColumn", {
|
|
217
223
|
enumerable: true,
|
|
218
224
|
get: function get() {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
|
-
exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = void 0;
|
|
7
|
+
exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = exports.hasMergedCellsInBetween = void 0;
|
|
8
|
+
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
7
9
|
var _editorTables = require("@atlaskit/editor-tables");
|
|
8
10
|
var hasMergedCells = function hasMergedCells(indexes, normalizeRect) {
|
|
9
11
|
return function (selection) {
|
|
@@ -63,4 +65,76 @@ var hasMergedCellsInRow = exports.hasMergedCellsInRow = function hasMergedCellsI
|
|
|
63
65
|
bottom: y === index ? y + 1 : y
|
|
64
66
|
};
|
|
65
67
|
});
|
|
68
|
+
};
|
|
69
|
+
var getRect = function getRect(index, type, map) {
|
|
70
|
+
if (type === 'column') {
|
|
71
|
+
var x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
|
|
72
|
+
return {
|
|
73
|
+
left: x,
|
|
74
|
+
right: x === index ? x + 1 : x,
|
|
75
|
+
top: 0,
|
|
76
|
+
bottom: map.height
|
|
77
|
+
};
|
|
78
|
+
} else {
|
|
79
|
+
var y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
|
|
80
|
+
return {
|
|
81
|
+
left: 0,
|
|
82
|
+
right: map.width,
|
|
83
|
+
top: y,
|
|
84
|
+
bottom: y === index ? y + 1 : y
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
var hasMergedCellsInBetween = exports.hasMergedCellsInBetween = function hasMergedCellsInBetween(indexes, type) {
|
|
89
|
+
return function (selection) {
|
|
90
|
+
var table = (0, _editorTables.findTable)(selection);
|
|
91
|
+
if (!table) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
var map = _editorTables.TableMap.get(table.node);
|
|
95
|
+
var cellPositions = new Set();
|
|
96
|
+
var mergedCells = new Set();
|
|
97
|
+
map.map.forEach(function (value) {
|
|
98
|
+
if (cellPositions.has(value)) {
|
|
99
|
+
mergedCells.add(value);
|
|
100
|
+
} else {
|
|
101
|
+
cellPositions.add(value);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
if (!mergedCells.size) {
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
var getMergedCellsInRect = function getMergedCellsInRect(index, type) {
|
|
108
|
+
var rect = getRect(index, type, map);
|
|
109
|
+
var isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
|
|
110
|
+
if (!isValidRectangle) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
var cells = map.cellsInRect(rect);
|
|
114
|
+
var allCellsInRect = [];
|
|
115
|
+
if (type === 'column') {
|
|
116
|
+
allCellsInRect = map.map.filter(function (_, key) {
|
|
117
|
+
return key % map.width === index;
|
|
118
|
+
});
|
|
119
|
+
} else {
|
|
120
|
+
allCellsInRect = map.map.filter(function (_, key) {
|
|
121
|
+
return Math.floor(key / map.width) === index;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
var mergedCell = allCellsInRect.filter(function (nodePos) {
|
|
125
|
+
return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
|
|
126
|
+
? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return (0, _toConsumableArray2.default)(new Set(mergedCell));
|
|
130
|
+
};
|
|
131
|
+
var mergedCellsInRectArr = indexes.map(function (index) {
|
|
132
|
+
return getMergedCellsInRect(index, type);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Currently only support 2 indexes, but we can extend this to support more indexes in the future.
|
|
136
|
+
return mergedCellsInRectArr[0].some(function (cell) {
|
|
137
|
+
return mergedCellsInRectArr[1].includes(cell);
|
|
138
|
+
});
|
|
139
|
+
};
|
|
66
140
|
};
|
|
@@ -3,8 +3,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
|
3
3
|
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
|
|
4
4
|
import { getCellsInRow } from '@atlaskit/editor-tables/utils';
|
|
5
5
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
6
|
-
import { findNearestCellIndexToPoint } from '../../utils';
|
|
7
|
-
import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils/merged-cells';
|
|
6
|
+
import { findNearestCellIndexToPoint, hasMergedCellsInBetween } from '../../utils';
|
|
8
7
|
import { getPluginState as getTablePluginState } from '../plugin-factory';
|
|
9
8
|
import { pluginKey as tablePluginKey } from '../plugin-key';
|
|
10
9
|
import { DragAndDropActionType } from './actions';
|
|
@@ -184,8 +183,7 @@ export const createPlugin = (dispatch, eventDispatcher) => {
|
|
|
184
183
|
}
|
|
185
184
|
|
|
186
185
|
// If the drop target index contains merged cells then we should not allow the drop to occur.
|
|
187
|
-
|
|
188
|
-
if (hasMergedCells(targetAdjustedIndex)(editorView.state.selection)) {
|
|
186
|
+
if (hasMergedCellsInBetween([targetAdjustedIndex - 1, targetAdjustedIndex], sourceType === 'table-row' ? DropTargetType.ROW : DropTargetType.COLUMN)(editorView.state.selection)) {
|
|
189
187
|
clearDropTarget(tr)(editorView.state, editorView.dispatch);
|
|
190
188
|
return;
|
|
191
189
|
}
|
|
@@ -85,9 +85,6 @@ export class FloatingInsertButton extends React.Component {
|
|
|
85
85
|
position: pos,
|
|
86
86
|
docSize: editorView.state.doc.nodeSize,
|
|
87
87
|
error: error === null || error === void 0 ? void 0 : error.toString()
|
|
88
|
-
},
|
|
89
|
-
nonPrivacySafeAttributes: {
|
|
90
|
-
errorStack: error.stack || undefined
|
|
91
88
|
}
|
|
92
89
|
};
|
|
93
90
|
dispatchAnalyticsEvent(payload);
|
|
@@ -8,4 +8,4 @@ export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getR
|
|
|
8
8
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
9
9
|
export { getMergedCellsPositions } from './table';
|
|
10
10
|
export { updatePluginStateDecorations } from './update-plugin-state-decorations';
|
|
11
|
-
export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
|
|
11
|
+
export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween } from './merged-cells';
|
|
@@ -45,4 +45,66 @@ export const hasMergedCellsInRow = rowIndexes => hasMergedCells(rowIndexes, (ind
|
|
|
45
45
|
top: y,
|
|
46
46
|
bottom: y === index ? y + 1 : y
|
|
47
47
|
};
|
|
48
|
-
});
|
|
48
|
+
});
|
|
49
|
+
const getRect = (index, type, map) => {
|
|
50
|
+
if (type === 'column') {
|
|
51
|
+
const x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
|
|
52
|
+
return {
|
|
53
|
+
left: x,
|
|
54
|
+
right: x === index ? x + 1 : x,
|
|
55
|
+
top: 0,
|
|
56
|
+
bottom: map.height
|
|
57
|
+
};
|
|
58
|
+
} else {
|
|
59
|
+
const y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
|
|
60
|
+
return {
|
|
61
|
+
left: 0,
|
|
62
|
+
right: map.width,
|
|
63
|
+
top: y,
|
|
64
|
+
bottom: y === index ? y + 1 : y
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
export const hasMergedCellsInBetween = (indexes, type) => selection => {
|
|
69
|
+
const table = findTable(selection);
|
|
70
|
+
if (!table) {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
const map = TableMap.get(table.node);
|
|
74
|
+
const cellPositions = new Set();
|
|
75
|
+
const mergedCells = new Set();
|
|
76
|
+
map.map.forEach(value => {
|
|
77
|
+
if (cellPositions.has(value)) {
|
|
78
|
+
mergedCells.add(value);
|
|
79
|
+
} else {
|
|
80
|
+
cellPositions.add(value);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (!mergedCells.size) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
const getMergedCellsInRect = (index, type) => {
|
|
87
|
+
const rect = getRect(index, type, map);
|
|
88
|
+
const isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
|
|
89
|
+
if (!isValidRectangle) {
|
|
90
|
+
return [];
|
|
91
|
+
}
|
|
92
|
+
const cells = map.cellsInRect(rect);
|
|
93
|
+
let allCellsInRect = [];
|
|
94
|
+
if (type === 'column') {
|
|
95
|
+
allCellsInRect = map.map.filter((_, key) => key % map.width === index);
|
|
96
|
+
} else {
|
|
97
|
+
allCellsInRect = map.map.filter((_, key) => Math.floor(key / map.width) === index);
|
|
98
|
+
}
|
|
99
|
+
const mergedCell = allCellsInRect.filter(nodePos => {
|
|
100
|
+
return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
|
|
101
|
+
? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
return [...new Set(mergedCell)];
|
|
105
|
+
};
|
|
106
|
+
const mergedCellsInRectArr = indexes.map(index => getMergedCellsInRect(index, type));
|
|
107
|
+
|
|
108
|
+
// Currently only support 2 indexes, but we can extend this to support more indexes in the future.
|
|
109
|
+
return mergedCellsInRectArr[0].some(cell => mergedCellsInRectArr[1].includes(cell));
|
|
110
|
+
};
|
|
@@ -7,8 +7,7 @@ import { DecorationSet } from '@atlaskit/editor-prosemirror/view';
|
|
|
7
7
|
import { CellSelection } from '@atlaskit/editor-tables/cell-selection';
|
|
8
8
|
import { getCellsInRow } from '@atlaskit/editor-tables/utils';
|
|
9
9
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
10
|
-
import { findNearestCellIndexToPoint } from '../../utils';
|
|
11
|
-
import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils/merged-cells';
|
|
10
|
+
import { findNearestCellIndexToPoint, hasMergedCellsInBetween } from '../../utils';
|
|
12
11
|
import { getPluginState as getTablePluginState } from '../plugin-factory';
|
|
13
12
|
import { pluginKey as tablePluginKey } from '../plugin-key';
|
|
14
13
|
import { DragAndDropActionType } from './actions';
|
|
@@ -175,8 +174,7 @@ export var createPlugin = function createPlugin(dispatch, eventDispatcher) {
|
|
|
175
174
|
}
|
|
176
175
|
|
|
177
176
|
// If the drop target index contains merged cells then we should not allow the drop to occur.
|
|
178
|
-
|
|
179
|
-
if (hasMergedCells(targetAdjustedIndex)(editorView.state.selection)) {
|
|
177
|
+
if (hasMergedCellsInBetween([targetAdjustedIndex - 1, targetAdjustedIndex], sourceType === 'table-row' ? DropTargetType.ROW : DropTargetType.COLUMN)(editorView.state.selection)) {
|
|
180
178
|
clearDropTarget(tr)(editorView.state, editorView.dispatch);
|
|
181
179
|
return;
|
|
182
180
|
}
|
|
@@ -95,9 +95,6 @@ export var FloatingInsertButton = /*#__PURE__*/function (_React$Component) {
|
|
|
95
95
|
position: pos,
|
|
96
96
|
docSize: editorView.state.doc.nodeSize,
|
|
97
97
|
error: error === null || error === void 0 ? void 0 : error.toString()
|
|
98
|
-
},
|
|
99
|
-
nonPrivacySafeAttributes: {
|
|
100
|
-
errorStack: error.stack || undefined
|
|
101
98
|
}
|
|
102
99
|
};
|
|
103
100
|
dispatchAnalyticsEvent(payload);
|
|
@@ -8,4 +8,4 @@ export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getR
|
|
|
8
8
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
9
9
|
export { getMergedCellsPositions } from './table';
|
|
10
10
|
export { updatePluginStateDecorations } from './update-plugin-state-decorations';
|
|
11
|
-
export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
|
|
11
|
+
export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween } from './merged-cells';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
1
2
|
import { findTable, TableMap } from '@atlaskit/editor-tables';
|
|
2
3
|
var hasMergedCells = function hasMergedCells(indexes, normalizeRect) {
|
|
3
4
|
return function (selection) {
|
|
@@ -57,4 +58,76 @@ export var hasMergedCellsInRow = function hasMergedCellsInRow(rowIndexes) {
|
|
|
57
58
|
bottom: y === index ? y + 1 : y
|
|
58
59
|
};
|
|
59
60
|
});
|
|
61
|
+
};
|
|
62
|
+
var getRect = function getRect(index, type, map) {
|
|
63
|
+
if (type === 'column') {
|
|
64
|
+
var x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
|
|
65
|
+
return {
|
|
66
|
+
left: x,
|
|
67
|
+
right: x === index ? x + 1 : x,
|
|
68
|
+
top: 0,
|
|
69
|
+
bottom: map.height
|
|
70
|
+
};
|
|
71
|
+
} else {
|
|
72
|
+
var y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
|
|
73
|
+
return {
|
|
74
|
+
left: 0,
|
|
75
|
+
right: map.width,
|
|
76
|
+
top: y,
|
|
77
|
+
bottom: y === index ? y + 1 : y
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
export var hasMergedCellsInBetween = function hasMergedCellsInBetween(indexes, type) {
|
|
82
|
+
return function (selection) {
|
|
83
|
+
var table = findTable(selection);
|
|
84
|
+
if (!table) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
var map = TableMap.get(table.node);
|
|
88
|
+
var cellPositions = new Set();
|
|
89
|
+
var mergedCells = new Set();
|
|
90
|
+
map.map.forEach(function (value) {
|
|
91
|
+
if (cellPositions.has(value)) {
|
|
92
|
+
mergedCells.add(value);
|
|
93
|
+
} else {
|
|
94
|
+
cellPositions.add(value);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
if (!mergedCells.size) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
var getMergedCellsInRect = function getMergedCellsInRect(index, type) {
|
|
101
|
+
var rect = getRect(index, type, map);
|
|
102
|
+
var isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
|
|
103
|
+
if (!isValidRectangle) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
var cells = map.cellsInRect(rect);
|
|
107
|
+
var allCellsInRect = [];
|
|
108
|
+
if (type === 'column') {
|
|
109
|
+
allCellsInRect = map.map.filter(function (_, key) {
|
|
110
|
+
return key % map.width === index;
|
|
111
|
+
});
|
|
112
|
+
} else {
|
|
113
|
+
allCellsInRect = map.map.filter(function (_, key) {
|
|
114
|
+
return Math.floor(key / map.width) === index;
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
var mergedCell = allCellsInRect.filter(function (nodePos) {
|
|
118
|
+
return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
|
|
119
|
+
? true : mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
return _toConsumableArray(new Set(mergedCell));
|
|
123
|
+
};
|
|
124
|
+
var mergedCellsInRectArr = indexes.map(function (index) {
|
|
125
|
+
return getMergedCellsInRect(index, type);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Currently only support 2 indexes, but we can extend this to support more indexes in the future.
|
|
129
|
+
return mergedCellsInRectArr[0].some(function (cell) {
|
|
130
|
+
return mergedCellsInRectArr[1].includes(cell);
|
|
131
|
+
});
|
|
132
|
+
};
|
|
60
133
|
};
|
|
@@ -9,4 +9,4 @@ export type { RowParams } from './row-controls';
|
|
|
9
9
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
10
10
|
export { getMergedCellsPositions } from './table';
|
|
11
11
|
export { updatePluginStateDecorations } from './update-plugin-state-decorations';
|
|
12
|
-
export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
|
|
12
|
+
export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween, } from './merged-cells';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
type MergeType = 'row' | 'column';
|
|
2
3
|
export declare const hasMergedCellsInColumn: (columnIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
3
4
|
export declare const hasMergedCellsInRow: (rowIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
5
|
+
export declare const hasMergedCellsInBetween: (indexes: number[], type: MergeType) => (selection: Selection) => boolean;
|
|
6
|
+
export {};
|
|
@@ -9,4 +9,4 @@ export type { RowParams } from './row-controls';
|
|
|
9
9
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
10
10
|
export { getMergedCellsPositions } from './table';
|
|
11
11
|
export { updatePluginStateDecorations } from './update-plugin-state-decorations';
|
|
12
|
-
export { hasMergedCellsInColumn, hasMergedCellsInRow } from './merged-cells';
|
|
12
|
+
export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween, } from './merged-cells';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
|
+
type MergeType = 'row' | 'column';
|
|
2
3
|
export declare const hasMergedCellsInColumn: (columnIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
3
4
|
export declare const hasMergedCellsInRow: (rowIndexes: number | number[]) => (selection: Selection) => boolean;
|
|
5
|
+
export declare const hasMergedCellsInBetween: (indexes: number[], type: MergeType) => (selection: Selection) => boolean;
|
|
6
|
+
export {};
|
package/package.json
CHANGED
|
@@ -144,9 +144,9 @@ describe('Floating Insert Button when findDomRefAtPos fails', () => {
|
|
|
144
144
|
docSize: 46,
|
|
145
145
|
error: 'Error: Error message from mock',
|
|
146
146
|
}),
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
});
|
|
148
|
+
expect(createAnalyticsEvent).not.toHaveBeenCalledWith({
|
|
149
|
+
nonPrivacySafeAttributes: expect.any(Object),
|
|
150
150
|
});
|
|
151
151
|
});
|
|
152
152
|
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { DocBuilder } from '@atlaskit/editor-common/types';
|
|
2
|
+
// eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
|
|
3
|
+
import { analyticsPlugin } from '@atlaskit/editor-plugin-analytics';
|
|
4
|
+
import { contentInsertionPlugin } from '@atlaskit/editor-plugin-content-insertion';
|
|
5
|
+
import { guidelinePlugin } from '@atlaskit/editor-plugin-guideline';
|
|
6
|
+
import { selectionPlugin } from '@atlaskit/editor-plugin-selection';
|
|
7
|
+
import { widthPlugin } from '@atlaskit/editor-plugin-width';
|
|
8
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
9
|
+
import type { LightEditorPlugin } from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
|
|
10
|
+
// eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
|
|
11
|
+
import {
|
|
12
|
+
createProsemirrorEditorFactory,
|
|
13
|
+
Preset,
|
|
14
|
+
} from '@atlaskit/editor-test-helpers/create-prosemirror-editor';
|
|
15
|
+
// eslint-disable-next-line import/no-extraneous-dependencies -- Removed import for fixing circular dependencies
|
|
16
|
+
import {
|
|
17
|
+
doc,
|
|
18
|
+
p,
|
|
19
|
+
table,
|
|
20
|
+
td,
|
|
21
|
+
tdEmpty,
|
|
22
|
+
tr,
|
|
23
|
+
} from '@atlaskit/editor-test-helpers/doc-builder';
|
|
24
|
+
|
|
25
|
+
import tablePlugin from '../../../plugins/table-plugin';
|
|
26
|
+
import { pluginKey } from '../../../plugins/table/pm-plugins/plugin-key';
|
|
27
|
+
import { hasMergedCellsInBetween } from '../../../plugins/table/utils';
|
|
28
|
+
|
|
29
|
+
describe('table merge cells logic', () => {
|
|
30
|
+
const createEditor = createProsemirrorEditorFactory();
|
|
31
|
+
|
|
32
|
+
const editor = (doc: DocBuilder) =>
|
|
33
|
+
createEditor({
|
|
34
|
+
doc,
|
|
35
|
+
preset: new Preset<LightEditorPlugin>()
|
|
36
|
+
.add([analyticsPlugin, {}])
|
|
37
|
+
.add(contentInsertionPlugin)
|
|
38
|
+
.add(widthPlugin)
|
|
39
|
+
.add(guidelinePlugin)
|
|
40
|
+
.add(selectionPlugin)
|
|
41
|
+
.add(tablePlugin),
|
|
42
|
+
pluginKey,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe('#hasMergedCellsInBetween', () => {
|
|
46
|
+
describe('when first and second columns are merged', () => {
|
|
47
|
+
const { editorView } = editor(
|
|
48
|
+
doc(
|
|
49
|
+
table()(
|
|
50
|
+
tr(td({ colspan: 2 })(p('')), tdEmpty, tdEmpty),
|
|
51
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
52
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
53
|
+
),
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
it('should return false when pass indexs [-1, 0]', () => {
|
|
58
|
+
expect(
|
|
59
|
+
hasMergedCellsInBetween(
|
|
60
|
+
[-1, 0],
|
|
61
|
+
'column',
|
|
62
|
+
)(editorView.state.selection),
|
|
63
|
+
).toEqual(false);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should return true when pass indexs [0,1]', () => {
|
|
67
|
+
expect(
|
|
68
|
+
hasMergedCellsInBetween([0, 1], 'column')(editorView.state.selection),
|
|
69
|
+
).toEqual(true);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('should return false when pass indexs [1,2]', () => {
|
|
73
|
+
expect(
|
|
74
|
+
hasMergedCellsInBetween([1, 2], 'column')(editorView.state.selection),
|
|
75
|
+
).toEqual(false);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('when second and third columns are merged', () => {
|
|
80
|
+
const { editorView } = editor(
|
|
81
|
+
doc(
|
|
82
|
+
table()(
|
|
83
|
+
tr(tdEmpty, td({ colspan: 2 })(p('')), tdEmpty),
|
|
84
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
85
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
86
|
+
),
|
|
87
|
+
),
|
|
88
|
+
);
|
|
89
|
+
it('should return false when pass indexs [0,1]', () => {
|
|
90
|
+
expect(
|
|
91
|
+
hasMergedCellsInBetween([0, 1], 'column')(editorView.state.selection),
|
|
92
|
+
).toEqual(false);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should return true when pass indexs [1,2]', () => {
|
|
96
|
+
expect(
|
|
97
|
+
hasMergedCellsInBetween([1, 2], 'column')(editorView.state.selection),
|
|
98
|
+
).toEqual(true);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('when first and second rows are merged', () => {
|
|
103
|
+
const { editorView } = editor(
|
|
104
|
+
doc(
|
|
105
|
+
table()(
|
|
106
|
+
tr(td({ rowspan: 2 })(p('')), tdEmpty, tdEmpty, tdEmpty),
|
|
107
|
+
tr(tdEmpty, tdEmpty, tdEmpty),
|
|
108
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
109
|
+
),
|
|
110
|
+
),
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
it('should return false when pass indexs [-1, 0]', () => {
|
|
114
|
+
expect(
|
|
115
|
+
hasMergedCellsInBetween([-1, 0], 'row')(editorView.state.selection),
|
|
116
|
+
).toEqual(false);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should return true when pass indexs [0,1]', () => {
|
|
120
|
+
expect(
|
|
121
|
+
hasMergedCellsInBetween([0, 1], 'row')(editorView.state.selection),
|
|
122
|
+
).toEqual(true);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
it('should return false when pass indexs [1,2]', () => {
|
|
126
|
+
expect(
|
|
127
|
+
hasMergedCellsInBetween([1, 2], 'row')(editorView.state.selection),
|
|
128
|
+
).toEqual(false);
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
describe('when second and third rows are merged', () => {
|
|
133
|
+
const { editorView } = editor(
|
|
134
|
+
doc(
|
|
135
|
+
table()(
|
|
136
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
137
|
+
tr(td({ rowspan: 2 })(p('')), tdEmpty, tdEmpty),
|
|
138
|
+
tr(tdEmpty, tdEmpty, tdEmpty, tdEmpty),
|
|
139
|
+
),
|
|
140
|
+
),
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
it('should return false when pass indexs [0,1]', () => {
|
|
144
|
+
expect(
|
|
145
|
+
hasMergedCellsInBetween([0, 1], 'row')(editorView.state.selection),
|
|
146
|
+
).toEqual(false);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
it('should return true when pass indexs [1,2]', () => {
|
|
150
|
+
expect(
|
|
151
|
+
hasMergedCellsInBetween([1, 2], 'row')(editorView.state.selection),
|
|
152
|
+
).toEqual(true);
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
@@ -10,11 +10,10 @@ import { getCellsInRow } from '@atlaskit/editor-tables/utils';
|
|
|
10
10
|
import { monitorForElements } from '@atlaskit/pragmatic-drag-and-drop/adapter/element';
|
|
11
11
|
|
|
12
12
|
import type { DraggableSourceData } from '../../types';
|
|
13
|
-
import { findNearestCellIndexToPoint } from '../../utils';
|
|
14
13
|
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
} from '../../utils
|
|
14
|
+
findNearestCellIndexToPoint,
|
|
15
|
+
hasMergedCellsInBetween,
|
|
16
|
+
} from '../../utils';
|
|
18
17
|
import { getPluginState as getTablePluginState } from '../plugin-factory';
|
|
19
18
|
import { pluginKey as tablePluginKey } from '../plugin-key';
|
|
20
19
|
|
|
@@ -215,12 +214,13 @@ export const createPlugin = (
|
|
|
215
214
|
}
|
|
216
215
|
|
|
217
216
|
// If the drop target index contains merged cells then we should not allow the drop to occur.
|
|
218
|
-
const hasMergedCells =
|
|
219
|
-
sourceType === 'table-row'
|
|
220
|
-
? hasMergedCellsInRow
|
|
221
|
-
: hasMergedCellsInColumn;
|
|
222
217
|
if (
|
|
223
|
-
|
|
218
|
+
hasMergedCellsInBetween(
|
|
219
|
+
[targetAdjustedIndex - 1, targetAdjustedIndex],
|
|
220
|
+
sourceType === 'table-row'
|
|
221
|
+
? DropTargetType.ROW
|
|
222
|
+
: DropTargetType.COLUMN,
|
|
223
|
+
)(editorView.state.selection)
|
|
224
224
|
) {
|
|
225
225
|
clearDropTarget(tr)(editorView.state, editorView.dispatch);
|
|
226
226
|
return;
|
|
@@ -153,9 +153,6 @@ export class FloatingInsertButton extends React.Component<
|
|
|
153
153
|
docSize: editorView.state.doc.nodeSize,
|
|
154
154
|
error: (error as any)?.toString(),
|
|
155
155
|
},
|
|
156
|
-
nonPrivacySafeAttributes: {
|
|
157
|
-
errorStack: (error as any).stack || undefined,
|
|
158
|
-
},
|
|
159
156
|
};
|
|
160
157
|
dispatchAnalyticsEvent(payload);
|
|
161
158
|
}
|
|
@@ -79,4 +79,8 @@ export type { RowParams } from './row-controls';
|
|
|
79
79
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
80
80
|
export { getMergedCellsPositions } from './table';
|
|
81
81
|
export { updatePluginStateDecorations } from './update-plugin-state-decorations';
|
|
82
|
-
export {
|
|
82
|
+
export {
|
|
83
|
+
hasMergedCellsInColumn,
|
|
84
|
+
hasMergedCellsInRow,
|
|
85
|
+
hasMergedCellsInBetween,
|
|
86
|
+
} from './merged-cells';
|
|
@@ -2,6 +2,8 @@ import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
|
2
2
|
import type { Rect } from '@atlaskit/editor-tables';
|
|
3
3
|
import { findTable, TableMap } from '@atlaskit/editor-tables';
|
|
4
4
|
|
|
5
|
+
type MergeType = 'row' | 'column';
|
|
6
|
+
|
|
5
7
|
const hasMergedCells =
|
|
6
8
|
(
|
|
7
9
|
indexes: number | number[],
|
|
@@ -65,3 +67,83 @@ export const hasMergedCellsInRow = (rowIndexes: number | number[]) =>
|
|
|
65
67
|
bottom: y === index ? y + 1 : y,
|
|
66
68
|
};
|
|
67
69
|
});
|
|
70
|
+
|
|
71
|
+
const getRect = (index: number, type: MergeType, map: TableMap) => {
|
|
72
|
+
if (type === 'column') {
|
|
73
|
+
const x = Math.max(Math.min(index, map.width - 1), 0); // clamped index
|
|
74
|
+
return {
|
|
75
|
+
left: x,
|
|
76
|
+
right: x === index ? x + 1 : x,
|
|
77
|
+
top: 0,
|
|
78
|
+
bottom: map.height,
|
|
79
|
+
};
|
|
80
|
+
} else {
|
|
81
|
+
const y = Math.max(Math.min(index, map.height - 1), 0); // clamped index
|
|
82
|
+
return {
|
|
83
|
+
left: 0,
|
|
84
|
+
right: map.width,
|
|
85
|
+
top: y,
|
|
86
|
+
bottom: y === index ? y + 1 : y,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const hasMergedCellsInBetween =
|
|
92
|
+
(indexes: number[], type: MergeType) =>
|
|
93
|
+
(selection: Selection): boolean => {
|
|
94
|
+
const table = findTable(selection);
|
|
95
|
+
if (!table) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const map = TableMap.get(table.node);
|
|
100
|
+
const cellPositions = new Set<number>();
|
|
101
|
+
const mergedCells = new Set<number>();
|
|
102
|
+
|
|
103
|
+
map.map.forEach((value) => {
|
|
104
|
+
if (cellPositions.has(value)) {
|
|
105
|
+
mergedCells.add(value);
|
|
106
|
+
} else {
|
|
107
|
+
cellPositions.add(value);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (!mergedCells.size) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const getMergedCellsInRect = (index: number, type: MergeType) => {
|
|
116
|
+
const rect = getRect(index, type, map);
|
|
117
|
+
const isValidRectangle = rect.left < rect.right && rect.top < rect.bottom;
|
|
118
|
+
if (!isValidRectangle) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const cells = map.cellsInRect(rect);
|
|
123
|
+
|
|
124
|
+
let allCellsInRect = [];
|
|
125
|
+
if (type === 'column') {
|
|
126
|
+
allCellsInRect = map.map.filter((_, key) => key % map.width === index);
|
|
127
|
+
} else {
|
|
128
|
+
allCellsInRect = map.map.filter(
|
|
129
|
+
(_, key) => Math.floor(key / map.width) === index,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
const mergedCell = allCellsInRect.filter((nodePos) => {
|
|
133
|
+
return !cells.includes(nodePos) // cell exists in Rect but not show in the map.cellsInRect list => merged cell
|
|
134
|
+
? true
|
|
135
|
+
: mergedCells.has(nodePos); // cell includes in mergedCells => merged cell
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
return [...new Set(mergedCell)];
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
const mergedCellsInRectArr = indexes.map((index) =>
|
|
142
|
+
getMergedCellsInRect(index, type),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Currently only support 2 indexes, but we can extend this to support more indexes in the future.
|
|
146
|
+
return mergedCellsInRectArr[0].some((cell) =>
|
|
147
|
+
mergedCellsInRectArr[1].includes(cell),
|
|
148
|
+
);
|
|
149
|
+
};
|