@atlaskit/editor-tables 2.2.4 → 2.2.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.
Files changed (158) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cjs/cell-bookmark.js +0 -10
  3. package/dist/cjs/cell-selection.js +37 -102
  4. package/dist/cjs/index.js +0 -4
  5. package/dist/cjs/pm-plugins/input.js +17 -83
  6. package/dist/cjs/pm-plugins/plugin-key.js +0 -2
  7. package/dist/cjs/pm-plugins/table-editing.js +17 -18
  8. package/dist/cjs/pm-plugins.js +0 -2
  9. package/dist/cjs/table-map.js +67 -138
  10. package/dist/cjs/utils/add-column-at.js +0 -9
  11. package/dist/cjs/utils/add-column.js +8 -24
  12. package/dist/cjs/utils/add-row-at.js +8 -37
  13. package/dist/cjs/utils/add-row.js +2 -23
  14. package/dist/cjs/utils/analytics-helpers.js +4 -15
  15. package/dist/cjs/utils/cells.js +0 -12
  16. package/dist/cjs/utils/clone-tr.js +0 -2
  17. package/dist/cjs/utils/colspan.js +2 -18
  18. package/dist/cjs/utils/copy-paste.js +51 -139
  19. package/dist/cjs/utils/create-table.js +14 -28
  20. package/dist/cjs/utils/draw-cell-selection.js +0 -4
  21. package/dist/cjs/utils/empty-cells.js +0 -6
  22. package/dist/cjs/utils/find.js +6 -18
  23. package/dist/cjs/utils/fix-tables.js +13 -56
  24. package/dist/cjs/utils/for-each-cell.js +3 -17
  25. package/dist/cjs/utils/get-cell-selection-ranges.js +2 -9
  26. package/dist/cjs/utils/get-cells-in-column.js +0 -7
  27. package/dist/cjs/utils/get-cells-in-row.js +0 -7
  28. package/dist/cjs/utils/get-cells-in-table.js +0 -8
  29. package/dist/cjs/utils/get-selection-range-in-column.js +6 -27
  30. package/dist/cjs/utils/get-selection-range-in-row.js +6 -27
  31. package/dist/cjs/utils/get-selection-rect.js +0 -7
  32. package/dist/cjs/utils/go-to-next-cell.js +3 -22
  33. package/dist/cjs/utils/handle-paste.js +5 -34
  34. package/dist/cjs/utils/is-selected.js +6 -23
  35. package/dist/cjs/utils/is-selection-type.js +0 -2
  36. package/dist/cjs/utils/move-column.js +0 -12
  37. package/dist/cjs/utils/move-row.js +0 -11
  38. package/dist/cjs/utils/normalize-selection.js +3 -27
  39. package/dist/cjs/utils/remove-column.js +10 -46
  40. package/dist/cjs/utils/remove-row.js +8 -49
  41. package/dist/cjs/utils/remove-table.js +0 -6
  42. package/dist/cjs/utils/reorder-utils.js +13 -37
  43. package/dist/cjs/utils/replace-table.js +0 -8
  44. package/dist/cjs/utils/select-nodes.js +11 -31
  45. package/dist/cjs/utils/selection-cell.js +0 -5
  46. package/dist/cjs/utils/selection-rect.js +0 -10
  47. package/dist/cjs/utils/set-cell-attrs.js +0 -4
  48. package/dist/cjs/utils/split-cell-with-type.js +2 -35
  49. package/dist/cjs/utils/split-cell.js +0 -4
  50. package/dist/cjs/utils/table-node-types.js +4 -8
  51. package/dist/cjs/utils/tables.js +0 -4
  52. package/dist/cjs/utils/test-utils.js +9 -26
  53. package/dist/cjs/utils/toggle-header.js +3 -16
  54. package/dist/cjs/utils/uuid.js +0 -3
  55. package/dist/cjs/utils.js +0 -42
  56. package/dist/cjs/version.json +1 -1
  57. package/dist/es2019/cell-bookmark.js +0 -5
  58. package/dist/es2019/cell-selection.js +37 -81
  59. package/dist/es2019/index.js +1 -0
  60. package/dist/es2019/pm-plugins/input.js +15 -67
  61. package/dist/es2019/pm-plugins/table-editing.js +3 -12
  62. package/dist/es2019/table-map.js +57 -127
  63. package/dist/es2019/utils/add-column-at.js +2 -4
  64. package/dist/es2019/utils/add-column.js +6 -16
  65. package/dist/es2019/utils/add-row-at.js +8 -22
  66. package/dist/es2019/utils/add-row.js +2 -17
  67. package/dist/es2019/utils/analytics-helpers.js +0 -5
  68. package/dist/es2019/utils/cells.js +4 -9
  69. package/dist/es2019/utils/colspan.js +6 -11
  70. package/dist/es2019/utils/copy-paste.js +41 -115
  71. package/dist/es2019/utils/create-table.js +3 -12
  72. package/dist/es2019/utils/draw-cell-selection.js +0 -1
  73. package/dist/es2019/utils/empty-cells.js +2 -3
  74. package/dist/es2019/utils/find.js +8 -8
  75. package/dist/es2019/utils/fix-tables.js +17 -47
  76. package/dist/es2019/utils/for-each-cell.js +6 -11
  77. package/dist/es2019/utils/get-cell-selection-ranges.js +2 -4
  78. package/dist/es2019/utils/get-cells-in-column.js +2 -3
  79. package/dist/es2019/utils/get-cells-in-row.js +2 -3
  80. package/dist/es2019/utils/get-cells-in-table.js +2 -4
  81. package/dist/es2019/utils/get-selection-range-in-column.js +8 -22
  82. package/dist/es2019/utils/get-selection-range-in-row.js +8 -22
  83. package/dist/es2019/utils/get-selection-rect.js +2 -2
  84. package/dist/es2019/utils/go-to-next-cell.js +3 -19
  85. package/dist/es2019/utils/handle-paste.js +3 -14
  86. package/dist/es2019/utils/is-selected.js +8 -10
  87. package/dist/es2019/utils/is-selection-type.js +0 -1
  88. package/dist/es2019/utils/move-column.js +3 -8
  89. package/dist/es2019/utils/move-row.js +3 -7
  90. package/dist/es2019/utils/normalize-selection.js +0 -16
  91. package/dist/es2019/utils/remove-column.js +10 -27
  92. package/dist/es2019/utils/remove-row.js +12 -32
  93. package/dist/es2019/utils/remove-table.js +2 -4
  94. package/dist/es2019/utils/reorder-utils.js +11 -26
  95. package/dist/es2019/utils/replace-table.js +0 -2
  96. package/dist/es2019/utils/select-nodes.js +9 -20
  97. package/dist/es2019/utils/selection-cell.js +0 -2
  98. package/dist/es2019/utils/selection-rect.js +0 -4
  99. package/dist/es2019/utils/set-cell-attrs.js +2 -2
  100. package/dist/es2019/utils/split-cell-with-type.js +8 -28
  101. package/dist/es2019/utils/split-cell.js +3 -2
  102. package/dist/es2019/utils/table-node-types.js +4 -7
  103. package/dist/es2019/utils/tables.js +0 -2
  104. package/dist/es2019/utils/test-utils.js +12 -16
  105. package/dist/es2019/utils/toggle-header.js +3 -10
  106. package/dist/es2019/utils/uuid.js +0 -2
  107. package/dist/es2019/version.json +1 -1
  108. package/dist/esm/cell-bookmark.js +0 -5
  109. package/dist/esm/cell-selection.js +37 -79
  110. package/dist/esm/index.js +1 -0
  111. package/dist/esm/pm-plugins/input.js +17 -71
  112. package/dist/esm/pm-plugins/table-editing.js +8 -13
  113. package/dist/esm/table-map.js +68 -133
  114. package/dist/esm/utils/add-column-at.js +2 -4
  115. package/dist/esm/utils/add-column.js +8 -20
  116. package/dist/esm/utils/add-row-at.js +8 -23
  117. package/dist/esm/utils/add-row.js +2 -21
  118. package/dist/esm/utils/analytics-helpers.js +4 -10
  119. package/dist/esm/utils/cells.js +0 -5
  120. package/dist/esm/utils/colspan.js +2 -14
  121. package/dist/esm/utils/copy-paste.js +44 -125
  122. package/dist/esm/utils/create-table.js +14 -25
  123. package/dist/esm/utils/draw-cell-selection.js +0 -1
  124. package/dist/esm/utils/empty-cells.js +2 -3
  125. package/dist/esm/utils/find.js +8 -8
  126. package/dist/esm/utils/fix-tables.js +13 -49
  127. package/dist/esm/utils/for-each-cell.js +6 -11
  128. package/dist/esm/utils/get-cell-selection-ranges.js +2 -4
  129. package/dist/esm/utils/get-cells-in-column.js +2 -3
  130. package/dist/esm/utils/get-cells-in-row.js +2 -3
  131. package/dist/esm/utils/get-cells-in-table.js +2 -4
  132. package/dist/esm/utils/get-selection-range-in-column.js +8 -24
  133. package/dist/esm/utils/get-selection-range-in-row.js +8 -24
  134. package/dist/esm/utils/get-selection-rect.js +2 -2
  135. package/dist/esm/utils/go-to-next-cell.js +3 -19
  136. package/dist/esm/utils/handle-paste.js +5 -23
  137. package/dist/esm/utils/is-selected.js +8 -10
  138. package/dist/esm/utils/is-selection-type.js +0 -1
  139. package/dist/esm/utils/move-column.js +3 -8
  140. package/dist/esm/utils/move-row.js +3 -7
  141. package/dist/esm/utils/normalize-selection.js +3 -22
  142. package/dist/esm/utils/remove-column.js +10 -31
  143. package/dist/esm/utils/remove-row.js +8 -35
  144. package/dist/esm/utils/remove-table.js +2 -4
  145. package/dist/esm/utils/reorder-utils.js +11 -26
  146. package/dist/esm/utils/replace-table.js +0 -2
  147. package/dist/esm/utils/select-nodes.js +11 -22
  148. package/dist/esm/utils/selection-cell.js +0 -2
  149. package/dist/esm/utils/selection-rect.js +0 -4
  150. package/dist/esm/utils/set-cell-attrs.js +2 -2
  151. package/dist/esm/utils/split-cell-with-type.js +2 -28
  152. package/dist/esm/utils/split-cell.js +3 -2
  153. package/dist/esm/utils/table-node-types.js +4 -7
  154. package/dist/esm/utils/tables.js +0 -2
  155. package/dist/esm/utils/test-utils.js +12 -16
  156. package/dist/esm/utils/toggle-header.js +3 -10
  157. package/dist/esm/version.json +1 -1
  158. package/package.json +6 -4
