handsontable 0.0.0-next-ff10728-20250410 → 0.0.0-next-9410a76-20250416

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 (106) hide show
  1. package/3rdparty/walkontable/src/cell/range.js +14 -0
  2. package/3rdparty/walkontable/src/cell/range.mjs +14 -0
  3. package/3rdparty/walkontable/src/renderer/rowHeaders.js +4 -1
  4. package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +4 -1
  5. package/3rdparty/walkontable/src/selection/border/border.js +5 -0
  6. package/3rdparty/walkontable/src/selection/border/border.mjs +5 -0
  7. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.js +3 -4
  8. package/3rdparty/walkontable/src/table/mixin/stickyColumnsStart.mjs +3 -4
  9. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.js +8 -10
  10. package/3rdparty/walkontable/src/table/mixin/stickyRowsBottom.mjs +8 -10
  11. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.js +3 -4
  12. package/3rdparty/walkontable/src/table/mixin/stickyRowsTop.mjs +3 -4
  13. package/3rdparty/walkontable/src/table.js +5 -2
  14. package/3rdparty/walkontable/src/table.mjs +5 -2
  15. package/CHANGELOG.md +39 -0
  16. package/base.js +2 -2
  17. package/base.mjs +2 -2
  18. package/core/focusCatcher/focusDetector.js +1 -1
  19. package/core/focusCatcher/focusDetector.mjs +2 -2
  20. package/core/hooks/constants.js +8 -0
  21. package/core/hooks/constants.mjs +8 -0
  22. package/core/hooks/index.d.ts +1 -0
  23. package/core.d.ts +0 -1
  24. package/core.js +32 -25
  25. package/core.mjs +33 -26
  26. package/dataMap/dataMap.js +0 -7
  27. package/dataMap/dataMap.mjs +0 -7
  28. package/dataMap/metaManager/metaSchema.js +1 -0
  29. package/dataMap/metaManager/metaSchema.mjs +1 -0
  30. package/dist/handsontable.css +3 -3
  31. package/dist/handsontable.full.css +3 -3
  32. package/dist/handsontable.full.js +437 -350
  33. package/dist/handsontable.full.min.css +3 -3
  34. package/dist/handsontable.full.min.js +17 -17
  35. package/dist/handsontable.js +437 -350
  36. package/dist/handsontable.min.css +3 -3
  37. package/dist/handsontable.min.js +18 -18
  38. package/editorManager.js +1 -7
  39. package/editorManager.mjs +1 -7
  40. package/editors/autocompleteEditor/autocompleteEditor.js +14 -4
  41. package/editors/autocompleteEditor/autocompleteEditor.mjs +14 -4
  42. package/editors/textEditor/textEditor.js +1 -1
  43. package/editors/textEditor/textEditor.mjs +2 -2
  44. package/helpers/browser.js +1 -1
  45. package/helpers/browser.mjs +1 -1
  46. package/helpers/dom/element.js +2 -2
  47. package/helpers/dom/element.mjs +1 -1
  48. package/helpers/mixed.js +2 -2
  49. package/helpers/mixed.mjs +2 -2
  50. package/helpers/object.js +3 -0
  51. package/helpers/object.mjs +3 -0
  52. package/package.json +1 -1
  53. package/plugins/autoColumnSize/autoColumnSize.js +1 -1
  54. package/plugins/autoColumnSize/autoColumnSize.mjs +1 -1
  55. package/plugins/autoRowSize/autoRowSize.js +1 -6
  56. package/plugins/autoRowSize/autoRowSize.mjs +1 -6
  57. package/plugins/columnSorting/columnSorting.js +0 -4
  58. package/plugins/columnSorting/columnSorting.mjs +0 -4
  59. package/plugins/comments/comments.js +1 -0
  60. package/plugins/comments/comments.mjs +1 -0
  61. package/plugins/contextMenu/menu/defaultShortcutsList.js +2 -2
  62. package/plugins/contextMenu/menu/defaultShortcutsList.mjs +2 -2
  63. package/plugins/contextMenu/menu/menu.js +1 -0
  64. package/plugins/contextMenu/menu/menu.mjs +1 -0
  65. package/plugins/contextMenu/menu/positioner.js +10 -2
  66. package/plugins/contextMenu/menu/positioner.mjs +10 -2
  67. package/plugins/copyPaste/copyPaste.js +12 -15
  68. package/plugins/copyPaste/copyPaste.mjs +13 -16
  69. package/plugins/copyPaste/pasteEvent.js +3 -0
  70. package/plugins/copyPaste/pasteEvent.mjs +3 -0
  71. package/plugins/filters/filters.js +25 -24
  72. package/plugins/filters/filters.mjs +25 -24
  73. package/plugins/filters/ui/multipleSelect.js +7 -1
  74. package/plugins/filters/ui/multipleSelect.mjs +7 -1
  75. package/plugins/hiddenColumns/hiddenColumns.js +1 -1
  76. package/plugins/hiddenColumns/hiddenColumns.mjs +1 -1
  77. package/plugins/hiddenRows/hiddenRows.js +1 -1
  78. package/plugins/hiddenRows/hiddenRows.mjs +1 -1
  79. package/plugins/manualColumnResize/manualColumnResize.js +4 -6
  80. package/plugins/manualColumnResize/manualColumnResize.mjs +4 -6
  81. package/plugins/manualRowResize/manualRowResize.js +4 -6
  82. package/plugins/manualRowResize/manualRowResize.mjs +4 -6
  83. package/plugins/mergeCells/mergeCells.js +8 -29
  84. package/plugins/mergeCells/mergeCells.mjs +8 -29
  85. package/plugins/mergeCells/renderer.js +15 -0
  86. package/plugins/mergeCells/renderer.mjs +15 -0
  87. package/plugins/mergeCells/utils.js +31 -0
  88. package/plugins/mergeCells/utils.mjs +27 -0
  89. package/plugins/nestedRows/data/dataManager.js +2 -2
  90. package/plugins/nestedRows/data/dataManager.mjs +2 -2
  91. package/plugins/undoRedo/actions/removeColumn.js +19 -14
  92. package/plugins/undoRedo/actions/removeColumn.mjs +19 -14
  93. package/plugins/undoRedo/actions/removeRow.js +12 -4
  94. package/plugins/undoRedo/actions/removeRow.mjs +12 -4
  95. package/selection/selection.js +3 -1
  96. package/selection/selection.mjs +3 -1
  97. package/styles/handsontable.css +14 -15
  98. package/styles/handsontable.min.css +3 -3
  99. package/styles/ht-theme-horizon.css +2 -2
  100. package/styles/ht-theme-horizon.min.css +2 -2
  101. package/styles/ht-theme-main.css +2 -2
  102. package/styles/ht-theme-main.min.css +2 -2
  103. package/tableView.js +5 -8
  104. package/tableView.mjs +5 -8
  105. package/utils/ghostTable.js +3 -0
  106. package/utils/ghostTable.mjs +3 -0
