@atlaskit/editor-plugin-table 7.4.1 → 7.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/nodeviews/TableComponent.js +2 -4
  3. package/dist/cjs/nodeviews/TableContainer.js +5 -10
  4. package/dist/cjs/nodeviews/TableResizer.js +3 -7
  5. package/dist/cjs/ui/DragHandle/index.js +34 -2
  6. package/dist/cjs/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
  7. package/dist/cjs/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
  8. package/dist/cjs/utils/analytics.js +1 -2
  9. package/dist/cjs/utils/index.js +18 -0
  10. package/dist/cjs/utils/merged-cells.js +95 -1
  11. package/dist/es2019/nodeviews/TableComponent.js +2 -4
  12. package/dist/es2019/nodeviews/TableContainer.js +5 -10
  13. package/dist/es2019/nodeviews/TableResizer.js +3 -7
  14. package/dist/es2019/ui/DragHandle/index.js +36 -2
  15. package/dist/es2019/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
  16. package/dist/es2019/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
  17. package/dist/es2019/utils/analytics.js +1 -2
  18. package/dist/es2019/utils/index.js +1 -1
  19. package/dist/es2019/utils/merged-cells.js +91 -0
  20. package/dist/esm/nodeviews/TableComponent.js +2 -4
  21. package/dist/esm/nodeviews/TableContainer.js +5 -10
  22. package/dist/esm/nodeviews/TableResizer.js +3 -7
  23. package/dist/esm/ui/DragHandle/index.js +35 -3
  24. package/dist/esm/ui/TableFloatingColumnControls/ColumnControls/index.js +1 -0
  25. package/dist/esm/ui/TableFloatingControls/RowControls/DragControls.js +1 -0
  26. package/dist/esm/utils/analytics.js +1 -2
  27. package/dist/esm/utils/index.js +1 -1
  28. package/dist/esm/utils/merged-cells.js +94 -0
  29. package/dist/types/nodeviews/TableContainer.d.ts +2 -4
  30. package/dist/types/nodeviews/TableResizer.d.ts +1 -2
  31. package/dist/types/ui/DragHandle/index.d.ts +2 -1
  32. package/dist/types/utils/analytics.d.ts +0 -1
  33. package/dist/types/utils/index.d.ts +1 -1
  34. package/dist/types/utils/merged-cells.d.ts +28 -0
  35. package/dist/types-ts4.5/nodeviews/TableContainer.d.ts +2 -4
  36. package/dist/types-ts4.5/nodeviews/TableResizer.d.ts +1 -2
  37. package/dist/types-ts4.5/ui/DragHandle/index.d.ts +2 -1
  38. package/dist/types-ts4.5/utils/analytics.d.ts +0 -1
  39. package/dist/types-ts4.5/utils/index.d.ts +1 -1
  40. package/dist/types-ts4.5/utils/merged-cells.d.ts +28 -0
  41. package/package.json +3 -3
  42. package/src/nodeviews/TableComponent.tsx +1 -2
  43. package/src/nodeviews/TableContainer.tsx +0 -9
  44. package/src/nodeviews/TableResizer.tsx +0 -6
  45. package/src/ui/DragHandle/index.tsx +64 -9
  46. package/src/ui/TableFloatingColumnControls/ColumnControls/index.tsx +1 -0
  47. package/src/ui/TableFloatingControls/RowControls/DragControls.tsx +1 -0
  48. package/src/utils/analytics.ts +0 -2
  49. package/src/utils/index.ts +3 -0
  50. package/src/utils/merged-cells.ts +104 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/editor-plugin-table
2
2
 
