@atlaskit/editor-tables 2.1.4 → 2.1.6

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,17 @@
1
1
  # @atlaskit/editor-tables
2
2
 
3
+ ## 2.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [`95f007063cf`](https://bitbucket.org/atlassian/atlassian-frontend/commits/95f007063cf) - Decoupling paste plugin and table plugin, copied `replaceSelectedTable` and `getSelectedTableInfo` utils to editor-tables utils package and analytics dependency shifted to paste plugin.
8
+
9
+ ## 2.1.5
10
+
11
+ ### Patch Changes
12
+
13
+ - [`e6f25536fe3`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e6f25536fe3) - [ux][ed-15168] Fixes a bug where a width-less column was created when pasting table cells into a table that had columns with set widths.
14
+
3
15
  ## 2.1.4
4
16
 
5
17
  ### Patch Changes
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/cell-bookmark.js",
4
4
  "module": "../dist/esm/cell-bookmark.js",
5
5
  "module:es2019": "../dist/es2019/cell-bookmark.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/cell-bookmark.d.ts"
7
8
  }
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/cell-selection.js",
4
4
  "module": "../dist/esm/cell-selection.js",
5
5
  "module:es2019": "../dist/es2019/cell-selection.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/cell-selection.d.ts"
7
8
  }
@@ -5,7 +5,7 @@ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefau
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.TableProblemTypes = exports.TableMap = exports.Rect = void 0;
8
+ exports.tableNewColumnMinWidth = exports.TableProblemTypes = exports.TableMap = exports.Rect = void 0;
9
9
 
10
10
  var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
11
11
 
@@ -76,10 +76,17 @@ exports.TableProblemTypes = TableProblemTypes;
76
76
  TableProblemTypes["COLWIDTH_MISMATCH"] = "colwidth mismatch";
77
77
  })(TableProblemTypes || (exports.TableProblemTypes = TableProblemTypes = {}));
78
78
 
79
- // ::- A table map describes the structore of a given table. To avoid
79
+ // Ideally tableNewColumnMinWidth should be imported
80
+ // from '@atlaskit/editor-common/styles';
81
+ // We don't want to introduce a new dependency.
82
+ // Thus we define the constant here.
83
+ var tableNewColumnMinWidth = 140; // ::- A table map describes the structore of a given table. To avoid
80
84
  // recomputing them all the time, they are cached per table node. To
81
85
  // be able to do that, positions saved in the map are relative to the
82
86
  // start of the table, rather than the start of the document.