package/editorManager.js CHANGED
@@ -80,13 +80,7 @@ class EditorManager {
80
80
  this.selection = _selection;
81
81
  this.eventManager = new _eventManager.default(hotInstance);
82
82
  this.hot.addHook('afterDocumentKeyDown', event => _assertClassBrand(_EditorManager_brand, this, _onAfterDocumentKeyDown).call(this, event));
83
-
84
- // Open editor when text composition is started (IME editor)
85
- this.eventManager.addEventListener(this.hot.rootDocument.documentElement, 'compositionstart', event => {
86
- if (!this.destroyed && this.hot.isListening()) {
87
- this.openEditor('', event);
88
- }
89
- });
83
+ this.hot.addHook('beforeCompositionStart', event => _assertClassBrand(_EditorManager_brand, this, _onAfterDocumentKeyDown).call(this, event));
90
84
  this.hot.view._wt.update('onCellDblClick', (event, coords, elem) => _assertClassBrand(_EditorManager_brand, this, _onCellDblClick).call(this, event, coords, elem));
91
85
  }
92
86
 
package/editorManager.mjs CHANGED
@@ -76,13 +76,7 @@ class EditorManager {
76
76
  this.selection = _selection;
77
77
  this.eventManager = new EventManager(hotInstance);
78
78
  this.hot.addHook('afterDocumentKeyDown', event => _assertClassBrand(_EditorManager_brand, this, _onAfterDocumentKeyDown).call(this, event));
79
-
80
- // Open editor when text composition is started (IME editor)
81
- this.eventManager.addEventListener(this.hot.rootDocument.documentElement, 'compositionstart', event => {
82
- if (!this.destroyed && this.hot.isListening()) {
83
- this.openEditor('', event);
84
- }
85
- });
79
+ this.hot.addHook('beforeCompositionStart', event => _assertClassBrand(_EditorManager_brand, this, _onAfterDocumentKeyDown).call(this, event));
86
80
  this.hot.view._wt.update('onCellDblClick', (event, coords, elem) => _assertClassBrand(_EditorManager_brand, this, _onCellDblClick).call(this, event, coords, elem));
87
81
  }
88
82
 
@@ -15,6 +15,7 @@ var _string = require("../../helpers/string");
15
15
  var _unicode = require("../../helpers/unicode");
16
16
  var _textRenderer = require("../../renderers/textRenderer");
17
17
  var _a11y = require("../../helpers/a11y");
18
+ var _function = require("../../helpers/function");
18
19
  function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
19
20
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
20
21
  function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
@@ -30,6 +31,7 @@ const EDITOR_TYPE = exports.EDITOR_TYPE = 'autocomplete';
30
31
  * @class AutocompleteEditor
31
32
  */
32
33
  var _idPrefix = /*#__PURE__*/new WeakMap();
34
+ var _focusDebounced = /*#__PURE__*/new WeakMap();
33
35
  var _AutocompleteEditor_brand = /*#__PURE__*/new WeakSet();
34
36
  class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
