@atlaskit/editor-plugin-table 5.4.12 → 5.4.13
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/event-handlers.js +10 -4
- package/dist/cjs/plugins/table/utils/column-controls.js +63 -1
- package/dist/cjs/plugins/table/utils/index.js +12 -0
- package/dist/es2019/plugins/table/event-handlers.js +11 -5
- package/dist/es2019/plugins/table/utils/column-controls.js +62 -0
- package/dist/es2019/plugins/table/utils/index.js +1 -1
- package/dist/esm/plugins/table/event-handlers.js +11 -5
- package/dist/esm/plugins/table/utils/column-controls.js +62 -0
- package/dist/esm/plugins/table/utils/index.js +1 -1
- package/dist/types/plugins/table/utils/column-controls.d.ts +3 -0
- package/dist/types/plugins/table/utils/index.d.ts +1 -1
- package/dist/types-ts4.5/plugins/table/utils/column-controls.d.ts +3 -0
- package/dist/types-ts4.5/plugins/table/utils/index.d.ts +1 -1
- package/package.json +2 -2
- package/src/__tests__/unit/utils/column-controls.ts +145 -1
- package/src/plugins/table/event-handlers.ts +22 -4
- package/src/plugins/table/utils/column-controls.ts +81 -0
- package/src/plugins/table/utils/index.ts +2 -0
- package/src/__tests__/integration/block-node-selection.ts +0 -165
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# @atlaskit/editor-plugin-table
|
|
2
2
|
|
|
3
|
+
## 5.4.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#58379](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/58379) [`985c068738e8`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/985c068738e8) - [ux] Add a util to convert cell index into actula colIndex to fix column drag handle position.
|
|
8
|
+
- Updated dependencies
|
|
9
|
+
|
|
3
10
|
## 5.4.12
|
|
4
11
|
|
|
5
12
|
### Patch Changes
|
|
@@ -348,13 +348,19 @@ var trackCellLocation = function trackCellLocation(view, mouseEvent) {
|
|
|
348
348
|
if (!maybeTableCell || !tableRef) {
|
|
349
349
|
return;
|
|
350
350
|
}
|
|
351
|
-
var
|
|
351
|
+
var htmlColIndex = maybeTableCell.cellIndex;
|
|
352
352
|
var rowElement = (0, _utils.closestElement)(target, 'tr');
|
|
353
|
-
var
|
|
353
|
+
var htmlRowIndex = rowElement && rowElement.rowIndex;
|
|
354
354
|
var colHeight = tableRef.offsetHeight;
|
|
355
355
|
var colWidth = maybeTableCell.offsetWidth;
|
|
356
|
-
|
|
357
|
-
|
|
356
|
+
var tableMap = tableNode && _tableMap.TableMap.get(tableNode);
|
|
357
|
+
var colIndex = htmlColIndex;
|
|
358
|
+
if (tableMap) {
|
|
359
|
+
var convertedColIndex = (0, _utils3.convertHTMLCellIndexToColumnIndex)(htmlColIndex, htmlRowIndex, tableMap);
|
|
360
|
+
colIndex = (0, _utils3.getColumnIndexMappedToColumnIndexInFirstRow)(convertedColIndex, htmlRowIndex, tableMap);
|
|
361
|
+
}
|
|
362
|
+
if (hoveredCell.colIndex !== colIndex || hoveredCell.rowIndex !== htmlRowIndex || hoveredCell.colWidth !== colWidth || hoveredCell.colHeight !== colHeight) {
|
|
363
|
+
(0, _commands.hoverCell)(htmlRowIndex, colIndex, colWidth, colHeight)(view.state, view.dispatch);
|
|
358
364
|
}
|
|
359
365
|
};
|
|
360
366
|
var withCellTracking = exports.withCellTracking = function withCellTracking(eventHandler, elementContentRects) {
|
|
@@ -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.isColumnDeleteButtonVisible = exports.getColumnsWidths = exports.getColumnDeleteButtonParams = exports.getColumnClassNames = exports.colWidthsForRow = void 0;
|
|
7
|
+
exports.isColumnDeleteButtonVisible = exports.getColumnsWidths = exports.getColumnIndexMappedToColumnIndexInFirstRow = exports.getColumnDeleteButtonParams = exports.getColumnClassNames = exports.convertHTMLCellIndexToColumnIndex = exports.colWidthsForRow = void 0;
|
|
8
8
|
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
|
|
9
9
|
var _utils = require("@atlaskit/editor-common/utils");
|
|
10
10
|
var _utils2 = require("@atlaskit/editor-prosemirror/utils");
|
|
@@ -189,4 +189,66 @@ var colWidthsForRow = exports.colWidthsForRow = function colWidthsForRow(tr) {
|
|
|
189
189
|
return pctWidths.map(function (pct) {
|
|
190
190
|
return "".concat(pct, "%");
|
|
191
191
|
}).join(' ');
|
|
192
|
+
};
|
|
193
|
+
var convertHTMLCellIndexToColumnIndex = exports.convertHTMLCellIndexToColumnIndex = function convertHTMLCellIndexToColumnIndex(htmlColIndex, htmlRowIndex, tableMap) {
|
|
194
|
+
// Same numbers (positions) in tableMap.map array mean that there are merged cells.
|
|
195
|
+
// Cells can be merged across columns. So we need to check if the cell on the left and current cell have the same value.
|
|
196
|
+
// Cells can be merged acroll rows. So we need to check if the cell above has the same value as current cell.
|
|
197
|
+
// When cell has the same value as the cell above it or the cell to the left of it, html cellIndex won't count it a separete column.
|
|
198
|
+
var width = tableMap.width;
|
|
199
|
+
var map = tableMap.map;
|
|
200
|
+
var htmlColCount = 0;
|
|
201
|
+
if (htmlRowIndex === 0) {
|
|
202
|
+
for (var colIndex = 0; colIndex < width; colIndex++) {
|
|
203
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
204
|
+
htmlColCount++;
|
|
205
|
+
}
|
|
206
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
207
|
+
return colIndex;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
} else {
|
|
211
|
+
for (var _colIndex = 0; _colIndex < width; _colIndex++) {
|
|
212
|
+
var currentCellMapIndex = htmlRowIndex * width + _colIndex;
|
|
213
|
+
var cellAboveMapIndex = (htmlRowIndex - 1) * width + _colIndex;
|
|
214
|
+
if (_colIndex > 0) {
|
|
215
|
+
if (map[currentCellMapIndex] !== map[currentCellMapIndex - 1] && map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
216
|
+
htmlColCount++;
|
|
217
|
+
}
|
|
218
|
+
} else {
|
|
219
|
+
if (map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
220
|
+
htmlColCount++;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
224
|
+
return _colIndex;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return 0;
|
|
229
|
+
};
|
|
230
|
+
|
|
231
|
+
// When first row has merged cells, our converted column index needs to be mapped.
|
|
232
|
+
var getColumnIndexMappedToColumnIndexInFirstRow = exports.getColumnIndexMappedToColumnIndexInFirstRow = function getColumnIndexMappedToColumnIndexInFirstRow(convertedColIndex, htmlRowIndex, tableMap) {
|
|
233
|
+
var width = tableMap.width;
|
|
234
|
+
var map = tableMap.map;
|
|
235
|
+
var mapColIndexToFistRowColIndex = [];
|
|
236
|
+
var htmlColCounFirstRow = 0;
|
|
237
|
+
var colSpan = 0;
|
|
238
|
+
if (htmlRowIndex === 0) {
|
|
239
|
+
return convertedColIndex;
|
|
240
|
+
}
|
|
241
|
+
for (var colIndex = 0; colIndex < width; colIndex++) {
|
|
242
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
243
|
+
if (colSpan > 0) {
|
|
244
|
+
htmlColCounFirstRow += colSpan;
|
|
245
|
+
colSpan = 0;
|
|
246
|
+
}
|
|
247
|
+
htmlColCounFirstRow++;
|
|
248
|
+
} else if (map[colIndex] === map[colIndex - 1]) {
|
|
249
|
+
colSpan++;
|
|
250
|
+
}
|
|
251
|
+
mapColIndexToFistRowColIndex[colIndex] = htmlColCounFirstRow - 1;
|
|
252
|
+
}
|
|
253
|
+
return mapColIndexToFistRowColIndex[convertedColIndex];
|
|
192
254
|
};
|
|
@@ -39,6 +39,12 @@ Object.defineProperty(exports, "containsHeaderRow", {
|
|
|
39
39
|
return _nodes.containsHeaderRow;
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
|
+
Object.defineProperty(exports, "convertHTMLCellIndexToColumnIndex", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
get: function get() {
|
|
45
|
+
return _columnControls.convertHTMLCellIndexToColumnIndex;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
42
48
|
Object.defineProperty(exports, "copyPreviousRow", {
|
|
43
49
|
enumerable: true,
|
|
44
50
|
get: function get() {
|
|
@@ -111,6 +117,12 @@ Object.defineProperty(exports, "getColumnDeleteButtonParams", {
|
|
|
111
117
|
return _columnControls.getColumnDeleteButtonParams;
|
|
112
118
|
}
|
|
113
119
|
});
|
|
120
|
+
Object.defineProperty(exports, "getColumnIndexMappedToColumnIndexInFirstRow", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
get: function get() {
|
|
123
|
+
return _columnControls.getColumnIndexMappedToColumnIndexInFirstRow;
|
|
124
|
+
}
|
|
125
|
+
});
|
|
114
126
|
Object.defineProperty(exports, "getColumnOrRowIndex", {
|
|
115
127
|
enumerable: true,
|
|
116
128
|
get: function get() {
|
|
@@ -10,7 +10,7 @@ import { getPluginState } from './pm-plugins/plugin-factory';
|
|
|
10
10
|
import { getPluginState as getResizePluginState } from './pm-plugins/table-resizing/plugin-factory';
|
|
11
11
|
import { deleteColumns, deleteRows } from './transforms';
|
|
12
12
|
import { RESIZE_HANDLE_AREA_DECORATION_GAP } from './types';
|
|
13
|
-
import { getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, hasResizeHandler, isCell, isColumnControlsDecorations, isCornerButton, isDragColumnFloatingInsertDot, isDragCornerButton, isDragRowFloatingInsertDot, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableContainerOrWrapper, isTableControlsButton } from './utils';
|
|
13
|
+
import { convertHTMLCellIndexToColumnIndex, getColumnIndexMappedToColumnIndexInFirstRow, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, hasResizeHandler, isCell, isColumnControlsDecorations, isCornerButton, isDragColumnFloatingInsertDot, isDragCornerButton, isDragRowFloatingInsertDot, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableContainerOrWrapper, isTableControlsButton } from './utils';
|
|
14
14
|
import { getAllowAddColumnCustomStep } from './utils/get-allow-add-column-custom-step';
|
|
15
15
|
const isFocusingCalendar = event => event instanceof FocusEvent && event.relatedTarget instanceof HTMLElement && event.relatedTarget.getAttribute('aria-label') === 'calendar';
|
|
16
16
|
const isFocusingModal = event => event instanceof FocusEvent && event.relatedTarget instanceof HTMLElement && event.relatedTarget.closest('[role="dialog"]');
|
|
@@ -356,13 +356,19 @@ const trackCellLocation = (view, mouseEvent) => {
|
|
|
356
356
|
if (!maybeTableCell || !tableRef) {
|
|
357
357
|
return;
|
|
358
358
|
}
|
|
359
|
-
const
|
|
359
|
+
const htmlColIndex = maybeTableCell.cellIndex;
|
|
360
360
|
const rowElement = closestElement(target, 'tr');
|
|
361
|
-
const
|
|
361
|
+
const htmlRowIndex = rowElement && rowElement.rowIndex;
|
|
362
362
|
const colHeight = tableRef.offsetHeight;
|
|
363
363
|
const colWidth = maybeTableCell.offsetWidth;
|
|
364
|
-
|
|
365
|
-
|
|
364
|
+
const tableMap = tableNode && TableMap.get(tableNode);
|
|
365
|
+
let colIndex = htmlColIndex;
|
|
366
|
+
if (tableMap) {
|
|
367
|
+
const convertedColIndex = convertHTMLCellIndexToColumnIndex(htmlColIndex, htmlRowIndex, tableMap);
|
|
368
|
+
colIndex = getColumnIndexMappedToColumnIndexInFirstRow(convertedColIndex, htmlRowIndex, tableMap);
|
|
369
|
+
}
|
|
370
|
+
if (hoveredCell.colIndex !== colIndex || hoveredCell.rowIndex !== htmlRowIndex || hoveredCell.colWidth !== colWidth || hoveredCell.colHeight !== colHeight) {
|
|
371
|
+
hoverCell(htmlRowIndex, colIndex, colWidth, colHeight)(view.state, view.dispatch);
|
|
366
372
|
}
|
|
367
373
|
};
|
|
368
374
|
export const withCellTracking = (eventHandler, elementContentRects) => (view, mouseEvent) => {
|
|
@@ -159,4 +159,66 @@ export const colWidthsForRow = tr => {
|
|
|
159
159
|
const visualColCount = rowColSpans.reduce((acc, val) => acc + val, 0);
|
|
160
160
|
const pctWidths = rowColSpans.map(cellColSpan => cellColSpan / visualColCount * 100);
|
|
161
161
|
return pctWidths.map(pct => `${pct}%`).join(' ');
|
|
162
|
+
};
|
|
163
|
+
export const convertHTMLCellIndexToColumnIndex = (htmlColIndex, htmlRowIndex, tableMap) => {
|
|
164
|
+
// Same numbers (positions) in tableMap.map array mean that there are merged cells.
|
|
165
|
+
// Cells can be merged across columns. So we need to check if the cell on the left and current cell have the same value.
|
|
166
|
+
// Cells can be merged acroll rows. So we need to check if the cell above has the same value as current cell.
|
|
167
|
+
// When cell has the same value as the cell above it or the cell to the left of it, html cellIndex won't count it a separete column.
|
|
168
|
+
const width = tableMap.width;
|
|
169
|
+
const map = tableMap.map;
|
|
170
|
+
let htmlColCount = 0;
|
|
171
|
+
if (htmlRowIndex === 0) {
|
|
172
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
173
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
174
|
+
htmlColCount++;
|
|
175
|
+
}
|
|
176
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
177
|
+
return colIndex;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
182
|
+
const currentCellMapIndex = htmlRowIndex * width + colIndex;
|
|
183
|
+
const cellAboveMapIndex = (htmlRowIndex - 1) * width + colIndex;
|
|
184
|
+
if (colIndex > 0) {
|
|
185
|
+
if (map[currentCellMapIndex] !== map[currentCellMapIndex - 1] && map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
186
|
+
htmlColCount++;
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
if (map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
190
|
+
htmlColCount++;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
194
|
+
return colIndex;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return 0;
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// When first row has merged cells, our converted column index needs to be mapped.
|
|
202
|
+
export const getColumnIndexMappedToColumnIndexInFirstRow = (convertedColIndex, htmlRowIndex, tableMap) => {
|
|
203
|
+
const width = tableMap.width;
|
|
204
|
+
const map = tableMap.map;
|
|
205
|
+
const mapColIndexToFistRowColIndex = [];
|
|
206
|
+
let htmlColCounFirstRow = 0;
|
|
207
|
+
let colSpan = 0;
|
|
208
|
+
if (htmlRowIndex === 0) {
|
|
209
|
+
return convertedColIndex;
|
|
210
|
+
}
|
|
211
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
212
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
213
|
+
if (colSpan > 0) {
|
|
214
|
+
htmlColCounFirstRow += colSpan;
|
|
215
|
+
colSpan = 0;
|
|
216
|
+
}
|
|
217
|
+
htmlColCounFirstRow++;
|
|
218
|
+
} else if (map[colIndex] === map[colIndex - 1]) {
|
|
219
|
+
colSpan++;
|
|
220
|
+
}
|
|
221
|
+
mapColIndexToFistRowColIndex[colIndex] = htmlColCounFirstRow - 1;
|
|
222
|
+
}
|
|
223
|
+
return mapColIndexToFistRowColIndex[convertedColIndex];
|
|
162
224
|
};
|
|
@@ -3,7 +3,7 @@ export { findControlsHoverDecoration, createControlsHoverDecoration, createColum
|
|
|
3
3
|
export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow } from './nodes';
|
|
4
4
|
export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell } from './paste';
|
|
5
5
|
export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, isDragRowControlsButton, isDragColumnFloatingInsertDot, isDragRowFloatingInsertDot, isDragCornerButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler } from './dom';
|
|
6
|
-
export { getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames } from './column-controls';
|
|
6
|
+
export { convertHTMLCellIndexToColumnIndex, getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, getColumnIndexMappedToColumnIndexInFirstRow } from './column-controls';
|
|
7
7
|
export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getRowsParams, getRowClassNames, copyPreviousRow } from './row-controls';
|
|
8
8
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
9
9
|
export { getMergedCellsPositions } from './table';
|
|
@@ -11,7 +11,7 @@ import { getPluginState } from './pm-plugins/plugin-factory';
|
|
|
11
11
|
import { getPluginState as getResizePluginState } from './pm-plugins/table-resizing/plugin-factory';
|
|
12
12
|
import { deleteColumns, deleteRows } from './transforms';
|
|
13
13
|
import { RESIZE_HANDLE_AREA_DECORATION_GAP } from './types';
|
|
14
|
-
import { getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, hasResizeHandler, isCell, isColumnControlsDecorations, isCornerButton, isDragColumnFloatingInsertDot, isDragCornerButton, isDragRowFloatingInsertDot, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableContainerOrWrapper, isTableControlsButton } from './utils';
|
|
14
|
+
import { convertHTMLCellIndexToColumnIndex, getColumnIndexMappedToColumnIndexInFirstRow, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, getSelectedCellInfo, hasResizeHandler, isCell, isColumnControlsDecorations, isCornerButton, isDragColumnFloatingInsertDot, isDragCornerButton, isDragRowFloatingInsertDot, isInsertRowButton, isResizeHandleDecoration, isRowControlsButton, isTableContainerOrWrapper, isTableControlsButton } from './utils';
|
|
15
15
|
import { getAllowAddColumnCustomStep } from './utils/get-allow-add-column-custom-step';
|
|
16
16
|
var isFocusingCalendar = function isFocusingCalendar(event) {
|
|
17
17
|
return event instanceof FocusEvent && event.relatedTarget instanceof HTMLElement && event.relatedTarget.getAttribute('aria-label') === 'calendar';
|
|
@@ -339,13 +339,19 @@ var trackCellLocation = function trackCellLocation(view, mouseEvent) {
|
|
|
339
339
|
if (!maybeTableCell || !tableRef) {
|
|
340
340
|
return;
|
|
341
341
|
}
|
|
342
|
-
var
|
|
342
|
+
var htmlColIndex = maybeTableCell.cellIndex;
|
|
343
343
|
var rowElement = closestElement(target, 'tr');
|
|
344
|
-
var
|
|
344
|
+
var htmlRowIndex = rowElement && rowElement.rowIndex;
|
|
345
345
|
var colHeight = tableRef.offsetHeight;
|
|
346
346
|
var colWidth = maybeTableCell.offsetWidth;
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
var tableMap = tableNode && TableMap.get(tableNode);
|
|
348
|
+
var colIndex = htmlColIndex;
|
|
349
|
+
if (tableMap) {
|
|
350
|
+
var convertedColIndex = convertHTMLCellIndexToColumnIndex(htmlColIndex, htmlRowIndex, tableMap);
|
|
351
|
+
colIndex = getColumnIndexMappedToColumnIndexInFirstRow(convertedColIndex, htmlRowIndex, tableMap);
|
|
352
|
+
}
|
|
353
|
+
if (hoveredCell.colIndex !== colIndex || hoveredCell.rowIndex !== htmlRowIndex || hoveredCell.colWidth !== colWidth || hoveredCell.colHeight !== colHeight) {
|
|
354
|
+
hoverCell(htmlRowIndex, colIndex, colWidth, colHeight)(view.state, view.dispatch);
|
|
349
355
|
}
|
|
350
356
|
};
|
|
351
357
|
export var withCellTracking = function withCellTracking(eventHandler, elementContentRects) {
|
|
@@ -182,4 +182,66 @@ export var colWidthsForRow = function colWidthsForRow(tr) {
|
|
|
182
182
|
return pctWidths.map(function (pct) {
|
|
183
183
|
return "".concat(pct, "%");
|
|
184
184
|
}).join(' ');
|
|
185
|
+
};
|
|
186
|
+
export var convertHTMLCellIndexToColumnIndex = function convertHTMLCellIndexToColumnIndex(htmlColIndex, htmlRowIndex, tableMap) {
|
|
187
|
+
// Same numbers (positions) in tableMap.map array mean that there are merged cells.
|
|
188
|
+
// Cells can be merged across columns. So we need to check if the cell on the left and current cell have the same value.
|
|
189
|
+
// Cells can be merged acroll rows. So we need to check if the cell above has the same value as current cell.
|
|
190
|
+
// When cell has the same value as the cell above it or the cell to the left of it, html cellIndex won't count it a separete column.
|
|
191
|
+
var width = tableMap.width;
|
|
192
|
+
var map = tableMap.map;
|
|
193
|
+
var htmlColCount = 0;
|
|
194
|
+
if (htmlRowIndex === 0) {
|
|
195
|
+
for (var colIndex = 0; colIndex < width; colIndex++) {
|
|
196
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
197
|
+
htmlColCount++;
|
|
198
|
+
}
|
|
199
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
200
|
+
return colIndex;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
} else {
|
|
204
|
+
for (var _colIndex = 0; _colIndex < width; _colIndex++) {
|
|
205
|
+
var currentCellMapIndex = htmlRowIndex * width + _colIndex;
|
|
206
|
+
var cellAboveMapIndex = (htmlRowIndex - 1) * width + _colIndex;
|
|
207
|
+
if (_colIndex > 0) {
|
|
208
|
+
if (map[currentCellMapIndex] !== map[currentCellMapIndex - 1] && map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
209
|
+
htmlColCount++;
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
if (map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
213
|
+
htmlColCount++;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
217
|
+
return _colIndex;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return 0;
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
// When first row has merged cells, our converted column index needs to be mapped.
|
|
225
|
+
export var getColumnIndexMappedToColumnIndexInFirstRow = function getColumnIndexMappedToColumnIndexInFirstRow(convertedColIndex, htmlRowIndex, tableMap) {
|
|
226
|
+
var width = tableMap.width;
|
|
227
|
+
var map = tableMap.map;
|
|
228
|
+
var mapColIndexToFistRowColIndex = [];
|
|
229
|
+
var htmlColCounFirstRow = 0;
|
|
230
|
+
var colSpan = 0;
|
|
231
|
+
if (htmlRowIndex === 0) {
|
|
232
|
+
return convertedColIndex;
|
|
233
|
+
}
|
|
234
|
+
for (var colIndex = 0; colIndex < width; colIndex++) {
|
|
235
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
236
|
+
if (colSpan > 0) {
|
|
237
|
+
htmlColCounFirstRow += colSpan;
|
|
238
|
+
colSpan = 0;
|
|
239
|
+
}
|
|
240
|
+
htmlColCounFirstRow++;
|
|
241
|
+
} else if (map[colIndex] === map[colIndex - 1]) {
|
|
242
|
+
colSpan++;
|
|
243
|
+
}
|
|
244
|
+
mapColIndexToFistRowColIndex[colIndex] = htmlColCounFirstRow - 1;
|
|
245
|
+
}
|
|
246
|
+
return mapColIndexToFistRowColIndex[convertedColIndex];
|
|
185
247
|
};
|
|
@@ -3,7 +3,7 @@ export { findControlsHoverDecoration, createControlsHoverDecoration, createColum
|
|
|
3
3
|
export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow } from './nodes';
|
|
4
4
|
export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell } from './paste';
|
|
5
5
|
export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, isDragRowControlsButton, isDragColumnFloatingInsertDot, isDragRowFloatingInsertDot, isDragCornerButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler } from './dom';
|
|
6
|
-
export { getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames } from './column-controls';
|
|
6
|
+
export { convertHTMLCellIndexToColumnIndex, getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, getColumnIndexMappedToColumnIndexInFirstRow } from './column-controls';
|
|
7
7
|
export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getRowsParams, getRowClassNames, copyPreviousRow } from './row-controls';
|
|
8
8
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
9
9
|
export { getMergedCellsPositions } from './table';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
2
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import { TableMap } from '@atlaskit/editor-tables/table-map';
|
|
3
4
|
export declare const getColumnsWidths: (view: EditorView) => Array<number | undefined>;
|
|
4
5
|
export declare const isColumnDeleteButtonVisible: (selection: Selection) => boolean;
|
|
5
6
|
export declare const getColumnDeleteButtonParams: (columnsWidths: Array<number | undefined>, selection: Selection) => {
|
|
@@ -8,3 +9,5 @@ export declare const getColumnDeleteButtonParams: (columnsWidths: Array<number |
|
|
|
8
9
|
} | null;
|
|
9
10
|
export declare const getColumnClassNames: (index: number, selection: Selection, hoveredColumns?: number[], isInDanger?: boolean, isResizing?: boolean) => string;
|
|
10
11
|
export declare const colWidthsForRow: (tr: HTMLTableRowElement) => string;
|
|
12
|
+
export declare const convertHTMLCellIndexToColumnIndex: (htmlColIndex: number, htmlRowIndex: number, tableMap: TableMap) => number;
|
|
13
|
+
export declare const getColumnIndexMappedToColumnIndexInFirstRow: (convertedColIndex: number, htmlRowIndex: number, tableMap: TableMap) => number;
|
|
@@ -3,7 +3,7 @@ export { findControlsHoverDecoration, createControlsHoverDecoration, createColum
|
|
|
3
3
|
export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow, } from './nodes';
|
|
4
4
|
export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell, } from './paste';
|
|
5
5
|
export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, isDragRowControlsButton, isDragColumnFloatingInsertDot, isDragRowFloatingInsertDot, isDragCornerButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler, } from './dom';
|
|
6
|
-
export { getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, } from './column-controls';
|
|
6
|
+
export { convertHTMLCellIndexToColumnIndex, getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, getColumnIndexMappedToColumnIndexInFirstRow, } from './column-controls';
|
|
7
7
|
export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getRowsParams, getRowClassNames, copyPreviousRow, } from './row-controls';
|
|
8
8
|
export type { RowParams } from './row-controls';
|
|
9
9
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Selection } from '@atlaskit/editor-prosemirror/state';
|
|
2
2
|
import type { EditorView } from '@atlaskit/editor-prosemirror/view';
|
|
3
|
+
import { TableMap } from '@atlaskit/editor-tables/table-map';
|
|
3
4
|
export declare const getColumnsWidths: (view: EditorView) => Array<number | undefined>;
|
|
4
5
|
export declare const isColumnDeleteButtonVisible: (selection: Selection) => boolean;
|
|
5
6
|
export declare const getColumnDeleteButtonParams: (columnsWidths: Array<number | undefined>, selection: Selection) => {
|
|
@@ -8,3 +9,5 @@ export declare const getColumnDeleteButtonParams: (columnsWidths: Array<number |
|
|
|
8
9
|
} | null;
|
|
9
10
|
export declare const getColumnClassNames: (index: number, selection: Selection, hoveredColumns?: number[], isInDanger?: boolean, isResizing?: boolean) => string;
|
|
10
11
|
export declare const colWidthsForRow: (tr: HTMLTableRowElement) => string;
|
|
12
|
+
export declare const convertHTMLCellIndexToColumnIndex: (htmlColIndex: number, htmlRowIndex: number, tableMap: TableMap) => number;
|
|
13
|
+
export declare const getColumnIndexMappedToColumnIndexInFirstRow: (convertedColIndex: number, htmlRowIndex: number, tableMap: TableMap) => number;
|
|
@@ -3,7 +3,7 @@ export { findControlsHoverDecoration, createControlsHoverDecoration, createColum
|
|
|
3
3
|
export { isIsolating, containsHeaderColumn, containsHeaderRow, checkIfHeaderColumnEnabled, checkIfHeaderRowEnabled, checkIfNumberColumnEnabled, isLayoutSupported, getTableWidth, tablesHaveDifferentColumnWidths, tablesHaveDifferentNoOfColumns, isTableNested, anyChildCellMergedAcrossRow, supportedHeaderRow, } from './nodes';
|
|
4
4
|
export { unwrapContentFromTable, removeTableFromFirstChild, removeTableFromLastChild, transformSliceToRemoveOpenTable, transformSliceToCorrectEmptyTableCells, transformSliceToFixHardBreakProblemOnCopyFromCell, } from './paste';
|
|
5
5
|
export { isCell, isCornerButton, isInsertRowButton, isColumnControlsDecorations, isTableControlsButton, isTableContainerOrWrapper, isRowControlsButton, isDragRowControlsButton, isDragColumnFloatingInsertDot, isDragRowFloatingInsertDot, isDragCornerButton, getColumnOrRowIndex, getMousePositionHorizontalRelativeByElement, getMousePositionVerticalRelativeByElement, updateResizeHandles, isResizeHandleDecoration, hasResizeHandler, } from './dom';
|
|
6
|
-
export { getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, } from './column-controls';
|
|
6
|
+
export { convertHTMLCellIndexToColumnIndex, getColumnsWidths, isColumnDeleteButtonVisible, getColumnDeleteButtonParams, getColumnClassNames, getColumnIndexMappedToColumnIndexInFirstRow, } from './column-controls';
|
|
7
7
|
export { getRowHeights, isRowDeleteButtonVisible, getRowDeleteButtonParams, getRowsParams, getRowClassNames, copyPreviousRow, } from './row-controls';
|
|
8
8
|
export type { RowParams } from './row-controls';
|
|
9
9
|
export { getSelectedTableInfo, getSelectedCellInfo } from './analytics';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/editor-plugin-table",
|
|
3
|
-
"version": "5.4.
|
|
3
|
+
"version": "5.4.13",
|
|
4
4
|
"description": "Table plugin for the @atlaskit/editor",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org/"
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@atlaskit/adf-schema": "^35.0.0",
|
|
31
31
|
"@atlaskit/custom-steps": "^0.0.6",
|
|
32
|
-
"@atlaskit/editor-common": "^76.
|
|
32
|
+
"@atlaskit/editor-common": "^76.25.0",
|
|
33
33
|
"@atlaskit/editor-palette": "1.5.2",
|
|
34
34
|
"@atlaskit/editor-plugin-analytics": "^0.3.0",
|
|
35
35
|
"@atlaskit/editor-plugin-content-insertion": "^0.1.0",
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { TableMap } from '@atlaskit/editor-tables';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
colWidthsForRow,
|
|
5
|
+
convertHTMLCellIndexToColumnIndex,
|
|
6
|
+
getColumnIndexMappedToColumnIndexInFirstRow,
|
|
7
|
+
} from '../../../plugins/table/utils/column-controls';
|
|
2
8
|
|
|
3
9
|
const createRow = (colCount: number, childType = 'td') => {
|
|
4
10
|
const tr = document.createElement('tr');
|
|
@@ -59,3 +65,141 @@ describe('table utilities', () => {
|
|
|
59
65
|
});
|
|
60
66
|
});
|
|
61
67
|
});
|
|
68
|
+
|
|
69
|
+
describe('table utilities - convertHTMLCellIndexToColumnIndex', () => {
|
|
70
|
+
/*
|
|
71
|
+
Table looks like this:
|
|
72
|
+
___ _______ ___ ___ ___
|
|
73
|
+
|___| |_A_|___|___|
|
|
74
|
+
|___| |___| |___|
|
|
75
|
+
|___|_______|_B_| |___|
|
|
76
|
+
|___|___|___|___| |___|
|
|
77
|
+
|___________|___|___|___|
|
|
78
|
+
|___________|___|_C_|___|
|
|
79
|
+
|___________|___|___|___|
|
|
80
|
+
|___|___|___|_D_|___|___|
|
|
81
|
+
|___|___|_E_____________|
|
|
82
|
+
*/
|
|
83
|
+
const tableMap = {
|
|
84
|
+
width: 6,
|
|
85
|
+
height: 9,
|
|
86
|
+
map: [
|
|
87
|
+
1, 5, 5, 9, 13, 17, 23, 5, 5, 27, 31, 35, 41, 5, 5, 45, 31, 49, 55, 59,
|
|
88
|
+
63, 67, 31, 71, 77, 77, 77, 81, 31, 85, 91, 91, 91, 95, 99, 103, 109, 109,
|
|
89
|
+
109, 113, 117, 121, 127, 131, 135, 139, 143, 147, 153, 157, 161, 161, 161,
|
|
90
|
+
161,
|
|
91
|
+
],
|
|
92
|
+
} as TableMap;
|
|
93
|
+
|
|
94
|
+
const testCases = [
|
|
95
|
+
[
|
|
96
|
+
'case A: when hovered cell is in the first row and first row has merged cells',
|
|
97
|
+
2, // htmlColIndex
|
|
98
|
+
0, // htmlRowIndex
|
|
99
|
+
3, // expected
|
|
100
|
+
],
|
|
101
|
+
[
|
|
102
|
+
'case B: when hoverd cell is not in the first row, but the row has merged cells',
|
|
103
|
+
1,
|
|
104
|
+
2,
|
|
105
|
+
3,
|
|
106
|
+
],
|
|
107
|
+
[
|
|
108
|
+
'case C: when a cell that is in the row above and to the left of current cell is merged',
|
|
109
|
+
3,
|
|
110
|
+
5,
|
|
111
|
+
5,
|
|
112
|
+
],
|
|
113
|
+
[
|
|
114
|
+
'case D: when first row has merged cell and hovered cell is below merged area',
|
|
115
|
+
2,
|
|
116
|
+
7,
|
|
117
|
+
2,
|
|
118
|
+
],
|
|
119
|
+
[
|
|
120
|
+
'case E: when first row has merged cell and hovered cell is below merged area and is part of merged area',
|
|
121
|
+
2,
|
|
122
|
+
8,
|
|
123
|
+
2,
|
|
124
|
+
],
|
|
125
|
+
];
|
|
126
|
+
|
|
127
|
+
describe('should convert cellIndex into colIndex correctly', () => {
|
|
128
|
+
test.each(testCases)(
|
|
129
|
+
'%s',
|
|
130
|
+
(message, htmlColIndex, htmlRowIndex, expected) => {
|
|
131
|
+
expect(
|
|
132
|
+
convertHTMLCellIndexToColumnIndex(
|
|
133
|
+
htmlColIndex as number,
|
|
134
|
+
htmlRowIndex as number,
|
|
135
|
+
tableMap,
|
|
136
|
+
),
|
|
137
|
+
).toEqual(expected);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
describe('tableUtilities - getColumnIndexMappedToColumnIndexInFirstRow', () => {
|
|
144
|
+
/*
|
|
145
|
+
Table used for this tests looks like this:
|
|
146
|
+
___ _______ ___ ___ ___ ___ ___ ___________ ___
|
|
147
|
+
|___|_______|___|___|___|___|___|___________|_D_|
|
|
148
|
+
|___|_A_|_B_|___|___|___|___|___|___|_E_|___|___|
|
|
149
|
+
|___|___|_______|___|_____C_|___|___|___|___|___|
|
|
150
|
+
|___|___|___|___|___|___|___|___|___|___|___|___|
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
const tableMap = {
|
|
154
|
+
width: 12,
|
|
155
|
+
height: 4,
|
|
156
|
+
map: [
|
|
157
|
+
1, 5, 5, 9, 13, 17, 21, 25, 29, 29, 29, 33, 39, 43, 47, 51, 55, 59, 63,
|
|
158
|
+
67, 71, 75, 79, 83, 89, 93, 97, 97, 101, 105, 105, 109, 113, 117, 121,
|
|
159
|
+
125, 131, 135, 139, 143, 147, 151, 155, 159, 163, 167, 171, 175,
|
|
160
|
+
],
|
|
161
|
+
} as TableMap;
|
|
162
|
+
|
|
163
|
+
const testCases = [
|
|
164
|
+
[
|
|
165
|
+
'case A: mouse is on a cell located below merged area of the first row closer to its start',
|
|
166
|
+
2, // convertedColIndex
|
|
167
|
+
1, // htmlRowIndex
|
|
168
|
+
1, // expected
|
|
169
|
+
],
|
|
170
|
+
[
|
|
171
|
+
'case B: mouse is on a cell located below merged area of the first row close to its end',
|
|
172
|
+
1,
|
|
173
|
+
1,
|
|
174
|
+
1,
|
|
175
|
+
],
|
|
176
|
+
[
|
|
177
|
+
'case E: mouse is on a cell located below merged area of the first row in the middle of the merged area',
|
|
178
|
+
9,
|
|
179
|
+
1,
|
|
180
|
+
8,
|
|
181
|
+
],
|
|
182
|
+
['case C: mouse is on a merged cell located below the first row', 5, 2, 5],
|
|
183
|
+
[
|
|
184
|
+
'case D: mouse is on a cell in the first row that is next to a merged cell',
|
|
185
|
+
11,
|
|
186
|
+
1,
|
|
187
|
+
11,
|
|
188
|
+
],
|
|
189
|
+
];
|
|
190
|
+
|
|
191
|
+
describe('should adapt converted colIndex when first row has merged cells', () => {
|
|
192
|
+
test.each(testCases)(
|
|
193
|
+
'%s',
|
|
194
|
+
(message, convertedColIndex, htmlRowIndex, expected) => {
|
|
195
|
+
expect(
|
|
196
|
+
getColumnIndexMappedToColumnIndexInFirstRow(
|
|
197
|
+
convertedColIndex as number,
|
|
198
|
+
htmlRowIndex as number,
|
|
199
|
+
tableMap,
|
|
200
|
+
),
|
|
201
|
+
).toEqual(expected);
|
|
202
|
+
},
|
|
203
|
+
);
|
|
204
|
+
});
|
|
205
|
+
});
|
|
@@ -48,6 +48,8 @@ import { deleteColumns, deleteRows } from './transforms';
|
|
|
48
48
|
import type { ElementContentRects } from './types';
|
|
49
49
|
import { RESIZE_HANDLE_AREA_DECORATION_GAP } from './types';
|
|
50
50
|
import {
|
|
51
|
+
convertHTMLCellIndexToColumnIndex,
|
|
52
|
+
getColumnIndexMappedToColumnIndexInFirstRow,
|
|
51
53
|
getColumnOrRowIndex,
|
|
52
54
|
getMousePositionHorizontalRelativeByElement,
|
|
53
55
|
getMousePositionVerticalRelativeByElement,
|
|
@@ -552,24 +554,40 @@ const trackCellLocation = (view: EditorView, mouseEvent: Event) => {
|
|
|
552
554
|
return;
|
|
553
555
|
}
|
|
554
556
|
|
|
555
|
-
const
|
|
557
|
+
const htmlColIndex = maybeTableCell.cellIndex;
|
|
556
558
|
const rowElement = closestElement(
|
|
557
559
|
target as HTMLElement,
|
|
558
560
|
'tr',
|
|
559
561
|
) as HTMLTableRowElement;
|
|
560
|
-
const
|
|
562
|
+
const htmlRowIndex = rowElement && rowElement.rowIndex;
|
|
561
563
|
|
|
562
564
|
const colHeight = tableRef.offsetHeight;
|
|
563
565
|
const colWidth = maybeTableCell.offsetWidth;
|
|
564
566
|
|
|
567
|
+
const tableMap = tableNode && TableMap.get(tableNode);
|
|
568
|
+
let colIndex = htmlColIndex;
|
|
569
|
+
if (tableMap) {
|
|
570
|
+
const convertedColIndex = convertHTMLCellIndexToColumnIndex(
|
|
571
|
+
htmlColIndex,
|
|
572
|
+
htmlRowIndex,
|
|
573
|
+
tableMap,
|
|
574
|
+
);
|
|
575
|
+
|
|
576
|
+
colIndex = getColumnIndexMappedToColumnIndexInFirstRow(
|
|
577
|
+
convertedColIndex,
|
|
578
|
+
htmlRowIndex,
|
|
579
|
+
tableMap,
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
|
|
565
583
|
if (
|
|
566
584
|
hoveredCell.colIndex !== colIndex ||
|
|
567
|
-
hoveredCell.rowIndex !==
|
|
585
|
+
hoveredCell.rowIndex !== htmlRowIndex ||
|
|
568
586
|
hoveredCell.colWidth !== colWidth ||
|
|
569
587
|
hoveredCell.colHeight !== colHeight
|
|
570
588
|
) {
|
|
571
589
|
hoverCell(
|
|
572
|
-
|
|
590
|
+
htmlRowIndex,
|
|
573
591
|
colIndex,
|
|
574
592
|
colWidth,
|
|
575
593
|
colHeight,
|
|
@@ -217,3 +217,84 @@ export const colWidthsForRow = (tr: HTMLTableRowElement) => {
|
|
|
217
217
|
|
|
218
218
|
return pctWidths.map((pct) => `${pct}%`).join(' ');
|
|
219
219
|
};
|
|
220
|
+
|
|
221
|
+
export const convertHTMLCellIndexToColumnIndex = (
|
|
222
|
+
htmlColIndex: number,
|
|
223
|
+
htmlRowIndex: number,
|
|
224
|
+
tableMap: TableMap,
|
|
225
|
+
): number => {
|
|
226
|
+
// Same numbers (positions) in tableMap.map array mean that there are merged cells.
|
|
227
|
+
// Cells can be merged across columns. So we need to check if the cell on the left and current cell have the same value.
|
|
228
|
+
// Cells can be merged acroll rows. So we need to check if the cell above has the same value as current cell.
|
|
229
|
+
// When cell has the same value as the cell above it or the cell to the left of it, html cellIndex won't count it a separete column.
|
|
230
|
+
const width = tableMap.width;
|
|
231
|
+
const map = tableMap.map;
|
|
232
|
+
let htmlColCount = 0;
|
|
233
|
+
|
|
234
|
+
if (htmlRowIndex === 0) {
|
|
235
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
236
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
237
|
+
htmlColCount++;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
241
|
+
return colIndex;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
246
|
+
const currentCellMapIndex = htmlRowIndex * width + colIndex;
|
|
247
|
+
const cellAboveMapIndex = (htmlRowIndex - 1) * width + colIndex;
|
|
248
|
+
if (colIndex > 0) {
|
|
249
|
+
if (
|
|
250
|
+
map[currentCellMapIndex] !== map[currentCellMapIndex - 1] &&
|
|
251
|
+
map[currentCellMapIndex] !== map[cellAboveMapIndex]
|
|
252
|
+
) {
|
|
253
|
+
htmlColCount++;
|
|
254
|
+
}
|
|
255
|
+
} else {
|
|
256
|
+
if (map[currentCellMapIndex] !== map[cellAboveMapIndex]) {
|
|
257
|
+
htmlColCount++;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (htmlColCount - 1 === htmlColIndex) {
|
|
262
|
+
return colIndex;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return 0;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
// When first row has merged cells, our converted column index needs to be mapped.
|
|
271
|
+
export const getColumnIndexMappedToColumnIndexInFirstRow = (
|
|
272
|
+
convertedColIndex: number,
|
|
273
|
+
htmlRowIndex: number,
|
|
274
|
+
tableMap: TableMap,
|
|
275
|
+
): number => {
|
|
276
|
+
const width = tableMap.width;
|
|
277
|
+
const map = tableMap.map;
|
|
278
|
+
const mapColIndexToFistRowColIndex = [];
|
|
279
|
+
let htmlColCounFirstRow = 0;
|
|
280
|
+
let colSpan = 0;
|
|
281
|
+
|
|
282
|
+
if (htmlRowIndex === 0) {
|
|
283
|
+
return convertedColIndex;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
for (let colIndex = 0; colIndex < width; colIndex++) {
|
|
287
|
+
if (colIndex === 0 || map[colIndex] !== map[colIndex - 1]) {
|
|
288
|
+
if (colSpan > 0) {
|
|
289
|
+
htmlColCounFirstRow += colSpan;
|
|
290
|
+
colSpan = 0;
|
|
291
|
+
}
|
|
292
|
+
htmlColCounFirstRow++;
|
|
293
|
+
} else if (map[colIndex] === map[colIndex - 1]) {
|
|
294
|
+
colSpan++;
|
|
295
|
+
}
|
|
296
|
+
mapColIndexToFistRowColIndex[colIndex] = htmlColCounFirstRow - 1;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
return mapColIndexToFistRowColIndex[convertedColIndex];
|
|
300
|
+
};
|
|
@@ -59,10 +59,12 @@ export {
|
|
|
59
59
|
hasResizeHandler,
|
|
60
60
|
} from './dom';
|
|
61
61
|
export {
|
|
62
|
+
convertHTMLCellIndexToColumnIndex,
|
|
62
63
|
getColumnsWidths,
|
|
63
64
|
isColumnDeleteButtonVisible,
|
|
64
65
|
getColumnDeleteButtonParams,
|
|
65
66
|
getColumnClassNames,
|
|
67
|
+
getColumnIndexMappedToColumnIndexInFirstRow,
|
|
66
68
|
} from './column-controls';
|
|
67
69
|
export {
|
|
68
70
|
getRowHeights,
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
it.todo('TODO: ED-15801 - Fix smart link async rendering integration test');
|
|
3
|
-
// import { runBlockNodeSelectionTestSuite } from '@atlaskit/editor-test-helpers/integration/selection';
|
|
4
|
-
//
|
|
5
|
-
// runBlockNodeSelectionTestSuite({
|
|
6
|
-
// nodeName: 'table',
|
|
7
|
-
// editorOptions: {
|
|
8
|
-
// allowTables: {
|
|
9
|
-
// advanced: true,
|
|
10
|
-
// },
|
|
11
|
-
// },
|
|
12
|
-
// selector: 'table',
|
|
13
|
-
// adfNode: {
|
|
14
|
-
// type: 'table',
|
|
15
|
-
// attrs: {
|
|
16
|
-
// isNumberColumnEnabled: false,
|
|
17
|
-
// layout: 'default',
|
|
18
|
-
// localId: '15804638-b946-4591-b64c-beffe5122733',
|
|
19
|
-
// },
|
|
20
|
-
// content: [
|
|
21
|
-
// {
|
|
22
|
-
// type: 'tableRow',
|
|
23
|
-
// content: [
|
|
24
|
-
// {
|
|
25
|
-
// type: 'tableHeader',
|
|
26
|
-
// attrs: {},
|
|
27
|
-
// content: [
|
|
28
|
-
// {
|
|
29
|
-
// type: 'paragraph',
|
|
30
|
-
// content: [],
|
|
31
|
-
// },
|
|
32
|
-
// ],
|
|
33
|
-
// },
|
|
34
|
-
// {
|
|
35
|
-
// type: 'tableHeader',
|
|
36
|
-
// attrs: {},
|
|
37
|
-
// content: [
|
|
38
|
-
// {
|
|
39
|
-
// type: 'paragraph',
|
|
40
|
-
// content: [],
|
|
41
|
-
// },
|
|
42
|
-
// ],
|
|
43
|
-
// },
|
|
44
|
-
// {
|
|
45
|
-
// type: 'tableHeader',
|
|
46
|
-
// attrs: {},
|
|
47
|
-
// content: [
|
|
48
|
-
// {
|
|
49
|
-
// type: 'paragraph',
|
|
50
|
-
// content: [],
|
|
51
|
-
// },
|
|
52
|
-
// ],
|
|
53
|
-
// },
|
|
54
|
-
// ],
|
|
55
|
-
// },
|
|
56
|
-
// {
|
|
57
|
-
// type: 'tableRow',
|
|
58
|
-
// content: [
|
|
59
|
-
// {
|
|
60
|
-
// type: 'tableCell',
|
|
61
|
-
// attrs: {},
|
|
62
|
-
// content: [
|
|
63
|
-
// {
|
|
64
|
-
// type: 'paragraph',
|
|
65
|
-
// content: [],
|
|
66
|
-
// },
|
|
67
|
-
// ],
|
|
68
|
-
// },
|
|
69
|
-
// {
|
|
70
|
-
// type: 'tableCell',
|
|
71
|
-
// attrs: {},
|
|
72
|
-
// content: [
|
|
73
|
-
// {
|
|
74
|
-
// type: 'paragraph',
|
|
75
|
-
// content: [],
|
|
76
|
-
// },
|
|
77
|
-
// ],
|
|
78
|
-
// },
|
|
79
|
-
// {
|
|
80
|
-
// type: 'tableCell',
|
|
81
|
-
// attrs: {},
|
|
82
|
-
// content: [
|
|
83
|
-
// {
|
|
84
|
-
// type: 'paragraph',
|
|
85
|
-
// content: [],
|
|
86
|
-
// },
|
|
87
|
-
// ],
|
|
88
|
-
// },
|
|
89
|
-
// ],
|
|
90
|
-
// },
|
|
91
|
-
// {
|
|
92
|
-
// type: 'tableRow',
|
|
93
|
-
// content: [
|
|
94
|
-
// {
|
|
95
|
-
// type: 'tableCell',
|
|
96
|
-
// attrs: {},
|
|
97
|
-
// content: [
|
|
98
|
-
// {
|
|
99
|
-
// type: 'paragraph',
|
|
100
|
-
// content: [],
|
|
101
|
-
// },
|
|
102
|
-
// ],
|
|
103
|
-
// },
|
|
104
|
-
// {
|
|
105
|
-
// type: 'tableCell',
|
|
106
|
-
// attrs: {},
|
|
107
|
-
// content: [
|
|
108
|
-
// {
|
|
109
|
-
// type: 'paragraph',
|
|
110
|
-
// content: [],
|
|
111
|
-
// },
|
|
112
|
-
// ],
|
|
113
|
-
// },
|
|
114
|
-
// {
|
|
115
|
-
// type: 'tableCell',
|
|
116
|
-
// attrs: {},
|
|
117
|
-
// content: [
|
|
118
|
-
// {
|
|
119
|
-
// type: 'paragraph',
|
|
120
|
-
// content: [],
|
|
121
|
-
// },
|
|
122
|
-
// ],
|
|
123
|
-
// },
|
|
124
|
-
// ],
|
|
125
|
-
// },
|
|
126
|
-
// ],
|
|
127
|
-
// },
|
|
128
|
-
// skipTests: {
|
|
129
|
-
// 'Extend selection right two characters to select [block-node] from line above with shift + arrow right': [
|
|
130
|
-
// 'chrome',
|
|
131
|
-
// 'safari',
|
|
132
|
-
// 'firefox',
|
|
133
|
-
// ],
|
|
134
|
-
// 'Extend selection left two characters to select [block-node] from line below with shift + arrow left': [
|
|
135
|
-
// 'chrome',
|
|
136
|
-
// 'safari',
|
|
137
|
-
// 'firefox',
|
|
138
|
-
// ],
|
|
139
|
-
// 'Extend a selection from end of the document to the start when [block-node] is the first node': [
|
|
140
|
-
// 'chrome',
|
|
141
|
-
// 'safari',
|
|
142
|
-
// 'firefox',
|
|
143
|
-
// ],
|
|
144
|
-
// 'Click and drag from the end to start of the document to select [block-node] when [block-node] is the first node': [
|
|
145
|
-
// 'chrome',
|
|
146
|
-
// 'safari',
|
|
147
|
-
// 'firefox',
|
|
148
|
-
// ],
|
|
149
|
-
// 'Extend a selection to the end of the document from start when [block-node] is the last node': [
|
|
150
|
-
// 'chrome',
|
|
151
|
-
// 'safari',
|
|
152
|
-
// 'firefox',
|
|
153
|
-
// ],
|
|
154
|
-
// 'Click and drag from start of the document to select [block-node] when [block-node] is the last node': [
|
|
155
|
-
// 'chrome',
|
|
156
|
-
// 'safari',
|
|
157
|
-
// 'firefox',
|
|
158
|
-
// ],
|
|
159
|
-
// "Extend selection down by one line multiple times to select [block-node]'s in sequence with shift + arrow down": [
|
|
160
|
-
// 'chrome',
|
|
161
|
-
// 'safari',
|
|
162
|
-
// 'firefox',
|
|
163
|
-
// ],
|
|
164
|
-
// },
|
|
165
|
-
// });
|