@atlaskit/editor-tables 2.2.3 → 2.2.5

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 (160) hide show
  1. package/CHANGELOG.md +14 -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 +24 -75
  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 +63 -134
  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 +94 -120
  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 +4 -33
  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 +4 -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 +27 -63
  61. package/dist/es2019/pm-plugins/table-editing.js +3 -12
  62. package/dist/es2019/table-map.js +54 -124
  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 +85 -99
  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 +4 -13
  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 +24 -63
  112. package/dist/esm/pm-plugins/table-editing.js +8 -13
  113. package/dist/esm/table-map.js +65 -130
  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 +88 -109
  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 +4 -22
  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 +4 -13
  157. package/dist/esm/version.json +1 -1
  158. package/dist/types/utils/toggle-header.d.ts +3 -0
  159. package/package.json +7 -5
  160. package/report.api.md +11 -0
@@ -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,49 +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)) {
71
+ var _maybeTableCell$paren;
85
72
  const end = view ? atEndOfCell(view, axis, dir) : null;
86
-
87
73
  if (end === null) {
88
74
  return false;
89
75
  }
90
-
76
+ const {
77
+ selection: {
78
+ $head,
79
+ $anchor
80
+ }
81
+ } = state;
82
+ const maybeTableCell = $head.blockRange($anchor);
83
+
84
+ // Make sure the selection is coming from the same cell
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) || '');
86
+ if (!sameCell) {
87
+ return false;
88
+ }
91
89
  sel = new CellSelection(state.doc.resolve(end));
92
90
  }
93
-
94
91
  const $head = nextCell(sel.$headCell, axis, dir);
95
-
96
92
  if (!$head) {
97
93
  return false;
98
94
  }
99
-
100
95
  if (dispatch) {
101
96
  return maybeSetSelection(state, dispatch, new CellSelection(sel.$anchorCell, $head));
102
97
  }
103
-
104
98
  return true;
105
99
  };
106
100
  }
107
-
108
101
  function deleteCellSelection(state, dispatch) {
109
102
  const sel = state.selection;
110
-
111
103
  if (!(sel instanceof CellSelection)) {
112
104
  return false;
113
105
  }
114
-
115
106
  if (dispatch) {
116
107
  const {
117
108
  tr
@@ -122,39 +113,32 @@ function deleteCellSelection(state, dispatch) {
122
113
  tr.replace(tr.mapping.map(pos + 1), tr.mapping.map(pos + cell.nodeSize - 1), new Slice(baseContent, 0, 0));
123
114
  }
124
115
  });
125
-
126
116
  if (tr.docChanged) {
127
117
  dispatch(tr);
128
118
  }
129
119
  }
130
-
131
120
  return true;
132
121
  }
133
-
134
122
  export function handleTripleClick(view, pos) {
135
123
  const {
136
124
  doc
137
125
  } = view.state;
138
126
  const $cell = cellAround(doc.resolve(pos));
139
-
140
127
  if (!$cell) {
141
128
  return false;
142
129
  }
143
-
144
130
  view.dispatch(view.state.tr.setSelection(new CellSelection($cell)));
145
131
  return true;
146
132
  }