35
37
  constructor() {
@@ -62,6 +64,12 @@ class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
62
64
  * @type {string}
63
65
  */
64
66
  _classPrivateFieldInitSpec(this, _idPrefix, this.hot.guid.slice(0, 9));
67
+ /**
68
+ * Runs focus method after debounce.
69
+ */
70
+ _classPrivateFieldInitSpec(this, _focusDebounced, (0, _function.debounce)(() => {
71
+ this.focus();
72
+ }, 100));
65
73
  /**
66
74
  * Filters and sorts by relevance.
67
75
  *
@@ -147,7 +155,6 @@ class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
147
155
  }
148
156
  return this.TEXTAREA.value;
149
157
  }
150
-
151
158
  /**
152
159
  * Creates an editor's elements and adds necessary CSS classnames.
153
160
  */
@@ -193,10 +200,10 @@ class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
193
200
  this.showEditableElement();
194
201
  this.focus();
195
202
  this.addHook('beforeKeyDown', event => this.onBeforeKeyDown(event));
203
+ this.htEditor.addHook('afterScroll', _classPrivateFieldGet(_focusDebounced, this));
196
204
  this.htEditor.updateSettings({
197
205
  colWidths: trimDropdown ? [(0, _element.outerWidth)(this.TEXTAREA) - 2] : undefined,
198
206
  autoColumnSize: true,
199
- autoRowSize: true,
200
207
  renderer: (hotInstance, TD, row, col, prop, value, cellProperties) => {
201
208
  (0, _textRenderer.textRenderer)(hotInstance, TD, row, col, prop, value, cellProperties);
202
209
  const {
@@ -468,7 +475,10 @@ class AutocompleteEditor extends _handsontableEditor.HandsontableEditor {
468
475
  const maxItems = Math.min(this.cellProperties.visibleRows, this.strippedChoices.length);
469
476
  const height = Array.from({
470
477
  length: maxItems
471
- }, (_, i) => i).reduce((h, index) => h + this.htEditor.getRowHeight(index), 0);
478
+ }, (_, i) => i).reduce((totalHeight, index) => {
479
+ const rowHeight = this.htEditor.getRowHeight(index) || this.htEditor.view.getDefaultRowHeight();
480
+ return totalHeight + rowHeight;
481
+ }, 0);
472
482
  return height + borderVerticalCompensation + 1;
473
483
  }
474
484
 
@@ -566,7 +576,7 @@ exports.AutocompleteEditor = AutocompleteEditor;
566
576
  function _fixDropdownWidth() {
567
577
  if (this.htEditor.view.hasVerticalScroll()) {
568
578
  this.htEditor.updateSettings({
569
- width: this.htEditor.getSettings().width + (0, _element.getScrollbarWidth)(this.hot.rootDocument)
579
+ width: this.getWidth() + (0, _element.getScrollbarWidth)(this.hot.rootDocument)
570
580
  });
571
581
  }
572
582
  }
@@ -20,6 +20,7 @@ import { stripTags } from "../../helpers/string.mjs";
20
20
  import { KEY_CODES, isPrintableChar } from "../../helpers/unicode.mjs";
21
21
  import { textRenderer } from "../../renderers/textRenderer/index.mjs";
22
22
  import { A11Y_ACTIVEDESCENDANT, A11Y_AUTOCOMPLETE, A11Y_COMBOBOX, A11Y_CONTROLS, A11Y_EXPANDED, A11Y_HASPOPUP, A11Y_LISTBOX, A11Y_LIVE, A11Y_OPTION, A11Y_POSINSET, A11Y_PRESENTATION, A11Y_RELEVANT, A11Y_SELECTED, A11Y_SETSIZE, A11Y_TEXT } from "../../helpers/a11y.mjs";
23
+ import { debounce } from "../../helpers/function.mjs";
23
24
  export const EDITOR_TYPE = 'autocomplete';
24
25
 
25
26
  /**
@@ -27,6 +28,7 @@ export const EDITOR_TYPE = 'autocomplete';
27
28
  * @class AutocompleteEditor
28
29
  */
29
30
  var _idPrefix = /*#__PURE__*/new WeakMap();
31
+ var _focusDebounced = /*#__PURE__*/new WeakMap();
30
32
  var _AutocompleteEditor_brand = /*#__PURE__*/new WeakSet();
31
33
  export class AutocompleteEditor extends HandsontableEditor {
32
34
  constructor() {
@@ -59,6 +61,12 @@ export class AutocompleteEditor extends HandsontableEditor {
59
61
  * @type {string}
60
62
  */
61
63
  _classPrivateFieldInitSpec(this, _idPrefix, this.hot.guid.slice(0, 9));
64
+ /**
65
+ * Runs focus method after debounce.
66
+ */
67
+ _classPrivateFieldInitSpec(this, _focusDebounced, debounce(() => {
68
+ this.focus();
69
+ }, 100));
62
70
  /**
63
71
  * Filters and sorts by relevance.
64
72
  *
@@ -144,7 +152,6 @@ export class AutocompleteEditor extends HandsontableEditor {
144
152
  }
145
153
  return this.TEXTAREA.value;
146
154
  }
147
-
148
155
  /**
149
156
  * Creates an editor's elements and adds necessary CSS classnames.
150
157
  */
@@ -190,10 +197,10 @@ export class AutocompleteEditor extends HandsontableEditor {
190
197
  this.showEditableElement();
191
198
  this.focus();
192
199
  this.addHook('beforeKeyDown', event => this.onBeforeKeyDown(event));
200
+ this.htEditor.addHook('afterScroll', _classPrivateFieldGet(_focusDebounced, this));
193
201
  this.htEditor.updateSettings({
194
202
  colWidths: trimDropdown ? [outerWidth(this.TEXTAREA) - 2] : undefined,
195
203
  autoColumnSize: true,
196
- autoRowSize: true,
197
204
  renderer: (hotInstance, TD, row, col, prop, value, cellProperties) => {
198
205
  textRenderer(hotInstance, TD, row, col, prop, value, cellProperties);
199
206
  const {
@@ -465,7 +472,10 @@ export class AutocompleteEditor extends HandsontableEditor {
465
472
  const maxItems = Math.min(this.cellProperties.visibleRows, this.strippedChoices.length);
466
473
  const height = Array.from({
467
474
  length: maxItems
468
- }, (_, i) => i).reduce((h, index) => h + this.htEditor.getRowHeight(index), 0);
475
+ }, (_, i) => i).reduce((totalHeight, index) => {
476
+ const rowHeight = this.htEditor.getRowHeight(index) || this.htEditor.view.getDefaultRowHeight();
477
+ return totalHeight + rowHeight;
478
+ }, 0);
469
479
  return height + borderVerticalCompensation + 1;
470
480
  }
471
481
 
@@ -562,7 +572,7 @@ export class AutocompleteEditor extends HandsontableEditor {
562
572
  function _fixDropdownWidth() {
563
573
  if (this.htEditor.view.hasVerticalScroll()) {
564
574
  this.htEditor.updateSettings({
565
- width: this.htEditor.getSettings().width + getScrollbarWidth(this.hot.rootDocument)
575
+ width: this.getWidth() + getScrollbarWidth(this.hot.rootDocument)
566
576
  });
567
577
  }
568
578
  }
@@ -123,7 +123,7 @@ class TextEditor extends _baseEditor.BaseEditor {
123
123
  */
124
124
  close() {
125
125
  this.autoResize.unObserve();
126
- if ((0, _element.isThisHotChild)(this.hot.rootDocument.activeElement, this.hot.rootElement)) {
126
+ if ((0, _element.isInternalElement)(this.hot.rootDocument.activeElement, this.hot.rootElement)) {
127
127
  this.hot.listen(); // don't refocus the table if user focused some cell outside of HT on purpose
128
128
  }
129
129
  this.hideEditableElement();
@@ -5,7 +5,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
5
5
  import { BaseEditor, EDITOR_STATE } from "../baseEditor/index.mjs";
6
6
  import EventManager from "../../eventManager.mjs";
7
7
  import { isEdge, isIOS } from "../../helpers/browser.mjs";
8
- import { addClass, isThisHotChild, setCaretPosition, hasClass, removeClass, setAttribute } from "../../helpers/dom/element.mjs";
8
+ import { addClass, isInternalElement, setCaretPosition, hasClass, removeClass, setAttribute } from "../../helpers/dom/element.mjs";
9
9
  import { rangeEach } from "../../helpers/number.mjs";
10
10
  import { createInputElementResizer } from "../../utils/autoResize.mjs";
11
11
  import { isDefined } from "../../helpers/mixed.mjs";
@@ -119,7 +119,7 @@ export class TextEditor extends BaseEditor {
119
119
  */
120
120
  close() {
121
121
  this.autoResize.unObserve();
122
- if (isThisHotChild(this.hot.rootDocument.activeElement, this.hot.rootElement)) {
122
+ if (isInternalElement(this.hot.rootDocument.activeElement, this.hot.rootElement)) {
123
123
  this.hot.listen(); // don't refocus the table if user focused some cell outside of HT on purpose
124
124
  }
125
125
  this.hideEditableElement();
@@ -41,7 +41,7 @@ const platforms = {
41
41
  mac: tester(platform => /^Mac/.test(platform)),
42
42
  win: tester(platform => /^Win/.test(platform)),
43
43
  linux: tester(platform => /^Linux/.test(platform)),
44
- ios: tester(ua => /iPhone|iPad|iPod/i.test(ua))
44
+ ios: tester(platform => /iPhone|iPad|iPod/i.test(platform))
45
45
  };
46
46
 
47
47
  /**
@@ -23,7 +23,7 @@ const platforms = {
23
23
  mac: tester(platform => /^Mac/.test(platform)),
24
24
  win: tester(platform => /^Win/.test(platform)),
25
25
  linux: tester(platform => /^Linux/.test(platform)),
26
- ios: tester(ua => /iPhone|iPad|iPod/i.test(ua))
26
+ ios: tester(platform => /iPhone|iPad|iPod/i.test(platform))
27
27
  };
28
28
 
29
29
  /**
@@ -38,8 +38,8 @@ exports.isChildOf = isChildOf;
38
38
  exports.isDetached = isDetached;
39
39
  exports.isHTMLElement = isHTMLElement;
40
40
  exports.isInput = isInput;
41
+ exports.isInternalElement = isInternalElement;
41
42
  exports.isOutsideInput = isOutsideInput;
42
- exports.isThisHotChild = isThisHotChild;
43
43
  exports.isVisible = isVisible;
44
44
  exports.makeElementContentEditableAndSelectItsContent = makeElementContentEditableAndSelectItsContent;
45
45
  exports.matchesCSSRules = matchesCSSRules;
@@ -100,7 +100,7 @@ function getParent(element) {
100
100
  * @param {HTMLElement} thisHotContainer The Handsontable container.
101
101
  * @returns {boolean}
102
102
  */
103
- function isThisHotChild(element, thisHotContainer) {
103
+ function isInternalElement(element, thisHotContainer) {
104
104
  const closestHandsontableContainer = element.closest('.handsontable');
105
105
  return !!closestHandsontableContainer && (closestHandsontableContainer.parentNode === thisHotContainer || closestHandsontableContainer === thisHotContainer);
106
106
  }
@@ -39,7 +39,7 @@ export function getParent(element) {
39
39
  * @param {HTMLElement} thisHotContainer The Handsontable container.
40
40
  * @returns {boolean}
41
41
  */
42
- export function isThisHotChild(element, thisHotContainer) {
42
+ export function isInternalElement(element, thisHotContainer) {
43
43
  const closestHandsontableContainer = element.closest('.handsontable');
44
44
  return !!closestHandsontableContainer && (closestHandsontableContainer.parentNode === thisHotContainer || closestHandsontableContainer === thisHotContainer);
45
45
  }
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-ff10728-20250410";
137
+ const hotVersion = "0.0.0-next-9410a76-20250416";
138
138
  let keyValidityDate;
139
139
  let consoleMessageState = 'invalid';
140
140
  let domMessageState = 'invalid';
@@ -142,7 +142,7 @@ function _injectProductInfo(key, element) {
142
142
  const schemaValidity = _checkKeySchema(key);
143
143
  if (hasValidType || isNonCommercial || schemaValidity) {
144
144
  if (schemaValidity) {
145
- const releaseDate = (0, _moment.default)("20/02/2025", 'DD/MM/YYYY');
145
+ const releaseDate = (0, _moment.default)("19/03/2025", 'DD/MM/YYYY');
146
146
  const releaseDays = Math.floor(releaseDate.toDate().getTime() / 8.64e7);
147
147
  const keyValidityDays = _extractTime(key);
148
148
  keyValidityDate = (0, _moment.default)((keyValidityDays + 1) * 8.64e7, 'x').format('MMMM DD, YYYY');
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-ff10728-20250410";
127
+ const hotVersion = "0.0.0-next-9410a76-20250416";
128
128
  let keyValidityDate;
129
129
  let consoleMessageState = 'invalid';
130
130
  let domMessageState = 'invalid';
@@ -132,7 +132,7 @@ export function _injectProductInfo(key, element) {
132
132
  const schemaValidity = _checkKeySchema(key);
133
133
  if (hasValidType || isNonCommercial || schemaValidity) {
134
134
  if (schemaValidity) {
135
- const releaseDate = moment("20/02/2025", 'DD/MM/YYYY');
135
+ const releaseDate = moment("19/03/2025", 'DD/MM/YYYY');
136
136
  const releaseDays = Math.floor(releaseDate.toDate().getTime() / 8.64e7);
137
137
  const keyValidityDays = _extractTime(key);
138
138
  keyValidityDate = moment((keyValidityDays + 1) * 8.64e7, 'x').format('MMMM DD, YYYY');
package/helpers/object.js CHANGED
@@ -281,6 +281,9 @@ function getProperty(object, name) {
281
281
  * @param {*} value Value to be assigned at the provided property.
282
282
  */
283
283
  function setProperty(object, name, value) {
284
+ if (typeof name !== 'string') {
285
+ return;
286
+ }
284
287
  const names = name.split('.');
285
288
  let workingObject = object;
286
289
  names.forEach((propName, index) => {
@@ -262,6 +262,9 @@ export function getProperty(object, name) {
262
262
  * @param {*} value Value to be assigned at the provided property.
263
263
  */
264
264
  export function setProperty(object, name, value) {
265
+ if (typeof name !== 'string') {
266
+ return;
267
+ }
265
268
  const names = name.split('.');
266
269
  let workingObject = object;
267
270
  names.forEach((propName, index) => {
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-ff10728-20250410",
13
+ "version": "0.0.0-next-9410a76-20250416",
14
14
  "main": "index",
15
15
  "module": "index.mjs",
16
16
  "jsnext:main": "index.mjs",
@@ -325,7 +325,7 @@ class AutoColumnSize extends _base.BasePlugin {
325
325
  if (firstVisibleColumn === -1 || lastVisibleColumn === -1) {
326
326
  return;
327
327
  }
328
- const overwriteCache = this.hot.renderCall;
328
+ const overwriteCache = this.hot.forceFullRender;
329
329
  this.calculateColumnsWidth({
330
330
  from: firstVisibleColumn,
331
331
  to: lastVisibleColumn
@@ -321,7 +321,7 @@ export class AutoColumnSize extends BasePlugin {
321
321
  if (firstVisibleColumn === -1 || lastVisibleColumn === -1) {
322
322
  return;
323
323
  }
324
- const overwriteCache = this.hot.renderCall;
324
+ const overwriteCache = this.hot.forceFullRender;
325
325
  this.calculateColumnsWidth({
326
326
  from: firstVisibleColumn,
327
327
  to: lastVisibleColumn
@@ -304,7 +304,7 @@ class AutoRowSize extends _base.BasePlugin {
304
304
  if (firstVisibleRow === -1 || lastVisibleRow === -1) {
305
305
  return;
306
306
  }
307
- const overwriteCache = this.hot.renderCall;
307
+ const overwriteCache = this.hot.forceFullRender;
308
308
  this.calculateRowsHeight({
309
309
  from: firstVisibleRow,
310
310
  to: lastVisibleRow
@@ -405,11 +405,6 @@ class AutoRowSize extends _base.BasePlugin {
405
405
 
406
406
  // @TODO Should call once per render cycle, currently fired separately in different plugins
407
407
  this.hot.view.adjustElementsSize();
408
-
409
- // tmp
410
- if (this.hot.view._wt.wtOverlays.inlineStartOverlay.needFullRender) {
411
- this.hot.view._wt.wtOverlays.inlineStartOverlay.clone.draw();
412
- }
413
408
  }
414
409
  };
415
410
  const syncLimit = this.getSyncCalculationLimit();
@@ -300,7 +300,7 @@ export class AutoRowSize extends BasePlugin {
300
300
  if (firstVisibleRow === -1 || lastVisibleRow === -1) {
301
301
  return;
302
302
  }
303
- const overwriteCache = this.hot.renderCall;
303
+ const overwriteCache = this.hot.forceFullRender;
304
304
  this.calculateRowsHeight({
305
305
  from: firstVisibleRow,
306
306
  to: lastVisibleRow
@@ -401,11 +401,6 @@ export class AutoRowSize extends BasePlugin {
401
401
 
402
402
  // @TODO Should call once per render cycle, currently fired separately in different plugins
403
403
  this.hot.view.adjustElementsSize();
404
-
405
- // tmp
406
- if (this.hot.view._wt.wtOverlays.inlineStartOverlay.needFullRender) {
407
- this.hot.view._wt.wtOverlays.inlineStartOverlay.clone.draw();
408
- }
409
404
  }
410
405
  };
411
406
  const syncLimit = this.getSyncCalculationLimit();
@@ -304,10 +304,6 @@ class ColumnSorting extends _base.BasePlugin {
304
304
  this.hot.runHooks('afterColumnSort', currentSortConfig, sortPossible ? destinationSortConfigs : currentSortConfig, sortPossible);
305
305
  if (sortPossible) {
306
306
  this.hot.render();
307
- // TODO: Workaround? This triggers fast redraw. One test won't pass after removal.
308
- // It should be refactored / described.
309
- this.hot.forceFullRender = false;
310
- this.hot.view.render();
311
307
  }
312
308
  }
313
309
 
@@ -301,10 +301,6 @@ export class ColumnSorting extends BasePlugin {
301
301
  this.hot.runHooks('afterColumnSort', currentSortConfig, sortPossible ? destinationSortConfigs : currentSortConfig, sortPossible);
302
302
  if (sortPossible) {
303
303
  this.hot.render();
304
- // TODO: Workaround? This triggers fast redraw. One test won't pass after removal.
305
- // It should be refactored / described.
306
- this.hot.forceFullRender = false;
307
- this.hot.view.render();
308
304
  }
309
305
  }
310
306
 
@@ -234,6 +234,7 @@ class Comments extends _base.BasePlugin {
234
234
  this.addHook('afterScroll', () => _assertClassBrand(_Comments_brand, this, _onAfterScroll).call(this));
235
235
  this.addHook('afterBeginEditing', () => this.hide());
236
236
  this.addHook('afterDocumentKeyDown', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
237
+ this.addHook('beforeCompositionStart', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
237
238
  this.addHook('afterSetTheme', function () {
238
239
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
239
240
  args[_key2] = arguments[_key2];
@@ -230,6 +230,7 @@ export class Comments extends BasePlugin {
230
230
  this.addHook('afterScroll', () => _assertClassBrand(_Comments_brand, this, _onAfterScroll).call(this));
231
231
  this.addHook('afterBeginEditing', () => this.hide());
232
232
  this.addHook('afterDocumentKeyDown', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
233
+ this.addHook('beforeCompositionStart', event => _assertClassBrand(_Comments_brand, this, _onAfterDocumentKeyDown).call(this, event));
233
234
  this.addHook('afterSetTheme', function () {
234
235
  for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
235
236
  args[_key2] = arguments[_key2];
@@ -39,7 +39,7 @@ function createDefaultShortcutsList(menu) {
39
39
  keys: [['ArrowUp']],
40
40
  callback: () => menu.getNavigator().toPreviousItem()
41
41
  }, {
42
- keys: [['ArrowRight']],
42
+ keys: [[hot.isRtl() ? 'ArrowLeft' : 'ArrowRight']],
43
43
  callback: () => {
44
44
  const selection = hotMenu.getSelectedLast();
45
45
  if (selection) {
@@ -50,7 +50,7 @@ function createDefaultShortcutsList(menu) {
50
50
  }
51
51
  }
52
52
  }, {
53
- keys: [['ArrowLeft']],
53
+ keys: [[hot.isRtl() ? 'ArrowRight' : 'ArrowLeft']],
54
54
  callback: () => {
55
55
  const selection = hotMenu.getSelectedLast();
56
56
  if (selection && menu.isSubMenu()) {
@@ -35,7 +35,7 @@ export function createDefaultShortcutsList(menu) {
35
35
  keys: [['ArrowUp']],
36
36
  callback: () => menu.getNavigator().toPreviousItem()
37
37
  }, {
38
- keys: [['ArrowRight']],
38
+ keys: [[hot.isRtl() ? 'ArrowLeft' : 'ArrowRight']],
39
39
  callback: () => {
40
40
  const selection = hotMenu.getSelectedLast();
41
41
  if (selection) {
@@ -46,7 +46,7 @@ export function createDefaultShortcutsList(menu) {
46
46
  }
47
47
  }
48
48
  }, {
49
- keys: [['ArrowLeft']],
49
+ keys: [[hot.isRtl() ? 'ArrowRight' : 'ArrowLeft']],
50
50
  callback: () => {
51
51
  const selection = hotMenu.getSelectedLast();
52
52
  if (selection && menu.isSubMenu()) {
@@ -293,6 +293,7 @@ class Menu {
293
293
  layoutDirection: this.hot.isRtl() ? 'rtl' : 'ltr',
294
294
  ariaTags: false,
295
295
  themeName: this.hot.getCurrentThemeName(),
296
+ beforeRefreshDimensions: () => false,
296
297
  beforeOnCellMouseOver: (event, coords) => {
297
298
  _classPrivateFieldGet(_navigator, this).setCurrentPage(coords.row);
298
299
  },
@@ -289,6 +289,7 @@ export class Menu {
289
289
  layoutDirection: this.hot.isRtl() ? 'rtl' : 'ltr',
290
290
  ariaTags: false,
291
291
  themeName: this.hot.getCurrentThemeName(),
292
+ beforeRefreshDimensions: () => false,
292
293
  beforeOnCellMouseOver: (event, coords) => {
293
294
  _classPrivateFieldGet(_navigator, this).setCurrentPage(coords.row);
294
295
  },
@@ -143,7 +143,11 @@ class Positioner {
143
143
  setPositionAboveCursor() {
144
144
  let top = _classPrivateFieldGet(_offset, this).above + _classPrivateFieldGet(_cursor, this).top - _classPrivateFieldGet(_container, this).offsetHeight;
145
145
  if (_classPrivateFieldGet(_parentContainer, this)) {
146
- top = _classPrivateFieldGet(_cursor, this).top + _classPrivateFieldGet(_cursor, this).cellHeight - _classPrivateFieldGet(_container, this).offsetHeight + 3;
146
+ const rootWindow = _classPrivateFieldGet(_parentContainer, this).ownerDocument.defaultView;
147
+ const style = rootWindow.getComputedStyle(_classPrivateFieldGet(_parentContainer, this).querySelector('.ht_master'));
148
+ const paddingTop = Number.parseInt(style.paddingTop, 10);
149
+ const borderTop = Number.parseInt(style.borderTop, 10);
150
+ top = _classPrivateFieldGet(_cursor, this).top + _classPrivateFieldGet(_cursor, this).cellHeight - _classPrivateFieldGet(_container, this).scrollHeight + paddingTop + borderTop;
147
151
  }
148
152
  _classPrivateFieldGet(_container, this).style.top = `${top}px`;
149
153
  }
@@ -154,7 +158,11 @@ class Positioner {
154
158
  setPositionBelowCursor() {
155
159
  let top = _classPrivateFieldGet(_offset, this).below + _classPrivateFieldGet(_cursor, this).top + 1;
156
160
  if (_classPrivateFieldGet(_parentContainer, this)) {
157
- top = _classPrivateFieldGet(_cursor, this).top - 1;
161
+ const rootWindow = _classPrivateFieldGet(_parentContainer, this).ownerDocument.defaultView;
162
+ const style = rootWindow.getComputedStyle(_classPrivateFieldGet(_parentContainer, this).querySelector('.ht_master'));
163
+ const paddingTop = Number.parseInt(style.paddingTop, 10);
164
+ const borderTop = Number.parseInt(style.borderTop, 10);
165
+ top = _classPrivateFieldGet(_cursor, this).top - paddingTop - borderTop - 1;
158
166
  }
159
167
  _classPrivateFieldGet(_container, this).style.top = `${top}px`;
160
168
  }
@@ -140,7 +140,11 @@ export class Positioner {
140
140
  setPositionAboveCursor() {
141
141
  let top = _classPrivateFieldGet(_offset, this).above + _classPrivateFieldGet(_cursor, this).top - _classPrivateFieldGet(_container, this).offsetHeight;
142
142
  if (_classPrivateFieldGet(_parentContainer, this)) {
143
- top = _classPrivateFieldGet(_cursor, this).top + _classPrivateFieldGet(_cursor, this).cellHeight - _classPrivateFieldGet(_container, this).offsetHeight + 3;
143
+ const rootWindow = _classPrivateFieldGet(_parentContainer, this).ownerDocument.defaultView;
144
+ const style = rootWindow.getComputedStyle(_classPrivateFieldGet(_parentContainer, this).querySelector('.ht_master'));
145
+ const paddingTop = Number.parseInt(style.paddingTop, 10);
146
+ const borderTop = Number.parseInt(style.borderTop, 10);
147
+ top = _classPrivateFieldGet(_cursor, this).top + _classPrivateFieldGet(_cursor, this).cellHeight - _classPrivateFieldGet(_container, this).scrollHeight + paddingTop + borderTop;
144
148
  }
145
149
  _classPrivateFieldGet(_container, this).style.top = `${top}px`;
146
150
  }
@@ -151,7 +155,11 @@ export class Positioner {
151
155
  setPositionBelowCursor() {
152
156
  let top = _classPrivateFieldGet(_offset, this).below + _classPrivateFieldGet(_cursor, this).top + 1;
153
157
  if (_classPrivateFieldGet(_parentContainer, this)) {
154
- top = _classPrivateFieldGet(_cursor, this).top - 1;
158
+ const rootWindow = _classPrivateFieldGet(_parentContainer, this).ownerDocument.defaultView;
159
+ const style = rootWindow.getComputedStyle(_classPrivateFieldGet(_parentContainer, this).querySelector('.ht_master'));
160
+ const paddingTop = Number.parseInt(style.paddingTop, 10);
161
+ const borderTop = Number.parseInt(style.borderTop, 10);
162
+ top = _classPrivateFieldGet(_cursor, this).top - paddingTop - borderTop - 1;
155
163
  }
156
164
  _classPrivateFieldGet(_container, this).style.top = `${top}px`;
157
165
  }
@@ -256,6 +256,9 @@ class CopyPaste extends _base.BasePlugin {
256
256
  return _assertClassBrand(_CopyPaste_brand, _this, _onAfterSelection).call(_this, ...args);
257
257
  });
258
258
  this.addHook('afterSelectionEnd', () => _assertClassBrand(_CopyPaste_brand, this, _onAfterSelectionEnd).call(this));
259
+
260
+ // Events are attached to the document, not the root table element - as it should,
261
+ // for Chrome 133 and lower to copy/paste/cut work properly (#dev-2277).
259
262
  this.eventManager.addEventListener(this.hot.rootDocument, 'copy', function () {
260
263
  return _this.onCopy(...arguments);
261
264
  });
@@ -562,12 +565,10 @@ class CopyPaste extends _base.BasePlugin {
562
565
  * @private
563
566
  */
564
567
  onCopy(event) {
565
- var _event$target, _this$hot$getSelected;
568
+ const eventTarget = event.composedPath()[0];
566
569
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
567
- const isHotInput = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.hasAttribute('data-hot-input');
568
- const selectedCell = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
569
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
570
- if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCopy, this) || this.isEditorOpened() || (0, _element.isHTMLElement)(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
570
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
571
+ if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCopy, this) || this.isEditorOpened() || (0, _element.isHTMLElement)(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !(0, _element.isInternalElement)(eventTarget, this.hot.rootElement))) {
571
572
  return;
572
573
  }
573
574
  event.preventDefault();
@@ -597,12 +598,10 @@ class CopyPaste extends _base.BasePlugin {
597
598
  * @private
598
599
  */
599
600
  onCut(event) {
600
- var _event$target2, _this$hot$getSelected2;
601
+ const eventTarget = event.composedPath()[0];
601
602
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
602
- const isHotInput = (_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.hasAttribute('data-hot-input');
603
- const selectedCell = (_this$hot$getSelected2 = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected2 === void 0 ? void 0 : _this$hot$getSelected2.highlight;
604
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
605
- if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCut, this) || this.isEditorOpened() || (0, _element.isHTMLElement)(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
603
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
604
+ if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCut, this) || this.isEditorOpened() || (0, _element.isHTMLElement)(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !(0, _element.isInternalElement)(eventTarget, this.hot.rootElement))) {
606
605
  return;
607
606
  }
608
607
  event.preventDefault();
@@ -631,12 +630,10 @@ class CopyPaste extends _base.BasePlugin {
631
630
  * @private
632
631
  */
633
632
  onPaste(event) {
634
- var _event$target3, _this$hot$getSelected3;
633
+ const eventTarget = event.composedPath()[0];
635
634
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
636
- const isHotInput = (_event$target3 = event.target) === null || _event$target3 === void 0 ? void 0 : _event$target3.hasAttribute('data-hot-input');
637
- const selectedCell = (_this$hot$getSelected3 = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected3 === void 0 ? void 0 : _this$hot$getSelected3.highlight;
638
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
639
- if (!this.hot.isListening() || this.isEditorOpened() || !this.hot.getSelected() || (0, _element.isHTMLElement)(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
635
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
636
+ if (!this.hot.isListening() || this.isEditorOpened() || !this.hot.getSelected() || (0, _element.isHTMLElement)(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !(0, _element.isInternalElement)(eventTarget, this.hot.rootElement))) {
640
637
  return;
641
638
  }
642
639
  event.preventDefault();