@@ -1,8 +1,10 @@
1
1
  // Was copied from https://github.com/ProseMirror/prosemirror-tables/blob/master/src/cellselection.js
2
+
2
3
  // This file defines a ProseMirror selection subclass that models
3
4
  // table cell selections. The table plugin needs to be active to wire
4
5
  // in the user interaction part of table selections (so that you
5
6
  // actually get such selections when you select across cells).
7
+
6
8
  import { Fragment, Slice } from 'prosemirror-model';
7
9
  import { Selection, TextSelection } from 'prosemirror-state';
8
10
  import { CellBookmark } from './cell-bookmark';
@@ -10,56 +12,52 @@ import { TableMap } from './table-map';
10
12
  import { pointsAtCell } from './utils/cells';
11
13
  import { removeColSpan } from './utils/colspan';
12
14
  import { getCellSelectionRanges } from './utils/get-cell-selection-ranges';
13
- import { inSameTable } from './utils/tables'; // ::- A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
15
+ import { inSameTable } from './utils/tables';
16
+
17
+ // ::- A [`Selection`](http://prosemirror.net/docs/ref/#state.Selection)
14
18
  // subclass that represents a cell selection spanning part of a table.
15
19
  // With the plugin enabled, these will be created when the user
16
20
  // selects across cells, and will be drawn by giving selected cells a