147
133
  export function handleMouseDown(view, event) {
148
- const startEvent = event; // Prevent right clicks from making a cell selection https://product-fabric.atlassian.net/browse/ED-12527
149
-
134
+ const startEvent = event;
135
+ // Prevent right clicks from making a cell selection https://product-fabric.atlassian.net/browse/ED-12527
150
136
  if (startEvent.ctrlKey || startEvent.metaKey || startEvent.button === 2 // right mouse click
151
137
  ) {
152
138
  return false;
153
139
  }
154
-
155
140
  const startDOMCell = domInCell(view, startEvent.target);
156
141
  const $anchor = cellAround(view.state.selection.$anchor);
157
-
158
142
  if (startEvent.shiftKey && view.state.selection instanceof CellSelection) {
159
143
  // Adding to an existing cell selection
160
144
  setCellSelection(view.state.selection.$anchorCell, startEvent);
@@ -167,14 +151,13 @@ export function handleMouseDown(view, event) {
167
151
  } else if (!startDOMCell) {
168
152
  // Not in a cell, let the default behavior happen.
169
153
  return false;
170
- } // Create and dispatch a cell selection between the given anchor and
171
- // the position under the mouse.
172
-
154
+ }
173
155
 
156
+ // Create and dispatch a cell selection between the given anchor and
157
+ // the position under the mouse.
174
158
  function setCellSelection($selectionAnchor, event) {
175
159
  let $head = cellUnderMouse(view, event);
176
160
  const starting = tableEditingKey.getState(view.state) == null;
177
-
178
161
  if (!$head || !inSameTable($selectionAnchor, $head)) {
179
162
  if (starting) {
180
163
  $head = $selectionAnchor;
@@ -182,109 +165,90 @@ export function handleMouseDown(view, event) {
182
165
  return false;
183
166
  }
184
167
  }
185
-
186
168
  const selection = new CellSelection($selectionAnchor, $head);
187
-
188
169
  if (starting || !view.state.selection.eq(selection)) {
189
170
  const tr = view.state.tr.setSelection(selection);
190
-
191
171
  if (starting) {
192
172
  tr.setMeta(tableEditingKey, $selectionAnchor.pos);
193
173
  }
194
-
195
174
  view.dispatch(tr);
196
175
  }
197
- } // Stop listening to mouse motion events.
198
-
176
+ }
199
177
 
178
+ // Stop listening to mouse motion events.
200
179
  function stop() {
201
180
  view.root.removeEventListener('mouseup', stop);
202
181
  view.root.removeEventListener('dragstart', stop);
203
182
  view.root.removeEventListener('mousemove', move);
204
-
205
183
  if (tableEditingKey.getState(view.state) != null) {
206
184
  view.dispatch(view.state.tr.setMeta(tableEditingKey, -1));
207
185
  }
208
186
  }
209
-
210
187
  function move(event) {
211
188
  const anchor = tableEditingKey.getState(view.state);
212
189
  let $moveAnchor;
213
-
214
190
  if (anchor != null) {
215
191
  // Continuing an existing cross-cell selection
216
192
  $moveAnchor = view.state.doc.resolve(anchor);
217
193
  } else if (domInCell(view, event.target) !== startDOMCell) {
218
194
  // Moving out of the initial cell -- start a new cell selection
219
195
  $moveAnchor = cellUnderMouse(view, startEvent);
220
-
221
196
  if (!$moveAnchor) {
222
197
  stop();
223
198
  return;
224
199
  }
225
200
  }
226
-
227
201
  if ($moveAnchor) {
228
202
  setCellSelection($moveAnchor, event);
229
203
  }
230
204
  }
231
-
232
205
  view.root.addEventListener('mouseup', stop);
233
206
  view.root.addEventListener('dragstart', stop);
234
207
  view.root.addEventListener('mousemove', move);
235
208
  return false;
236
- } // Check whether the cursor is at the end of a cell (so that further
237
- // motion would move out of the cell)
209
+ }
238
210
 
211
+ // Check whether the cursor is at the end of a cell (so that further
212
+ // motion would move out of the cell)
239
213
  function atEndOfCell(view, axis, dir) {
240
214
  if (!(view.state.selection instanceof TextSelection)) {
241
215
  return null;
242
216
  }
243
-
244
217
  const {
245
218
  $head
246
219
  } = view.state.selection;
247
-
248
220
  for (let d = $head.depth - 1; d >= 0; d--) {
249
221
  const parent = $head.node(d);
250
222
  const index = dir < 0 ? $head.index(d) : $head.indexAfter(d);
251
-
252
223
  if (index !== (dir < 0 ? 0 : parent.childCount)) {
253
224
  return null;
254
225
  }
255
-
256
226
  if (parent.type.spec.tableRole === 'cell' || parent.type.spec.tableRole === 'header_cell') {
257
227
  const cellPos = $head.before(d);
258
- const dirStr = // eslint-disable-next-line no-nested-ternary
228
+ const dirStr =
229
+ // eslint-disable-next-line no-nested-ternary
259
230
  axis === 'vert' ? dir > 0 ? 'down' : 'up' : dir > 0 ? 'right' : 'left';
260
231
  return view.endOfTextblock(dirStr) ? cellPos : null;
261
232
  }
262
233
  }
263
-
264
234
  return null;
265
235
  }
266
-
267
236
  function domInCell(view, inputDom) {
268
237
  let dom = inputDom;
269
-
270
238
  for (; dom && dom !== view.dom; dom = dom.parentNode) {
271
239
  if (dom.nodeName === 'TD' || dom.nodeName === 'TH') {
272
240
  return dom;
273
241
  }
274
242
  }
275
-
276
243
  return null;
277
244
  }
278
-
279
245
  function cellUnderMouse(view, event) {
280
246
  const mousePos = view.posAtCoords({
281
247
  left: event.clientX,
282
248
  top: event.clientY
283
249
  });
284
-
285
250
  if (!mousePos) {
286
251
  return null;
287
252
  }
288
-
289
253
  return cellAround(view.state.doc.resolve(mousePos.pos));
290
254
  }