3
+ ## 7.4.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#72037](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/72037) [`e59f0b7a9115`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/e59f0b7a9115) - [ux] add flexiable to make merged cells detection allow to detect edge merged cells
8
+
9
+ ## 7.4.2
10
+
11
+ ### Patch Changes
12
+
13
+ - [#76112](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/76112) [`1cd6cd3382d9`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/1cd6cd3382d9) - remove table performance experiment
14
+
3
15
  ## 7.4.1
4
16
 
5
17
  ### Patch Changes
@@ -571,8 +571,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
571
571
  var isNested = (0, _utils5.isTableNested)(view.state, tablePos);
572
572
  var topStickyShadowPosition = isDragAndDropEnabled ? this.state.stickyHeader && this.state.stickyHeader.top + this.state.stickyHeader.padding + 2 : this.state.stickyHeader && this.state.stickyHeader.top + this.state.stickyHeader.padding + shadowPadding + 2;
573
573
  var _getEditorFeatureFlag3 = getEditorFeatureFlags(),
574
- stickyScrollbar = _getEditorFeatureFlag3.stickyScrollbar,
575
- tableResizePerformance = _getEditorFeatureFlag3.tableResizePerformance;
574
+ stickyScrollbar = _getEditorFeatureFlag3.stickyScrollbar;
576
575
  return /*#__PURE__*/_react.default.createElement(_TableContainer.TableContainer, {
577
576
  className: (0, _classnames2.default)(_types.TableCssClassName.TABLE_CONTAINER, (_classnames = {}, (0, _defineProperty3.default)(_classnames, _types.TableCssClassName.WITH_CONTROLS, allowControls && tableActive), (0, _defineProperty3.default)(_classnames, _types.TableCssClassName.TABLE_STICKY, this.state.stickyHeader && hasHeaderRow), (0, _defineProperty3.default)(_classnames, _types.TableCssClassName.HOVERED_DELETE_BUTTON, isInDanger), (0, _defineProperty3.default)(_classnames, _types.TableCssClassName.TABLE_SELECTED, (0, _utils2.isTableSelected)(view.state.selection)), _classnames)),
578
577
  editorView: view,
@@ -584,8 +583,7 @@ var TableComponent = /*#__PURE__*/function (_React$Component) {
584
583
  isNested: isNested,
585
584
  pluginInjectionApi: pluginInjectionApi,
586
585
  isTableResizingEnabled: options === null || options === void 0 ? void 0 : options.isTableResizingEnabled,
587
- isResizing: isResizing,
588
- tableResizePerformance: tableResizePerformance
586
+ isResizing: isResizing
589
587
  }, /*#__PURE__*/_react.default.createElement("div", {
590
588
  className: _types.TableCssClassName.TABLE_STICKY_SENTINEL_TOP,
591
589
  "data-testid": "sticky-sentinel-top"
@@ -53,8 +53,7 @@ var ResizableTableContainer = exports.ResizableTableContainer = /*#__PURE__*/_re
53
53
  getPos = _ref2.getPos,
54
54
  tableRef = _ref2.tableRef,
55
55
  isResizing = _ref2.isResizing,
56
- pluginInjectionApi = _ref2.pluginInjectionApi,
57
- tableResizePerformance = _ref2.tableResizePerformance;
56
+ pluginInjectionApi = _ref2.pluginInjectionApi;
58
57
  var containerRef = (0, _react.useRef)(null);
59
58
  var tableWidthRef = (0, _react.useRef)(_editorSharedStyles.akEditorDefaultLayoutWidth);
60
59
  var updateContainerHeight = (0, _react.useCallback)(function (height) {
@@ -135,8 +134,7 @@ var ResizableTableContainer = exports.ResizableTableContainer = /*#__PURE__*/_re
135
134
  tableRef: tableRef,
136
135
  displayGuideline: displayGuideline,
137
136
  attachAnalyticsEvent: attachAnalyticsEvent,
138
- displayGapCursor: displayGapCursor,
139
- tableResizePerformance: tableResizePerformance
137
+ displayGapCursor: displayGapCursor
140
138
  };
141
139
  if ((0, _platformFeatureFlags.getBooleanFF)('platform.editor.resizing-table-height-improvement')) {
142
140
  tableResizerProps = _objectSpread(_objectSpread({}, tableResizerProps), {}, {
@@ -148,8 +146,7 @@ var ResizableTableContainer = exports.ResizableTableContainer = /*#__PURE__*/_re
148
146
  style: {
149
147
  display: 'flex',
150
148
  justifyContent: 'center'
151
- },
152
- contentEditable: tableResizePerformance && isResizing ? 'false' : undefined
149
+ }
153
150
  }, /*#__PURE__*/_react.default.createElement("div", {
154
151
  style: {
155
152
  width: tableWidthRef.current
@@ -175,8 +172,7 @@ var TableContainer = exports.TableContainer = function TableContainer(_ref3) {
175
172
  tableRef = _ref3.tableRef,
176
173
  isNested = _ref3.isNested,
177
174
  isResizing = _ref3.isResizing,
178
- pluginInjectionApi = _ref3.pluginInjectionApi,
179
- tableResizePerformance = _ref3.tableResizePerformance;
175
+ pluginInjectionApi = _ref3.pluginInjectionApi;
180
176
  if (isTableResizingEnabled && !isNested) {
181
177
  return /*#__PURE__*/_react.default.createElement(ResizableTableContainer, {
182
178
  className: className,
@@ -186,8 +182,7 @@ var TableContainer = exports.TableContainer = function TableContainer(_ref3) {
186
182
  getPos: getPos,
187
183
  tableRef: tableRef,
188
184
  isResizing: isResizing,
189
- pluginInjectionApi: pluginInjectionApi,
190
- tableResizePerformance: tableResizePerformance
185
+ pluginInjectionApi: pluginInjectionApi
191
186
  }, children);
192
187
  }
193
188
  var tableWidth = isBreakoutEnabled ? (0, _styles.calcTableWidth)(node.attrs.layout, editorWidth) : 'inherit';
@@ -97,8 +97,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
97
97
  tableRef = _ref.tableRef,
98
98
  displayGuideline = _ref.displayGuideline,
99
99
  attachAnalyticsEvent = _ref.attachAnalyticsEvent,
100
- displayGapCursor = _ref.displayGapCursor,
101
- tableResizePerformance = _ref.tableResizePerformance;
100
+ displayGapCursor = _ref.displayGapCursor;
102
101
  var currentGap = (0, _react.useRef)(0);
103
102
  // track resizing state - use ref over state to avoid re-render
104
103
  var isResizing = (0, _react.useRef)(false);
@@ -228,10 +227,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
228
227
  var resizeFrameRatePayloads = (0, _analytics2.generateResizeFrameRatePayloads)({
229
228
  docSize: state.doc.nodeSize,
230
229
  frameRateSamples: frameRateSamples,
231
- originalNode: node,
232
- experiments: {
233
- tableResizePerformance: tableResizePerformance
234
- }
230
+ originalNode: node
235
231
  });
236
232
  resizeFrameRatePayloads.forEach(function (payload) {
237
233
  var _attachAnalyticsEvent;
@@ -267,7 +263,7 @@ var TableResizer = exports.TableResizer = function TableResizer(_ref) {
267
263
  onResizeStop();
268
264
  }
269
265
  return newWidth;
270
- }, [displayGapCursor, updateWidth, editorView, getPos, node, tableRef, scheduleResize, displayGuideline, attachAnalyticsEvent, endMeasure, onResizeStop, tableResizePerformance]);
266
+ }, [displayGapCursor, updateWidth, editorView, getPos, node, tableRef, scheduleResize, displayGuideline, attachAnalyticsEvent, endMeasure, onResizeStop]);
271
267
  var handleTableSizeChangeOnKeypress = (0, _react.useCallback)(function (step) {
272
268
  var newWidth = width + step;
273
269
  if (newWidth > maxWidth || newWidth < resizerMinWidth) {
@@ -14,6 +14,8 @@ var _reactDom = _interopRequireDefault(require("react-dom"));
14
14
  var _reactIntlNext = require("react-intl-next");
15
15
  var _messages = require("@atlaskit/editor-common/messages");
16
16
  var _utils = require("@atlaskit/editor-common/utils");
17
+ var _state = require("@atlaskit/editor-prosemirror/state");
18
+ var _editorTables = require("@atlaskit/editor-tables");
17
19
  var _adapter = require("@atlaskit/pragmatic-drag-and-drop/element/adapter");
18
20
  var _setCustomNativeDragPreview = require("@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview");
19
21
  var _pluginFactory = require("../../pm-plugins/drag-and-drop/plugin-factory");
@@ -40,6 +42,7 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
40
42
  onMouseOver = _ref.onMouseOver,
41
43
  onMouseOut = _ref.onMouseOut,
42
44
  toggleDragMenu = _ref.toggleDragMenu,
45
+ hoveredCell = _ref.hoveredCell,
43
46
  onClick = _ref.onClick,
44
47
  editorView = _ref.editorView,
45
48
  formatMessage = _ref.intl.formatMessage;
@@ -60,8 +63,37 @@ var DragHandleComponent = function DragHandleComponent(_ref) {
60
63
  var isRowHandleHovered = isRow && hoveredRows.length > 0;
61
64
  var isColumnHandleHovered = isColumn && hoveredColumns.length > 0;
62
65
  var hasMergedCells = (0, _react.useMemo)(function () {
63
- return isRow ? (0, _utils2.hasMergedCellsInRow)(indexes[0])(selection) : (0, _utils2.hasMergedCellsInColumn)(indexes[0])(selection);
64
- }, [indexes, isRow, selection]);
66
+ var table = (0, _editorTables.findTable)(selection);
67
+ if (!table) {
68
+ return false;
69
+ }
70
+ var map = _editorTables.TableMap.get(table === null || table === void 0 ? void 0 : table.node);
71
+ if (!map.hasMergedCells() || indexes.length < 1) {
72
+ return false;
73
+ }
74
+ var mapByColumn = map.mapByColumn,
75
+ mapByRow = map.mapByRow;
76
+
77
+ // this handle when hover to first column or row which has merged cells.
78
+ if (hoveredCell && hoveredCell.rowIndex !== undefined && hoveredCell.colIndex !== undefined && selection instanceof _state.TextSelection) {
79
+ var rowIndex = hoveredCell.rowIndex,
80
+ colIndex = hoveredCell.colIndex;
81
+ var mergedPositionInRow = (0, _utils2.findDuplicatePosition)(mapByRow[rowIndex]);
82
+ var mergedPositionInCol = (0, _utils2.findDuplicatePosition)(mapByColumn[colIndex]);
83
+ var hasMergedCellsInFirstRowOrColumn = direction === 'column' ? mergedPositionInRow.includes(mapByRow[0][colIndex]) : mergedPositionInCol.includes(mapByColumn[0][rowIndex]);
84
+ var isHoveredOnFirstRowOrColumn = direction === 'column' ? hoveredCell.rowIndex === 0 && hasMergedCellsInFirstRowOrColumn : hoveredCell.colIndex === 0 && hasMergedCellsInFirstRowOrColumn;
85
+ if (isHoveredOnFirstRowOrColumn) {
86
+ var mergedSizes = direction === 'column' ? mapByRow[0].filter(function (el) {
87
+ return el === mapByRow[0][colIndex];
88
+ }).length : mapByColumn[0].filter(function (el) {
89
+ return el === mapByColumn[0][rowIndex];
90
+ }).length;
91
+ var mergedSelection = (0, _utils2.hasMergedCellsInSelection)(direction === 'column' ? [colIndex, colIndex + mergedSizes - 1] : [rowIndex, rowIndex + mergedSizes - 1], direction)(selection);
92
+ return mergedSelection;
93
+ }
94
+ }
95
+ return (0, _utils2.hasMergedCellsInSelection)(indexes, direction)(selection);
96
+ }, [indexes, selection, direction, hoveredCell]);
65
97
  var handleIconProps = {
66
98
  forceDefaultHandle: forceDefaultHandle,
67
99
  isHandleHovered: isColumnHandleHovered || isRowHandleHovered,
@@ -148,6 +148,7 @@ var ColumnControls = exports.ColumnControls = function ColumnControls(_ref) {
148
148
  direction: "column",
149
149
  tableLocalId: localId || '',
150
150
  indexes: indexes,
151
+ hoveredCell: hoveredCell,
151
152
  previewWidth: previewWidth,
152
153
  forceDefaultHandle: !isHover,
153
154
  previewHeight: previewHeight,
@@ -151,6 +151,7 @@ var DragControlsComponent = function DragControlsComponent(_ref) {
151
151
  previewWidth: tableWidth,
152
152
  previewHeight: previewHeight,
153
153
  appearance: appearance,
154
+ hoveredCell: hoveredCell,
154
155
  onClick: handleClick,
155
156
  onMouseOver: handleMouseOver,
156
157
  onMouseOut: handleMouseOut,
@@ -116,8 +116,7 @@ var generateResizeFrameRatePayloads = exports.generateResizeFrameRatePayloads =
116
116
  frameRate: frameRateSample,
117
117
  nodeSize: props.originalNode.nodeSize,
118
118
  docSize: props.docSize,
119
- isInitialSample: index === 0,
120
- experiments: props.experiments
119
+ isInitialSample: index === 0
121
120
  }
122
121
  };
123
122
  });
@@ -9,6 +9,12 @@ Object.defineProperty(exports, "anyChildCellMergedAcrossRow", {
9
9
  return _nodes.anyChildCellMergedAcrossRow;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "checkEdgeHasMergedCells", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _mergedCells.checkEdgeHasMergedCells;
16
+ }
17
+ });
12
18
  Object.defineProperty(exports, "checkIfHeaderColumnEnabled", {
13
19
  enumerable: true,
14
20
  get: function get() {
@@ -105,6 +111,12 @@ Object.defineProperty(exports, "findControlsHoverDecoration", {
105
111
  return _decoration.findControlsHoverDecoration;
106
112
  }
107
113
  });
114
+ Object.defineProperty(exports, "findDuplicatePosition", {
115
+ enumerable: true,
116
+ get: function get() {
117
+ return _mergedCells.findDuplicatePosition;
118
+ }
119
+ });
108
120
  Object.defineProperty(exports, "findNearestCellIndexToPoint", {
109
121
  enumerable: true,
110
122
  get: function get() {
@@ -231,6 +243,12 @@ Object.defineProperty(exports, "hasMergedCellsInRow", {
231
243
  return _mergedCells.hasMergedCellsInRow;
232
244
  }
233
245
  });
246
+ Object.defineProperty(exports, "hasMergedCellsInSelection", {
247
+ enumerable: true,
248
+ get: function get() {
249
+ return _mergedCells.hasMergedCellsInSelection;
250
+ }
251
+ });
234
252
  Object.defineProperty(exports, "hasResizeHandler", {
235
253
  enumerable: true,
236
254
  get: function get() {
@@ -4,7 +4,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
4
4
  Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
- exports.hasMergedCellsWithRowNextToRowIndex = exports.hasMergedCellsWithColumnNextToColumnIndex = exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = exports.hasMergedCellsInBetween = void 0;
7
+ exports.hasMergedCellsWithRowNextToRowIndex = exports.hasMergedCellsWithColumnNextToColumnIndex = exports.hasMergedCellsInSelection = exports.hasMergedCellsInRow = exports.hasMergedCellsInColumn = exports.hasMergedCellsInBetween = exports.getTableMapByRowOrColumn = exports.findDuplicatePosition = exports.checkEdgeHasMergedCells = void 0;
8
8
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
9
  var _editorTables = require("@atlaskit/editor-tables");
10
10
  var hasMergedCells = function hasMergedCells(indexes, normalizeRect) {
@@ -202,4 +202,98 @@ var hasMergedCellsWithRowNextToRowIndex = exports.hasMergedCellsWithRowNextToRow
202
202
  }
203
203
  }
204
204
  return false;
205
+ };
206
+ var hasMergedCellsInSelection = exports.hasMergedCellsInSelection = function hasMergedCellsInSelection(indexes, type) {
207
+ return function (selection) {
208
+ var table = (0, _editorTables.findTable)(selection);
209
+ if (!table) {
210
+ return false;
211
+ }
212
+ var map = _editorTables.TableMap.get(table.node);
213
+ if (!map.hasMergedCells()) {
214
+ return false;
215
+ }
216
+ return checkEdgeHasMergedCells(indexes, map, type);
217
+ };
218
+ };
219
+
220
+ /**
221
+ * handle table map by preprocess table's map row or column.
222
+ *
223
+ * @param map TableMap
224
+ * @returns object including mapByRow and mapByColumn
225
+ */
226
+ var getTableMapByRowOrColumn = exports.getTableMapByRowOrColumn = function getTableMapByRowOrColumn(map) {
227
+ var mapByRow = Array(map.height);
228
+ var mapByColumn = Array(map.width);
229
+ var mapCopy = (0, _toConsumableArray2.default)(map.map);
230
+ for (var i = 0; i < mapCopy.length; i++) {
231
+ var _mapByColumn$columnIn, _mapByRow$rowIndex;
232
+ var columnIndex = i % map.width;
233
+ mapByColumn[columnIndex] = [].concat((0, _toConsumableArray2.default)((_mapByColumn$columnIn = mapByColumn[columnIndex]) !== null && _mapByColumn$columnIn !== void 0 ? _mapByColumn$columnIn : []), [mapCopy[i]]);
234
+ var rowIndex = Math.trunc(i / map.width);
235
+ mapByRow[rowIndex] = [].concat((0, _toConsumableArray2.default)((_mapByRow$rowIndex = mapByRow[rowIndex]) !== null && _mapByRow$rowIndex !== void 0 ? _mapByRow$rowIndex : []), [mapCopy[i]]);
236
+ }
237
+ return {
238
+ mapByRow: mapByRow,
239
+ mapByColumn: mapByColumn
240
+ };
241
+ };
242
+
243
+ /**
244
+ * this check the selection has merged cells with previous/next col or row.
245
+ *
246
+ * @param indexes - this get the indexes of the selection,e.g. [0,1] for selecting first two rows or columns.
247
+ * @param tableMap - this return a TableMap object.
248
+ * @param direction - check selection is selected by row or column
249
+ * @returns boolean
250
+ */
251
+ var checkEdgeHasMergedCells = exports.checkEdgeHasMergedCells = function checkEdgeHasMergedCells(indexes, tableMap, direction) {
252
+ var _getTableMapByRowOrCo = getTableMapByRowOrColumn(tableMap),
253
+ mapByRow = _getTableMapByRowOrCo.mapByRow,
254
+ mapByColumn = _getTableMapByRowOrCo.mapByColumn;
255
+ var map = 'row' === direction ? mapByRow : mapByColumn;
256
+ var lengthLimiter = direction === 'row' ? tableMap.width : tableMap.height;
257
+ var minIndex = Math.min.apply(Math, (0, _toConsumableArray2.default)(indexes));
258
+ var maxIndex = Math.max.apply(Math, (0, _toConsumableArray2.default)(indexes));
259
+ var isTopSideHaveMergedCells = false;
260
+ var isBottomSideHaveMergedCells = false;
261
+ var isOldMinIndex = !map[minIndex - 1] && !map[minIndex];
262
+ var isOldMaxIndex = !map[maxIndex + 1] && !map[maxIndex];
263
+ if (minIndex > 0 && !isOldMinIndex) {
264
+ var prevSelectionSet = map[minIndex - 1];
265
+ var minSelectionSet = map[minIndex];
266
+ for (var i = 0; i < lengthLimiter; i++) {
267
+ if (prevSelectionSet[i] === minSelectionSet[i]) {
268
+ isTopSideHaveMergedCells = true;
269
+ break;
270
+ }
271
+ }
272
+ }
273
+ if (maxIndex < map.length - 1 && !isOldMaxIndex) {
274
+ var afterSelectionSet = map[maxIndex + 1];
275
+ var maxSelectionSet = map[maxIndex];
276
+ for (var _i = 0; _i < lengthLimiter; _i++) {
277
+ if (afterSelectionSet[_i] === maxSelectionSet[_i]) {
278
+ isBottomSideHaveMergedCells = true;
279
+ break;
280
+ }
281
+ }
282
+ }
283
+ return isTopSideHaveMergedCells || isBottomSideHaveMergedCells;
284
+ };
285
+
286
+ /**
287
+ * this function will find the duplicate position in the array(table map position array).
288
+ *
289
+ * @param array this usually be the array including positions of the table map.
290
+ * @returns []
291
+ */
292
+ var findDuplicatePosition = exports.findDuplicatePosition = function findDuplicatePosition(array) {
293
+ if (!array) {
294
+ return [];
295
+ }
296
+ return array.filter(function (item, index) {
297
+ return array.indexOf(item) !== index;
298
+ });
205
299
  };
@@ -568,8 +568,7 @@ class TableComponent extends React.Component {
568
568
  const isNested = isTableNested(view.state, tablePos);
569
569
  const topStickyShadowPosition = isDragAndDropEnabled ? this.state.stickyHeader && this.state.stickyHeader.top + this.state.stickyHeader.padding + 2 : this.state.stickyHeader && this.state.stickyHeader.top + this.state.stickyHeader.padding + shadowPadding + 2;
570
570
  const {
571
- stickyScrollbar,
572
- tableResizePerformance
571
+ stickyScrollbar
573
572
  } = getEditorFeatureFlags();
574
573
  return /*#__PURE__*/React.createElement(TableContainer, {
575
574
  className: classnames(ClassName.TABLE_CONTAINER, {
@@ -587,8 +586,7 @@ class TableComponent extends React.Component {
587
586
  isNested: isNested,
588
587
  pluginInjectionApi: pluginInjectionApi,
589
588
  isTableResizingEnabled: options === null || options === void 0 ? void 0 : options.isTableResizingEnabled,
590
- isResizing: isResizing,
591
- tableResizePerformance: tableResizePerformance
589
+ isResizing: isResizing
592
590
  }, /*#__PURE__*/React.createElement("div", {
593
591
  className: ClassName.TABLE_STICKY_SENTINEL_TOP,
594
592
  "data-testid": "sticky-sentinel-top"
@@ -41,8 +41,7 @@ export const ResizableTableContainer = /*#__PURE__*/React.memo(({
41
41
  getPos,
42
42
  tableRef,
43
43
  isResizing,
44
- pluginInjectionApi,
45
- tableResizePerformance
44
+ pluginInjectionApi
46
45
  }) => {
47
46
  const containerRef = useRef(null);
48
47
  const tableWidthRef = useRef(akEditorDefaultLayoutWidth);
@@ -124,8 +123,7 @@ export const ResizableTableContainer = /*#__PURE__*/React.memo(({
124
123
  tableRef,
125
124
  displayGuideline,
126
125
  attachAnalyticsEvent,
127
- displayGapCursor,
128
- tableResizePerformance
126
+ displayGapCursor
129
127
  };
130
128
  if (getBooleanFF('platform.editor.resizing-table-height-improvement')) {
131
129
  tableResizerProps = {
@@ -138,8 +136,7 @@ export const ResizableTableContainer = /*#__PURE__*/React.memo(({
138
136
  style: {
139
137
  display: 'flex',
140
138
  justifyContent: 'center'
141
- },
142
- contentEditable: tableResizePerformance && isResizing ? 'false' : undefined
139
+ }
143
140
  }, /*#__PURE__*/React.createElement("div", {
144
141
  style: {
145
142
  width: tableWidthRef.current
@@ -166,8 +163,7 @@ export const TableContainer = ({
166
163
  tableRef,
167
164
  isNested,
168
165
  isResizing,
169
- pluginInjectionApi,
170
- tableResizePerformance
166
+ pluginInjectionApi
171
167
  }) => {
172
168
  if (isTableResizingEnabled && !isNested) {
173
169
  return /*#__PURE__*/React.createElement(ResizableTableContainer, {
@@ -178,8 +174,7 @@ export const TableContainer = ({
178
174
  getPos: getPos,
179
175
  tableRef: tableRef,
180
176
  isResizing: isResizing,
181
- pluginInjectionApi: pluginInjectionApi,
182
- tableResizePerformance: tableResizePerformance
177
+ pluginInjectionApi: pluginInjectionApi
183
178
  }, children);
184
179
  }
185
180
  const tableWidth = isBreakoutEnabled ? calcTableWidth(node.attrs.layout, editorWidth) : 'inherit';
@@ -82,8 +82,7 @@ export const TableResizer = ({
82
82
  tableRef,
83
83
  displayGuideline,
84
84
  attachAnalyticsEvent,
85
- displayGapCursor,
86
- tableResizePerformance
85
+ displayGapCursor
87
86
  }) => {
88
87
  var _findTable, _editorView$state;
89
88
  const currentGap = useRef(0);
@@ -219,10 +218,7 @@ export const TableResizer = ({
219
218
  const resizeFrameRatePayloads = generateResizeFrameRatePayloads({
220
219
  docSize: state.doc.nodeSize,
221
220
  frameRateSamples,
222
- originalNode: node,
223
- experiments: {
224
- tableResizePerformance
225
- }
221
+ originalNode: node
226
222
  });
227
223
  resizeFrameRatePayloads.forEach(payload => {
228
224
  var _attachAnalyticsEvent;
@@ -259,7 +255,7 @@ export const TableResizer = ({
259
255
  onResizeStop();
260
256
  }
261
257
  return newWidth;
262
- }, [displayGapCursor, updateWidth, editorView, getPos, node, tableRef, scheduleResize, displayGuideline, attachAnalyticsEvent, endMeasure, onResizeStop, tableResizePerformance]);
258
+ }, [displayGapCursor, updateWidth, editorView, getPos, node, tableRef, scheduleResize, displayGuideline, attachAnalyticsEvent, endMeasure, onResizeStop]);
263
259
  const handleTableSizeChangeOnKeypress = useCallback(step => {
264
260
  const newWidth = width + step;
265
261
  if (newWidth > maxWidth || newWidth < resizerMinWidth) {
@@ -4,12 +4,14 @@ import ReactDOM from 'react-dom';
4
4
  import { injectIntl } from 'react-intl-next';
5
5
  import { tableMessages as messages } from '@atlaskit/editor-common/messages';
6
6
  import { browser } from '@atlaskit/editor-common/utils';
7
+ import { TextSelection } from '@atlaskit/editor-prosemirror/state';
8
+ import { findTable, TableMap } from '@atlaskit/editor-tables';
7
9
  import { draggable } from '@atlaskit/pragmatic-drag-and-drop/element/adapter';
8
10
  import { setCustomNativeDragPreview } from '@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview';
9
11
  import { getPluginState as getDnDPluginState } from '../../pm-plugins/drag-and-drop/plugin-factory';
10
12
  import { getPluginState } from '../../pm-plugins/plugin-factory';
11
13
  import { TableCssClassName as ClassName } from '../../types';
12
- import { hasMergedCellsInColumn, hasMergedCellsInRow } from '../../utils';
14
+ import { findDuplicatePosition, hasMergedCellsInSelection } from '../../utils';
13
15
  import { dragTableInsertColumnButtonSize } from '../consts';
14
16
  import { DragPreview } from '../DragPreview';
15
17
  import { HandleIconComponent } from './HandleIconComponent';
@@ -25,6 +27,7 @@ const DragHandleComponent = ({
25
27
  onMouseOver,
26
28
  onMouseOut,
27
29
  toggleDragMenu,
30
+ hoveredCell,
28
31
  onClick,
29
32
  editorView,
30
33
  intl: {
@@ -50,7 +53,38 @@ const DragHandleComponent = ({
50
53
  const isColumn = direction === 'column';
51
54
  const isRowHandleHovered = isRow && hoveredRows.length > 0;
52
55
  const isColumnHandleHovered = isColumn && hoveredColumns.length > 0;
53
- const hasMergedCells = useMemo(() => isRow ? hasMergedCellsInRow(indexes[0])(selection) : hasMergedCellsInColumn(indexes[0])(selection), [indexes, isRow, selection]);
56
+ const hasMergedCells = useMemo(() => {
57
+ const table = findTable(selection);
58
+ if (!table) {
59
+ return false;
60
+ }
61
+ const map = TableMap.get(table === null || table === void 0 ? void 0 : table.node);
62
+ if (!map.hasMergedCells() || indexes.length < 1) {
63
+ return false;
64
+ }
65
+ const {
66
+ mapByColumn,
67
+ mapByRow
68
+ } = map;
69
+
70
+ // this handle when hover to first column or row which has merged cells.
71
+ if (hoveredCell && hoveredCell.rowIndex !== undefined && hoveredCell.colIndex !== undefined && selection instanceof TextSelection) {
72
+ const {
73
+ rowIndex,
74
+ colIndex
75
+ } = hoveredCell;
76
+ const mergedPositionInRow = findDuplicatePosition(mapByRow[rowIndex]);
77
+ const mergedPositionInCol = findDuplicatePosition(mapByColumn[colIndex]);
78
+ const hasMergedCellsInFirstRowOrColumn = direction === 'column' ? mergedPositionInRow.includes(mapByRow[0][colIndex]) : mergedPositionInCol.includes(mapByColumn[0][rowIndex]);
79
+ const isHoveredOnFirstRowOrColumn = direction === 'column' ? hoveredCell.rowIndex === 0 && hasMergedCellsInFirstRowOrColumn : hoveredCell.colIndex === 0 && hasMergedCellsInFirstRowOrColumn;
80
+ if (isHoveredOnFirstRowOrColumn) {
81
+ const mergedSizes = direction === 'column' ? mapByRow[0].filter(el => el === mapByRow[0][colIndex]).length : mapByColumn[0].filter(el => el === mapByColumn[0][rowIndex]).length;
82
+ const mergedSelection = hasMergedCellsInSelection(direction === 'column' ? [colIndex, colIndex + mergedSizes - 1] : [rowIndex, rowIndex + mergedSizes - 1], direction)(selection);
83
+ return mergedSelection;
84
+ }
85
+ }
86
+ return hasMergedCellsInSelection(indexes, direction)(selection);
87
+ }, [indexes, selection, direction, hoveredCell]);
54
88
  const handleIconProps = {
55
89
  forceDefaultHandle,
56
90
  isHandleHovered: isColumnHandleHovered || isRowHandleHovered,
@@ -143,6 +143,7 @@ export const ColumnControls = ({
143
143
  direction: "column",
144
144
  tableLocalId: localId || '',
145
145
  indexes: indexes,
146
+ hoveredCell: hoveredCell,
146
147
  previewWidth: previewWidth,
147
148
  forceDefaultHandle: !isHover,
148
149
  previewHeight: previewHeight,
@@ -139,6 +139,7 @@ const DragControlsComponent = ({
139
139
  previewWidth: tableWidth,
140
140
  previewHeight: previewHeight,
141
141
  appearance: appearance,
142
+ hoveredCell: hoveredCell,
142
143
  onClick: handleClick,
143
144
  onMouseOver: handleMouseOver,
144
145
  onMouseOut: handleMouseOut,
@@ -101,8 +101,7 @@ export const generateResizeFrameRatePayloads = props => {
101
101
  frameRate: frameRateSample,
102
102
  nodeSize: props.originalNode.nodeSize,
103
103
  docSize: props.docSize,
104
- isInitialSample: index === 0,
105
- experiments: props.experiments
104
+ isInitialSample: index === 0
106
105
  }
107
106
  }));
108
107
  };
@@ -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, hasMergedCellsInBetween } from './merged-cells';
11
+ export { hasMergedCellsInColumn, hasMergedCellsInRow, hasMergedCellsInBetween, hasMergedCellsInSelection, findDuplicatePosition, checkEdgeHasMergedCells } from './merged-cells';
@@ -180,4 +180,95 @@ export const hasMergedCellsWithRowNextToRowIndex = (rowIndex, selection) => {
180
180
  }
181
181
  }
182
182
  return false;
183
+ };
184
+ export const hasMergedCellsInSelection = (indexes, type) => selection => {
185
+ const table = findTable(selection);
186
+ if (!table) {
187
+ return false;
188
+ }
189
+ const map = TableMap.get(table.node);
190
+ if (!map.hasMergedCells()) {
191
+ return false;
192
+ }
193
+ return checkEdgeHasMergedCells(indexes, map, type);
194
+ };
195
+
196
+ /**
197
+ * handle table map by preprocess table's map row or column.
198
+ *
199
+ * @param map TableMap
200
+ * @returns object including mapByRow and mapByColumn
201
+ */
202
+ export const getTableMapByRowOrColumn = map => {
203
+ let mapByRow = Array(map.height);
204
+ let mapByColumn = Array(map.width);
205
+ const mapCopy = [...map.map];
206
+ for (let i = 0; i < mapCopy.length; i++) {
207
+ var _mapByColumn$columnIn, _mapByRow$rowIndex;
208
+ const columnIndex = i % map.width;
209
+ mapByColumn[columnIndex] = [...((_mapByColumn$columnIn = mapByColumn[columnIndex]) !== null && _mapByColumn$columnIn !== void 0 ? _mapByColumn$columnIn : []), mapCopy[i]];
210
+ const rowIndex = Math.trunc(i / map.width);
211
+ mapByRow[rowIndex] = [...((_mapByRow$rowIndex = mapByRow[rowIndex]) !== null && _mapByRow$rowIndex !== void 0 ? _mapByRow$rowIndex : []), mapCopy[i]];
212
+ }
213
+ return {
214
+ mapByRow,
215
+ mapByColumn
216
+ };
217
+ };
218
+
219
+ /**
220
+ * this check the selection has merged cells with previous/next col or row.
221
+ *
222
+ * @param indexes - this get the indexes of the selection,e.g. [0,1] for selecting first two rows or columns.
223
+ * @param tableMap - this return a TableMap object.
224
+ * @param direction - check selection is selected by row or column
225
+ * @returns boolean
226
+ */
227
+ export const checkEdgeHasMergedCells = (indexes, tableMap, direction) => {
228
+ const {
229
+ mapByRow,
230
+ mapByColumn
231
+ } = getTableMapByRowOrColumn(tableMap);
232
+ const map = 'row' === direction ? mapByRow : mapByColumn;
233
+ const lengthLimiter = direction === 'row' ? tableMap.width : tableMap.height;
234
+ let minIndex = Math.min(...indexes);
235
+ let maxIndex = Math.max(...indexes);
236
+ let isTopSideHaveMergedCells = false;
237
+ let isBottomSideHaveMergedCells = false;
238
+ let isOldMinIndex = !map[minIndex - 1] && !map[minIndex];
239
+ let isOldMaxIndex = !map[maxIndex + 1] && !map[maxIndex];
240
+ if (minIndex > 0 && !isOldMinIndex) {
241
+ const prevSelectionSet = map[minIndex - 1];
242
+ const minSelectionSet = map[minIndex];
243
+ for (let i = 0; i < lengthLimiter; i++) {
244
+ if (prevSelectionSet[i] === minSelectionSet[i]) {
245
+ isTopSideHaveMergedCells = true;
246
+ break;
247
+ }
248
+ }
249
+ }
250
+ if (maxIndex < map.length - 1 && !isOldMaxIndex) {
251
+ const afterSelectionSet = map[maxIndex + 1];
252
+ const maxSelectionSet = map[maxIndex];
253
+ for (let i = 0; i < lengthLimiter; i++) {
254
+ if (afterSelectionSet[i] === maxSelectionSet[i]) {
255
+ isBottomSideHaveMergedCells = true;
256
+ break;
257
+ }
258
+ }
259
+ }
260
+ return isTopSideHaveMergedCells || isBottomSideHaveMergedCells;
261
+ };
262
+
263
+ /**
264
+ * this function will find the duplicate position in the array(table map position array).
265
+ *
266
+ * @param array this usually be the array including positions of the table map.
267
+ * @returns []
268
+ */
269
+ export const findDuplicatePosition = array => {
270
+ if (!array) {
271
+ return [];
272
+ }
273
+ return array.filter((item, index) => array.indexOf(item) !== index);
183
274
  };