handsontable 0.0.0-next-d96e9b5-20240220 → 0.0.0-next-d4816a9-20240221

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 (89) hide show
  1. package/3rdparty/walkontable/src/cell/range.d.ts +0 -1
  2. package/3rdparty/walkontable/src/cell/range.js +0 -12
  3. package/3rdparty/walkontable/src/cell/range.mjs +0 -12
  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.js +0 -14
  9. package/core.mjs +0 -14
  10. package/dist/handsontable.css +2 -2
  11. package/dist/handsontable.full.css +2 -2
  12. package/dist/handsontable.full.js +1328 -1606
  13. package/dist/handsontable.full.min.css +2 -2
  14. package/dist/handsontable.full.min.js +151 -151
  15. package/dist/handsontable.js +1328 -1606
  16. package/dist/handsontable.min.css +2 -2
  17. package/dist/handsontable.min.js +19 -19
  18. package/editorManager.js +8 -12
  19. package/editorManager.mjs +8 -12
  20. package/helpers/mixed.js +1 -1
  21. package/helpers/mixed.mjs +1 -1
  22. package/package.json +1 -1
  23. package/pluginHooks.d.ts +0 -1
  24. package/pluginHooks.js +1 -43
  25. package/pluginHooks.mjs +1 -43
  26. package/plugins/collapsibleColumns/collapsibleColumns.js +1 -7
  27. package/plugins/collapsibleColumns/collapsibleColumns.mjs +1 -7
  28. package/plugins/columnSorting/columnSorting.js +0 -6
  29. package/plugins/columnSorting/columnSorting.mjs +0 -6
  30. package/plugins/contextMenu/menu/defaultShortcutsList.js +10 -26
  31. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +10 -26
  32. package/plugins/mergeCells/calculations/selection.js +70 -1
  33. package/plugins/mergeCells/calculations/selection.mjs +70 -1
  34. package/plugins/mergeCells/contextMenuItem/toggleMerge.js +1 -11
  35. package/plugins/mergeCells/contextMenuItem/toggleMerge.mjs +1 -11
  36. package/plugins/mergeCells/mergeCells.js +207 -182
  37. package/plugins/mergeCells/mergeCells.mjs +207 -182
  38. package/plugins/multiColumnSorting/multiColumnSorting.js +0 -6
  39. package/plugins/multiColumnSorting/multiColumnSorting.mjs +0 -6
  40. package/plugins/nestedHeaders/nestedHeaders.js +0 -1
  41. package/plugins/nestedHeaders/nestedHeaders.mjs +0 -1
  42. package/plugins/nestedRows/nestedRows.js +1 -7
  43. package/plugins/nestedRows/nestedRows.mjs +1 -7
  44. package/renderers/checkboxRenderer/checkboxRenderer.js +4 -4
  45. package/renderers/checkboxRenderer/checkboxRenderer.mjs +4 -4
  46. package/selection/highlight/visualSelection.js +0 -2
  47. package/selection/highlight/visualSelection.mjs +0 -2
  48. package/selection/selection.js +34 -195
  49. package/selection/selection.mjs +33 -194
  50. package/selection/transformation.js +30 -45
  51. package/selection/transformation.mjs +30 -45
  52. package/shortcutContexts/commands/editor/closeAndSave.js +2 -2
  53. package/shortcutContexts/commands/editor/closeAndSave.mjs +2 -2
  54. package/shortcutContexts/commands/editor/open.js +3 -18
  55. package/shortcutContexts/commands/editor/open.mjs +3 -18
  56. package/shortcutContexts/commands/extendCellsSelection/down.js +1 -1
  57. package/shortcutContexts/commands/extendCellsSelection/down.mjs +1 -1
  58. package/shortcutContexts/commands/extendCellsSelection/left.js +1 -1
  59. package/shortcutContexts/commands/extendCellsSelection/left.mjs +1 -1
  60. package/shortcutContexts/commands/extendCellsSelection/right.js +1 -1
  61. package/shortcutContexts/commands/extendCellsSelection/right.mjs +1 -1
  62. package/shortcutContexts/commands/extendCellsSelection/toColumns.js +1 -1
  63. package/shortcutContexts/commands/extendCellsSelection/toColumns.mjs +1 -1
  64. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.js +1 -3
  65. package/shortcutContexts/commands/extendCellsSelection/toMostBottom.mjs +1 -3
  66. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.js +3 -9
  67. package/shortcutContexts/commands/extendCellsSelection/toMostInlineEnd.mjs +3 -9
  68. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.js +3 -10
  69. package/shortcutContexts/commands/extendCellsSelection/toMostInlineStart.mjs +3 -10
  70. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.js +1 -3
  71. package/shortcutContexts/commands/extendCellsSelection/toMostLeft.mjs +1 -3
  72. package/shortcutContexts/commands/extendCellsSelection/toMostRight.js +1 -3
  73. package/shortcutContexts/commands/extendCellsSelection/toMostRight.mjs +1 -3
  74. package/shortcutContexts/commands/extendCellsSelection/toMostTop.js +1 -3
  75. package/shortcutContexts/commands/extendCellsSelection/toMostTop.mjs +1 -3
  76. package/shortcutContexts/commands/extendCellsSelection/toRows.js +1 -1
  77. package/shortcutContexts/commands/extendCellsSelection/toRows.mjs +1 -1
  78. package/shortcutContexts/commands/extendCellsSelection/up.js +1 -1
  79. package/shortcutContexts/commands/extendCellsSelection/up.mjs +1 -1
  80. package/shortcutContexts/commands/moveCellSelection/inlineEnd.js +1 -6
  81. package/shortcutContexts/commands/moveCellSelection/inlineEnd.mjs +1 -6
  82. package/shortcutContexts/commands/moveCellSelection/inlineStart.js +1 -6
  83. package/shortcutContexts/commands/moveCellSelection/inlineStart.mjs +1 -6
  84. package/shortcutContexts/grid.js +2 -2
  85. package/shortcutContexts/grid.mjs +2 -2
  86. package/shortcuts/context.js +1 -2
  87. package/shortcuts/context.mjs +1 -2
  88. package/core/viewportScroll/scrollStrategies/focusScroll.js +0 -15
  89. package/core/viewportScroll/scrollStrategies/focusScroll.mjs +0 -11
