handsontable 0.0.0-next-f748da8-20240318 → 0.0.0-next-76fc9bd-20240319

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.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

Files changed (96) hide show
  1. package/3rdparty/walkontable/src/cell/range.d.ts +1 -2
  2. package/3rdparty/walkontable/src/cell/range.js +5 -22
  3. package/3rdparty/walkontable/src/cell/range.mjs +5 -22
  4. package/base.js +2 -2
  5. package/base.mjs +2 -2
  6. package/core/viewportScroll/index.js +1 -4
  7. package/core/viewportScroll/index.mjs +1 -4
  8. package/core.d.ts +3 -4
  9. package/core.js +21 -76
  10. package/core.mjs +21 -76
  11. package/dist/handsontable.css +2 -2
  12. package/dist/handsontable.full.css +2 -2
  13. package/dist/handsontable.full.js +1359 -2612
  14. package/dist/handsontable.full.min.css +2 -2
  15. package/dist/handsontable.full.min.js +64 -64
  16. package/dist/handsontable.js +1363 -2616
  17. package/dist/handsontable.min.css +2 -2
  18. package/dist/handsontable.min.js +19 -19
  19. package/editorManager.js +8 -12
  20. package/editorManager.mjs +8 -12
  21. package/helpers/mixed.js +1 -1
  22. package/helpers/mixed.mjs +1 -1
  23. package/package.json +1 -1
  24. package/pluginHooks.d.ts +0 -4
  25. package/pluginHooks.js +1 -69
  26. package/pluginHooks.mjs +1 -69
  27. package/plugins/collapsibleColumns/collapsibleColumns.js +3 -9
  28. package/plugins/collapsibleColumns/collapsibleColumns.mjs +3 -9
  29. package/plugins/columnSorting/columnSorting.js +2 -8
  30. package/plugins/columnSorting/columnSorting.mjs +2 -8
  31. package/plugins/contextMenu/menu/defaultShortcutsList.js +10 -26
  32. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +10 -26
  33. package/plugins/mergeCells/calculations/selection.js +70 -1
  34. package/plugins/mergeCells/calculations/selection.mjs +70 -1
  35. package/plugins/mergeCells/cellsCollection.js +0 -116
  36. package/plugins/mergeCells/cellsCollection.mjs +0 -116
  37. package/plugins/mergeCells/contextMenuItem/toggleMerge.js +1 -11
  38. package/plugins/mergeCells/contextMenuItem/toggleMerge.mjs +1 -11
  39. package/plugins/mergeCells/mergeCells.js +192 -336
  40. package/plugins/mergeCells/mergeCells.mjs +192 -336
  41. package/plugins/multiColumnSorting/multiColumnSorting.js +2 -8
  42. package/plugins/multiColumnSorting/multiColumnSorting.mjs +2 -8
  43. package/plugins/nestedHeaders/nestedHeaders.js +0 -1
  44. package/plugins/nestedHeaders/nestedHeaders.mjs +0 -1
  45. package/plugins/nestedRows/nestedRows.js +3 -9
  46. package/plugins/nestedRows/nestedRows.mjs +3 -9
  47. package/renderers/checkboxRenderer/checkboxRenderer.js +5 -8
  48. package/renderers/checkboxRenderer/checkboxRenderer.mjs +5 -8
  49. package/selection/highlight/visualSelection.js +0 -2
  50. package/selection/highlight/visualSelection.mjs +0 -2
  51. package/selection/selection.js +40 -209
  52. package/selection/selection.mjs +39 -208
  53. package/selection/transformation.js +32 -83
  54. package/selection/transformation.mjs +32 -83
  55. package/shortcutContexts/commands/editor/closeAndSave.js +2 -2
  56. package/shortcutContexts/commands/editor/closeAndSave.mjs +2 -2
  57. package/shortcutContexts/commands/editor/open.js +3 -18
  58. package/shortcutContexts/commands/editor/open.mjs +3 -18
  59. package/shortcutContexts/commands/extendCellsSelection/down.js +1 -1
  60. package/shortcutContexts/commands/extendCellsSelection/down.mjs +1 -1
  61. package/shortcutContexts/commands/extendCellsSelection/left.js +1 -1
  62. package/shortcutContexts/commands/extendCellsSelection/left.mjs +1 -1
  63. package/shortcutContexts/commands/extendCellsSelection/right.js +1 -1
  64. package/shortcutContexts/commands/extendCellsSelection/right.mjs +1 -1
  65. package/shortcutContexts/commands/extendCellsSelection/toColumns.js +1 -1
  66. package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +1 -1
  67. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +1 -3
  68. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +1 -3
  69. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +3 -9
  70. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +3 -9
  71. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +3 -10
  72. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +3 -10
  73. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +1 -3
  74. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +1 -3
  75. package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +1 -3
  76. package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +1 -3
  77. package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +1 -3
  78. package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +1 -3
  79. package/shortcutContexts/commands/extendCellsSelection/toRows.js +1 -1
  80. package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +1 -1
  81. package/shortcutContexts/commands/extendCellsSelection/up.js +1 -1
  82. package/shortcutContexts/commands/extendCellsSelection/up.mjs +1 -1
  83. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +1 -6
  84. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +1 -6
  85. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +1 -6
  86. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +1 -6
  87. package/shortcutContexts/grid.js +9 -3
  88. package/shortcutContexts/grid.mjs +9 -3
  89. package/shortcuts/context.js +1 -2
  90. package/shortcuts/context.mjs +1 -2
  91. package/utils/dataStructures/linkedList.js +1 -6
  92. package/utils/dataStructures/linkedList.mjs +1 -6
  93. package/core/viewportScroll/scrollStrategies/focusScroll.js +0 -15
  94. package/core/viewportScroll/scrollStrategies/focusScroll.mjs +0 -11
  95. package/plugins/mergeCells/focusOrder.js +0 -303
  96. package/plugins/mergeCells/focusOrder.mjs +0 -298
@@ -17,7 +17,6 @@ var _number = require("../../helpers/number");
17
17
  var _utils = require("./utils");
18
18
  var _element = require("../../helpers/dom/element");