87
+
88
+ exports.tableNewColumnMinWidth = tableNewColumnMinWidth;
89
+
83
90
  var TableMap = /*#__PURE__*/function () {
84
91
  // The width of the table
85
92
  // The table's height
@@ -355,6 +362,19 @@ function computeMap(table) {
355
362
  if (colWidths[_i2] != null && colWidths[_i2 + 1] < height) {
356
363
  badWidths = true;
357
364
  }
365
+ } // colWidths is an array of numbers, it can look like this
366
+ // const colWidths = [255, 3, 125, 3, 150, 2, 130, 1];
367
+ // 255 is a colWidth and 3 is a number of cells with this colwidth.
368
+ // This check exists to make sure that the table has been resized,
369
+ // which means there will be elements in the colWidths array.
370
+
371
+
372
+ if (colWidths.length > 0 && colWidths.length !== width * 2) {
373
+ for (var _i3 = 0; _i3 < width * 2 - colWidths.length; _i3++) {
374
+ colWidths.push(tableNewColumnMinWidth, 0);
375
+ }
376
+
377
+ badWidths = true;
358
378
  }
359
379
 
360
380
  if (badWidths) {
@@ -386,8 +406,8 @@ function findWidth(table) {
386
406
  }
387
407
  }
388
408
 
389
- for (var _i3 = 0; _i3 < rowNode.childCount; _i3++) {
390
- var _cell = rowNode.child(_i3);
409
+ for (var _i4 = 0; _i4 < rowNode.childCount; _i4++) {
410
+ var _cell = rowNode.child(_i4);
391
411
 
392
412
  rowWidth += _cell.attrs.colspan;
393
413
 
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getSelectedCellInfo = getSelectedCellInfo;
7
+ exports.getSelectedTableInfo = getSelectedTableInfo;
8
+
9
+ var _tableMap = require("../table-map");
10
+
11
+ var _find = require("./find");
12
+
13
+ var _getSelectionRect = require("./get-selection-rect");
14
+
15
+ function getSelectedTableInfo(selection) {
16
+ var map;
17
+ var totalRowCount = 0;
18
+ var totalColumnCount = 0;
19
+ var table = (0, _find.findTable)(selection);
20
+
21
+ if (table) {
22
+ map = _tableMap.TableMap.get(table.node);
23
+ totalRowCount = map.height;
24
+ totalColumnCount = map.width;
25
+ }
26
+
27
+ return {
28
+ table: table,
29
+ map: map,
30
+ totalRowCount: totalRowCount,
31
+ totalColumnCount: totalColumnCount
32
+ };
33
+ }
34
+
35
+ function getSelectedCellInfo(selection) {
36
+ var horizontalCells = 1;
37
+ var verticalCells = 1;
38
+ var totalCells = 1;
39
+
40
+ var _getSelectedTableInfo = getSelectedTableInfo(selection),
41
+ table = _getSelectedTableInfo.table,
42
+ map = _getSelectedTableInfo.map,
43
+ totalRowCount = _getSelectedTableInfo.totalRowCount,
44
+ totalColumnCount = _getSelectedTableInfo.totalColumnCount;
45
+
46
+ if (table && map) {
47
+ var rect = (0, _getSelectionRect.getSelectionRect)(selection);
48
+
49
+ if (rect) {
50
+ totalCells = map.cellsInRect(rect).length;
51
+ horizontalCells = rect.right - rect.left;
52
+ verticalCells = rect.bottom - rect.top;
53
+ }
54
+ }
55
+
56
+ return {
57
+ totalRowCount: totalRowCount,
58
+ totalColumnCount: totalColumnCount,
59
+ horizontalCells: horizontalCells,
60
+ verticalCells: verticalCells,
61
+ totalCells: totalCells
62
+ };
63
+ }
@@ -9,7 +9,7 @@ var _prosemirrorModel = require("prosemirror-model");
9
9
 
10
10
  var _cellSelection = require("../cell-selection");
11
11
 
12
- var _tableMap = require("../table-map");
12
+ var _tableMap2 = require("../table-map");
13
13
 
14
14
  var _selectionCell = require("../utils/selection-cell");
15
15
 
@@ -19,6 +19,12 @@ var _tables = require("../utils/tables");
19
19
 
20
20
  var _copyPaste = require("./copy-paste");
21
21
 
22
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
23
+
24
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
25
+
26
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
27
+
22
28
  function handlePaste(view, event, slice) {
23
29
  if (!(0, _tables.isInTable)(view.state)) {
24
30
  return false;
@@ -39,10 +45,11 @@ function handlePaste(view, event, slice) {
39
45
  var table = sel.$anchorCell.node(-1);
40
46
  var start = sel.$anchorCell.start(-1);
41
47
 
42
- var rect = _tableMap.TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
48
+ var tableMap = _tableMap2.TableMap.get(table);
43
49
 
50
+ var rect = tableMap.rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
44
51
  cells = (0, _copyPaste.clipCells)(cells, rect.right - rect.left, rect.bottom - rect.top);
45
- (0, _copyPaste.insertCells)(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells));
52
+ (0, _copyPaste.insertCells)(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells, rect, tableMap));
46
53
  return true;
47
54
  }
48
55
 
@@ -55,20 +62,54 @@ function handlePaste(view, event, slice) {
55
62
 
56
63
  var _start = $cell.start(-1);
57
64
 
58
- (0, _copyPaste.insertCells)(view.state, view.dispatch, _start, _tableMap.TableMap.get($cell.node(-1)).findCell($cell.pos - _start), clearColumnWidthOfCells(cells));
65
+ var _rect = _tableMap2.TableMap.get($cell.node(-1)).findCell($cell.pos - _start);
66
+
67
+ var _tableMap = _tableMap2.TableMap.get($cell.node(-1));
68
+
69
+ (0, _copyPaste.insertCells)(view.state, view.dispatch, _start, _rect, clearColumnWidthOfCells(cells, _rect, _tableMap));
59
70
  return true;
60
71
  }
61
72
 
62
73
  return false;
63
74
  } // Clear the pasted cells column widths so that it maintains
64
- // the column widths of the destination table
75
+ // the column widths of the destination table only if the pasted
76
+ // cells overlap with existing cells in the destination table.
77
+ // If the table grows on paste, keep the column widhts of the
78
+ // original table.
79
+
80
+
81
+ var clearColumnWidthOfCells = function clearColumnWidthOfCells(cells, rect, table) {
82
+ var overlappingCells = [];
65
83
 
84
+ var _iterator = _createForOfIteratorHelper(cells.rows),
85
+ _step;
66
86
 
67
- var clearColumnWidthOfCells = function clearColumnWidthOfCells(cells) {
68
- cells.rows.forEach(function (row) {
69
- for (var i = 0; i < row.childCount; i++) {
70
- row.child(i).attrs.colwidth = null;
87
+ try {
88
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
89
+ var row = _step.value;
90
+ var colNum = rect.left;
91
+
92
+ for (var index = 0; index < row.childCount; index++) {
93
+ var _cell = row.child(index);
94
+
95
+ if (colNum + _cell.attrs.colspan <= table.width) {
96
+ overlappingCells.push(_cell);
97
+ colNum += _cell.attrs.colspan;
98
+ } else {
99
+ break;
100
+ }
101
+ }
71
102
  }
72
- });
103
+ } catch (err) {
104
+ _iterator.e(err);
105
+ } finally {
106
+ _iterator.f();
107
+ }
108
+
109
+ for (var _i = 0, _overlappingCells = overlappingCells; _i < _overlappingCells.length; _i++) {
110
+ var cell = _overlappingCells[_i];
111
+ cell.attrs.colwidth = null;
112
+ }
113
+
73
114
  return cells;
74
115
  };
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.replaceSelectedTable = void 0;
7
+
8
+ var _prosemirrorModel = require("prosemirror-model");
9
+
10
+ var _prosemirrorState = require("prosemirror-state");
11
+
12
+ var _find = require("./find");
13
+
14
+ var _isSelected = require("./is-selected");
15
+
16
+ var replaceSelectedTable = function replaceSelectedTable(state, content) {
17
+ if ((0, _isSelected.isTableSelected)(state.selection)) {
18
+ var table = (0, _find.findTable)(state.selection);
19
+
20
+ if (table) {
21
+ var slice = typeof content === 'string' ? new _prosemirrorModel.Slice(_prosemirrorModel.Fragment.from(state.schema.text(content)), 0, 0) : content;
22
+ var tr = state.tr.replace(table.pos, table.pos + table.node.nodeSize, slice);
23
+ tr.setSelection(_prosemirrorState.TextSelection.create(tr.doc, table.pos + slice.size + 1));
24
+ return tr;
25
+ }
26
+ }
27
+
28
+ return state.tr;
29
+ };
30
+
31
+ exports.replaceSelectedTable = replaceSelectedTable;
package/dist/cjs/utils.js CHANGED
@@ -159,6 +159,18 @@ Object.defineProperty(exports, "getCellsInTable", {
159
159
  return _getCellsInTable.getCellsInTable;
160
160
  }
161
161
  });
162
+ Object.defineProperty(exports, "getSelectedCellInfo", {
163
+ enumerable: true,
164
+ get: function get() {
165
+ return _analyticsHelpers.getSelectedCellInfo;
166
+ }
167
+ });
168
+ Object.defineProperty(exports, "getSelectedTableInfo", {
169
+ enumerable: true,
170
+ get: function get() {
171
+ return _analyticsHelpers.getSelectedTableInfo;
172
+ }
173
+ });
162
174
  Object.defineProperty(exports, "getSelectionRangeInColumn", {
163
175
  enumerable: true,
164
176
  get: function get() {
@@ -309,6 +321,12 @@ Object.defineProperty(exports, "removeTable", {
309
321
  return _removeTable.removeTable;
310
322
  }
311
323
  });
324
+ Object.defineProperty(exports, "replaceSelectedTable", {
325
+ enumerable: true,
326
+ get: function get() {
327
+ return _replaceTable.replaceSelectedTable;
328
+ }
329
+ });
312
330
  Object.defineProperty(exports, "selectColumn", {
313
331
  enumerable: true,
314
332
  get: function get() {
@@ -448,4 +466,8 @@ var _toggleHeader = require("./utils/toggle-header");
448
466
 
449
467
  var _reorderUtils = require("./utils/reorder-utils");
450
468
 
451
- var _handlePaste = require("./utils/handle-paste");
469
+ var _handlePaste = require("./utils/handle-paste");
470
+
471
+ var _replaceTable = require("./utils/replace-table");
472
+
473
+ var _analyticsHelpers = require("./utils/analytics-helpers");
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-tables",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "sideEffects": false
5
5
  }
@@ -61,10 +61,15 @@ export let TableProblemTypes;
61
61
  TableProblemTypes["COLWIDTH_MISMATCH"] = "colwidth mismatch";
62
62
  })(TableProblemTypes || (TableProblemTypes = {}));
63
63
 
64
- // ::- A table map describes the structore of a given table. To avoid
64
+ // Ideally tableNewColumnMinWidth should be imported
65
+ // from '@atlaskit/editor-common/styles';
66
+ // We don't want to introduce a new dependency.
67
+ // Thus we define the constant here.
68
+ export const tableNewColumnMinWidth = 140; // ::- A table map describes the structore of a given table. To avoid
65
69
  // recomputing them all the time, they are cached per table node. To
66
70
  // be able to do that, positions saved in the map are relative to the
67
71
  // start of the table, rather than the start of the document.
72
+
68
73
  export class TableMap {
69
74
  // The width of the table
70
75
  // The table's height
@@ -329,6 +334,19 @@ function computeMap(table) {
329
334
  if (colWidths[i] != null && colWidths[i + 1] < height) {
330
335
  badWidths = true;
331
336
  }
337
+ } // colWidths is an array of numbers, it can look like this
338
+ // const colWidths = [255, 3, 125, 3, 150, 2, 130, 1];
339
+ // 255 is a colWidth and 3 is a number of cells with this colwidth.
340
+ // This check exists to make sure that the table has been resized,
341
+ // which means there will be elements in the colWidths array.
342
+
343
+
344
+ if (colWidths.length > 0 && colWidths.length !== width * 2) {
345
+ for (let i = 0; i < width * 2 - colWidths.length; i++) {
346
+ colWidths.push(tableNewColumnMinWidth, 0);
347
+ }
348
+
349
+ badWidths = true;
332
350
  }
333
351
 
334
352
  if (badWidths) {
@@ -0,0 +1,51 @@
1
+ import { TableMap } from '../table-map';
2
+ import { findTable } from './find';
3
+ import { getSelectionRect } from './get-selection-rect';
4
+ export function getSelectedTableInfo(selection) {
5
+ let map;
6
+ let totalRowCount = 0;
7
+ let totalColumnCount = 0;
8
+ const table = findTable(selection);
9
+
10
+ if (table) {
11
+ map = TableMap.get(table.node);
12
+ totalRowCount = map.height;
13
+ totalColumnCount = map.width;
14
+ }
15
+
16
+ return {
17
+ table,
18
+ map,
19
+ totalRowCount,
20
+ totalColumnCount
21
+ };
22
+ }
23
+ export function getSelectedCellInfo(selection) {
24
+ let horizontalCells = 1;
25
+ let verticalCells = 1;
26
+ let totalCells = 1;
27
+ const {
28
+ table,
29
+ map,
30
+ totalRowCount,
31
+ totalColumnCount
32
+ } = getSelectedTableInfo(selection);
33
+
34
+ if (table && map) {
35
+ const rect = getSelectionRect(selection);
36
+
37
+ if (rect) {
38
+ totalCells = map.cellsInRect(rect).length;
39
+ horizontalCells = rect.right - rect.left;
40
+ verticalCells = rect.bottom - rect.top;
41
+ }
42
+ }
43
+
44
+ return {
45
+ totalRowCount,
46
+ totalColumnCount,
47
+ horizontalCells,
48
+ verticalCells,
49
+ totalCells
50
+ };
51
+ }
@@ -24,9 +24,10 @@ export function handlePaste(view, event, slice) {
24
24
 
25
25
  const table = sel.$anchorCell.node(-1);
26
26
  const start = sel.$anchorCell.start(-1);
27
- const rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
27
+ const tableMap = TableMap.get(table);
28
+ const rect = tableMap.rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
28
29
  cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
29
- insertCells(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells));
30
+ insertCells(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells, rect, tableMap));
30
31
  return true;
31
32
  }
32
33
 
@@ -38,19 +39,40 @@ export function handlePaste(view, event, slice) {
38
39
  }
39
40
 
40
41
  const start = $cell.start(-1);
41
- insertCells(view.state, view.dispatch, start, TableMap.get($cell.node(-1)).findCell($cell.pos - start), clearColumnWidthOfCells(cells));
42
+ const rect = TableMap.get($cell.node(-1)).findCell($cell.pos - start);
43
+ const tableMap = TableMap.get($cell.node(-1));
44
+ insertCells(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells, rect, tableMap));
42
45
  return true;
43
46
  }
44
47
 
45
48
  return false;
46
49
  } // Clear the pasted cells column widths so that it maintains
47
- // the column widths of the destination table
50
+ // the column widths of the destination table only if the pasted
51
+ // cells overlap with existing cells in the destination table.
52
+ // If the table grows on paste, keep the column widhts of the
53
+ // original table.
48
54
 
49
- const clearColumnWidthOfCells = cells => {
50
- cells.rows.forEach(row => {
51
- for (let i = 0; i < row.childCount; i++) {
52
- row.child(i).attrs.colwidth = null;
55
+ const clearColumnWidthOfCells = (cells, rect, table) => {
56
+ const overlappingCells = [];
57
+
58
+ for (const row of cells.rows) {
59
+ let colNum = rect.left;
60
+
61
+ for (let index = 0; index < row.childCount; index++) {
62
+ const cell = row.child(index);
63
+
64
+ if (colNum + cell.attrs.colspan <= table.width) {
65
+ overlappingCells.push(cell);
66
+ colNum += cell.attrs.colspan;
67
+ } else {
68
+ break;
69
+ }
53
70
  }
54
- });
71
+ }
72
+
73
+ for (const cell of overlappingCells) {
74
+ cell.attrs.colwidth = null;
75
+ }
76
+
55
77
  return cells;
56
78
  };
@@ -0,0 +1,18 @@
1
+ import { Fragment, Slice } from 'prosemirror-model';
2
+ import { TextSelection } from 'prosemirror-state';
3
+ import { findTable } from './find';
4
+ import { isTableSelected } from './is-selected';
5
+ export const replaceSelectedTable = (state, content) => {
6
+ if (isTableSelected(state.selection)) {
7
+ const table = findTable(state.selection);
8
+
9
+ if (table) {
10
+ const slice = typeof content === 'string' ? new Slice(Fragment.from(state.schema.text(content)), 0, 0) : content;
11
+ let tr = state.tr.replace(table.pos, table.pos + table.node.nodeSize, slice);
12
+ tr.setSelection(TextSelection.create(tr.doc, table.pos + slice.size + 1));
13
+ return tr;
14
+ }
15
+ }
16
+
17
+ return state.tr;
18
+ };
@@ -37,4 +37,6 @@ export { tableNodeTypes } from './utils/table-node-types';
37
37
  export { isInTable, inSameTable } from './utils/tables';
38
38
  export { toggleHeader } from './utils/toggle-header';
39
39
  export { convertArrayOfRowsToTableNode, convertTableNodeToArrayOfRows } from './utils/reorder-utils';
40
- export { handlePaste } from './utils/handle-paste';
40
+ export { handlePaste } from './utils/handle-paste';
41
+ export { replaceSelectedTable } from './utils/replace-table';
42
+ export { getSelectedTableInfo, getSelectedCellInfo } from './utils/analytics-helpers';
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-tables",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "sideEffects": false
5
5
  }
@@ -64,10 +64,15 @@ export var TableProblemTypes;
64
64
  TableProblemTypes["COLWIDTH_MISMATCH"] = "colwidth mismatch";
65
65
  })(TableProblemTypes || (TableProblemTypes = {}));