package/editorManager.js CHANGED
@@ -318,22 +318,18 @@ class EditorManager {
318
318
  }
319
319
 
320
320
  /**
321
- * Controls selection's behavior after clicking `Enter`.
321
+ * Controls selection's behaviour after clicking `Enter`.
322
322
  *
323
323
  * @private
324
- * @param {KeyboardEvent} event The keyboard event object.
324
+ * @param {boolean} isShiftPressed If `true`, then the selection will move up after hit enter.
325
325
  */
326
- moveSelectionAfterEnter(event) {
327
- const enterMoves = {
328
- ...(typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves)
329
- };
330
- if (event.shiftKey) {
331
- enterMoves.row = -enterMoves.row;
332
- enterMoves.col = -enterMoves.col;
333
- }
334
- if (this.hot.selection.isMultiple()) {
335
- this.selection.transformFocus(enterMoves.row, enterMoves.col);
326
+ moveSelectionAfterEnter(isShiftPressed) {
327
+ const enterMoves = typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves;
328
+ if (isShiftPressed) {
329
+ // move selection up
330
+ this.selection.transformStart(-enterMoves.row, -enterMoves.col);
336
331
  } else {
332
+ // move selection down (add a new row if needed)
337
333
  this.selection.transformStart(enterMoves.row, enterMoves.col, true);
338
334
  }
339
335
  }
package/editorManager.mjs CHANGED
@@ -314,22 +314,18 @@ class EditorManager {
314
314
  }
315
315
 
316
316
  /**
317
- * Controls selection's behavior after clicking `Enter`.
317
+ * Controls selection's behaviour after clicking `Enter`.
318
318
  *
319
319
  * @private
320
- * @param {KeyboardEvent} event The keyboard event object.
320
+ * @param {boolean} isShiftPressed If `true`, then the selection will move up after hit enter.
321
321
  */
322
- moveSelectionAfterEnter(event) {
323
- const enterMoves = {
324
- ...(typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves)
325
- };
326
- if (event.shiftKey) {
327
- enterMoves.row = -enterMoves.row;
328
- enterMoves.col = -enterMoves.col;
329
- }
330
- if (this.hot.selection.isMultiple()) {
331
- this.selection.transformFocus(enterMoves.row, enterMoves.col);
322
+ moveSelectionAfterEnter(isShiftPressed) {
323
+ const enterMoves = typeof this.tableMeta.enterMoves === 'function' ? this.tableMeta.enterMoves(event) : this.tableMeta.enterMoves;
324
+ if (isShiftPressed) {
325
+ // move selection up
326
+ this.selection.transformStart(-enterMoves.row, -enterMoves.col);
332
327
  } else {
328
+ // move selection down (add a new row if needed)
333
329
  this.selection.transformStart(enterMoves.row, enterMoves.col, true);
334
330
  }
335
331
  }
package/helpers/mixed.js CHANGED
@@ -134,7 +134,7 @@ const domMessages = {
134
134
  function _injectProductInfo(key, element) {
135
135
  const hasValidType = !isEmpty(key);
136
136
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
137
- const hotVersion = "0.0.0-next-d96e9b5-20240220";
137
+ const hotVersion = "0.0.0-next-d4816a9-20240221";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
package/helpers/mixed.mjs CHANGED
@@ -124,7 +124,7 @@ const domMessages = {
124
124
  export function _injectProductInfo(key, element) {
125
125
  const hasValidType = !isEmpty(key);
126
126
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
127
- const hotVersion = "0.0.0-next-d96e9b5-20240220";
127
+ const hotVersion = "0.0.0-next-d4816a9-20240221";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "url": "https://github.com/handsontable/handsontable/issues"
11
11
  },
12
12
  "author": "Handsoncode <hello@handsontable.com>",
13
- "version": "0.0.0-next-d96e9b5-20240220",
13
+ "version": "0.0.0-next-d4816a9-20240221",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
package/pluginHooks.d.ts CHANGED
@@ -133,7 +133,6 @@ export interface Events {
133
133
  afterSelectionByProp?: (row: number, prop: string, row2: number, prop2: string, preventScrolling: { value: boolean }, selectionLayerLevel: number) => void;
134
134
  afterSelectionEnd?: (row: number, column: number, row2: number, column2: number, selectionLayerLevel: number) => void;
135
135
  afterSelectionEndByProp?: (row: number, prop: string, row2: number, prop2: string, selectionLayerLevel: number) => void;
136
- afterSelectionFocusSet?: (row: number, column: number, preventScrolling: { value: boolean }) => void;
137
136
  afterSelectRows?: (from: CellCoords, to: CellCoords, highlight: CellCoords) => void;
138
137
  afterSetCellMeta?: (row: number, column: number, key: string, value: any) => void;
139
138
  afterSetDataAtCell?: (changes: CellChange[], source?: ChangeSource) => void;
package/pluginHooks.js CHANGED
@@ -650,9 +650,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
650
650
  * @param {string} prop Selection start data source object property name.
651
651
  * @param {number} row2 Selection end visual row index.
652
652
  * @param {string} prop2 Selection end data source object property name.
653
- * @param {object} preventScrolling A reference to the observable object with the `value` property.
654
- * Property `preventScrolling.value` expects a boolean value that
655
- * Handsontable uses to control scroll behavior after selection.
653
+ * @param {object} preventScrolling Object with `value` property where its value change will be observed.
656
654
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
657
655
  * @example
658
656
  * ```js
@@ -702,46 +700,6 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
702
700
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
703
701
  */
704
702
  'afterSelectionEndByProp',
705
- /**
706
- * Fired after the focus position within a selected range is changed.
707
- *
708
- * @since 14.2.0
709
- * @event Hooks#afterSelectionFocusSet
710
- * @param {number} row The focus visual row index position.
711
- * @param {number} column The focus visual column index position.
712
- * @param {object} preventScrolling A reference to the observable object with the `value` property.
713
- * Property `preventScrolling.value` expects a boolean value that
714
- * Handsontable uses to control scroll behavior after selection.
715
- * @example
716
- * ```js
717
- * ::: only-for javascript
718
- * new Handsontable(element, {
719
- * afterSelectionFocusSet: (row, column, preventScrolling) => {
720
- * // If set to `false` (default): when focused cell selection is outside the viewport,
721
- * // Handsontable scrolls the viewport to that cell.
722
- * // If set to `true`: when focused cell selection is outside the viewport,
723
- * // Handsontable doesn't scroll the viewport.
724
- * preventScrolling.value = true;
725
- * }
726
- * })
727
- * ```
728
- * :::
729
- *
730
- * ::: only-for react
731
- * ```jsx
732
- * <HotTable
733
- * afterSelectionFocusSet={(row, column, preventScrolling) => {
734
- * // If set to `false` (default): when focused cell selection is outside the viewport,
735
- * // Handsontable scrolls the viewport to that cell.
736
- * // If set to `true`: when focused cell selection is outside the viewport,
737
- * // Handsontable doesn't scroll the viewport.
738
- * preventScrolling.value = true;
739
- * }}
740
- * />
741
- * ```
742
- * :::
743
- */
744
- 'afterSelectionFocusSet',
745
703
  /**
746
704
  * Fired before one or more columns are selected (e.g. During mouse header click or {@link Core#selectColumns} API call).
747
705
  *
package/pluginHooks.mjs CHANGED
@@ -646,9 +646,7 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
646
646
  * @param {string} prop Selection start data source object property name.
647
647
  * @param {number} row2 Selection end visual row index.
648
648
  * @param {string} prop2 Selection end data source object property name.
649
- * @param {object} preventScrolling A reference to the observable object with the `value` property.
650
- * Property `preventScrolling.value` expects a boolean value that
651
- * Handsontable uses to control scroll behavior after selection.
649
+ * @param {object} preventScrolling Object with `value` property where its value change will be observed.
652
650
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
653
651
  * @example
654
652
  * ```js
@@ -698,46 +696,6 @@ const REGISTERED_HOOKS = [/* eslint-disable jsdoc/require-description-complete-s
698
696
  * @param {number} selectionLayerLevel The number which indicates what selection layer is currently modified.
699
697
  */
700
698
  'afterSelectionEndByProp',
701
- /**
702
- * Fired after the focus position within a selected range is changed.
703
- *
704
- * @since 14.2.0
705
- * @event Hooks#afterSelectionFocusSet
706
- * @param {number} row The focus visual row index position.
707
- * @param {number} column The focus visual column index position.
708
- * @param {object} preventScrolling A reference to the observable object with the `value` property.
709
- * Property `preventScrolling.value` expects a boolean value that
710
- * Handsontable uses to control scroll behavior after selection.
711
- * @example
712
- * ```js
713
- * ::: only-for javascript
714
- * new Handsontable(element, {
715
- * afterSelectionFocusSet: (row, column, preventScrolling) => {
716
- * // If set to `false` (default): when focused cell selection is outside the viewport,
717
- * // Handsontable scrolls the viewport to that cell.
718
- * // If set to `true`: when focused cell selection is outside the viewport,
719
- * // Handsontable doesn't scroll the viewport.
720
- * preventScrolling.value = true;
721
- * }
722
- * })
723
- * ```
724
- * :::
725
- *
726
- * ::: only-for react
727
- * ```jsx
728
- * <HotTable
729
- * afterSelectionFocusSet={(row, column, preventScrolling) => {
730
- * // If set to `false` (default): when focused cell selection is outside the viewport,
731
- * // Handsontable scrolls the viewport to that cell.
732
- * // If set to `true`: when focused cell selection is outside the viewport,
733
- * // Handsontable doesn't scroll the viewport.
734
- * preventScrolling.value = true;
735
- * }}
736
- * />
737
- * ```
738
- * :::
739
- */
740
- 'afterSelectionFocusSet',
741
699
  /**
742
700
  * Fired before one or more columns are selected (e.g. During mouse header click or {@link Core#selectColumns} API call).
743
701
  *
@@ -9,7 +9,6 @@ var _number = require("../../helpers/number");
9
9
  var _console = require("../../helpers/console");
10
10
  var _element = require("../../helpers/dom/element");
11
11
  var _event = require("../../helpers/dom/event");
12
- var _shortcutContexts = require("../../shortcutContexts");
13
12
  var _a11y = require("../../helpers/a11y");
14
13
  function _classPrivateMethodInitSpec(obj, privateSet) { _checkPrivateRedeclaration(obj, privateSet); privateSet.add(obj); }
15
14
  function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); }
@@ -309,17 +308,12 @@ class CollapsibleColumns extends _base.BasePlugin {
309
308
  col: columnIndex
310
309
  });
311
310
  }
312
-
313
- // prevent default Enter behavior (move to the next row within a selection range)
314
- return false;
315
311
  },
316
312
  runOnlyIf: () => {
317
313
  var _this$hot$getSelected;
318
314
  return (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight.isHeader();
319
315
  },
320
- group: SHORTCUTS_GROUP,
321
- relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
322
- position: 'before'
316
+ group: SHORTCUTS_GROUP
323
317
  });
324
318
  }
325
319
 
@@ -18,7 +18,6 @@ import { rangeEach } from "../../helpers/number.mjs";
18
18
  import { warn } from "../../helpers/console.mjs";
19
19
  import { addClass, hasClass, removeClass, fastInnerText, removeAttribute, setAttribute } from "../../helpers/dom/element.mjs";
20
20
  import { stopImmediatePropagation } from "../../helpers/dom/event.mjs";
21
- import { EDITOR_EDIT_GROUP as SHORTCUTS_GROUP_EDITOR } from "../../shortcutContexts/index.mjs";
22
21
  import { A11Y_EXPANDED, A11Y_HIDDEN } from "../../helpers/a11y.mjs";
23
22
  export const PLUGIN_KEY = 'collapsibleColumns';
24
23
  export const PLUGIN_PRIORITY = 290;
@@ -306,17 +305,12 @@ export class CollapsibleColumns extends BasePlugin {
306
305
  col: columnIndex
307
306
  });
308
307
  }
309
-
310
- // prevent default Enter behavior (move to the next row within a selection range)
311
- return false;
312
308
  },
313
309
  runOnlyIf: () => {
314
310
  var _this$hot$getSelected;
315
311
  return (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight.isHeader();
316
312
  },
317
- group: SHORTCUTS_GROUP,
318
- relativeToGroup: SHORTCUTS_GROUP_EDITOR,
319
- position: 'before'
313
+ group: SHORTCUTS_GROUP
320
314
  });
321
315
  }
322
316
 
@@ -12,7 +12,6 @@ var _base = require("../base");
12
12
  var _translations = require("../../translations");
13
13
  var _pluginHooks = _interopRequireDefault(require("../../pluginHooks"));
14
14
  var _columnStatesManager = require("./columnStatesManager");
15
- var _shortcutContexts = require("../../shortcutContexts");
16
15
  var _utils = require("./utils");
17
16
  var _domHelpers = require("./domHelpers");
18
17
  var _rootComparator = require("./rootComparator");
@@ -250,17 +249,12 @@ class ColumnSorting extends _base.BasePlugin {
250
249
  if (highlight.row === -1 && highlight.col >= 0) {
251
250
  this.sort(this.getColumnNextConfig(highlight.col));
252
251
  }
253
-
254
- // prevent default Enter behavior (move to the next row within a selection range)
255
- return false;
256
252
  },
257
253
  runOnlyIf: () => {
258
254
  var _this$hot$getSelected;
259
255
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
260
256
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
261
257
  },
262
- relativeToGroup: _shortcutContexts.EDITOR_EDIT_GROUP,
263
- position: 'before',
264
258
  group: SHORTCUTS_GROUP
265
259
  });
266
260
  }
@@ -15,7 +15,6 @@ import { BasePlugin } from "../base/index.mjs";
15
15
  import { IndexesSequence, PhysicalIndexToValueMap as IndexToValueMap } from "../../translations/index.mjs";
16
16
  import Hooks from "../../pluginHooks.mjs";
17
17
  import { ColumnStatesManager } from "./columnStatesManager.mjs";
18
- import { EDITOR_EDIT_GROUP as SHORTCUTS_GROUP_EDITOR } from "../../shortcutContexts/index.mjs";
19
18
  import { HEADER_SPAN_CLASS, getNextSortOrder, areValidSortStates, getHeaderSpanElement, isFirstLevelColumnHeader, wasHeaderClickedProperly } from "./utils.mjs";
20
19
  import { getClassesToRemove, getClassesToAdd } from "./domHelpers.mjs";
21
20
  import { rootComparator } from "./rootComparator.mjs";
@@ -246,17 +245,12 @@ export class ColumnSorting extends BasePlugin {
246
245
  if (highlight.row === -1 && highlight.col >= 0) {
247
246
  this.sort(this.getColumnNextConfig(highlight.col));
248
247
  }
249
-
250
- // prevent default Enter behavior (move to the next row within a selection range)
251
- return false;
252
248
  },
253
249
  runOnlyIf: () => {
254
250
  var _this$hot$getSelected;
255
251
  const highlight = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
256
252
  return highlight && this.hot.selection.isCellVisible(highlight) && highlight.isHeader();
257
253
  },
258
- relativeToGroup: SHORTCUTS_GROUP_EDITOR,
259
- position: 'before',
260
254
  group: SHORTCUTS_GROUP
261
255
  });
262
256
  }
@@ -9,26 +9,10 @@ exports.createDefaultShortcutsList = createDefaultShortcutsList;
9
9
  * @returns {KeyboardShortcut[]}
10
10
  */
11
11
  function createDefaultShortcutsList(menu) {
12
- const {
13
- hot,
14
- hotMenu
15
- } = menu;
16
12
  return [{
17
- keys: [['Control/Meta', 'A']],
18
- forwardToContext: hot.getShortcutManager().getContext('grid'),
13
+ keys: [['Tab'], ['Shift', 'Tab'], ['Control/Meta', 'A']],
14
+ forwardToContext: menu.hot.getShortcutManager().getContext('grid'),
19
15
  callback: () => menu.close(true)
20
- }, {
21
- keys: [['Tab'], ['Shift', 'Tab']],
22
- callback: (event, keys) => {
23
- const settings = hot.getSettings();
24
- const tabMoves = typeof settings.tabMoves === 'function' ? settings.tabMoves(event) : settings.tabMoves;
25
- if (keys.includes('shift')) {
26
- hot.selection.transformStart(-tabMoves.row, -tabMoves.col);
27
- } else {
28
- hot.selection.transformStart(tabMoves.row, tabMoves.col);
29
- }
30
- menu.close(true);
31
- }
32
16
  }, {
33
17
  keys: [['Escape']],
34
18
  callback: () => menu.close()
@@ -41,7 +25,7 @@ function createDefaultShortcutsList(menu) {
41
25
  }, {
42
26
  keys: [['ArrowRight']],
43
27
  callback: () => {
44
- const selection = hotMenu.getSelectedLast();
28
+ const selection = menu.hotMenu.getSelectedLast();
45
29
  if (selection) {
46
30
  const subMenu = menu.openSubMenu(selection[0]);
47
31
  if (subMenu) {
@@ -52,7 +36,7 @@ function createDefaultShortcutsList(menu) {
52
36
  }, {
53
37
  keys: [['ArrowLeft']],
54
38
  callback: () => {
55
- const selection = hotMenu.getSelectedLast();
39
+ const selection = menu.hotMenu.getSelectedLast();
56
40
  if (selection && menu.isSubMenu()) {
57
41
  menu.close();
58
42
  if (menu.isSubMenu()) {
@@ -69,11 +53,11 @@ function createDefaultShortcutsList(menu) {
69
53
  }, {
70
54
  keys: [['Enter'], ['Space']],
71
55
  callback: event => {
72
- const selection = hotMenu.getSelectedLast();
56
+ const selection = menu.hotMenu.getSelectedLast();
73
57
  if (!selection) {
74
58
  return;
75
59
  }
76
- if (hotMenu.getSourceDataAtRow(selection[0]).submenu) {
60
+ if (menu.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
77
61
  menu.openSubMenu(selection[0]).getNavigator().toFirstItem();
78
62
  } else {
79
63
  menu.executeCommand(event);
@@ -83,9 +67,9 @@ function createDefaultShortcutsList(menu) {
83
67
  }, {
84
68
  keys: [['PageUp']],
85
69
  callback: () => {
86
- const selection = hotMenu.getSelectedLast();
70
+ const selection = menu.hotMenu.getSelectedLast();
87
71
  if (selection) {
88
- hotMenu.selection.transformStart(-hotMenu.countVisibleRows(), 0);
72
+ menu.hotMenu.selection.transformStart(-menu.hotMenu.countVisibleRows(), 0);
89
73
  } else {
90
74
  menu.getNavigator().toFirstItem();
91
75
  }
@@ -93,9 +77,9 @@ function createDefaultShortcutsList(menu) {
93
77
  }, {
94
78
  keys: [['PageDown']],
95
79
  callback: () => {
96
- const selection = hotMenu.getSelectedLast();
80
+ const selection = menu.hotMenu.getSelectedLast();
97
81
  if (selection) {
98
- hotMenu.selection.transformStart(hotMenu.countVisibleRows(), 0);
82
+ menu.hotMenu.selection.transformStart(menu.hotMenu.countVisibleRows(), 0);
99
83
  } else {
100
84
  menu.getNavigator().toLastItem();
101
85
  }
@@ -5,26 +5,10 @@
5
5
  * @returns {KeyboardShortcut[]}
6
6
  */
7
7
  export function createDefaultShortcutsList(menu) {
8
- const {
9
- hot,
10
- hotMenu
11
- } = menu;
12
8
  return [{
13
- keys: [['Control/Meta', 'A']],
14
- forwardToContext: hot.getShortcutManager().getContext('grid'),
9
+ keys: [['Tab'], ['Shift', 'Tab'], ['Control/Meta', 'A']],
10
+ forwardToContext: menu.hot.getShortcutManager().getContext('grid'),
15
11
  callback: () => menu.close(true)
16
- }, {
17
- keys: [['Tab'], ['Shift', 'Tab']],
18
- callback: (event, keys) => {
19
- const settings = hot.getSettings();
20
- const tabMoves = typeof settings.tabMoves === 'function' ? settings.tabMoves(event) : settings.tabMoves;
21
- if (keys.includes('shift')) {
22
- hot.selection.transformStart(-tabMoves.row, -tabMoves.col);
23
- } else {
24
- hot.selection.transformStart(tabMoves.row, tabMoves.col);
25
- }
26
- menu.close(true);
27
- }
28
12
  }, {
29
13
  keys: [['Escape']],
30
14
  callback: () => menu.close()
@@ -37,7 +21,7 @@ export function createDefaultShortcutsList(menu) {
37
21
  }, {
38
22
  keys: [['ArrowRight']],
39
23
  callback: () => {
40
- const selection = hotMenu.getSelectedLast();
24
+ const selection = menu.hotMenu.getSelectedLast();
41
25
  if (selection) {
42
26
  const subMenu = menu.openSubMenu(selection[0]);
43
27
  if (subMenu) {
@@ -48,7 +32,7 @@ export function createDefaultShortcutsList(menu) {
48
32
  }, {
49
33
  keys: [['ArrowLeft']],
50
34
  callback: () => {
51
- const selection = hotMenu.getSelectedLast();
35
+ const selection = menu.hotMenu.getSelectedLast();
52
36
  if (selection && menu.isSubMenu()) {
53
37
  menu.close();
54
38
  if (menu.isSubMenu()) {
@@ -65,11 +49,11 @@ export function createDefaultShortcutsList(menu) {
65
49
  }, {
66
50
  keys: [['Enter'], ['Space']],
67
51
  callback: event => {
68
- const selection = hotMenu.getSelectedLast();
52
+ const selection = menu.hotMenu.getSelectedLast();
69
53
  if (!selection) {
70
54
  return;
71
55
  }
72
- if (hotMenu.getSourceDataAtRow(selection[0]).submenu) {
56
+ if (menu.hotMenu.getSourceDataAtRow(selection[0]).submenu) {
73
57
  menu.openSubMenu(selection[0]).getNavigator().toFirstItem();
74
58
  } else {
75
59
  menu.executeCommand(event);
@@ -79,9 +63,9 @@ export function createDefaultShortcutsList(menu) {
79
63
  }, {
80
64
  keys: [['PageUp']],
81
65
  callback: () => {
82
- const selection = hotMenu.getSelectedLast();
66
+ const selection = menu.hotMenu.getSelectedLast();
83
67
  if (selection) {
84
- hotMenu.selection.transformStart(-hotMenu.countVisibleRows(), 0);
68
+ menu.hotMenu.selection.transformStart(-menu.hotMenu.countVisibleRows(), 0);
85
69
  } else {
86
70
  menu.getNavigator().toFirstItem();
87
71
  }
@@ -89,9 +73,9 @@ export function createDefaultShortcutsList(menu) {
89
73
  }, {
90
74
  keys: [['PageDown']],
91
75
  callback: () => {
92
- const selection = hotMenu.getSelectedLast();
76
+ const selection = menu.hotMenu.getSelectedLast();
93
77
  if (selection) {
94
- hotMenu.selection.transformStart(hotMenu.countVisibleRows(), 0);
78
+ menu.hotMenu.selection.transformStart(menu.hotMenu.countVisibleRows(), 0);
95
79
  } else {
96
80
  menu.getNavigator().toLastItem();
97
81
  }
@@ -36,6 +36,74 @@ class SelectionCalculations {
36
36
  this.hot = plugin.hot;
37
37
  }
38
38
 
39
+ /**
40
+ * "Snap" the delta value according to defined merged cells. (In other words, compensate the rowspan -
41
+ * e.g. Going up with `delta.row = -1` over a merged cell with `rowspan = 3`, `delta.row` should change to `-3`.).
42
+ *
43
+ * @param {object} delta The delta object containing `row` and `col` properties.
44
+ * @param {CellRange} selectionRange The selection range.
45
+ * @param {object} mergedCell A merged cell object.
46
+ */
47
+ snapDelta(delta, selectionRange, mergedCell) {
48
+ const cellCoords = selectionRange.to;
49
+ const newRow = cellCoords.row + delta.row;
50
+ const newColumn = cellCoords.col + delta.col;
51
+ if (delta.row) {
52
+ this.jumpOverMergedCell(delta, mergedCell, newRow);
53
+ } else if (delta.col) {
54
+ this.jumpOverMergedCell(delta, mergedCell, newColumn);
55
+ }
56
+ }
57
+
58
+ /**
59
+ * "Jump" over the merged cell (compensate for the indexes within the merged cell to get past it).
60
+ *
61
+ * @private
62
+ * @param {object} delta The delta object.
63
+ * @param {MergedCellCoords} mergedCell The merge cell object.
64
+ * @param {number} newIndex New row/column index, created with the delta.
65
+ */
66
+ jumpOverMergedCell(delta, mergedCell, newIndex) {
67
+ let flatDelta = delta.row || delta.col;
68
+ let includesIndex = null;
69
+ let firstIndex = null;
70
+ let lastIndex = null;
71
+ if (delta.row) {
72
+ includesIndex = mergedCell.includesVertically(newIndex);
73
+ firstIndex = mergedCell.row;
74
+ lastIndex = mergedCell.getLastRow();
75
+ } else if (delta.col) {
76
+ includesIndex = mergedCell.includesHorizontally(newIndex);
77
+ firstIndex = mergedCell.col;
78
+ lastIndex = mergedCell.getLastColumn();
79
+ }
80
+ if (flatDelta === 0) {
81
+ return;
82
+ } else if (flatDelta > 0) {
83
+ if (includesIndex && newIndex !== firstIndex) {
84
+ flatDelta += lastIndex - newIndex + 1;
85
+ }
86
+ } else if (includesIndex && newIndex !== lastIndex) {
87
+ flatDelta -= newIndex - firstIndex + 1;
88
+ }
89
+ if (delta.row) {
90
+ delta.row = flatDelta;
91
+ } else if (delta.col) {
92
+ delta.col = flatDelta;
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Get a selection range with `to` property incremented by the provided delta.
98
+ *
99
+ * @param {CellRange} oldSelectionRange The base selection range.
100
+ * @param {object} delta The delta object with `row` and `col` properties.
101
+ * @returns {CellRange} A new `CellRange` object.
102
+ */
103
+ getUpdatedSelectionRange(oldSelectionRange, delta) {
104
+ return this.hot._createCellRange(oldSelectionRange.highlight, oldSelectionRange.from, this.hot._createCellCoords(oldSelectionRange.to.row + delta.row, oldSelectionRange.to.col + delta.col));
105
+ }
106
+
39
107
  /**
40
108
  * Generate an additional class name for the entirely-selected merged cells.
41
109
  *
@@ -68,7 +136,8 @@ class SelectionCalculations {
68
136
  const fullMergeAreaWithinSelection = startRow <= mergedCell.row && startColumn <= mergedCell.col && endRow >= mergeRowEnd && endColumn >= mergeColumnEnd;
69
137
  if (fullMergeAreaWithinSelection) {
70
138
  return `${this.fullySelectedMergedCellClassName}-${layerLevel}`;
71
- } else if (this.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
139
+ } else if (this.plugin.selectionCalculations.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
140
+ // eslint-disable-line max-len
72
141
  return `${this.fullySelectedMergedCellClassName}-multiple`;
73
142
  }
74
143
  }
@@ -33,6 +33,74 @@ class SelectionCalculations {
33
33
  this.hot = plugin.hot;
34
34
  }
35
35
 
36
+ /**
37
+ * "Snap" the delta value according to defined merged cells. (In other words, compensate the rowspan -
38
+ * e.g. Going up with `delta.row = -1` over a merged cell with `rowspan = 3`, `delta.row` should change to `-3`.).
39
+ *
40
+ * @param {object} delta The delta object containing `row` and `col` properties.
41
+ * @param {CellRange} selectionRange The selection range.
42
+ * @param {object} mergedCell A merged cell object.
43
+ */
44
+ snapDelta(delta, selectionRange, mergedCell) {
45
+ const cellCoords = selectionRange.to;
46
+ const newRow = cellCoords.row + delta.row;
47
+ const newColumn = cellCoords.col + delta.col;
48
+ if (delta.row) {
49
+ this.jumpOverMergedCell(delta, mergedCell, newRow);
50
+ } else if (delta.col) {
51
+ this.jumpOverMergedCell(delta, mergedCell, newColumn);
52
+ }
53
+ }
54
+
55
+ /**
56
+ * "Jump" over the merged cell (compensate for the indexes within the merged cell to get past it).
57
+ *
58
+ * @private
59
+ * @param {object} delta The delta object.
60
+ * @param {MergedCellCoords} mergedCell The merge cell object.
61
+ * @param {number} newIndex New row/column index, created with the delta.
62
+ */
63
+ jumpOverMergedCell(delta, mergedCell, newIndex) {
64
+ let flatDelta = delta.row || delta.col;
65
+ let includesIndex = null;
66
+ let firstIndex = null;
67
+ let lastIndex = null;
68
+ if (delta.row) {
69
+ includesIndex = mergedCell.includesVertically(newIndex);
70
+ firstIndex = mergedCell.row;
71
+ lastIndex = mergedCell.getLastRow();
72
+ } else if (delta.col) {
73
+ includesIndex = mergedCell.includesHorizontally(newIndex);
74
+ firstIndex = mergedCell.col;
75
+ lastIndex = mergedCell.getLastColumn();
76
+ }
77
+ if (flatDelta === 0) {
78
+ return;
79
+ } else if (flatDelta > 0) {
80
+ if (includesIndex && newIndex !== firstIndex) {
81
+ flatDelta += lastIndex - newIndex + 1;
82
+ }
83
+ } else if (includesIndex && newIndex !== lastIndex) {
84
+ flatDelta -= newIndex - firstIndex + 1;
85
+ }
86
+ if (delta.row) {
87
+ delta.row = flatDelta;
88
+ } else if (delta.col) {
89
+ delta.col = flatDelta;
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Get a selection range with `to` property incremented by the provided delta.
95
+ *
96
+ * @param {CellRange} oldSelectionRange The base selection range.
97
+ * @param {object} delta The delta object with `row` and `col` properties.
98
+ * @returns {CellRange} A new `CellRange` object.
99
+ */
100
+ getUpdatedSelectionRange(oldSelectionRange, delta) {
101
+ return this.hot._createCellRange(oldSelectionRange.highlight, oldSelectionRange.from, this.hot._createCellCoords(oldSelectionRange.to.row + delta.row, oldSelectionRange.to.col + delta.col));
102
+ }
103
+
36
104
  /**
37
105
  * Generate an additional class name for the entirely-selected merged cells.
38
106
  *
@@ -65,7 +133,8 @@ class SelectionCalculations {
65
133
  const fullMergeAreaWithinSelection = startRow <= mergedCell.row && startColumn <= mergedCell.col && endRow >= mergeRowEnd && endColumn >= mergeColumnEnd;
66
134
  if (fullMergeAreaWithinSelection) {
67
135
  return `${this.fullySelectedMergedCellClassName}-${layerLevel}`;
68
- } else if (this.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
136
+ } else if (this.plugin.selectionCalculations.isMergeCellFullySelected(mergedCell, this.plugin.hot.getSelectedRange())) {
137
+ // eslint-disable-line max-len
69
138
  return `${this.fullySelectedMergedCellClassName}-multiple`;
70
139
  }
71
140
  }