17
21
  // `selectedCell` CSS class.
18
-
19
22
  export class CellSelection extends Selection {
20
23
  // :: (ResolvedPos, ?ResolvedPos)
21
24
  // A table selection is identified by its anchor and head cells. The
22
25
  // positions given to this constructor should point _before_ two
23
26
  // cells in the same table. They may be the same, to select a single
24
27
  // cell.
28
+
25
29
  constructor($anchorCell, $headCell = $anchorCell) {
26
30
  const ranges = getCellSelectionRanges($anchorCell, $headCell);
27
- super(ranges[0].$from, ranges[0].$to, ranges); // :: ResolvedPos
31
+ super(ranges[0].$from, ranges[0].$to, ranges);
32
+ // :: ResolvedPos
28
33
  // A resolved position pointing _in front of_ the anchor cell (the one
29
34
  // that doesn't move when extending the selection).
30
-
31
- this.$anchorCell = $anchorCell; // :: ResolvedPos
35
+ this.$anchorCell = $anchorCell;
36
+ // :: ResolvedPos
32
37
  // A resolved position pointing in front of the head cell (the one
33
38
  // moves when extending the selection).
34
-
35
39
  this.$headCell = $headCell;
36
40
  this.visible = false;
37
41
  }
38
-
39
42
  map(doc, mapping) {
40
43
  const $anchorCell = doc.resolve(mapping.map(this.$anchorCell.pos));
41
44
  const $headCell = doc.resolve(mapping.map(this.$headCell.pos));
42
-
43
45
  if (pointsAtCell($anchorCell) && pointsAtCell($headCell) && inSameTable($anchorCell, $headCell)) {
44
46
  const tableChanged = this.$anchorCell.node(-1) !== $anchorCell.node(-1);
45
-
46
47
  if (tableChanged && this.isRowSelection()) {
47
48
  return CellSelection.rowSelection($anchorCell, $headCell);
48
49
  }
49
-
50
50
  if (tableChanged && this.isColSelection()) {
51
51
  return CellSelection.colSelection($anchorCell, $headCell);
52
52
  }
53
-
54
53
  return new CellSelection($anchorCell, $headCell);
55
54
  }
56
-
57
55
  return TextSelection.between($anchorCell, $headCell);
58
- } // :: () → Slice
56
+ }
57
+
58
+ // :: () → Slice
59
59
  // Returns a rectangular slice of table rows containing the selected
60
60
  // cells.
