@atlaskit/editor-tables 2.5.8 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @atlaskit/editor-tables
2
2
 
3
+ ## 2.6.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#83612](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/83612) [`25b32cbfbb7e`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/25b32cbfbb7e) - [ux] Added new clone row/column behaviour to tables drag N drop. When the user holds the alt modifier during the operation the row/column will be duplicated rather then moved.
8
+
3
9
  ## 2.5.8
4
10
 
5
11
  ### Patch Changes
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/cell-bookmark.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/cell-bookmark.d.ts"
12
12
  ]
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/cell-selection.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/cell-selection.d.ts"
12
12
  ]
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.cloneColumn = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _cellSelection = require("../cell-selection");
10
+ var _tableMap = require("../table-map");
11
+ var _analyseTable = require("./analyse-table");
12
+ var _cloneTr = require("./clone-tr");
13
+ var _find = require("./find");
14
+ var _getSelectionRangeInColumn = require("./get-selection-range-in-column");
15
+ var _reorderUtils = require("./reorder-utils");
16
+ var _tableNodeTypes = require("./table-node-types");
17
+ function normalizeDirection(targetDirection, options) {
18
+ var _options$direction;
19
+ var override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
20
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
21
+ }
22
+ var cloneColumn = exports.cloneColumn = function cloneColumn(state, originColumnIndex, targetColumnIndex, targetDirection) {
23
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
24
+ tryToFit: false,
25
+ direction: 0,
26
+ selectAfterClone: false
27
+ };
28
+ return function (tr) {
29
+ var _originalColumnRanges, _targetColumnRanges$i;
30
+ var table = (0, _find.findTable)(tr.selection);
31
+ if (!table) {
32
+ return tr;
33
+ }
34
+
35
+ // normalize the origin index to an array since this supports moving both a single & multiple cols in a single action.
36
+ if (!Array.isArray(originColumnIndex)) {
37
+ originColumnIndex = [originColumnIndex];
38
+ }
39
+ var tableMap = _tableMap.TableMap.get(table.node);
40
+ var originalColumnRanges = (0, _getSelectionRangeInColumn.getSelectionRangeInColumn)(Math.min.apply(Math, (0, _toConsumableArray2.default)(originColumnIndex)), Math.max.apply(Math, (0, _toConsumableArray2.default)(originColumnIndex)))(tr);
41
+ var targetColumnRanges = (0, _getSelectionRangeInColumn.getSelectionRangeInColumn)(targetColumnIndex)(tr);
42
+ var indexesOriginColumn = (_originalColumnRanges = originalColumnRanges === null || originalColumnRanges === void 0 ? void 0 : originalColumnRanges.indexes) !== null && _originalColumnRanges !== void 0 ? _originalColumnRanges : [];
43
+ var indexesTargetColumn = (_targetColumnRanges$i = targetColumnRanges === null || targetColumnRanges === void 0 ? void 0 : targetColumnRanges.indexes) !== null && _targetColumnRanges$i !== void 0 ? _targetColumnRanges$i : [];
44
+ var min = indexesOriginColumn[0];
45
+ var max = indexesOriginColumn[indexesOriginColumn.length - 1];
46
+ if (!options.tryToFit && indexesTargetColumn.length > 1) {
47
+ (0, _reorderUtils.isValidReorder)(originColumnIndex[0], targetColumnIndex, indexesTargetColumn, 'column');
48
+ }
49
+ var types = (0, _tableNodeTypes.tableNodeTypes)(state.schema);
50
+ var direction = normalizeDirection(targetDirection, options);
51
+ var actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'].apply(Math, (0, _toConsumableArray2.default)(indexesTargetColumn));
52
+ var _determineTableHeader = (0, _analyseTable.determineTableHeaderStateFromTableNode)(table.node, tableMap, types),
53
+ rowHeaderEnabled = _determineTableHeader.rowHeaderEnabled,
54
+ columnHeaderEnabled = _determineTableHeader.columnHeaderEnabled;
55
+ var createContentNode = createContentNodeFactory(table);
56
+ var newTr = (0, _cloneTr.cloneTr)(tr);
57
+ var origins = [];
58
+ for (var y = 0; y < tableMap.height; y++) {
59
+ origins.push([]);
60
+ for (var x = min; x <= max; x++) {
61
+ if (tableMap.isCellMergedTopLeft(y, x)) {
62
+ continue;
63
+ }
64
+ var nodePos = tableMap.map[y * tableMap.width + x];
65
+ origins[y].push(createContentNode(nodePos));
66
+ }
67
+ if (columnHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
68
+ // This block is handling the situation where a col is moved in/out of the header position. If the header col option
69
+ // is enabled then;
70
+ // When a col is moved out, the col will be converted to a normal col and the col to the right will become the header.
71
+ // When a col is moved in, the old col header needs to be made normal, and the incoming col needs to be made a header.
72
+ // This section only manages what happens to the other col, not the one being moved.
73
+ var nearHeaderCol = min === 0 ? max + 1 : actualTargetIndex;
74
+ var _nodePos = tableMap.map[y * tableMap.width + nearHeaderCol];
75
+ var _createContentNode = createContentNode(_nodePos),
76
+ pos = _createContentNode.pos,
77
+ node = _createContentNode.node;
78
+ newTr.setNodeMarkup(pos, actualTargetIndex !== 0 || rowHeaderEnabled && y === 0 ? types.header_cell : types.cell, node.attrs);
79
+ }
80
+ }
81
+ origins.forEach(function (row, y) {
82
+ if (!row.length) {
83
+ // If the origin has no cells to be moved then we can skip moving for this row. This can occur when a cell above rowspans
84
+ // into the current row.
85
+ return;
86
+ }
87
+
88
+ // The actual target index needs to be translated per row, this is because row/col spans can affect the amount of
89
+ // cells each row contains.
90
+ var rowTargetPosition = translateTargetPosition(y, actualTargetIndex, tableMap);
91
+ var node = table.node.nodeAt(rowTargetPosition);
92
+ var pos = table.start + rowTargetPosition;
93
+ var insertPos = direction === 'end' ? newTr.mapping.map(pos + node.nodeSize, 1) : newTr.mapping.map(pos, -1);
94
+ return newTr.insert(insertPos, row.map(function (_ref, x) {
95
+ var node = _ref.node;
96
+ return normalizeCellNode(node, rowHeaderEnabled && y === 0, columnHeaderEnabled && actualTargetIndex === 0 && x === 0 && direction === 'start', types);
97
+ }));
98
+ });
99
+ if (options.selectAfterClone) {
100
+ var offset = direction === 'end' ? 1 : 0;
101
+ var selectionRange = (0, _getSelectionRangeInColumn.getSelectionRangeInColumn)(actualTargetIndex + offset, actualTargetIndex + offset + indexesOriginColumn.length - 1)(newTr);
102
+ if (selectionRange) {
103
+ newTr.setSelection(new _cellSelection.CellSelection(selectionRange.$anchor, selectionRange.$head));
104
+ }
105
+ }
106
+ return newTr;
107
+ };
108
+ };
109
+ function normalizeCellNode(cellNode, rowHeaderEnabled, columnHeaderEnabled, types) {
110
+ var newTargetType = rowHeaderEnabled || columnHeaderEnabled ? types.header_cell : types.cell;
111
+ return cellNode.type !== newTargetType ? newTargetType.create(cellNode.attrs, cellNode.content, cellNode.marks) : cellNode;
112
+ }
113
+ function createContentNodeFactory(table) {
114
+ return function (nodePos) {
115
+ var node = table.node.nodeAt(nodePos);
116
+ var pos = nodePos + table.start;
117
+ return {
118
+ pos: pos,
119
+ start: pos + 1,
120
+ node: node,
121
+ depth: table.depth + 2
122
+ };
123
+ };
124
+ }
125
+ function translateTargetPosition(row, startIndex, tableMap) {
126
+ if (tableMap.isCellMergedTopLeft(row, startIndex)) {
127
+ // find the closet unmerged position to the left of the target. We scan left first because merged cells will actually
128
+ // reduce the amount of cells in a row.
129
+ for (var x = startIndex - 1; x >= 0; x--) {
130
+ if (!tableMap.isCellMergedTopLeft(row, x)) {
131
+ return tableMap.map[row * tableMap.width + x];
132
+ }
133
+ }
134
+
135
+ // If no index found then we need to look to the right, this can occur when the first cell in the row is merged.
136
+ for (var _x = startIndex + 1; _x < tableMap.width; _x++) {
137
+ if (!tableMap.isCellMergedTopLeft(row, _x)) {
138
+ return tableMap.map[row * tableMap.width + _x];
139
+ }
140
+ }
141
+ }
142
+ return tableMap.map[row * tableMap.width + startIndex];
143
+ }
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.cloneRow = void 0;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _cellSelection = require("../cell-selection");
11
+ var _tableMap = require("../table-map");
12
+ var _analyseTable = require("./analyse-table");
13
+ var _cloneTr = require("./clone-tr");
14
+ var _find = require("./find");
15
+ var _getSelectionRangeInRow = require("./get-selection-range-in-row");
16
+ var _reorderUtils = require("./reorder-utils");
17
+ var _tableNodeTypes = require("./table-node-types");
18
+ function normalizeDirection(targetDirection, options) {
19
+ var _options$direction;
20
+ var override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
21
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
22
+ }
23
+ var cloneRow = exports.cloneRow = function cloneRow(state, originRowIndex, targetRowIndex, targetDirection) {
24
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
25
+ tryToFit: false,
26
+ direction: 0,
27
+ selectAfterClone: false
28
+ };
29
+ return function (tr) {
30
+ var table = (0, _find.findTable)(tr.selection);
31
+ if (!table) {
32
+ return tr;
33
+ }
34
+
35
+ // normalize the origin index to an array since move row support moving both a single & multiple rows in a single action.
36
+ if (!Array.isArray(originRowIndex)) {
37
+ originRowIndex = [originRowIndex];
38
+ }
39
+ var tableMap = _tableMap.TableMap.get(table.node);
40
+ var _originRowIndex$reduc = originRowIndex.reduce(function (_ref, cur) {
41
+ var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
42
+ min = _ref2[0],
43
+ max = _ref2[1];
44
+ return [Math.min(min, cur), Math.max(max, cur)];
45
+ }, [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER]),
46
+ _originRowIndex$reduc2 = (0, _slicedToArray2.default)(_originRowIndex$reduc, 2),
47
+ originMin = _originRowIndex$reduc2[0],
48
+ originMax = _originRowIndex$reduc2[1];
49
+ var originalRowRanges = (0, _getSelectionRangeInRow.getSelectionRangeInRow)(originMin, originMax)(tr);
50
+ var targetRowRanges = (0, _getSelectionRangeInRow.getSelectionRangeInRow)(targetRowIndex)(tr);
51
+ var indexesOriginRow = (originalRowRanges === null || originalRowRanges === void 0 ? void 0 : originalRowRanges.indexes) || [];
52
+ var indexesTargetRow = (targetRowRanges === null || targetRowRanges === void 0 ? void 0 : targetRowRanges.indexes) || [];
53
+ if (originMin < 0 || originMin === Number.MAX_SAFE_INTEGER || originMax >= tableMap.height || originMax === Number.MIN_SAFE_INTEGER) {
54
+ return tr;
55
+ }
56
+ if (!options.tryToFit && indexesTargetRow.length > 1) {
57
+ (0, _reorderUtils.isValidReorder)(originMin, targetRowIndex, indexesTargetRow, 'row');
58
+ }
59
+ var types = (0, _tableNodeTypes.tableNodeTypes)(state.schema);
60
+ var direction = normalizeDirection(targetDirection, options);
61
+ var actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'].apply(Math, (0, _toConsumableArray2.default)(indexesTargetRow));
62
+ var originPositions = indexesOriginRow.map(function (index) {
63
+ return tableMap.positionAt(index, 0, table.node) + table.pos;
64
+ });
65
+ var originNodes = originPositions.reduce(function (acc, pos) {
66
+ var node = tr.doc.nodeAt(tr.mapping.map(pos));
67
+ if (node) {
68
+ return [].concat((0, _toConsumableArray2.default)(acc), [{
69
+ pos: pos,
70
+ node: node
71
+ }]);
72
+ }
73
+ return acc;
74
+ }, []);
75
+ var targetPos = tableMap.positionAt(actualTargetIndex, 0, table.node) + table.pos;
76
+ var targetNode = tr.doc.nodeAt(tr.mapping.map(targetPos));
77
+ if (originNodes !== null && originNodes !== void 0 && originNodes.length && targetNode) {
78
+ var newTr = (0, _cloneTr.cloneTr)(tr);
79
+ var _determineTableHeader = (0, _analyseTable.determineTableHeaderStateFromTableNode)(table.node, tableMap, types),
80
+ rowHeaderEnabled = _determineTableHeader.rowHeaderEnabled,
81
+ columnHeaderEnabled = _determineTableHeader.columnHeaderEnabled;
82
+ if (rowHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
83
+ // This block is handling the situation where a row is moved in/out of the header position. If the header row option
84
+ // is enabled then;
85
+ // When a row is moved out, the row will be converted to a normal row and the row below it will become the header.
86
+ // When a row is moved in, the old row header needs to be made normal, and the incoming row needs to be made a header.
87
+ // This section only manages what happens to the other row, no the one being moved.
88
+ var nearHeaderPos = tableMap.positionAt(originMin === 0 ? originMax + 1 : actualTargetIndex, 0, table.node) + table.pos;
89
+ var nearHeaderNode = newTr.doc.nodeAt(newTr.mapping.map(nearHeaderPos));
90
+ if (nearHeaderNode) {
91
+ nearHeaderNode.forEach(function (node, offset, index) {
92
+ var start = newTr.mapping.map(nearHeaderPos + 1 + offset);
93
+ newTr.setNodeMarkup(start, actualTargetIndex !== 0 || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell, node.attrs);
94
+ });
95
+ }
96
+ }
97
+ var insertPos = direction === 'end' ? newTr.mapping.map(targetPos + targetNode.nodeSize, 1) : newTr.mapping.map(targetPos, -1);
98
+ newTr.insert(insertPos, originNodes.map(function (_ref3, index) {
99
+ var node = _ref3.node;
100
+ return normalizeRowNode(node, rowHeaderEnabled && actualTargetIndex === 0 && index === 0 && direction === 'start', columnHeaderEnabled, types);
101
+ }));
102
+ if (options.selectAfterClone) {
103
+ var offset = direction === 'end' ? 1 : 0;
104
+ var selectionRange = (0, _getSelectionRangeInRow.getSelectionRangeInRow)(actualTargetIndex + offset, actualTargetIndex + offset + originNodes.length - 1)(newTr);
105
+ if (selectionRange) {
106
+ newTr.setSelection(new _cellSelection.CellSelection(selectionRange.$anchor, selectionRange.$head));
107
+ }
108
+ }
109
+ return newTr;
110
+ }
111
+ return tr;
112
+ };
113
+ };
114
+
115
+ /**
116
+ * This ensures the row node cell type correctly reflect what they should be.
117
+ * @returns A copy of the rowNode
118
+ */
119
+ function normalizeRowNode(rowNode, rowHeaderEnabled, columnHeaderEnabled, types) {
120
+ var content = [];
121
+ rowNode.forEach(function (node, offset, index) {
122
+ var newTargetType = rowHeaderEnabled || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell;
123
+ content.push(node.type !== newTargetType ? newTargetType.create(node.attrs, node.content, node.marks) : node);
124
+ });
125
+ return rowNode.type.create(rowNode.attrs, content, rowNode.marks);
126
+ }
package/dist/cjs/utils.js CHANGED
@@ -51,6 +51,18 @@ Object.defineProperty(exports, "cellWrapping", {
51
51
  return _splitCellWithType.cellWrapping;
52
52
  }
53
53
  });