66
66
 
67
- // ::- A table map describes the structore of a given table. To avoid
67
+ // Ideally tableNewColumnMinWidth should be imported
68
+ // from '@atlaskit/editor-common/styles';
69
+ // We don't want to introduce a new dependency.
70
+ // Thus we define the constant here.
71
+ export var tableNewColumnMinWidth = 140; // ::- A table map describes the structore of a given table. To avoid
68
72
  // recomputing them all the time, they are cached per table node. To
69
73
  // be able to do that, positions saved in the map are relative to the
70
74
  // start of the table, rather than the start of the document.
75
+
71
76
  export var TableMap = /*#__PURE__*/function () {
72
77
  // The width of the table
73
78
  // The table's height
@@ -342,6 +347,19 @@ function computeMap(table) {
342
347
  if (colWidths[_i2] != null && colWidths[_i2 + 1] < height) {
343
348
  badWidths = true;
344
349
  }
350
+ } // colWidths is an array of numbers, it can look like this
351
+ // const colWidths = [255, 3, 125, 3, 150, 2, 130, 1];
352
+ // 255 is a colWidth and 3 is a number of cells with this colwidth.
353
+ // This check exists to make sure that the table has been resized,
354
+ // which means there will be elements in the colWidths array.
355
+
356
+
357
+ if (colWidths.length > 0 && colWidths.length !== width * 2) {
358
+ for (var _i3 = 0; _i3 < width * 2 - colWidths.length; _i3++) {
359
+ colWidths.push(tableNewColumnMinWidth, 0);
360
+ }
361
+
362
+ badWidths = true;
345
363
  }
346
364
 
347
365
  if (badWidths) {
@@ -373,8 +391,8 @@ function findWidth(table) {
373
391
  }
374
392
  }
375
393
 
376
- for (var _i3 = 0; _i3 < rowNode.childCount; _i3++) {
377
- var _cell = rowNode.child(_i3);
394
+ for (var _i4 = 0; _i4 < rowNode.childCount; _i4++) {
395
+ var _cell = rowNode.child(_i4);
378
396
 
379
397
  rowWidth += _cell.attrs.colspan;
380
398
 
@@ -0,0 +1,51 @@
1
+ import { TableMap } from '../table-map';
2
+ import { findTable } from './find';
3
+ import { getSelectionRect } from './get-selection-rect';
4
+ export function getSelectedTableInfo(selection) {
5
+ var map;
6
+ var totalRowCount = 0;
7
+ var totalColumnCount = 0;
8
+ var table = findTable(selection);
9
+
10
+ if (table) {
11
+ map = TableMap.get(table.node);
12
+ totalRowCount = map.height;
13
+ totalColumnCount = map.width;
14
+ }
15
+
16
+ return {
17
+ table: table,
18
+ map: map,
19
+ totalRowCount: totalRowCount,
20
+ totalColumnCount: totalColumnCount
21
+ };
22
+ }
23
+ export function getSelectedCellInfo(selection) {
24
+ var horizontalCells = 1;
25
+ var verticalCells = 1;
26
+ var totalCells = 1;
27
+
28
+ var _getSelectedTableInfo = getSelectedTableInfo(selection),
29
+ table = _getSelectedTableInfo.table,
30
+ map = _getSelectedTableInfo.map,
31
+ totalRowCount = _getSelectedTableInfo.totalRowCount,
32
+ totalColumnCount = _getSelectedTableInfo.totalColumnCount;
33
+
34
+ if (table && map) {
35
+ var rect = getSelectionRect(selection);
36
+
37
+ if (rect) {
38
+ totalCells = map.cellsInRect(rect).length;
39
+ horizontalCells = rect.right - rect.left;
40
+ verticalCells = rect.bottom - rect.top;
41
+ }
42
+ }
43
+
44
+ return {
45
+ totalRowCount: totalRowCount,
46
+ totalColumnCount: totalColumnCount,
47
+ horizontalCells: horizontalCells,
48
+ verticalCells: verticalCells,
49
+ totalCells: totalCells
50
+ };
51
+ }
@@ -1,3 +1,9 @@
1
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
2
+
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+
5
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
6
+
1
7
  import { Fragment } from 'prosemirror-model';
2
8
  import { CellSelection } from '../cell-selection';
3
9
  import { TableMap } from '../table-map';
@@ -24,9 +30,10 @@ export function handlePaste(view, event, slice) {
24
30
 
25
31
  var table = sel.$anchorCell.node(-1);
26
32
  var start = sel.$anchorCell.start(-1);
27
- var rect = TableMap.get(table).rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
33
+ var tableMap = TableMap.get(table);
34
+ var rect = tableMap.rectBetween(sel.$anchorCell.pos - start, sel.$headCell.pos - start);
28
35
  cells = clipCells(cells, rect.right - rect.left, rect.bottom - rect.top);
29
- insertCells(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells));
36
+ insertCells(view.state, view.dispatch, start, rect, clearColumnWidthOfCells(cells, rect, tableMap));
30
37
  return true;
31
38
  }
32
39
 
@@ -39,19 +46,53 @@ export function handlePaste(view, event, slice) {
39
46
 
40
47
  var _start = $cell.start(-1);
41
48
 
42
- insertCells(view.state, view.dispatch, _start, TableMap.get($cell.node(-1)).findCell($cell.pos - _start), clearColumnWidthOfCells(cells));
49
+ var _rect = TableMap.get($cell.node(-1)).findCell($cell.pos - _start);
50
+
51
+ var _tableMap = TableMap.get($cell.node(-1));
52
+
53
+ insertCells(view.state, view.dispatch, _start, _rect, clearColumnWidthOfCells(cells, _rect, _tableMap));
43
54
  return true;
44
55
  }
45
56
 
46
57
  return false;
47
58
  } // Clear the pasted cells column widths so that it maintains
48
- // the column widths of the destination table
59
+ // the column widths of the destination table only if the pasted
60
+ // cells overlap with existing cells in the destination table.
61
+ // If the table grows on paste, keep the column widhts of the
62
+ // original table.
63
+
64
+ var clearColumnWidthOfCells = function clearColumnWidthOfCells(cells, rect, table) {
65
+ var overlappingCells = [];
66
+
67
+ var _iterator = _createForOfIteratorHelper(cells.rows),
68
+ _step;
49
69
 
50
- var clearColumnWidthOfCells = function clearColumnWidthOfCells(cells) {
51
- cells.rows.forEach(function (row) {
52
- for (var i = 0; i < row.childCount; i++) {
53
- row.child(i).attrs.colwidth = null;
70
+ try {
71
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
72
+ var row = _step.value;
73
+ var colNum = rect.left;
74
+
75
+ for (var index = 0; index < row.childCount; index++) {
76
+ var _cell = row.child(index);
77
+
78
+ if (colNum + _cell.attrs.colspan <= table.width) {
79
+ overlappingCells.push(_cell);
80
+ colNum += _cell.attrs.colspan;
81
+ } else {
82
+ break;
83
+ }
84
+ }
54
85
  }
55
- });
86
+ } catch (err) {
87
+ _iterator.e(err);
88
+ } finally {
89
+ _iterator.f();
90
+ }
91
+
92
+ for (var _i = 0, _overlappingCells = overlappingCells; _i < _overlappingCells.length; _i++) {
93
+ var cell = _overlappingCells[_i];
94
+ cell.attrs.colwidth = null;
95
+ }
96
+
56
97
  return cells;
57
98
  };
@@ -0,0 +1,18 @@
1
+ import { Fragment, Slice } from 'prosemirror-model';
2
+ import { TextSelection } from 'prosemirror-state';
3
+ import { findTable } from './find';
4
+ import { isTableSelected } from './is-selected';
5
+ export var replaceSelectedTable = function replaceSelectedTable(state, content) {
6
+ if (isTableSelected(state.selection)) {
7
+ var table = findTable(state.selection);
8
+
9
+ if (table) {
10
+ var slice = typeof content === 'string' ? new Slice(Fragment.from(state.schema.text(content)), 0, 0) : content;
11
+ var tr = state.tr.replace(table.pos, table.pos + table.node.nodeSize, slice);
12
+ tr.setSelection(TextSelection.create(tr.doc, table.pos + slice.size + 1));
13
+ return tr;
14
+ }
15
+ }
16
+
17
+ return state.tr;
18
+ };
package/dist/esm/utils.js CHANGED
@@ -37,4 +37,6 @@ export { tableNodeTypes } from './utils/table-node-types';
37
37
  export { isInTable, inSameTable } from './utils/tables';
38
38
  export { toggleHeader } from './utils/toggle-header';
39
39
  export { convertArrayOfRowsToTableNode, convertTableNodeToArrayOfRows } from './utils/reorder-utils';
40
- export { handlePaste } from './utils/handle-paste';
40
+ export { handlePaste } from './utils/handle-paste';
41
+ export { replaceSelectedTable } from './utils/replace-table';
42
+ export { getSelectedTableInfo, getSelectedCellInfo } from './utils/analytics-helpers';
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-tables",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
4
4
  "sideEffects": false
5
5
  }
@@ -45,6 +45,7 @@ export declare type TableProblemColWidthMismatch = {
45
45
  colwidth: number;
46
46
  };
47
47
  export declare type TableProblem = TableProblemCollision | TableProblemLongRowspan | TableProblemMissing | TableProblemColWidthMismatch;
48
+ export declare const tableNewColumnMinWidth = 140;
48
49
  export declare class TableMap {
49
50
  width: number;
50
51
  height: number;
@@ -0,0 +1,15 @@
1
+ import { Selection } from 'prosemirror-state';
2
+ import { TableMap } from '../table-map';
3
+ export declare function getSelectedTableInfo(selection: Selection): {
4
+ table: import("prosemirror-utils").ContentNodeWithPos | undefined;
5
+ map: TableMap | undefined;
6
+ totalRowCount: number;
7
+ totalColumnCount: number;
8
+ };
9
+ export declare function getSelectedCellInfo(selection: Selection): {
10
+ totalRowCount: number;
11
+ totalColumnCount: number;
12
+ horizontalCells: number;
13
+ verticalCells: number;
14
+ totalCells: number;
15
+ };
@@ -0,0 +1,3 @@
1
+ import { Slice } from 'prosemirror-model';
2
+ import { EditorState, Transaction } from 'prosemirror-state';
3
+ export declare const replaceSelectedTable: (state: EditorState, content: string | Slice) => Transaction;
@@ -39,3 +39,5 @@ export { isInTable, inSameTable } from './utils/tables';
39
39
  export { toggleHeader } from './utils/toggle-header';
40
40
  export { convertArrayOfRowsToTableNode, convertTableNodeToArrayOfRows, } from './utils/reorder-utils';
41
41
  export { handlePaste } from './utils/handle-paste';
42
+ export { replaceSelectedTable } from './utils/replace-table';
43
+ export { getSelectedTableInfo, getSelectedCellInfo, } from './utils/analytics-helpers';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/editor-tables",
3
- "version": "2.1.4",
3
+ "version": "2.1.6",
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/"
@@ -29,8 +29,8 @@
29
29
  "prosemirror-view": "1.23.2"
30
30
  },
31
31
  "devDependencies": {
32
- "@atlaskit/adf-schema": "^23.0.0",
33
- "@atlaskit/editor-test-helpers": "^17.0.0",
32
+ "@atlaskit/adf-schema": "^24.0.0",
33
+ "@atlaskit/editor-test-helpers": "^17.1.0",
34
34
  "@atlassian/atlassian-frontend-prettier-config-1.0.1": "npm:@atlassian/atlassian-frontend-prettier-config@1.0.1"
35
35
  },
36
36
  "techstack": {
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/pm-plugins.js",
4
4
  "module": "../dist/esm/pm-plugins.js",
5
5
  "module:es2019": "../dist/es2019/pm-plugins.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/pm-plugins.d.ts"
7
8
  }
package/report.api.md ADDED
@@ -0,0 +1,137 @@
1
+ ## API Report File for "@atlaskit/editor-tables"
2
+
3
+ > Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4
+
5
+ ```ts
6
+ import { ContentNodeWithPos } from 'prosemirror-utils';
7
+ import { Mapping } from 'prosemirror-transform';
8
+ import { Node as Node_2 } from 'prosemirror-model';
9
+ import { ResolvedPos } from 'prosemirror-model';
10
+ import { Selection as Selection_2 } from 'prosemirror-state';
11
+ import { Slice } from 'prosemirror-model';
12
+ import { Transaction } from 'prosemirror-state';
13
+
14
+ declare type Axis = 'horiz' | 'vert';
15
+
16
+ declare class CellBookmark {
17
+ readonly anchor: number;
18
+ readonly head: number;
19
+ constructor(anchor: number, head: number);
20
+ map(mapping: Mapping): CellBookmark;
21
+ resolve(doc: Node_2): Selection_2;
22
+ }
23
+
24
+ export declare class CellSelection extends Selection_2 {
25
+ readonly $anchorCell: ResolvedPos;
26
+ readonly $headCell: ResolvedPos;
27
+ readonly visible: boolean;
28
+ constructor($anchorCell: ResolvedPos, $headCell?: ResolvedPos);
29
+ map(doc: Node_2, mapping: Mapping): Selection_2;
30
+ content(): Slice;
31
+ replace(tr: Transaction, content?: Slice<any>): void;
32
+ replaceWith(tr: Transaction, node: Node_2): void;
33
+ forEachCell(f: (node: Node_2, pos: number) => void): void;
34
+ isColSelection(): boolean;
35
+ static colSelection(
36
+ $anchorCell: ResolvedPos,
37
+ $headCell?: ResolvedPos,
38
+ ): CellSelection;
39
+ isRowSelection(): boolean;
40
+ eq(other: CellSelection): boolean;
41
+ static rowSelection(
42
+ $anchorCell: ResolvedPos,
43
+ $headCell?: ResolvedPos,
44
+ ): CellSelection;
45
+ toJSON(): SerializedCellSelection;
46
+ static fromJSON(doc: Node_2, json: SerializedCellSelection): CellSelection;
47
+ static create(
48
+ doc: Node_2,
49
+ anchorCell: number,
50
+ headCell?: number,
51
+ ): CellSelection;
52
+ getBookmark(): CellBookmark;
53
+ }
54
+
55
+ export declare const findTable: (
56
+ selection: Selection_2,
57
+ ) => ContentNodeWithPos | undefined;
58
+
59
+ export declare class Rect {
60
+ left: number;
61
+ top: number;
62
+ right: number;
63
+ bottom: number;
64
+ constructor(left: number, top: number, right: number, bottom: number);
65
+ }
66
+
67
+ declare interface SerializedCellSelection {
68
+ type: 'cell';
69
+ anchor: number;
70
+ head: number;
71
+ }
72
+
73
+ export declare class TableMap {
74
+ width: number;
75
+ height: number;
76
+ map: number[];
77
+ problems?: TableProblem[] | null;
78
+ constructor(
79
+ width: number,
80
+ height: number,
81
+ map: number[],
82
+ problems?: TableProblem[] | null,
83
+ );
84
+ findCell(pos: number): Rect;
85
+ colCount(pos: number): number;
86
+ nextCell(pos: number, axis: Axis, dir: number): number | null;
87
+ rectBetween(a: number, b: number): Rect;
88
+ cellsInRect(rect: Rect): number[];
89
+ positionAt(row: number, col: number, table: Node_2): number;
90
+ static get(table: Node_2): TableMap;
91
+ }
92
+
93
+ declare type TableProblem =
94
+ | TableProblemCollision
95
+ | TableProblemLongRowspan
96
+ | TableProblemMissing
97
+ | TableProblemColWidthMismatch;
98
+
99
+ declare type TableProblemCollision = {
100
+ type: TableProblemTypes.COLLISION;
101
+ row: number;
102
+ pos: number;
103
+ n: number;
104
+ };
105
+
106
+ declare type TableProblemColWidthMismatch = {
107
+ type: TableProblemTypes;
108
+ pos: number;
109
+ colwidth: number;
110
+ };
111
+
112
+ declare type TableProblemLongRowspan = {
113
+ type: TableProblemTypes.OVERLONG_ROWSPAN;
114
+ pos: number;
115
+ n: number;
116
+ };
117
+
118
+ declare type TableProblemMissing = {
119
+ type: TableProblemTypes.MISSING;
120
+ row: number;
121
+ n: number;
122
+ };
123
+
124
+ declare enum TableProblemTypes {
125
+ COLLISION = 'collision',
126
+ OVERLONG_ROWSPAN = 'overlong_rowspan',
127
+ MISSING = 'missing',
128
+ COLWIDTH_MISMATCH = 'colwidth mismatch',
129
+ }
130
+
131
+ export declare const uuid: {
132
+ setStatic(value: string | false): void;
133
+ generate(): string;
134
+ };
135
+
136
+ export {};
137
+ ```
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/table-map.js",
4
4
  "module": "../dist/esm/table-map.js",
5
5
  "module:es2019": "../dist/es2019/table-map.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/table-map.d.ts"
7
8
  }
package/tsconfig.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "extends": "../../../tsconfig.json",
3
3
  "compilerOptions": {
4
- "noImplicitAny": true,
5
4
  "baseUrl": "./"
6
5
  },
7
6
  "include": [
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/types.js",
4
4
  "module": "../dist/esm/types.js",
5
5
  "module:es2019": "../dist/es2019/types.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/types.d.ts"
7
8
  }
@@ -3,5 +3,6 @@
3
3
  "main": "../dist/cjs/utils.js",
4
4
  "module": "../dist/esm/utils.js",
5
5
  "module:es2019": "../dist/es2019/utils.js",
6
+ "sideEffects": false,
6
7
  "types": "../dist/types/utils.d.ts"
7
8
  }