61
-
62
-
63
61
  content() {
64
62
  const table = this.$anchorCell.node(-1);
65
63
  const map = TableMap.get(table);
@@ -67,86 +65,68 @@ export class CellSelection extends Selection {
67
65
  const rect = map.rectBetween(this.$anchorCell.pos - start, this.$headCell.pos - start);
68
66
  const seen = {};
69
67
  const rows = [];
70
-
71
68
  for (let row = rect.top; row < rect.bottom; row++) {
72
69
  const rowContent = [];
73
-
74
70
  for (let index = row * map.width + rect.left, col = rect.left; col < rect.right; col++, index++) {
75
71
  const pos = map.map[index];
76
-
77
72
  if (!seen[pos]) {
78
73
  seen[pos] = true;
79
74
  const cellRect = map.findCell(pos);
80
75
  let cell = table.nodeAt(pos);
81
-
82
76
  if (cell === null || cell === undefined) {
83
77
  throw new Error(`No cell at position ${pos}`);
84
78
  }
85
-
86
79
  const extraLeft = rect.left - cellRect.left;
87
80
  const extraRight = cellRect.right - rect.right;
88
-
89
81
  if (extraLeft > 0 || extraRight > 0) {
90
82
  let {
91
83
  attrs
92
84
  } = cell;
93
-
94
85
  if (!attrs) {
95
86
  throw new Error(`No cell at position ${pos}`);
96
87
  }
97
-
98
88
  if (extraLeft > 0) {
99
89
  attrs = removeColSpan(attrs, 0, extraLeft);
100
90
  }
101
-
102
91
  if (extraRight > 0) {
103
92
  attrs = removeColSpan(attrs, attrs.colspan - extraRight, extraRight);
104
93
  }
105
-
106
94
  if (cellRect.left < rect.left) {
107
95
  cell = cell.type.createAndFill(attrs);
108
96
  } else {
109
97
  cell = cell.type.create(attrs, cell.content);
110
98
  }
111
99
  }
112
-
113
100
  if (cell === null || cell === undefined) {
114
101
  throw new Error(`No cell at position after create/createAndFill`);
115
102
  }
116
-
117
103
  if (cellRect.top < rect.top || cellRect.bottom > rect.bottom) {
118
- const attrs = { ...cell.attrs,
104
+ const attrs = {
105
+ ...cell.attrs,
119
106
  rowspan: Math.min(cellRect.bottom, rect.bottom) - Math.max(cellRect.top, rect.top)
120
107
  };
121
-
122
108
  if (cellRect.top < rect.top) {
123
109
  cell = cell.type.createAndFill(attrs);
124
110
  } else {
125
111
  cell = cell.type.create(attrs, cell.content);
126
112
  }
127
113
  }
128
-
129
114
  if (cell === null || cell === undefined) {
130
115
  throw new Error(`No cell at position before rowContent.push`);
131
116
  }
132
-
133
117
  rowContent.push(cell);
134
118
  }
135
119
  }
136
-
137
120
  rows.push(table.child(row).copy(Fragment.from(rowContent)));
138
121
  }
139
-
140
122
  const fragment = this.isColSelection() && this.isRowSelection() ? table : rows;
141
123
  return new Slice(Fragment.from(fragment), 1, 1);
142
124
  }
143
-
144
125
  replace(tr, content = Slice.empty) {
145
126
  const mapFrom = tr.steps.length;
146
127
  const {
147
128
  ranges
148
129
  } = this;
149
-
150
130
  for (let i = 0; i < ranges.length; i++) {
151
131
  const {
152
132
  $from,
@@ -155,58 +135,48 @@ export class CellSelection extends Selection {
155
135
  const mapping = tr.mapping.slice(mapFrom);
156
136
  tr.replace(mapping.map($from.pos), mapping.map($to.pos), i ? Slice.empty : content);
157
137
  }
158
-
159
138
  const sel = Selection.findFrom(tr.doc.resolve(tr.mapping.slice(mapFrom).map(this.to)), -1);
160
-
161
139
  if (sel) {
162
140
  tr.setSelection(sel);
163
141
  }
164
142
  }
165
-
166
143
  replaceWith(tr, node) {
167
144
  this.replace(tr, new Slice(Fragment.from(node), 0, 0));
168
145
  }
169
-
170
146
  forEachCell(f) {
171
147
  const table = this.$anchorCell.node(-1);
172
148
  const map = TableMap.get(table);
173
149
  const start = this.$anchorCell.start(-1);
174
150
  const cells = map.cellsInRect(map.rectBetween(this.$anchorCell.pos - start, this.$headCell.pos - start));
175
-
176
151
  for (let i = 0; i < cells.length; i++) {
177
152
  const cell = table.nodeAt(cells[i]);
178
-
179
153
  if (cell === null || cell === undefined) {
180
154
  throw new Error(`undefined cell at pos ${cells[i]}`);
181
155
  }
182
-
183
156
  f(cell, start + cells[i]);
184
157
  }
185
- } // :: () → bool
158
+ }
159
+
160
+ // :: () → bool
186
161
  // True if this selection goes all the way from the top to the
187
162
  // bottom of the table.
188
-
189
-
190
163
  isColSelection() {
191
164
  if (!this.$anchorCell || !this.$headCell) {
192
165
  throw new Error('invalid $anchorCell or $headCell');
193
166
  }
194
-
195
167
  const anchorTop = this.$anchorCell.index(-1);
196
168
  const headTop = this.$headCell.index(-1);
197
-
198
169
  if (Math.min(anchorTop, headTop) > 0) {
199
170
  return false;
200
171
  }
201
-
202
172
  const anchorBot = anchorTop + this.$anchorCell.nodeAfter.attrs.rowspan;
203
173
  const headBot = headTop + this.$headCell.nodeAfter.attrs.rowspan;
204
174
  return Math.max(anchorBot, headBot) === this.$headCell.node(-1).childCount;
205
- } // :: (ResolvedPos, ?ResolvedPos) → CellSelection
175
+ }
176
+
177
+ // :: (ResolvedPos, ?ResolvedPos) → CellSelection
206
178
  // Returns the smallest column selection that covers the given anchor
207
179
  // and head cell.
208
-
209
-
210
180
  static colSelection($anchorCell, $headCell = $anchorCell) {
211
181
  let $calculatedAnchorCell = $anchorCell;
212
182
  let $calculatedHeadCell = $headCell;
@@ -215,12 +185,10 @@ export class CellSelection extends Selection {
215
185
  const anchorRect = map.findCell($calculatedAnchorCell.pos - start);
216
186
  const headRect = map.findCell($calculatedHeadCell.pos - start);
217
187
  const doc = $calculatedAnchorCell.node(0);
218
-
219
188
  if (anchorRect.top <= headRect.top) {
220
189
  if (anchorRect.top > 0) {
221
190
  $calculatedAnchorCell = doc.resolve(start + map.map[anchorRect.left]);
222
191
  }
223
-
224
192
  if (headRect.bottom < map.height) {
225
193
  $calculatedHeadCell = doc.resolve(start + map.map[map.width * (map.height - 1) + headRect.right - 1]);
226
194
  }
@@ -228,59 +196,55 @@ export class CellSelection extends Selection {
228
196
  if (headRect.top > 0) {
229
197
  $calculatedHeadCell = doc.resolve(start + map.map[headRect.left]);
230
198
  }
231
-
232
199
  if (anchorRect.bottom < map.height) {
233
200
  $calculatedAnchorCell = doc.resolve(start + map.map[map.width * (map.height - 1) + anchorRect.right - 1]);
234
201
  }
235
202
  }
236
-
237
203
  return new CellSelection($calculatedAnchorCell, $calculatedHeadCell);
238
- } // :: () → bool
204
+ }
205
+
206
+ // :: () → bool
239
207
  // True if this selection goes all the way from the left to the
240
208
  // right of the table.
241
-
242
-
243
209
  isRowSelection() {
244
210
  if (!this.$anchorCell || !this.$headCell) {
245
211
  return false;
246
212
  }
247
-
248
213
  const start = this.$anchorCell.start(-1);
249
214
  const map = TableMap.get(this.$anchorCell.node(-1));
250
215
  const rowAtAnchorCell = map.rowCount(this.$anchorCell.pos - start);
251
216
  const rowAtHeadCell = map.rowCount(this.$headCell.pos - start);
252
- const isSelectionSameRow = rowAtAnchorCell === rowAtHeadCell; // if anchor and head in the same line, counting how many cells
217
+ const isSelectionSameRow = rowAtAnchorCell === rowAtHeadCell;
218
+
219
+ // if anchor and head in the same line, counting how many cells
253
220
  // should be in the row except merged cell
221
+ let maxColumnInSelectedRow = map.getMaxColInRow(this.$anchorCell);
254
222
 
255
- let maxColumnInSelectedRow = map.getMaxColInRow(this.$anchorCell); // if selected cells less than table max column amount, and
223
+ // if selected cells less than table max column amount, and
256
224
  // the anchor/head not in a merged cell
257
225
  // it should be select maxColumnInSelectedRow to be TRUE
258
-
259
226
  if (isSelectionSameRow && this.ranges.length <= map.width && !map.isPosMerged(this.$anchorCell.pos - start) && !map.isPosMerged(this.$headCell.pos - start)) {
260
227
  return this.ranges.length === maxColumnInSelectedRow;
261
- } // If anchor and head in different row, it should be always in first and
262
- // last column to select the whole row.
263
-
228
+ }
264
229
 
230
+ // If anchor and head in different row, it should be always in first and
231
+ // last column to select the whole row.
265
232
  const anchorLeft = map.colCount(this.$anchorCell.pos - start);
266
233
  const headLeft = map.colCount(this.$headCell.pos - start);
267
-
268
234
  if (Math.min(anchorLeft, headLeft) > 0) {
269
235
  return false;
270
236
  }
271
-
272
237
  const anchorRight = anchorLeft + this.$anchorCell.nodeAfter.attrs.colspan;
273
238
  const headRight = headLeft + this.$headCell.nodeAfter.attrs.colspan;
274
239
  return Math.max(anchorRight, headRight) === map.width;
275
240
  }
276
-
277
241
  eq(other) {
278
242
  return other instanceof CellSelection && other.$anchorCell.pos === this.$anchorCell.pos && other.$headCell.pos === this.$headCell.pos;
279
- } // :: (ResolvedPos, ?ResolvedPos) → CellSelection
243
+ }
244
+
245
+ // :: (ResolvedPos, ?ResolvedPos) → CellSelection
280
246
  // Returns the smallest row selection that covers the given anchor
281
247
  // and head cell.
282
-
283
-
284
248
  static rowSelection($anchorCell, $headCell = $anchorCell) {
285
249
  let $calculatedAnchorCell = $anchorCell;
286
250
  let $calculatedHeadCell = $headCell;
@@ -289,12 +253,10 @@ export class CellSelection extends Selection {
289
253
  const anchorRect = map.findCell($calculatedAnchorCell.pos - start);
290
254
  const headRect = map.findCell($calculatedHeadCell.pos - start);
291
255
  const doc = $calculatedAnchorCell.node(0);
292
-
293
256
  if (anchorRect.left <= headRect.left) {
294
257
  if (anchorRect.left > 0) {
295
258
  $calculatedAnchorCell = doc.resolve(start + map.map[anchorRect.top * map.width]);
296
259
  }
297
-
298
260
  if (headRect.right < map.width) {
299
261
  $calculatedHeadCell = doc.resolve(start + map.map[map.width * (headRect.top + 1) - 1]);
300
262
  }
@@ -302,15 +264,12 @@ export class CellSelection extends Selection {
302
264
  if (headRect.left > 0) {
303
265
  $calculatedHeadCell = doc.resolve(start + map.map[headRect.top * map.width]);
304
266
  }
305
-
306
267
  if (anchorRect.right < map.width) {
307
268
  $calculatedAnchorCell = doc.resolve(start + map.map[map.width * (anchorRect.top + 1) - 1]);
308
269
  }
309
270
  }
310
-
311
271
  return new CellSelection($calculatedAnchorCell, $calculatedHeadCell);
312
272
  }
313
-
314
273
  toJSON() {
315
274
  return {
316
275
  type: 'cell',
@@ -318,19 +277,16 @@ export class CellSelection extends Selection {
318
277
  head: this.$headCell.pos
319
278
  };
320
279
  }
321
-
322
280
  static fromJSON(doc, json) {
323
281
  return new CellSelection(doc.resolve(json.anchor), doc.resolve(json.head));
324
- } // :: (Node, number, ?number) → CellSelection
325
-
282
+ }
326
283
 
284
+ // :: (Node, number, ?number) → CellSelection
327
285
  static create(doc, anchorCell, headCell = anchorCell) {
328
286
  return new CellSelection(doc.resolve(anchorCell), doc.resolve(headCell));
329
287
  }
330
-
331
288
  getBookmark() {
332
289
  return new CellBookmark(this.$anchorCell.pos, this.$headCell.pos);
333
290
  }
334
-
335
291
  }
336
292
  Selection.jsonID('cell', CellSelection);
@@ -21,6 +21,7 @@
21
21
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  THE SOFTWARE.
23
23
  */
24
+
24
25
  export { TableMap, Rect } from './table-map';
25
26
  export { CellSelection } from './cell-selection';
26
27
  export { findTable } from './utils/find';
@@ -1,5 +1,6 @@
1
1
  // This file defines a number of helpers for wiring up user input to
2
2
  // table-related functionality.
3
+
3
4
  import { keydownHandler } from 'prosemirror-keymap';
4
5
  import { Slice } from 'prosemirror-model';
5
6
  import { Selection, TextSelection } from 'prosemirror-state';
@@ -22,46 +23,35 @@ export const handleKeyDown = keydownHandler({
22
23
  Delete: deleteCellSelection,
23
24
  'Mod-Delete': deleteCellSelection
24
25
  });
25
-
26
26
  function maybeSetSelection(state, dispatch, selection) {
27
27
  if (selection.eq(state.selection)) {
28
28
  return false;
29
29
  }
30
-
31
30
  if (dispatch) {
32
31
  dispatch(state.tr.setSelection(selection).scrollIntoView());
33
32
  }
34
-
35
33
  return true;
36
34
  }
37
-
38
35
  function arrow(axis, dir) {
39
36
  return (state, dispatch, view) => {
40
37
  if (dispatch) {
41
38
  const sel = state.selection;
42
-
43
39
  if (sel instanceof CellSelection) {
44
40
  return maybeSetSelection(state, dispatch, Selection.near(sel.$headCell, dir));
45
41
  }
46
-
47
42
  if (axis !== 'horiz' && !sel.empty) {
48
43
  return false;
49
44
  }
50
-
51
45
  const end = view ? atEndOfCell(view, axis, dir) : null;
52
-
53
46
  if (end === null) {
54
47
  return false;
55
48
  }
56
-
57
49
  if (axis === 'horiz') {
58
50
  return maybeSetSelection(state, dispatch, Selection.near(state.doc.resolve(sel.head + dir), dir));
59
51
  }
60
-
61
52
  const $cell = state.doc.resolve(end);
62
53
  const $next = nextCell($cell, axis, dir);
63
54
  let newSel;
64
-
65
55
  if ($next) {
66
56
  newSel = Selection.near($next, 1);
67
57
  } else if (dir < 0) {
@@ -69,65 +59,50 @@ function arrow(axis, dir) {
69
59
  } else {
70
60
  newSel = Selection.near(state.doc.resolve($cell.after(-1)), 1);
71
61
  }
72
-
73
62
  return maybeSetSelection(state, dispatch, newSel);
74
63
  }
75
-
76
64
  return true;
77
65
  };
78
66
  }
79
-
80
67
  function shiftArrow(axis, dir) {
81
68
  return (state, dispatch, view) => {
82
69
  let sel = state.selection;
83
-
84
70
  if (!(sel instanceof CellSelection)) {
85
71
  var _maybeTableCell$paren;
86
-
87
72
  const end = view ? atEndOfCell(view, axis, dir) : null;
88
-
89
73
  if (end === null) {
90
74
  return false;
91
75
  }
92
-
93
76
  const {
94
77
  selection: {
95
78
  $head,
96
79
  $anchor
97
80
  }
98
81
  } = state;
99
- const maybeTableCell = $head.blockRange($anchor); // Make sure the selection is coming from the same cell
82
+ const maybeTableCell = $head.blockRange($anchor);
100
83
 
84
+ // Make sure the selection is coming from the same cell
101
85
  const sameCell = ['tableCell', 'tableHeader'].includes((maybeTableCell === null || maybeTableCell === void 0 ? void 0 : (_maybeTableCell$paren = maybeTableCell.parent) === null || _maybeTableCell$paren === void 0 ? void 0 : _maybeTableCell$paren.type.name) || '');
102
-
103
86
  if (!sameCell) {
104
87
  return false;
105
88
  }
106
-
107
89
  sel = new CellSelection(state.doc.resolve(end));
108
90
  }
109
-
110
91
  const $head = nextCell(sel.$headCell, axis, dir);
111
-
112
92
  if (!$head) {
113
93
  return false;
114
94
  }
115
-
116
95
  if (dispatch) {
117
96
  return maybeSetSelection(state, dispatch, new CellSelection(sel.$anchorCell, $head));
118
97
  }
119
-
120
98
  return true;
121
99
  };
122
100
  }
123
-
124
101
  function deleteCellSelection(state, dispatch) {
125
102
  const sel = state.selection;
126
-
127
103
  if (!(sel instanceof CellSelection)) {
128
104
  return false;
129
105
  }
130
-
131
106
  if (dispatch) {
132
107
  const {
133
108
  tr
@@ -138,39 +113,32 @@ function deleteCellSelection(state, dispatch) {
138
113
  tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
139
114
  }
140
115
  });
141
-
142
116
  if (tr.docChanged) {
143
117
  dispatch(tr);
144
118
  }
145
119
  }
146
-
147
120
  return true;
148
121
  }
149
-
150
122
  export function handleTripleClick(view, pos) {
151
123
  const {
152
124
  doc
153
125
  } = view.state;
154
126
  const $cell = cellAround(doc.resolve(pos));
155
-
156
127
  if (!$cell) {
157
128
  return false;
158
129
  }
159
-
160
130
  view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
161
131
  return true;
162
132
  }
163
133
  export function handleMouseDown(view, event) {
164
- const startEvent = event; // Prevent right clicks from making a cell selection https://product-fabric.atlassian.net/browse/ED-12527
165
-
134
+ const startEvent = event;
135
+ // Prevent right clicks from making a cell selection https://product-fabric.atlassian.net/browse/ED-12527
166
136
  if (startEvent.ctrlKey || startEvent.metaKey || startEvent.button === 2 // right mouse click
167
137
  ) {
168
138
  return false;
169
139
  }
170
-
171
140
  const startDOMCell = domInCell(view, startEvent.target);
172
141
  const $anchor = cellAround(view.state.selection.$anchor);
173
-
174
142
  if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
175
143
  // Adding to an existing cell selection
176
144
  setCellSelection(view.state.selection.$anchorCell, startEvent);
@@ -183,14 +151,13 @@ export function handleMouseDown(view, event) {
183
151
  } else if (!startDOMCell) {
184
152
  // Not in a cell, let the default behavior happen.
185
153
  return false;
186
- } // Create and dispatch a cell selection between the given anchor and
187
- // the position under the mouse.
188
-
154
+ }
189
155
 
156
+ // Create and dispatch a cell selection between the given anchor and
157
+ // the position under the mouse.
190
158
  function setCellSelection($selectionAnchor, event) {
191
159
  let $head = cellUnderMouse(view, event);
192
160
  const starting = tableEditingKey.getState(view.state) == null;
193
-
194
161
  if (!$head || !inSameTable($selectionAnchor, $head)) {
195
162
  if (starting) {
196
163
  $head = $selectionAnchor;
@@ -198,109 +165,90 @@ export function handleMouseDown(view, event) {
198
165
  return false;
199
166
  }
200
167
  }
201
-
202
168
  const selection = new CellSelection($selectionAnchor, $head);
203
-
204
169
  if (starting || !view.state.selection.eq(selection)) {
205
170
  const tr = view.state.tr.setSelection(selection);
206
-
207
171
  if (starting) {
208
172
  tr.setMeta(tableEditingKey, $selectionAnchor.pos);
209
173
  }
210
-
211
174
  view.dispatch(tr);
212
175
  }
213
- } // Stop listening to mouse motion events.
214
-
176
+ }
215
177
 
178
+ // Stop listening to mouse motion events.
216
179
  function stop() {
217
180
  view.root.removeEventListener('mouseup', stop);
218
181
  view.root.removeEventListener('dragstart', stop);
219
182
  view.root.removeEventListener('mousemove', move);
220
-
221
183
  if (tableEditingKey.getState(view.state) != null) {
222
184
  view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
223
185
  }
224
186
  }
225
-
226
187
  function move(event) {
227
188
  const anchor = tableEditingKey.getState(view.state);
228
189
  let $moveAnchor;
229
-
230
190
  if (anchor != null) {
231
191
  // Continuing an existing cross-cell selection
232
192
  $moveAnchor = view.state.doc.resolve(anchor);
233
193
  } else if (domInCell(view, event.target) !== startDOMCell) {
234
194
  // Moving out of the initial cell -- start a new cell selection
235
195
  $moveAnchor = cellUnderMouse(view, startEvent);
236
-
237
196
  if (!$moveAnchor) {
238
197
  stop();
239
198
  return;
240
199
  }
241
200
  }
242
-
243
201
  if ($moveAnchor) {
244
202
  setCellSelection($moveAnchor, event);
245
203
  }
246
204
  }
247
-
248
205
  view.root.addEventListener('mouseup', stop);
249
206
  view.root.addEventListener('dragstart', stop);
250
207
  view.root.addEventListener('mousemove', move);
251
208
  return false;
252
- } // Check whether the cursor is at the end of a cell (so that further
253
- // motion would move out of the cell)
209
+ }
254
210
 