19
19
  var _browser = require("../../helpers/browser");
20
- var _focusOrder2 = require("./focusOrder");
21
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22
21
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
23
22
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
@@ -73,9 +72,7 @@ const SHORTCUTS_GROUP = PLUGIN_KEY;
73
72
  * ```
74
73
  * :::
75
74
  */
76
- var _lastSelectedFocus = /*#__PURE__*/new WeakMap();
77
- var _lastFocusDelta = /*#__PURE__*/new WeakMap();
78
- var _focusOrder = /*#__PURE__*/new WeakMap();
75
+ var _lastDesiredCoords = /*#__PURE__*/new WeakMap();
79
76
  var _MergeCells_brand = /*#__PURE__*/new WeakSet();
80
77
  class MergeCells extends _base.BasePlugin {
81
78
  constructor() {
@@ -106,32 +103,9 @@ class MergeCells extends _base.BasePlugin {
106
103
  */
107
104
  _defineProperty(this, "selectionCalculations", null);
108
105
  /**
109
- * The holder for the last selected focus coordinates. This allows keeping the correct coordinates in cases after the
110
- * focus is moved out of the merged cell.
111
- *
112
106
  * @type {CellCoords}
113
107
  */
114
- _classPrivateFieldInitSpec(this, _lastSelectedFocus, null);
115
- /**
116
- * The last used transformation delta.
117
- *
118
- * @type {{ row: number, col: number }}
119
- */
120
- _classPrivateFieldInitSpec(this, _lastFocusDelta, {
121
- row: 0,
122
- col: 0
123
- });
124
- /**
125
- * The module responsible for providing the correct focus order (vertical and horizontal) within a selection that
126
- * contains merged cells.
127
- *
128
- * @type {FocusOrder}
129
- */
130
- _classPrivateFieldInitSpec(this, _focusOrder, new _focusOrder2.FocusOrder({
131
- mergedCellsGetter: (row, column) => this.mergedCellsCollection.get(row, column),
132
- rowIndexMapper: this.hot.rowIndexMapper,
133
- columnIndexMapper: this.hot.columnIndexMapper
134
- }));
108
+ _classPrivateFieldInitSpec(this, _lastDesiredCoords, null);
135
109
  }
136
110
  static get PLUGIN_KEY() {
137
111
  return PLUGIN_KEY;
@@ -166,17 +140,17 @@ class MergeCells extends _base.BasePlugin {
166
140
  }
167
141
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterInit).call(_this, ...args);
168
142
  });
169
- this.addHook('modifyTransformFocus', function () {
143
+ this.addHook('modifyTransformStart', function () {
170
144
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
171
145
  args[_key2] = arguments[_key2];
172
146
  }
173
- return _assertClassBrand(_MergeCells_brand, _this, _onModifyTransformFocus).call(_this, ...args);
147
+ return _assertClassBrand(_MergeCells_brand, _this, _onModifyTransformStart).call(_this, ...args);
174
148
  });
175
- this.addHook('modifyTransformStart', function () {
149
+ this.addHook('afterModifyTransformStart', function () {
176
150
  for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
177
151
  args[_key3] = arguments[_key3];
178
152
  }
179
- return _assertClassBrand(_MergeCells_brand, _this, _onModifyTransformStart).call(_this, ...args);
153
+ return _assertClassBrand(_MergeCells_brand, _this, _onAfterModifyTransformStart).call(_this, ...args);
180
154
  });
181
155
  this.addHook('modifyTransformEnd', function () {
182
156
  for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) {
@@ -184,11 +158,11 @@ class MergeCells extends _base.BasePlugin {
184
158
  }
185
159
  return _assertClassBrand(_MergeCells_brand, _this, _onModifyTransformEnd).call(_this, ...args);
186
160
  });
187
- this.addHook('beforeSelectionHighlightSet', function () {
161
+ this.addHook('modifyGetCellCoords', function () {
188
162
  for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
189
163
  args[_key5] = arguments[_key5];
190
164
  }
191
- return _assertClassBrand(_MergeCells_brand, _this, _onBeforeSelectionHighlightSet).call(_this, ...args);
165
+ return _assertClassBrand(_MergeCells_brand, _this, _onModifyGetCellCoords).call(_this, ...args);
192
166
  });
193
167
  this.addHook('beforeSetRangeStart', function () {
194
168
  for (var _len6 = arguments.length, args = new Array(_len6), _key6 = 0; _key6 < _len6; _key6++) {
@@ -202,123 +176,105 @@ class MergeCells extends _base.BasePlugin {
202
176
  }
203
177
  return _assertClassBrand(_MergeCells_brand, _this, _onBeforeSetRangeStart).call(_this, ...args);
204
178
  });
205
- this.addHook('beforeSelectionFocusSet', function () {
179
+ this.addHook('beforeSetRangeEnd', function () {
206
180
  for (var _len8 = arguments.length, args = new Array(_len8), _key8 = 0; _key8 < _len8; _key8++) {
207
181
  args[_key8] = arguments[_key8];
208
182
  }
209
- return _assertClassBrand(_MergeCells_brand, _this, _onBeforeSelectionFocusSet).call(_this, ...args);
183
+ return _assertClassBrand(_MergeCells_brand, _this, _onBeforeSetRangeEnd).call(_this, ...args);
210
184
  });
211
- this.addHook('afterSelectionFocusSet', function () {
185
+ this.addHook('afterIsMultipleSelection', function () {
212
186
  for (var _len9 = arguments.length, args = new Array(_len9), _key9 = 0; _key9 < _len9; _key9++) {
213
187
  args[_key9] = arguments[_key9];
214
188
  }
215
- return _assertClassBrand(_MergeCells_brand, _this, _onAfterSelectionFocusSet).call(_this, ...args);
216
- });
217
- this.addHook('afterSelectionEnd', function () {
218
- for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
219
- args[_key10] = arguments[_key10];
220
- }
221
- return _assertClassBrand(_MergeCells_brand, _this, _onAfterSelectionEnd).call(_this, ...args);
222
- });
223
- this.addHook('modifyGetCellCoords', function () {
224
- for (var _len11 = arguments.length, args = new Array(_len11), _key11 = 0; _key11 < _len11; _key11++) {
225
- args[_key11] = arguments[_key11];
226
- }
227
- return _assertClassBrand(_MergeCells_brand, _this, _onModifyGetCellCoords).call(_this, ...args);
228
- });
229
- this.addHook('afterIsMultipleSelection', function () {
230
- for (var _len12 = arguments.length, args = new Array(_len12), _key12 = 0; _key12 < _len12; _key12++) {
231
- args[_key12] = arguments[_key12];
232
- }
233
189
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterIsMultipleSelection).call(_this, ...args);
234
190
  });
235
191
  this.addHook('afterRenderer', function () {
236
- for (var _len13 = arguments.length, args = new Array(_len13), _key13 = 0; _key13 < _len13; _key13++) {
237
- args[_key13] = arguments[_key13];
192
+ for (var _len10 = arguments.length, args = new Array(_len10), _key10 = 0; _key10 < _len10; _key10++) {
193
+ args[_key10] = arguments[_key10];
238
194
  }
239
195
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterRenderer).call(_this, ...args);
240
196
  });
241
197
  this.addHook('afterContextMenuDefaultOptions', function () {
242
- for (var _len14 = arguments.length, args = new Array(_len14), _key14 = 0; _key14 < _len14; _key14++) {
243
- args[_key14] = arguments[_key14];
198
+ for (var _len11 = arguments.length, args = new Array(_len11), _key11 = 0; _key11 < _len11; _key11++) {
199
+ args[_key11] = arguments[_key11];
244
200
  }
245
201
  return _assertClassBrand(_MergeCells_brand, _this, _addMergeActionsToContextMenu).call(_this, ...args);
246
202
  });
247
203
  this.addHook('afterGetCellMeta', function () {
248
- for (var _len15 = arguments.length, args = new Array(_len15), _key15 = 0; _key15 < _len15; _key15++) {
249
- args[_key15] = arguments[_key15];
204
+ for (var _len12 = arguments.length, args = new Array(_len12), _key12 = 0; _key12 < _len12; _key12++) {
205
+ args[_key12] = arguments[_key12];
250
206
  }
251
207
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterGetCellMeta).call(_this, ...args);
252
208
  });
253
209
  this.addHook('afterViewportRowCalculatorOverride', function () {
254
- for (var _len16 = arguments.length, args = new Array(_len16), _key16 = 0; _key16 < _len16; _key16++) {
255
- args[_key16] = arguments[_key16];
210
+ for (var _len13 = arguments.length, args = new Array(_len13), _key13 = 0; _key13 < _len13; _key13++) {
211
+ args[_key13] = arguments[_key13];
256
212
  }
257
213
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterViewportRowCalculatorOverride).call(_this, ...args);
258
214
  });
259
215
  this.addHook('afterViewportColumnCalculatorOverride', function () {
260
- for (var _len17 = arguments.length, args = new Array(_len17), _key17 = 0; _key17 < _len17; _key17++) {
261
- args[_key17] = arguments[_key17];
216
+ for (var _len14 = arguments.length, args = new Array(_len14), _key14 = 0; _key14 < _len14; _key14++) {
217
+ args[_key14] = arguments[_key14];
262
218
  }
263
219
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterViewportColumnCalculatorOverride).call(_this, ...args);
264
220
  });
265
221
  this.addHook('modifyAutofillRange', function () {
266
- for (var _len18 = arguments.length, args = new Array(_len18), _key18 = 0; _key18 < _len18; _key18++) {
267
- args[_key18] = arguments[_key18];
222
+ for (var _len15 = arguments.length, args = new Array(_len15), _key15 = 0; _key15 < _len15; _key15++) {
223
+ args[_key15] = arguments[_key15];
268
224
  }
269
225
  return _assertClassBrand(_MergeCells_brand, _this, _onModifyAutofillRange).call(_this, ...args);
270
226
  });
271
227
  this.addHook('afterCreateCol', function () {
272
- for (var _len19 = arguments.length, args = new Array(_len19), _key19 = 0; _key19 < _len19; _key19++) {
273
- args[_key19] = arguments[_key19];
228
+ for (var _len16 = arguments.length, args = new Array(_len16), _key16 = 0; _key16 < _len16; _key16++) {
229
+ args[_key16] = arguments[_key16];
274
230
  }
275
231
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterCreateCol).call(_this, ...args);
276
232
  });
277
233
  this.addHook('afterRemoveCol', function () {
278
- for (var _len20 = arguments.length, args = new Array(_len20), _key20 = 0; _key20 < _len20; _key20++) {
279
- args[_key20] = arguments[_key20];
234
+ for (var _len17 = arguments.length, args = new Array(_len17), _key17 = 0; _key17 < _len17; _key17++) {
235
+ args[_key17] = arguments[_key17];
280
236
  }
281
237
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterRemoveCol).call(_this, ...args);
282
238
  });
283
239
  this.addHook('afterCreateRow', function () {
284
- for (var _len21 = arguments.length, args = new Array(_len21), _key21 = 0; _key21 < _len21; _key21++) {
285
- args[_key21] = arguments[_key21];
240
+ for (var _len18 = arguments.length, args = new Array(_len18), _key18 = 0; _key18 < _len18; _key18++) {
241
+ args[_key18] = arguments[_key18];
286
242
  }
287
243
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterCreateRow).call(_this, ...args);
288
244
  });
289
245
  this.addHook('afterRemoveRow', function () {
290
- for (var _len22 = arguments.length, args = new Array(_len22), _key22 = 0; _key22 < _len22; _key22++) {
291
- args[_key22] = arguments[_key22];
246
+ for (var _len19 = arguments.length, args = new Array(_len19), _key19 = 0; _key19 < _len19; _key19++) {
247
+ args[_key19] = arguments[_key19];
292
248
  }
293
249
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterRemoveRow).call(_this, ...args);
294
250
  });
295
251
  this.addHook('afterChange', function () {
296
- for (var _len23 = arguments.length, args = new Array(_len23), _key23 = 0; _key23 < _len23; _key23++) {
297
- args[_key23] = arguments[_key23];
252
+ for (var _len20 = arguments.length, args = new Array(_len20), _key20 = 0; _key20 < _len20; _key20++) {
253
+ args[_key20] = arguments[_key20];
298
254
  }
299
255
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterChange).call(_this, ...args);
300
256
  });
301
257
  this.addHook('beforeDrawBorders', function () {
302
- for (var _len24 = arguments.length, args = new Array(_len24), _key24 = 0; _key24 < _len24; _key24++) {
303
- args[_key24] = arguments[_key24];
258
+ for (var _len21 = arguments.length, args = new Array(_len21), _key21 = 0; _key21 < _len21; _key21++) {
259
+ args[_key21] = arguments[_key21];
304
260
  }
305
261
  return _assertClassBrand(_MergeCells_brand, _this, _onBeforeDrawAreaBorders).call(_this, ...args);
306
262
  });
307
263
  this.addHook('afterDrawSelection', function () {
308
- for (var _len25 = arguments.length, args = new Array(_len25), _key25 = 0; _key25 < _len25; _key25++) {
309
- args[_key25] = arguments[_key25];
264
+ for (var _len22 = arguments.length, args = new Array(_len22), _key22 = 0; _key22 < _len22; _key22++) {
265
+ args[_key22] = arguments[_key22];
310
266
  }
311
267
  return _assertClassBrand(_MergeCells_brand, _this, _onAfterDrawSelection).call(_this, ...args);
312
268
  });
313
269
  this.addHook('beforeRemoveCellClassNames', function () {
314
- for (var _len26 = arguments.length, args = new Array(_len26), _key26 = 0; _key26 < _len26; _key26++) {
315
- args[_key26] = arguments[_key26];
270
+ for (var _len23 = arguments.length, args = new Array(_len23), _key23 = 0; _key23 < _len23; _key23++) {
271
+ args[_key23] = arguments[_key23];
316
272
  }
317
273
  return _assertClassBrand(_MergeCells_brand, _this, _onBeforeRemoveCellClassNames).call(_this, ...args);
318
274
  });
319
275
  this.addHook('beforeBeginEditing', function () {
320
- for (var _len27 = arguments.length, args = new Array(_len27), _key27 = 0; _key27 < _len27; _key27++) {
321
- args[_key27] = arguments[_key27];
276
+ for (var _len24 = arguments.length, args = new Array(_len24), _key24 = 0; _key24 < _len24; _key24++) {
277
+ args[_key24] = arguments[_key24];
322
278
  }
323
279
  return _assertClassBrand(_MergeCells_brand, _this, _onBeforeBeginEditing).call(_this, ...args);
324
280
  });
@@ -488,6 +444,25 @@ class MergeCells extends _base.BasePlugin {
488
444
  return auto ? true : this.validateSetting(newMergedCellInfo);
489
445
  }
490
446
 
447
+ /**
448
+ * Merge or unmerge, based on last selected range.
449
+ *
450
+ * @private
451
+ */
452
+ toggleMergeOnSelection() {
453
+ const currentRange = this.hot.getSelectedRangeLast();
454
+ if (!currentRange) {
455
+ return;
456
+ }
457
+ currentRange.setDirection(this.hot.isRtl() ? 'NE-SW' : 'NW-SE');
458
+ const {
459
+ from,
460
+ to
461
+ } = currentRange;
462
+ this.toggleMerge(currentRange);
463
+ this.hot.selectCell(from.row, from.col, to.row, to.col, false);
464
+ }
465
+
491
466
  /**
492
467
  * Merges the selection provided as a cell range.
493
468
  *
@@ -882,191 +857,94 @@ function _onAfterIsMultipleSelection(isMultiple) {
882
857
  if (isMultiple) {
883
858
  const mergedCells = this.mergedCellsCollection.mergedCells;
884
859
  const selectionRange = this.hot.getSelectedRangeLast();
885
- const topStartCoords = selectionRange.getTopStartCorner();
886
- const bottomEndCoords = selectionRange.getBottomEndCorner();
887
860
  for (let group = 0; group < mergedCells.length; group += 1) {
888
- if (topStartCoords.row === mergedCells[group].row && topStartCoords.col === mergedCells[group].col && bottomEndCoords.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && bottomEndCoords.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
861
+ if (selectionRange.from.row === mergedCells[group].row && selectionRange.from.col === mergedCells[group].col && selectionRange.to.row === mergedCells[group].row + mergedCells[group].rowspan - 1 && selectionRange.to.col === mergedCells[group].col + mergedCells[group].colspan - 1) {
889
862
  return false;
890
863
  }
891
864
  }
892
865
  }
893
866
  return isMultiple;
894
867
  }
895
- /**
896
- * `modifyTransformFocus` hook callback.
897
- *
898
- * @param {object} delta The transformation delta.
899
- */
900
- function _onModifyTransformFocus(delta) {
901
- _classPrivateFieldGet(_lastFocusDelta, this).row = delta.row;
902
- _classPrivateFieldGet(_lastFocusDelta, this).col = delta.col;
903
- }
904
868
  /**
905
869
  * `modifyTransformStart` hook callback.
906
870
  *
907
871
  * @param {object} delta The transformation delta.
908
872
  */
909
873
  function _onModifyTransformStart(delta) {
910
- const selectedRange = this.hot.getSelectedRangeLast();
911
- const {
912
- highlight
913
- } = selectedRange;
914
- const {
915
- columnIndexMapper,
916
- rowIndexMapper
917
- } = this.hot;
918
- if (_classPrivateFieldGet(_lastSelectedFocus, this)) {
919
- if (rowIndexMapper.getRenderableFromVisualIndex(_classPrivateFieldGet(_lastSelectedFocus, this).row) !== null) {
920
- highlight.row = _classPrivateFieldGet(_lastSelectedFocus, this).row;
874
+ const currentlySelectedRange = this.hot.getSelectedRangeLast();
875
+ let newDelta = {
876
+ row: delta.row,
877
+ col: delta.col
878
+ };
879
+ let nextPosition = null;
880
+ const currentPosition = this.hot._createCellCoords(currentlySelectedRange.highlight.row, currentlySelectedRange.highlight.col);
881
+ const mergedParent = this.mergedCellsCollection.get(currentPosition.row, currentPosition.col);
882
+ if (!_classPrivateFieldGet(_lastDesiredCoords, this)) {
883
+ _classPrivateFieldSet(_lastDesiredCoords, this, this.hot._createCellCoords(null, null));
884
+ }
885
+ if (mergedParent) {
886
+ // only merge selected
887
+ const mergeTopLeft = this.hot._createCellCoords(mergedParent.row, mergedParent.col);
888
+ const mergeBottomRight = this.hot._createCellCoords(mergedParent.row + mergedParent.rowspan - 1, mergedParent.col + mergedParent.colspan - 1);
889
+ const mergeRange = this.hot._createCellRange(mergeTopLeft, mergeTopLeft, mergeBottomRight);
890
+ if (!mergeRange.includes(_classPrivateFieldGet(_lastDesiredCoords, this))) {
891
+ _classPrivateFieldSet(_lastDesiredCoords, this, this.hot._createCellCoords(null, null)); // reset outdated version of lastDesiredCoords
921
892
  }
922
- if (columnIndexMapper.getRenderableFromVisualIndex(_classPrivateFieldGet(_lastSelectedFocus, this).col) !== null) {
923
- highlight.col = _classPrivateFieldGet(_lastSelectedFocus, this).col;
893
+ newDelta.row = _classPrivateFieldGet(_lastDesiredCoords, this).row ? _classPrivateFieldGet(_lastDesiredCoords, this).row - currentPosition.row : newDelta.row;
894
+ newDelta.col = _classPrivateFieldGet(_lastDesiredCoords, this).col ? _classPrivateFieldGet(_lastDesiredCoords, this).col - currentPosition.col : newDelta.col;
895
+ if (delta.row > 0) {
896
+ // moving down
897
+ newDelta.row = mergedParent.row + mergedParent.rowspan - 1 - currentPosition.row + delta.row;
898
+ } else if (delta.row < 0) {
899
+ // moving up
900
+ newDelta.row = currentPosition.row - mergedParent.row + delta.row;
901
+ }
902
+ if (delta.col > 0) {
903
+ // moving right
904
+ newDelta.col = mergedParent.col + mergedParent.colspan - 1 - currentPosition.col + delta.col;
905
+ } else if (delta.col < 0) {
906
+ // moving left
907
+ newDelta.col = currentPosition.col - mergedParent.col + delta.col;
924
908
  }
925
- _classPrivateFieldSet(_lastSelectedFocus, this, null);
926
909
  }
927
- const mergedParent = this.mergedCellsCollection.get(highlight.row, highlight.col);
928
- if (!mergedParent) {
929
- return;
910
+ nextPosition = this.hot._createCellCoords(currentlySelectedRange.highlight.row + newDelta.row, currentlySelectedRange.highlight.col + newDelta.col);
911
+ const nextPositionMergedCell = this.mergedCellsCollection.get(nextPosition.row, nextPosition.col);
912
+ if (nextPositionMergedCell) {
913
+ // skipping the invisible cells in the merge range
914
+ const firstRenderableCoords = this.mergedCellsCollection.getFirstRenderableCoords(nextPositionMergedCell.row, nextPositionMergedCell.col);
915
+ _classPrivateFieldSet(_lastDesiredCoords, this, nextPosition);
916
+ newDelta = {
917
+ row: firstRenderableCoords.row - currentPosition.row,
918
+ col: firstRenderableCoords.col - currentPosition.col
919
+ };
930
920
  }
931
- const visualColumnIndexStart = mergedParent.col;
932
- const visualColumnIndexEnd = mergedParent.col + mergedParent.colspan - 1;
933
- if (delta.col < 0) {
934
- const nextColumn = highlight.col >= visualColumnIndexStart && highlight.col <= visualColumnIndexEnd ? visualColumnIndexStart - 1 : visualColumnIndexEnd;
935
- const notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(nextColumn, -1);
936
- if (notHiddenColumnIndex === null) {
937
- // There are no visible columns anymore, so move the selection out of the table edge. This will
938
- // be processed by the selection Transformer class as a move selection to the previous row (if autoWrapRow is enabled).
939
- delta.col = -this.hot.view.countRenderableColumnsInRange(0, highlight.col);
940
- } else {
941
- delta.col = -Math.max(this.hot.view.countRenderableColumnsInRange(notHiddenColumnIndex, highlight.col) - 1, 1);
942
- }
943
- } else if (delta.col > 0) {
944
- const nextColumn = highlight.col >= visualColumnIndexStart && highlight.col <= visualColumnIndexEnd ? visualColumnIndexEnd + 1 : visualColumnIndexStart;
945
- const notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(nextColumn, 1);
946
- if (notHiddenColumnIndex === null) {
947
- // There are no visible columns anymore, so move the selection out of the table edge. This will
948
- // be processed by the selection Transformer class as a move selection to the next row (if autoWrapRow is enabled).
949
- delta.col = this.hot.view.countRenderableColumnsInRange(highlight.col, this.hot.countCols());
950
- } else {
951
- delta.col = Math.max(this.hot.view.countRenderableColumnsInRange(highlight.col, notHiddenColumnIndex) - 1, 1);
952
- }
921
+ if (newDelta.row !== 0) {
922
+ delta.row = newDelta.row;
953
923
  }
954
- const visualRowIndexStart = mergedParent.row;
955
- const visualRowIndexEnd = mergedParent.row + mergedParent.rowspan - 1;
956
- if (delta.row < 0) {
957
- const nextRow = highlight.row >= visualRowIndexStart && highlight.row <= visualRowIndexEnd ? visualRowIndexStart - 1 : visualRowIndexEnd;
958
- const notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(nextRow, -1);
959
- if (notHiddenRowIndex === null) {
960
- // There are no visible rows anymore, so move the selection out of the table edge. This will
961
- // be processed by the selection Transformer class as a move selection to the previous column (if autoWrapCol is enabled).
962
- delta.row = -this.hot.view.countRenderableRowsInRange(0, highlight.row);
963
- } else {
964
- delta.row = -Math.max(this.hot.view.countRenderableRowsInRange(notHiddenRowIndex, highlight.row) - 1, 1);
965
- }
966
- } else if (delta.row > 0) {
967
- const nextRow = highlight.row >= visualRowIndexStart && highlight.row <= visualRowIndexEnd ? visualRowIndexEnd + 1 : visualRowIndexStart;
968
- const notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(nextRow, 1);
969
- if (notHiddenRowIndex === null) {
970
- // There are no visible rows anymore, so move the selection out of the table edge. This will
971
- // be processed by the selection Transformer class as a move selection to the next column (if autoWrapCol is enabled).
972
- delta.row = this.hot.view.countRenderableRowsInRange(highlight.row, this.hot.countRows());
973
- } else {
974
- delta.row = Math.max(this.hot.view.countRenderableRowsInRange(highlight.row, notHiddenRowIndex) - 1, 1);
975
- }
924
+ if (newDelta.col !== 0) {
925
+ delta.col = newDelta.col;
976
926
  }
977
927
  }
978
928
  /**
979
- * The hook allows to modify the delta transformation object necessary for correct selection end transformations.
980
- * The logic here handles "jumping over" merged merged cells, while selecting.
929
+ * `modifyTransformEnd` hook callback. Needed to handle "jumping over" merged merged cells, while selecting.
981
930
  *
982
- * @param {{ row: number, col: number }} delta The transformation delta.
931
+ * @param {object} delta The transformation delta.
983
932
  */
984
933
  function _onModifyTransformEnd(delta) {
985
- const selectedRange = this.hot.getSelectedRangeLast();
986
- const cloneRange = selectedRange.clone();
987
- const {
988
- to
989
- } = selectedRange;
990
- const {
991
- columnIndexMapper,
992
- rowIndexMapper
993
- } = this.hot;
994
- const expandCloneRange = (row, col) => {
995
- cloneRange.expand(this.hot._createCellCoords(row, col));
996
- for (let i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
997
- cloneRange.expandByRange(this.mergedCellsCollection.mergedCells[i].getRange());
998
- }
999
- };
1000
- if (delta.col < 0) {
1001
- let nextColumn = this.mergedCellsCollection.getStartMostColumnIndex(selectedRange, to.col) + delta.col;
1002
- expandCloneRange(to.row, nextColumn);
1003
- if (selectedRange.getHorizontalDirection() === 'E-W' && cloneRange.getHorizontalDirection() === 'E-W') {
1004
- nextColumn = cloneRange.getTopStartCorner().col;
1005
- }
1006
- const notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(nextColumn, 1);
1007
- if (notHiddenColumnIndex !== null) {
1008
- delta.col = -Math.max(this.hot.view.countRenderableColumnsInRange(notHiddenColumnIndex, to.col) - 1, 1);
1009
- }
1010
- } else if (delta.col > 0) {
1011
- let nextColumn = this.mergedCellsCollection.getEndMostColumnIndex(selectedRange, to.col) + delta.col;
1012
- expandCloneRange(to.row, nextColumn);
1013
- if (selectedRange.getHorizontalDirection() === 'W-E' && cloneRange.getHorizontalDirection() === 'W-E') {
1014
- nextColumn = cloneRange.getBottomEndCorner().col;
1015
- }
1016
- const notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(nextColumn, -1);
1017
- if (notHiddenColumnIndex !== null) {
1018
- delta.col = Math.max(this.hot.view.countRenderableColumnsInRange(to.col, notHiddenColumnIndex) - 1, 1);
1019
- }
1020
- }
1021
- if (delta.row < 0) {
1022
- let nextRow = this.mergedCellsCollection.getTopMostRowIndex(selectedRange, to.row) + delta.row;
1023
- expandCloneRange(nextRow, to.col);
1024
- if (selectedRange.getVerticalDirection() === 'S-N' && cloneRange.getVerticalDirection() === 'S-N') {
1025
- nextRow = cloneRange.getTopStartCorner().row;
1026
- }
1027
- const notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(nextRow, 1);
1028
- if (notHiddenRowIndex !== null) {
1029
- delta.row = -Math.max(this.hot.view.countRenderableRowsInRange(notHiddenRowIndex, to.row) - 1, 1);
1030
- }
1031
- } else if (delta.row > 0) {
1032
- let nextRow = this.mergedCellsCollection.getBottomMostRowIndex(selectedRange, to.row) + delta.row;
1033
- expandCloneRange(nextRow, to.col);
1034
- if (selectedRange.getVerticalDirection() === 'N-S' && cloneRange.getVerticalDirection() === 'N-S') {
1035
- nextRow = cloneRange.getBottomStartCorner().row;
1036
- }
1037
- const notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(nextRow, -1);
1038
- if (notHiddenRowIndex !== null) {
1039
- delta.row = Math.max(this.hot.view.countRenderableRowsInRange(to.row, notHiddenRowIndex) - 1, 1);
1040
- }
1041
- }
1042
- }
1043
- /**
1044
- * The hook corrects the range (before drawing it) after the selection was made on the merged cells.
1045
- * It expands the range to cover the entire area of the selected merged cells.
1046
- */
1047
- function _onBeforeSelectionHighlightSet() {
1048
- const selectedRange = this.hot.getSelectedRangeLast();
1049
- const {
1050
- highlight
1051
- } = selectedRange;
1052
- if (this.hot.selection.isSelectedByColumnHeader() || this.hot.selection.isSelectedByRowHeader()) {
1053
- _classPrivateFieldSet(_lastSelectedFocus, this, highlight.clone());
1054
- return;
1055
- }
1056
- for (let i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
1057
- selectedRange.expandByRange(this.mergedCellsCollection.mergedCells[i].getRange(), false);
1058
- }
1059
- // TODO: This is a workaround for an issue with the selection not being extended properly.
1060
- // In some cases when the merge cells are defined in random order the selection is not
1061
- // extended in that way that it covers all overlapped merge cells.
1062
- for (let i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
1063
- selectedRange.expandByRange(this.mergedCellsCollection.mergedCells[i].getRange(), false);
1064
- }
1065
- const mergedParent = this.mergedCellsCollection.get(highlight.row, highlight.col);
1066
- _classPrivateFieldSet(_lastSelectedFocus, this, highlight.clone());
1067
- if (mergedParent) {
1068
- highlight.assign(mergedParent);
1069
- }
934
+ const currentSelectionRange = this.hot.getSelectedRangeLast();
935
+ const newDelta = (0, _object.clone)(delta);
936
+ const newSelectionRange = this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, delta);
937
+ let tempDelta = (0, _object.clone)(newDelta);
938
+ const mergedCellsWithinRange = this.mergedCellsCollection.getWithinRange(newSelectionRange, true);
939
+ do {
940
+ tempDelta = (0, _object.clone)(newDelta);
941
+ this.selectionCalculations.getUpdatedSelectionRange(currentSelectionRange, newDelta);
942
+ (0, _array.arrayEach)(mergedCellsWithinRange, mergedCell => {
943
+ this.selectionCalculations.snapDelta(newDelta, currentSelectionRange, mergedCell);
944
+ });
945
+ } while (newDelta.row !== tempDelta.row || newDelta.col !== tempDelta.col);
946
+ delta.row = newDelta.row;
947
+ delta.col = newDelta.col;
1070
948
  }
1071
949
  /**
1072
950
  * `modifyGetCellCoords` hook callback. Swaps the `getCell` coords with the merged parent coords.
@@ -1145,104 +1023,51 @@ function _onAfterRenderer(TD, row, col) {
1145
1023
  (0, _utils.applySpanProperties)(TD, mergedCellCopy, row, col);
1146
1024
  }
1147
1025
  /**
1148
- * Clears the last selected coordinates before setting a new selection range.
1149
- */
1150
- function _onBeforeSetRangeStart() {
1151
- _classPrivateFieldSet(_lastSelectedFocus, this, null);
1152
- }
1153
- /**
1154
- * Detects if the last selected cell was a header cell if so update the order list active node for further
1155
- * computations.
1156
- */
1157
- function _onBeforeSelectionFocusSet() {
1158
- if (_classPrivateFieldGet(_lastSelectedFocus, this).isCell()) {
1159
- return;
1160
- }
1161
- const selectedRange = this.hot.getSelectedRangeLast();
1162
- const verticalDir = selectedRange.getVerticalDirection();
1163
- const horizontalDir = selectedRange.getHorizontalDirection();
1164
- const focusCoords = _classPrivateFieldGet(_lastSelectedFocus, this).clone().normalize();
1165
- _classPrivateFieldGet(_focusOrder, this).setActiveNode(focusCoords.row, focusCoords.col);
1166
- if (_classPrivateFieldGet(_lastFocusDelta, this).row > 0 || _classPrivateFieldGet(_lastFocusDelta, this).col > 0) {
1167
- _classPrivateFieldGet(_focusOrder, this).setPrevNodeAsActive();
1168
- } else if (horizontalDir === 'E-W' && _classPrivateFieldGet(_lastFocusDelta, this).col < 0 || verticalDir === 'S-N' && _classPrivateFieldGet(_lastFocusDelta, this).row < 0) {
1169
- _classPrivateFieldGet(_focusOrder, this).setNextNodeAsActive();
1170
- }
1171
- }
1172
- /**
1173
- * Changes the focus selection to the next or previous cell or merged cell position.
1026
+ * `beforeSetRangeStart` and `beforeSetRangeStartOnly` hook callback.
1027
+ * A selection within merge area should be rewritten to the start of merge area.
1174
1028
  *
1175
- * @param {number} row The visual row index.
1176
- * @param {number} column The visual column index.
1029
+ * @param {object} coords Cell coords.
1177
1030
  */
1178
- function _onAfterSelectionFocusSet(row, column) {
1179
- const selectedRange = this.hot.getSelectedRangeLast();
1180
- const {
1181
- columnIndexMapper,
1182
- rowIndexMapper
1183
- } = this.hot;
1184
- let notHiddenRowIndex = null;
1185
- let notHiddenColumnIndex = null;
1186
- if (_classPrivateFieldGet(_lastFocusDelta, this).col < 0) {
1187
- const {
1188
- rowEnd,
1189
- colEnd
1190
- } = _classPrivateFieldGet(_focusOrder, this).getPrevHorizontalNode();
1191
- notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(colEnd, -1);
1192
- notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(rowEnd, -1);
1193
- } else if (_classPrivateFieldGet(_lastFocusDelta, this).col > 0) {
1194
- const {
1195
- rowStart,
1196
- colStart
1197
- } = _classPrivateFieldGet(_focusOrder, this).getNextHorizontalNode();
1198
- notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(colStart, 1);
1199
- notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(rowStart, 1);
1200
- } else if (_classPrivateFieldGet(_lastFocusDelta, this).row < 0) {
1201
- const {
1202
- rowEnd,
1203
- colEnd
1204
- } = _classPrivateFieldGet(_focusOrder, this).getPrevVerticalNode();
1205
- notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(colEnd, -1);
1206
- notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(rowEnd, -1);
1207
- } else if (_classPrivateFieldGet(_lastFocusDelta, this).row > 0) {
1208
- const {
1209
- rowStart,
1210
- colStart
1211
- } = _classPrivateFieldGet(_focusOrder, this).getNextVerticalNode();
1212
- notHiddenColumnIndex = columnIndexMapper.getNearestNotHiddenIndex(colStart, 1);
1213
- notHiddenRowIndex = rowIndexMapper.getNearestNotHiddenIndex(rowStart, 1);
1214
- }
1215
- if (notHiddenRowIndex !== null || notHiddenColumnIndex !== null) {
1216
- const coords = this.hot._createCellCoords(notHiddenRowIndex, notHiddenColumnIndex);
1031
+ function _onBeforeSetRangeStart(coords) {
1032
+ // TODO: It is a workaround, but probably this hook may be needed. Every selection on the merge area
1033
+ // could set start point of the selection to the start of the merge area. However, logic inside `expandByRange` need
1034
+ // an initial start point. Click on the merge cell when there are some hidden indexes break the logic in some cases.
1035
+ // Please take a look at #7010 for more information. I'm not sure if selection directions are calculated properly
1036
+ // and what was idea for flipping direction inside `expandByRange` method.
1037
+ if (this.mergedCellsCollection.isFirstRenderableMergedCell(coords.row, coords.col)) {
1217
1038
  const mergeParent = this.mergedCellsCollection.get(coords.row, coords.col);
1218
- const focusHighlight = this.hot.selection.highlight.getFocus();
1219
- row = coords.row;
1220
- column = coords.col;
1221
- if (mergeParent) {
1222
- selectedRange.highlight.assign({
1223
- row: this.hot.rowIndexMapper.getNearestNotHiddenIndex(mergeParent.row, 1),
1224
- col: this.hot.columnIndexMapper.getNearestNotHiddenIndex(mergeParent.col, 1)
1225
- });
1226
- } else {
1227
- selectedRange.highlight.assign(coords);
1228
- }
1229
- focusHighlight.clear();
1230
- focusHighlight.add(coords).commit();
1039
+ [coords.row, coords.col] = [mergeParent.row, mergeParent.col];
1231
1040
  }
1232
- _classPrivateFieldGet(_focusOrder, this).setActiveNode(row, column);
1233
- _classPrivateFieldSet(_lastFocusDelta, this, {
1234
- row: 0,
1235
- col: 0
1236
- });
1237
1041
  }
1238
1042
  /**
1239
- * Creates the horizontal and vertical cells order matrix (linked lists) for focused cell.
1043
+ * `beforeSetRangeEnd` hook callback.
1044
+ * While selecting cells with keyboard or mouse, make sure that rectangular area is expanded to the extent of the
1045
+ * merged cell.
1046
+ *
1047
+ * Note: Please keep in mind that callback may modify both start and end range coordinates by the reference.
1048
+ *
1049
+ * @param {object} coords Cell coords.
1240
1050
  */
1241
- function _onAfterSelectionEnd() {
1242
- const selection = this.hot.getSelectedRangeLast();
1243
- if (!selection.isHeader()) {
1244
- _classPrivateFieldGet(_focusOrder, this).buildFocusOrder(this.hot.getSelectedRangeLast());
1051
+ function _onBeforeSetRangeEnd(coords) {
1052
+ const selRange = this.hot.getSelectedRangeLast();
1053
+ selRange.highlight = this.hot._createCellCoords(selRange.highlight.row, selRange.highlight.col); // clone in case we will modify its reference
1054
+ selRange.to = coords;
1055
+ let rangeExpanded = false;
1056
+ if (this.hot.selection.isSelectedByColumnHeader() || this.hot.selection.isSelectedByRowHeader()) {
1057
+ return;
1245
1058
  }
1059
+ do {
1060
+ rangeExpanded = false;
1061
+ for (let i = 0; i < this.mergedCellsCollection.mergedCells.length; i += 1) {
1062
+ const cellInfo = this.mergedCellsCollection.mergedCells[i];
1063
+ const mergedCellRange = cellInfo.getRange();
1064
+ if (selRange.expandByRange(mergedCellRange)) {
1065
+ coords.row = selRange.to.row;
1066
+ coords.col = selRange.to.col;
1067
+ rangeExpanded = true;
1068
+ }
1069
+ }
1070
+ } while (rangeExpanded);
1246
1071
  }
1247
1072
  /**
1248
1073
  * The `afterGetCellMeta` hook callback.
@@ -1371,6 +1196,37 @@ function _onBeforeDrawAreaBorders(corners, className) {
1371
1196
  });
1372
1197
  }
1373
1198
  }
1199
+ /**
1200
+ * `afterModifyTransformStart` hook callback. Fixes a problem with navigating through merged cells at the edges of
1201
+ * the table with the <kbd>**Enter**</kbd>/<kbd>**Shift**</kbd>+<kbd>**Enter**</kbd>/<kbd>**Tab**</kbd>/<kbd>**Shift**</kbd>+<kbd>**Tab**</kbd> keys.
1202
+ *
1203
+ * @param {CellCoords} coords Coordinates of the to-be-selected cell.
1204
+ * @param {number} rowTransformDir Row transformation direction (negative value = up, 0 = none, positive value =
1205
+ * down).
1206
+ * @param {number} colTransformDir Column transformation direction (negative value = up, 0 = none, positive value =
1207
+ * down).
1208
+ */
1209
+ function _onAfterModifyTransformStart(coords, rowTransformDir, colTransformDir) {
1210
+ if (!this.enabled) {
1211
+ return;
1212
+ }
1213
+ const mergedCellAtCoords = this.mergedCellsCollection.get(coords.row, coords.col);
1214
+ if (!mergedCellAtCoords) {
1215
+ return;
1216
+ }
1217
+ const goingDown = rowTransformDir > 0;
1218
+ const goingUp = rowTransformDir < 0;
1219
+ const goingLeft = colTransformDir < 0;
1220
+ const goingRight = colTransformDir > 0;
1221
+ const mergedCellOnBottomEdge = mergedCellAtCoords.row + mergedCellAtCoords.rowspan - 1 === this.hot.countRows() - 1;
1222
+ const mergedCellOnTopEdge = mergedCellAtCoords.row === 0;
1223
+ const mergedCellOnRightEdge = mergedCellAtCoords.col + mergedCellAtCoords.colspan - 1 === this.hot.countCols() - 1;
1224
+ const mergedCellOnLeftEdge = mergedCellAtCoords.col === 0;
1225
+ if (goingDown && mergedCellOnBottomEdge || goingUp && mergedCellOnTopEdge || goingRight && mergedCellOnRightEdge || goingLeft && mergedCellOnLeftEdge) {
1226
+ coords.row = mergedCellAtCoords.row;
1227
+ coords.col = mergedCellAtCoords.col;
1228
+ }
1229
+ }
1374
1230
  /**
1375
1231
  * `afterDrawSelection` hook callback. Used to add the additional class name for the entirely-selected merged cells.
1376
1232
  *