54
+ Object.defineProperty(exports, "cloneColumn", {
55
+ enumerable: true,
56
+ get: function get() {
57
+ return _cloneColumn.cloneColumn;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "cloneRow", {
61
+ enumerable: true,
62
+ get: function get() {
63
+ return _cloneRow.cloneRow;
64
+ }
65
+ });
54
66
  Object.defineProperty(exports, "cloneTr", {
55
67
  enumerable: true,
56
68
  get: function get() {
@@ -430,6 +442,8 @@ var _isSelected = require("./utils/is-selected");
430
442
  var _isSelectionType = require("./utils/is-selection-type");
431
443
  var _moveColumn = require("./utils/move-column");
432
444
  var _moveRow = require("./utils/move-row");
445
+ var _cloneColumn = require("./utils/clone-column");
446
+ var _cloneRow = require("./utils/clone-row");
433
447
  var _normalizeSelection = require("./utils/normalize-selection");
434
448
  var _removeColumn = require("./utils/remove-column");
435
449
  var _removeRow = require("./utils/remove-row");
@@ -0,0 +1,133 @@
1
+ import { CellSelection } from '../cell-selection';
2
+ import { TableMap } from '../table-map';
3
+ import { determineTableHeaderStateFromTableNode } from './analyse-table';
4
+ import { cloneTr } from './clone-tr';
5
+ import { findTable } from './find';
6
+ import { getSelectionRangeInColumn } from './get-selection-range-in-column';
7
+ import { isValidReorder } from './reorder-utils';
8
+ import { tableNodeTypes } from './table-node-types';
9
+ function normalizeDirection(targetDirection, options) {
10
+ var _options$direction;
11
+ const override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
12
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
13
+ }
14
+ export const cloneColumn = (state, originColumnIndex, targetColumnIndex, targetDirection, options = {
15
+ tryToFit: false,
16
+ direction: 0,
17
+ selectAfterClone: false
18
+ }) => tr => {
19
+ var _originalColumnRanges, _targetColumnRanges$i;
20
+ const table = findTable(tr.selection);
21
+ if (!table) {
22
+ return tr;
23
+ }
24
+
25
+ // normalize the origin index to an array since this supports moving both a single & multiple cols in a single action.
26
+ if (!Array.isArray(originColumnIndex)) {
27
+ originColumnIndex = [originColumnIndex];
28
+ }
29
+ const tableMap = TableMap.get(table.node);
30
+ const originalColumnRanges = getSelectionRangeInColumn(Math.min(...originColumnIndex), Math.max(...originColumnIndex))(tr);
31
+ const targetColumnRanges = getSelectionRangeInColumn(targetColumnIndex)(tr);
32
+ const indexesOriginColumn = (_originalColumnRanges = originalColumnRanges === null || originalColumnRanges === void 0 ? void 0 : originalColumnRanges.indexes) !== null && _originalColumnRanges !== void 0 ? _originalColumnRanges : [];
33
+ const indexesTargetColumn = (_targetColumnRanges$i = targetColumnRanges === null || targetColumnRanges === void 0 ? void 0 : targetColumnRanges.indexes) !== null && _targetColumnRanges$i !== void 0 ? _targetColumnRanges$i : [];
34
+ const min = indexesOriginColumn[0];
35
+ const max = indexesOriginColumn[indexesOriginColumn.length - 1];
36
+ if (!options.tryToFit && indexesTargetColumn.length > 1) {
37
+ isValidReorder(originColumnIndex[0], targetColumnIndex, indexesTargetColumn, 'column');
38
+ }
39
+ const types = tableNodeTypes(state.schema);
40
+ const direction = normalizeDirection(targetDirection, options);
41
+ const actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'](...indexesTargetColumn);
42
+ const {
43
+ rowHeaderEnabled,
44
+ columnHeaderEnabled
45
+ } = determineTableHeaderStateFromTableNode(table.node, tableMap, types);
46
+ const createContentNode = createContentNodeFactory(table);
47
+ const newTr = cloneTr(tr);
48
+ const origins = [];
49
+ for (let y = 0; y < tableMap.height; y++) {
50
+ origins.push([]);
51
+ for (let x = min; x <= max; x++) {
52
+ if (tableMap.isCellMergedTopLeft(y, x)) {
53
+ continue;
54
+ }
55
+ const nodePos = tableMap.map[y * tableMap.width + x];
56
+ origins[y].push(createContentNode(nodePos));
57
+ }
58
+ if (columnHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
59
+ // This block is handling the situation where a col is moved in/out of the header position. If the header col option
60
+ // is enabled then;
61
+ // When a col is moved out, the col will be converted to a normal col and the col to the right will become the header.
62
+ // When a col is moved in, the old col header needs to be made normal, and the incoming col needs to be made a header.
63
+ // This section only manages what happens to the other col, not the one being moved.
64
+ const nearHeaderCol = min === 0 ? max + 1 : actualTargetIndex;
65
+ const nodePos = tableMap.map[y * tableMap.width + nearHeaderCol];
66
+ const {
67
+ pos,
68
+ node
69
+ } = createContentNode(nodePos);
70
+ newTr.setNodeMarkup(pos, actualTargetIndex !== 0 || rowHeaderEnabled && y === 0 ? types.header_cell : types.cell, node.attrs);
71
+ }
72
+ }
73
+ origins.forEach((row, y) => {
74
+ if (!row.length) {
75
+ // If the origin has no cells to be moved then we can skip moving for this row. This can occur when a cell above rowspans
76
+ // into the current row.
77
+ return;
78
+ }
79
+
80
+ // The actual target index needs to be translated per row, this is because row/col spans can affect the amount of
81
+ // cells each row contains.
82
+ const rowTargetPosition = translateTargetPosition(y, actualTargetIndex, tableMap);
83
+ const node = table.node.nodeAt(rowTargetPosition);
84
+ const pos = table.start + rowTargetPosition;
85
+ const insertPos = direction === 'end' ? newTr.mapping.map(pos + node.nodeSize, 1) : newTr.mapping.map(pos, -1);
86
+ return newTr.insert(insertPos, row.map(({
87
+ node
88
+ }, x) => normalizeCellNode(node, rowHeaderEnabled && y === 0, columnHeaderEnabled && actualTargetIndex === 0 && x === 0 && direction === 'start', types)));
89
+ });
90
+ if (options.selectAfterClone) {
91
+ const offset = direction === 'end' ? 1 : 0;
92
+ const selectionRange = getSelectionRangeInColumn(actualTargetIndex + offset, actualTargetIndex + offset + indexesOriginColumn.length - 1)(newTr);
93
+ if (selectionRange) {
94
+ newTr.setSelection(new CellSelection(selectionRange.$anchor, selectionRange.$head));
95
+ }
96
+ }
97
+ return newTr;
98
+ };
99
+ function normalizeCellNode(cellNode, rowHeaderEnabled, columnHeaderEnabled, types) {
100
+ const newTargetType = rowHeaderEnabled || columnHeaderEnabled ? types.header_cell : types.cell;
101
+ return cellNode.type !== newTargetType ? newTargetType.create(cellNode.attrs, cellNode.content, cellNode.marks) : cellNode;
102
+ }
103
+ function createContentNodeFactory(table) {
104
+ return nodePos => {
105
+ const node = table.node.nodeAt(nodePos);
106
+ const pos = nodePos + table.start;
107
+ return {
108
+ pos,
109
+ start: pos + 1,
110
+ node,
111
+ depth: table.depth + 2
112
+ };
113
+ };
114
+ }
115
+ function translateTargetPosition(row, startIndex, tableMap) {
116
+ if (tableMap.isCellMergedTopLeft(row, startIndex)) {
117
+ // find the closet unmerged position to the left of the target. We scan left first because merged cells will actually
118
+ // reduce the amount of cells in a row.
119
+ for (let x = startIndex - 1; x >= 0; x--) {
120
+ if (!tableMap.isCellMergedTopLeft(row, x)) {
121
+ return tableMap.map[row * tableMap.width + x];
122
+ }
123
+ }
124
+
125
+ // If no index found then we need to look to the right, this can occur when the first cell in the row is merged.
126
+ for (let x = startIndex + 1; x < tableMap.width; x++) {
127
+ if (!tableMap.isCellMergedTopLeft(row, x)) {
128
+ return tableMap.map[row * tableMap.width + x];
129
+ }
130
+ }
131
+ }
132
+ return tableMap.map[row * tableMap.width + startIndex];
133
+ }
@@ -0,0 +1,104 @@
1
+ import { CellSelection } from '../cell-selection';
2
+ import { TableMap } from '../table-map';
3
+ import { determineTableHeaderStateFromTableNode } from './analyse-table';
4
+ import { cloneTr } from './clone-tr';
5
+ import { findTable } from './find';
6
+ import { getSelectionRangeInRow } from './get-selection-range-in-row';
7
+ import { isValidReorder } from './reorder-utils';
8
+ import { tableNodeTypes } from './table-node-types';
9
+ function normalizeDirection(targetDirection, options) {
10
+ var _options$direction;
11
+ const override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
12
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
13
+ }
14
+ export const cloneRow = (state, originRowIndex, targetRowIndex, targetDirection, options = {
15
+ tryToFit: false,
16
+ direction: 0,
17
+ selectAfterClone: false
18
+ }) => tr => {
19
+ const table = findTable(tr.selection);
20
+ if (!table) {
21
+ return tr;
22
+ }
23
+
24
+ // normalize the origin index to an array since move row support moving both a single & multiple rows in a single action.
25
+ if (!Array.isArray(originRowIndex)) {
26
+ originRowIndex = [originRowIndex];
27
+ }
28
+ const tableMap = TableMap.get(table.node);
29
+ const [originMin, originMax] = originRowIndex.reduce(([min, max], cur) => [Math.min(min, cur), Math.max(max, cur)], [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER]);
30
+ const originalRowRanges = getSelectionRangeInRow(originMin, originMax)(tr);
31
+ const targetRowRanges = getSelectionRangeInRow(targetRowIndex)(tr);
32
+ const indexesOriginRow = (originalRowRanges === null || originalRowRanges === void 0 ? void 0 : originalRowRanges.indexes) || [];
33
+ const indexesTargetRow = (targetRowRanges === null || targetRowRanges === void 0 ? void 0 : targetRowRanges.indexes) || [];
34
+ if (originMin < 0 || originMin === Number.MAX_SAFE_INTEGER || originMax >= tableMap.height || originMax === Number.MIN_SAFE_INTEGER) {
35
+ return tr;
36
+ }
37
+ if (!options.tryToFit && indexesTargetRow.length > 1) {
38
+ isValidReorder(originMin, targetRowIndex, indexesTargetRow, 'row');
39
+ }
40
+ const types = tableNodeTypes(state.schema);
41
+ const direction = normalizeDirection(targetDirection, options);
42
+ const actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'](...indexesTargetRow);
43
+ const originPositions = indexesOriginRow.map(index => tableMap.positionAt(index, 0, table.node) + table.pos);
44
+ const originNodes = originPositions.reduce((acc, pos) => {
45
+ const node = tr.doc.nodeAt(tr.mapping.map(pos));
46
+ if (node) {
47
+ return [...acc, {
48
+ pos,
49
+ node
50
+ }];
51
+ }
52
+ return acc;
53
+ }, []);
54
+ const targetPos = tableMap.positionAt(actualTargetIndex, 0, table.node) + table.pos;
55
+ const targetNode = tr.doc.nodeAt(tr.mapping.map(targetPos));
56
+ if (originNodes !== null && originNodes !== void 0 && originNodes.length && targetNode) {
57
+ const newTr = cloneTr(tr);
58
+ const {
59
+ rowHeaderEnabled,
60
+ columnHeaderEnabled
61
+ } = determineTableHeaderStateFromTableNode(table.node, tableMap, types);
62
+ if (rowHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
63
+ // This block is handling the situation where a row is moved in/out of the header position. If the header row option
64
+ // is enabled then;
65
+ // When a row is moved out, the row will be converted to a normal row and the row below it will become the header.
66
+ // When a row is moved in, the old row header needs to be made normal, and the incoming row needs to be made a header.
67
+ // This section only manages what happens to the other row, no the one being moved.
68
+ const nearHeaderPos = tableMap.positionAt(originMin === 0 ? originMax + 1 : actualTargetIndex, 0, table.node) + table.pos;
69
+ const nearHeaderNode = newTr.doc.nodeAt(newTr.mapping.map(nearHeaderPos));
70
+ if (nearHeaderNode) {
71
+ nearHeaderNode.forEach((node, offset, index) => {
72
+ const start = newTr.mapping.map(nearHeaderPos + 1 + offset);
73
+ newTr.setNodeMarkup(start, actualTargetIndex !== 0 || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell, node.attrs);
74
+ });
75
+ }
76
+ }
77
+ const insertPos = direction === 'end' ? newTr.mapping.map(targetPos + targetNode.nodeSize, 1) : newTr.mapping.map(targetPos, -1);
78
+ newTr.insert(insertPos, originNodes.map(({
79
+ node
80
+ }, index) => normalizeRowNode(node, rowHeaderEnabled && actualTargetIndex === 0 && index === 0 && direction === 'start', columnHeaderEnabled, types)));
81
+ if (options.selectAfterClone) {
82
+ const offset = direction === 'end' ? 1 : 0;
83
+ const selectionRange = getSelectionRangeInRow(actualTargetIndex + offset, actualTargetIndex + offset + originNodes.length - 1)(newTr);
84
+ if (selectionRange) {
85
+ newTr.setSelection(new CellSelection(selectionRange.$anchor, selectionRange.$head));
86
+ }
87
+ }
88
+ return newTr;
89
+ }
90
+ return tr;
91
+ };
92
+
93
+ /**
94
+ * This ensures the row node cell type correctly reflect what they should be.
95
+ * @returns A copy of the rowNode
96
+ */
97
+ function normalizeRowNode(rowNode, rowHeaderEnabled, columnHeaderEnabled, types) {
98
+ let content = [];
99
+ rowNode.forEach((node, offset, index) => {
100
+ const newTargetType = rowHeaderEnabled || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell;
101
+ content.push(node.type !== newTargetType ? newTargetType.create(node.attrs, node.content, node.marks) : node);
102
+ });
103
+ return rowNode.type.create(rowNode.attrs, content, rowNode.marks);
104
+ }
@@ -23,6 +23,8 @@ export { isRectSelected, isColumnSelected, isRowSelected, isTableSelected } from
23
23
  export { isSelectionType } from './utils/is-selection-type';
24
24
  export { moveColumn } from './utils/move-column';
25
25
  export { moveRow } from './utils/move-row';
26
+ export { cloneColumn } from './utils/clone-column';
27
+ export { cloneRow } from './utils/clone-row';
26
28
  export { normalizeSelection } from './utils/normalize-selection';
27
29
  export { removeColumnAt, removeSelectedColumns, removeColumnClosestToPos } from './utils/remove-column';
28
30
  export { removeRowAt, removeSelectedRows, removeRowClosestToPos } from './utils/remove-row';
@@ -0,0 +1,136 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import { CellSelection } from '../cell-selection';
3
+ import { TableMap } from '../table-map';
4
+ import { determineTableHeaderStateFromTableNode } from './analyse-table';
5
+ import { cloneTr } from './clone-tr';
6
+ import { findTable } from './find';
7
+ import { getSelectionRangeInColumn } from './get-selection-range-in-column';
8
+ import { isValidReorder } from './reorder-utils';
9
+ import { tableNodeTypes } from './table-node-types';
10
+ function normalizeDirection(targetDirection, options) {
11
+ var _options$direction;
12
+ var override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
13
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
14
+ }
15
+ export var cloneColumn = function cloneColumn(state, originColumnIndex, targetColumnIndex, targetDirection) {
16
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
17
+ tryToFit: false,
18
+ direction: 0,
19
+ selectAfterClone: false
20
+ };
21
+ return function (tr) {
22
+ var _originalColumnRanges, _targetColumnRanges$i;
23
+ var table = findTable(tr.selection);
24
+ if (!table) {
25
+ return tr;
26
+ }
27
+
28
+ // normalize the origin index to an array since this supports moving both a single & multiple cols in a single action.
29
+ if (!Array.isArray(originColumnIndex)) {
30
+ originColumnIndex = [originColumnIndex];
31
+ }
32
+ var tableMap = TableMap.get(table.node);
33
+ var originalColumnRanges = getSelectionRangeInColumn(Math.min.apply(Math, _toConsumableArray(originColumnIndex)), Math.max.apply(Math, _toConsumableArray(originColumnIndex)))(tr);
34
+ var targetColumnRanges = getSelectionRangeInColumn(targetColumnIndex)(tr);
35
+ var indexesOriginColumn = (_originalColumnRanges = originalColumnRanges === null || originalColumnRanges === void 0 ? void 0 : originalColumnRanges.indexes) !== null && _originalColumnRanges !== void 0 ? _originalColumnRanges : [];
36
+ var indexesTargetColumn = (_targetColumnRanges$i = targetColumnRanges === null || targetColumnRanges === void 0 ? void 0 : targetColumnRanges.indexes) !== null && _targetColumnRanges$i !== void 0 ? _targetColumnRanges$i : [];
37
+ var min = indexesOriginColumn[0];
38
+ var max = indexesOriginColumn[indexesOriginColumn.length - 1];
39
+ if (!options.tryToFit && indexesTargetColumn.length > 1) {
40
+ isValidReorder(originColumnIndex[0], targetColumnIndex, indexesTargetColumn, 'column');
41
+ }
42
+ var types = tableNodeTypes(state.schema);
43
+ var direction = normalizeDirection(targetDirection, options);
44
+ var actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'].apply(Math, _toConsumableArray(indexesTargetColumn));
45
+ var _determineTableHeader = determineTableHeaderStateFromTableNode(table.node, tableMap, types),
46
+ rowHeaderEnabled = _determineTableHeader.rowHeaderEnabled,
47
+ columnHeaderEnabled = _determineTableHeader.columnHeaderEnabled;
48
+ var createContentNode = createContentNodeFactory(table);
49
+ var newTr = cloneTr(tr);
50
+ var origins = [];
51
+ for (var y = 0; y < tableMap.height; y++) {
52
+ origins.push([]);
53
+ for (var x = min; x <= max; x++) {
54
+ if (tableMap.isCellMergedTopLeft(y, x)) {
55
+ continue;
56
+ }
57
+ var nodePos = tableMap.map[y * tableMap.width + x];
58
+ origins[y].push(createContentNode(nodePos));
59
+ }
60
+ if (columnHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
61
+ // This block is handling the situation where a col is moved in/out of the header position. If the header col option
62
+ // is enabled then;
63
+ // When a col is moved out, the col will be converted to a normal col and the col to the right will become the header.
64
+ // When a col is moved in, the old col header needs to be made normal, and the incoming col needs to be made a header.
65
+ // This section only manages what happens to the other col, not the one being moved.
66
+ var nearHeaderCol = min === 0 ? max + 1 : actualTargetIndex;
67
+ var _nodePos = tableMap.map[y * tableMap.width + nearHeaderCol];
68
+ var _createContentNode = createContentNode(_nodePos),
69
+ pos = _createContentNode.pos,
70
+ node = _createContentNode.node;
71
+ newTr.setNodeMarkup(pos, actualTargetIndex !== 0 || rowHeaderEnabled && y === 0 ? types.header_cell : types.cell, node.attrs);
72
+ }
73
+ }
74
+ origins.forEach(function (row, y) {
75
+ if (!row.length) {
76
+ // If the origin has no cells to be moved then we can skip moving for this row. This can occur when a cell above rowspans
77
+ // into the current row.
78
+ return;
79
+ }
80
+
81
+ // The actual target index needs to be translated per row, this is because row/col spans can affect the amount of
82
+ // cells each row contains.
83
+ var rowTargetPosition = translateTargetPosition(y, actualTargetIndex, tableMap);
84
+ var node = table.node.nodeAt(rowTargetPosition);
85
+ var pos = table.start + rowTargetPosition;
86
+ var insertPos = direction === 'end' ? newTr.mapping.map(pos + node.nodeSize, 1) : newTr.mapping.map(pos, -1);
87
+ return newTr.insert(insertPos, row.map(function (_ref, x) {
88
+ var node = _ref.node;
89
+ return normalizeCellNode(node, rowHeaderEnabled && y === 0, columnHeaderEnabled && actualTargetIndex === 0 && x === 0 && direction === 'start', types);
90
+ }));
91
+ });
92
+ if (options.selectAfterClone) {
93
+ var offset = direction === 'end' ? 1 : 0;
94
+ var selectionRange = getSelectionRangeInColumn(actualTargetIndex + offset, actualTargetIndex + offset + indexesOriginColumn.length - 1)(newTr);
95
+ if (selectionRange) {
96
+ newTr.setSelection(new CellSelection(selectionRange.$anchor, selectionRange.$head));
97
+ }
98
+ }
99
+ return newTr;
100
+ };
101
+ };
102
+ function normalizeCellNode(cellNode, rowHeaderEnabled, columnHeaderEnabled, types) {
103
+ var newTargetType = rowHeaderEnabled || columnHeaderEnabled ? types.header_cell : types.cell;
104
+ return cellNode.type !== newTargetType ? newTargetType.create(cellNode.attrs, cellNode.content, cellNode.marks) : cellNode;
105
+ }
106
+ function createContentNodeFactory(table) {
107
+ return function (nodePos) {
108
+ var node = table.node.nodeAt(nodePos);
109
+ var pos = nodePos + table.start;
110
+ return {
111
+ pos: pos,
112
+ start: pos + 1,
113
+ node: node,
114
+ depth: table.depth + 2
115
+ };
116
+ };
117
+ }
118
+ function translateTargetPosition(row, startIndex, tableMap) {
119
+ if (tableMap.isCellMergedTopLeft(row, startIndex)) {
120
+ // find the closet unmerged position to the left of the target. We scan left first because merged cells will actually
121
+ // reduce the amount of cells in a row.
122
+ for (var x = startIndex - 1; x >= 0; x--) {
123
+ if (!tableMap.isCellMergedTopLeft(row, x)) {
124
+ return tableMap.map[row * tableMap.width + x];
125
+ }
126
+ }
127
+
128
+ // If no index found then we need to look to the right, this can occur when the first cell in the row is merged.
129
+ for (var _x = startIndex + 1; _x < tableMap.width; _x++) {
130
+ if (!tableMap.isCellMergedTopLeft(row, _x)) {
131
+ return tableMap.map[row * tableMap.width + _x];
132
+ }
133
+ }
134
+ }
135
+ return tableMap.map[row * tableMap.width + startIndex];
136
+ }
@@ -0,0 +1,119 @@
1
+ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
2
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
+ import { CellSelection } from '../cell-selection';
4
+ import { TableMap } from '../table-map';
5
+ import { determineTableHeaderStateFromTableNode } from './analyse-table';
6
+ import { cloneTr } from './clone-tr';
7
+ import { findTable } from './find';
8
+ import { getSelectionRangeInRow } from './get-selection-range-in-row';
9
+ import { isValidReorder } from './reorder-utils';
10
+ import { tableNodeTypes } from './table-node-types';
11
+ function normalizeDirection(targetDirection, options) {
12
+ var _options$direction;
13
+ var override = ((_options$direction = options === null || options === void 0 ? void 0 : options.direction) !== null && _options$direction !== void 0 ? _options$direction : 0) < 0 ? 'start' : 'end';
14
+ return options !== null && options !== void 0 && options.tryToFit && !!(options !== null && options !== void 0 && options.direction) ? override : targetDirection;
15
+ }
16
+ export var cloneRow = function cloneRow(state, originRowIndex, targetRowIndex, targetDirection) {
17
+ var options = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : {
18
+ tryToFit: false,
19
+ direction: 0,
20
+ selectAfterClone: false
21
+ };
22
+ return function (tr) {
23
+ var table = findTable(tr.selection);
24
+ if (!table) {
25
+ return tr;
26
+ }
27
+
28
+ // normalize the origin index to an array since move row support moving both a single & multiple rows in a single action.
29
+ if (!Array.isArray(originRowIndex)) {
30
+ originRowIndex = [originRowIndex];
31
+ }
32
+ var tableMap = TableMap.get(table.node);
33
+ var _originRowIndex$reduc = originRowIndex.reduce(function (_ref, cur) {
34
+ var _ref2 = _slicedToArray(_ref, 2),
35
+ min = _ref2[0],
36
+ max = _ref2[1];
37
+ return [Math.min(min, cur), Math.max(max, cur)];
38
+ }, [Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER]),
39
+ _originRowIndex$reduc2 = _slicedToArray(_originRowIndex$reduc, 2),
40
+ originMin = _originRowIndex$reduc2[0],
41
+ originMax = _originRowIndex$reduc2[1];
42
+ var originalRowRanges = getSelectionRangeInRow(originMin, originMax)(tr);
43
+ var targetRowRanges = getSelectionRangeInRow(targetRowIndex)(tr);
44
+ var indexesOriginRow = (originalRowRanges === null || originalRowRanges === void 0 ? void 0 : originalRowRanges.indexes) || [];
45
+ var indexesTargetRow = (targetRowRanges === null || targetRowRanges === void 0 ? void 0 : targetRowRanges.indexes) || [];
46
+ if (originMin < 0 || originMin === Number.MAX_SAFE_INTEGER || originMax >= tableMap.height || originMax === Number.MIN_SAFE_INTEGER) {
47
+ return tr;
48
+ }
49
+ if (!options.tryToFit && indexesTargetRow.length > 1) {
50
+ isValidReorder(originMin, targetRowIndex, indexesTargetRow, 'row');
51
+ }
52
+ var types = tableNodeTypes(state.schema);
53
+ var direction = normalizeDirection(targetDirection, options);
54
+ var actualTargetIndex = Math[direction === 'start' ? 'min' : 'max'].apply(Math, _toConsumableArray(indexesTargetRow));
55
+ var originPositions = indexesOriginRow.map(function (index) {
56
+ return tableMap.positionAt(index, 0, table.node) + table.pos;
57
+ });
58
+ var originNodes = originPositions.reduce(function (acc, pos) {
59
+ var node = tr.doc.nodeAt(tr.mapping.map(pos));
60
+ if (node) {
61
+ return [].concat(_toConsumableArray(acc), [{
62
+ pos: pos,
63
+ node: node
64
+ }]);
65
+ }
66
+ return acc;
67
+ }, []);
68
+ var targetPos = tableMap.positionAt(actualTargetIndex, 0, table.node) + table.pos;
69
+ var targetNode = tr.doc.nodeAt(tr.mapping.map(targetPos));
70
+ if (originNodes !== null && originNodes !== void 0 && originNodes.length && targetNode) {
71
+ var newTr = cloneTr(tr);
72
+ var _determineTableHeader = determineTableHeaderStateFromTableNode(table.node, tableMap, types),
73
+ rowHeaderEnabled = _determineTableHeader.rowHeaderEnabled,
74
+ columnHeaderEnabled = _determineTableHeader.columnHeaderEnabled;
75
+ if (rowHeaderEnabled && actualTargetIndex === 0 && direction === 'start') {
76
+ // This block is handling the situation where a row is moved in/out of the header position. If the header row option
77
+ // is enabled then;
78
+ // When a row is moved out, the row will be converted to a normal row and the row below it will become the header.
79
+ // When a row is moved in, the old row header needs to be made normal, and the incoming row needs to be made a header.
80
+ // This section only manages what happens to the other row, no the one being moved.
81
+ var nearHeaderPos = tableMap.positionAt(originMin === 0 ? originMax + 1 : actualTargetIndex, 0, table.node) + table.pos;
82
+ var nearHeaderNode = newTr.doc.nodeAt(newTr.mapping.map(nearHeaderPos));
83
+ if (nearHeaderNode) {
84
+ nearHeaderNode.forEach(function (node, offset, index) {
85
+ var start = newTr.mapping.map(nearHeaderPos + 1 + offset);
86
+ newTr.setNodeMarkup(start, actualTargetIndex !== 0 || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell, node.attrs);
87
+ });
88
+ }
89
+ }
90
+ var insertPos = direction === 'end' ? newTr.mapping.map(targetPos + targetNode.nodeSize, 1) : newTr.mapping.map(targetPos, -1);
91
+ newTr.insert(insertPos, originNodes.map(function (_ref3, index) {
92
+ var node = _ref3.node;
93
+ return normalizeRowNode(node, rowHeaderEnabled && actualTargetIndex === 0 && index === 0 && direction === 'start', columnHeaderEnabled, types);
94
+ }));
95
+ if (options.selectAfterClone) {
96
+ var offset = direction === 'end' ? 1 : 0;
97
+ var selectionRange = getSelectionRangeInRow(actualTargetIndex + offset, actualTargetIndex + offset + originNodes.length - 1)(newTr);
98
+ if (selectionRange) {
99
+ newTr.setSelection(new CellSelection(selectionRange.$anchor, selectionRange.$head));
100
+ }
101
+ }
102
+ return newTr;
103
+ }
104
+ return tr;
105
+ };
106
+ };
107
+
108
+ /**
109
+ * This ensures the row node cell type correctly reflect what they should be.
110
+ * @returns A copy of the rowNode
111
+ */
112
+ function normalizeRowNode(rowNode, rowHeaderEnabled, columnHeaderEnabled, types) {
113
+ var content = [];
114
+ rowNode.forEach(function (node, offset, index) {
115
+ var newTargetType = rowHeaderEnabled || columnHeaderEnabled && index === 0 ? types.header_cell : types.cell;
116
+ content.push(node.type !== newTargetType ? newTargetType.create(node.attrs, node.content, node.marks) : node);
117
+ });
118
+ return rowNode.type.create(rowNode.attrs, content, rowNode.marks);
119
+ }
package/dist/esm/utils.js CHANGED
@@ -23,6 +23,8 @@ export { isRectSelected, isColumnSelected, isRowSelected, isTableSelected } from
23
23
  export { isSelectionType } from './utils/is-selection-type';
24
24
  export { moveColumn } from './utils/move-column';
25
25
  export { moveRow } from './utils/move-row';
26
+ export { cloneColumn } from './utils/clone-column';
27
+ export { cloneRow } from './utils/clone-row';
26
28
  export { normalizeSelection } from './utils/normalize-selection';
27
29
  export { removeColumnAt, removeSelectedColumns, removeColumnClosestToPos } from './utils/remove-column';
28
30
  export { removeRowAt, removeSelectedRows, removeRowClosestToPos } from './utils/remove-row';
@@ -42,3 +42,8 @@ export interface MoveOptions {
42
42
  direction?: number;
43
43
  selectAfterMove?: boolean;
44
44
  }
45
+ export interface CloneOptions {
46
+ tryToFit?: boolean;
47
+ direction?: number;
48
+ selectAfterClone?: boolean;
49
+ }
@@ -0,0 +1,3 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { CloneOptions } from '../types';
3
+ export declare const cloneColumn: (state: EditorState, originColumnIndex: number | number[], targetColumnIndex: number, targetDirection: 'start' | 'end', options?: CloneOptions) => (tr: Transaction) => Transaction;
@@ -0,0 +1,3 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { CloneOptions } from '../types';
3
+ export declare const cloneRow: (state: EditorState, originRowIndex: number | number[], targetRowIndex: number, targetDirection: 'start' | 'end', options?: CloneOptions) => (tr: Transaction) => Transaction;
@@ -23,6 +23,8 @@ export { isRectSelected, isColumnSelected, isRowSelected, isTableSelected, } fro
23
23
  export { isSelectionType } from './utils/is-selection-type';
24
24
  export { moveColumn } from './utils/move-column';
25
25
  export { moveRow } from './utils/move-row';
26
+ export { cloneColumn } from './utils/clone-column';
27
+ export { cloneRow } from './utils/clone-row';
26
28
  export { normalizeSelection } from './utils/normalize-selection';
27
29
  export { removeColumnAt, removeSelectedColumns, removeColumnClosestToPos, } from './utils/remove-column';
28
30
  export { removeRowAt, removeSelectedRows, removeRowClosestToPos, } from './utils/remove-row';
@@ -42,3 +42,8 @@ export interface MoveOptions {
42
42
  direction?: number;
43
43
  selectAfterMove?: boolean;
44
44
  }
45
+ export interface CloneOptions {
46
+ tryToFit?: boolean;
47
+ direction?: number;
48
+ selectAfterClone?: boolean;
49
+ }
@@ -0,0 +1,3 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { CloneOptions } from '../types';
3
+ export declare const cloneColumn: (state: EditorState, originColumnIndex: number | number[], targetColumnIndex: number, targetDirection: 'start' | 'end', options?: CloneOptions) => (tr: Transaction) => Transaction;
@@ -0,0 +1,3 @@
1
+ import type { EditorState, Transaction } from '@atlaskit/editor-prosemirror/state';
2
+ import type { CloneOptions } from '../types';
3
+ export declare const cloneRow: (state: EditorState, originRowIndex: number | number[], targetRowIndex: number, targetDirection: 'start' | 'end', options?: CloneOptions) => (tr: Transaction) => Transaction;
@@ -23,6 +23,8 @@ export { isRectSelected, isColumnSelected, isRowSelected, isTableSelected, } fro
23
23
  export { isSelectionType } from './utils/is-selection-type';
24
24
  export { moveColumn } from './utils/move-column';
25
25
  export { moveRow } from './utils/move-row';
26
+ export { cloneColumn } from './utils/clone-column';
27
+ export { cloneRow } from './utils/clone-row';
26
28
  export { normalizeSelection } from './utils/normalize-selection';
27
29
  export { removeColumnAt, removeSelectedColumns, removeColumnClosestToPos, } from './utils/remove-column';
28
30
  export { removeRowAt, removeSelectedRows, removeRowClosestToPos, } from './utils/remove-row';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-tables",
3
- "version": "2.5.8",
3
+ "version": "2.6.0",
4
4
  "description": "A package that contains common classes and utility functions for editor tables",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -71,4 +71,4 @@
71
71
  "./types": "./src/types.ts",
72
72
  "./utils": "./src/utils.ts"
73
73
  }
74
- }
74
+ }
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/pm-plugins.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/pm-plugins.d.ts"
12
12
  ]
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/table-map.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/table-map.d.ts"
12
12
  ]
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/types.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/types.d.ts"
12
12
  ]
@@ -6,7 +6,7 @@
6
6
  "sideEffects": false,
7
7
  "types": "../dist/types/utils.d.ts",
8
8
  "typesVersions": {
9
- ">=4.5 <4.9": {
9
+ ">=4.5 <5.4": {
10
10
  "*": [
11
11
  "../dist/types-ts4.5/utils.d.ts"
12
12
  ]