211
+ // Check whether the cursor is at the end of a cell (so that further
212
+ // motion would move out of the cell)
255
213
  function atEndOfCell(view, axis, dir) {
256
214
  if (!(view.state.selection instanceof TextSelection)) {
257
215
  return null;
258
216
  }
259
-
260
217
  const {
261
218
  $head
262
219
  } = view.state.selection;
263
-
264
220
  for (let d = $head.depth - 1; d >= 0; d--) {
265
221
  const parent = $head.node(d);
266
222
  const index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
267
-
268
223
  if (index !== (dir < 0 ? 0 : parent.childCount)) {
269
224
  return null;
270
225
  }
271
-
272
226
  if (parent.type.spec.tableRole === 'cell' || parent.type.spec.tableRole === 'header_cell') {
273
227
  const cellPos = $head.before(d);
274
- const dirStr = // eslint-disable-next-line no-nested-ternary
228
+ const dirStr =
229
+ // eslint-disable-next-line no-nested-ternary
275
230
  axis === 'vert' ? dir > 0 ? 'down' : 'up' : dir > 0 ? 'right' : 'left';
276
231
  return view.endOfTextblock(dirStr) ? cellPos : null;
277
232
  }
278
233
  }
279
-
280
234
  return null;
281
235
  }
282
-
283
236
  function domInCell(view, inputDom) {
284
237
  let dom = inputDom;
285
-
286
238
  for (; dom && dom !== view.dom; dom = dom.parentNode) {
287
239
  if (dom.nodeName === 'TD' || dom.nodeName === 'TH') {
288
240
  return dom;
289
241
  }
290
242
  }
291
-
292
243
  return null;
293
244
  }
294
-
295
245
  function cellUnderMouse(view, event) {
296
246
  const mousePos = view.posAtCoords({
297
247
  left: event.clientX,
298
248
  top: event.clientY
299
249
  });
300
-
301
250
  if (!mousePos) {
302
251
  return null;
303
252
  }
304
-
305
253
  return cellAround(view.state.doc.resolve(mousePos.pos));
306
254
  }