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
@@ -17,7 +17,7 @@ import { Hooks } from "../../core/hooks/index.mjs";
17
17
  import { stringify, parse } from "../../3rdparty/SheetClip/index.mjs";
18
18
  import { arrayEach } from "../../helpers/array.mjs";
19
19
  import { sanitize } from "../../helpers/string.mjs";
20
- import { removeContentEditableFromElementAndDeselect, runWithSelectedContendEditableElement, makeElementContentEditableAndSelectItsContent, isHTMLElement } from "../../helpers/dom/element.mjs";
20
+ import { removeContentEditableFromElementAndDeselect, runWithSelectedContendEditableElement, makeElementContentEditableAndSelectItsContent, isHTMLElement, isInternalElement } from "../../helpers/dom/element.mjs";
21
21
  import { isSafari } from "../../helpers/browser.mjs";
22
22
  import copyItem from "./contextMenuItem/copy.mjs";
23
23
  import copyColumnHeadersOnlyItem from "./contextMenuItem/copyColumnHeadersOnly.mjs";
@@ -252,6 +252,9 @@ export class CopyPaste extends BasePlugin {
252
252
  return _assertClassBrand(_CopyPaste_brand, _this, _onAfterSelection).call(_this, ...args);
253
253
  });
254
254
  this.addHook('afterSelectionEnd', () => _assertClassBrand(_CopyPaste_brand, this, _onAfterSelectionEnd).call(this));
255
+
256
+ // Events are attached to the document, not the root table element - as it should,
257
+ // for Chrome 133 and lower to copy/paste/cut work properly (#dev-2277).
255
258
  this.eventManager.addEventListener(this.hot.rootDocument, 'copy', function () {
256
259
  return _this.onCopy(...arguments);
257
260
  });
@@ -558,12 +561,10 @@ export class CopyPaste extends BasePlugin {
558
561
  * @private
559
562
  */
560
563
  onCopy(event) {
561
- var _event$target, _this$hot$getSelected;
564
+ const eventTarget = event.composedPath()[0];
562
565
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
563
- const isHotInput = (_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.hasAttribute('data-hot-input');
564
- const selectedCell = (_this$hot$getSelected = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected === void 0 ? void 0 : _this$hot$getSelected.highlight;
565
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
566
- if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCopy, this) || this.isEditorOpened() || isHTMLElement(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
566
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
567
+ if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCopy, this) || this.isEditorOpened() || isHTMLElement(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !isInternalElement(eventTarget, this.hot.rootElement))) {
567
568
  return;
568
569
  }
569
570
  event.preventDefault();
@@ -593,12 +594,10 @@ export class CopyPaste extends BasePlugin {
593
594
  * @private
594
595
  */
595
596
  onCut(event) {
596
- var _event$target2, _this$hot$getSelected2;
597
+ const eventTarget = event.composedPath()[0];
597
598
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
598
- const isHotInput = (_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.hasAttribute('data-hot-input');
599
- const selectedCell = (_this$hot$getSelected2 = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected2 === void 0 ? void 0 : _this$hot$getSelected2.highlight;
600
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
601
- if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCut, this) || this.isEditorOpened() || isHTMLElement(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
599
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
600
+ if (!this.hot.isListening() && !_classPrivateFieldGet(_isTriggeredByCut, this) || this.isEditorOpened() || isHTMLElement(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !isInternalElement(eventTarget, this.hot.rootElement))) {
602
601
  return;
603
602
  }
604
603
  event.preventDefault();
@@ -627,12 +626,10 @@ export class CopyPaste extends BasePlugin {
627
626
  * @private
628
627
  */
629
628
  onPaste(event) {
630
- var _event$target3, _this$hot$getSelected3;
629
+ const eventTarget = event.composedPath()[0];
631
630
  const focusedElement = this.hot.getFocusManager().getRefocusElement();
632
- const isHotInput = (_event$target3 = event.target) === null || _event$target3 === void 0 ? void 0 : _event$target3.hasAttribute('data-hot-input');
633
- const selectedCell = (_this$hot$getSelected3 = this.hot.getSelectedRangeLast()) === null || _this$hot$getSelected3 === void 0 ? void 0 : _this$hot$getSelected3.highlight;
634
- const TD = selectedCell ? this.hot.getCell(selectedCell.row, selectedCell.col, true) : null;
635
- if (!this.hot.isListening() || this.isEditorOpened() || !this.hot.getSelected() || isHTMLElement(event.target) && (isHotInput && event.target !== focusedElement || !isHotInput && event.target !== this.hot.rootDocument.body && TD !== event.target)) {
631
+ const isHotInput = eventTarget === null || eventTarget === void 0 ? void 0 : eventTarget.hasAttribute('data-hot-input');
632
+ if (!this.hot.isListening() || this.isEditorOpened() || !this.hot.getSelected() || isHTMLElement(eventTarget) && (isHotInput && eventTarget !== focusedElement || !isHotInput && eventTarget !== this.hot.rootDocument.body && !isInternalElement(eventTarget, this.hot.rootElement))) {
636
633
  return;
637
634
  }
638
635
  event.preventDefault();
@@ -11,5 +11,8 @@ class PasteEvent {
11
11
  this.clipboardData = new _clipboardData.default();
12
12
  }
13
13
  preventDefault() {}
14
+ composedPath() {
15
+ return [];
16
+ }
14
17
  }
15
18
  exports.default = PasteEvent;
@@ -7,4 +7,7 @@ export default class PasteEvent {
7
7
  this.clipboardData = new ClipboardData();
8
8
  }
9
9
  preventDefault() {}
10
+ composedPath() {
11
+ return [];
12
+ }
10
13
  }
@@ -542,10 +542,10 @@ class Filters extends _base.BasePlugin {
542
542
  *
543
543
  * @returns {Array}
544
544
  */
545
- /* eslint-enable jsdoc/require-description-complete-sentence */
546
545
  exportConditions() {
547
546
  return this.conditionCollection.exportAllConditions();
548
547
  }
548
+ /* eslint-enable jsdoc/require-description-complete-sentence */
549
549
 
550
550
  /**
551
551
  * Filters data based on added filter conditions.
@@ -562,38 +562,39 @@ class Filters extends _base.BasePlugin {
562
562
  let visibleVisualRows = [];
563
563
  const conditions = this.exportConditions();
564
564
  const allowFiltering = this.hot.runHooks('beforeFilter', conditions, _classPrivateFieldGet(_previousConditionStack, this));
565
- if (allowFiltering !== false) {
566
- if (needToFilter) {
567
- const trimmedRows = [];
568
- this.hot.batchExecution(() => {
569
- this.filtersRowsMap.clear();
570
- visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), rowData => rowData.meta.visualRow);
571
- const visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
572
- (0, _number.rangeEach)(this.hot.countSourceRows() - 1, row => {
573
- if (!visibleVisualRowsAssertion(row)) {
574
- trimmedRows.push(row);
575
- }
576
- });
577
- (0, _array.arrayEach)(trimmedRows, physicalRow => {
578
- this.filtersRowsMap.setValueAtIndex(physicalRow, true);
579
- });
580
- }, true);
581
- if (!navigableHeaders && !visibleVisualRows.length) {
582
- this.hot.deselectCell();
583
- }
584
- } else {
565
+ if (allowFiltering !== false && needToFilter) {
566
+ const trimmedRows = [];
567
+ this.hot.batchExecution(() => {
585
568
  this.filtersRowsMap.clear();
569
+ visibleVisualRows = (0, _array.arrayMap)(dataFilter.filter(), rowData => rowData.meta.visualRow);
570
+ const visibleVisualRowsAssertion = (0, _utils.createArrayAssertion)(visibleVisualRows);
571
+ (0, _number.rangeEach)(this.hot.countSourceRows() - 1, row => {
572
+ if (!visibleVisualRowsAssertion(row)) {
573
+ trimmedRows.push(row);
574
+ }
575
+ });
576
+ (0, _array.arrayEach)(trimmedRows, physicalRow => {
577
+ this.filtersRowsMap.setValueAtIndex(physicalRow, true);
578
+ });
579
+ }, true);
580
+ if (!navigableHeaders && !visibleVisualRows.length) {
581
+ this.hot.deselectCell();
586
582
  }
587
583
  _classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
588
- this.hot.runHooks('afterFilter', conditions);
589
- this.hot.view.adjustElementsSize();
590
- this.hot.render();
584
+ } else if (allowFiltering !== false && !needToFilter) {
585
+ _classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
586
+ this.filtersRowsMap.clear();
591
587
  } else {
592
588
  this.importConditions(_classPrivateFieldGet(_previousConditionStack, this));
593
589
  }
594
590
  if (this.hot.selection.isSelected()) {
595
591
  this.hot.selectCell(navigableHeaders ? -1 : 0, this.hot.getSelectedRangeLast().highlight.col);
596
592
  }
593
+ if (allowFiltering !== false) {
594
+ this.hot.runHooks('afterFilter', conditions);
595
+ this.hot.view.adjustElementsSize();
596
+ this.hot.render();
597
+ }
597
598
  }
598
599
 
599
600
  /**
@@ -536,10 +536,10 @@ export class Filters extends BasePlugin {
536
536
  *
537
537
  * @returns {Array}
538
538
  */
539
- /* eslint-enable jsdoc/require-description-complete-sentence */
540
539
  exportConditions() {
541
540
  return this.conditionCollection.exportAllConditions();
542
541
  }
542
+ /* eslint-enable jsdoc/require-description-complete-sentence */
543
543
 
544
544
  /**
545
545
  * Filters data based on added filter conditions.
@@ -556,38 +556,39 @@ export class Filters extends BasePlugin {
556
556
  let visibleVisualRows = [];
557
557
  const conditions = this.exportConditions();
558
558
  const allowFiltering = this.hot.runHooks('beforeFilter', conditions, _classPrivateFieldGet(_previousConditionStack, this));
559
- if (allowFiltering !== false) {
560
- if (needToFilter) {
561
- const trimmedRows = [];
562
- this.hot.batchExecution(() => {
563
- this.filtersRowsMap.clear();
564
- visibleVisualRows = arrayMap(dataFilter.filter(), rowData => rowData.meta.visualRow);
565
- const visibleVisualRowsAssertion = createArrayAssertion(visibleVisualRows);
566
- rangeEach(this.hot.countSourceRows() - 1, row => {
567
- if (!visibleVisualRowsAssertion(row)) {
568
- trimmedRows.push(row);
569
- }
570
- });
571
- arrayEach(trimmedRows, physicalRow => {
572
- this.filtersRowsMap.setValueAtIndex(physicalRow, true);
573
- });
574
- }, true);
575
- if (!navigableHeaders && !visibleVisualRows.length) {
576
- this.hot.deselectCell();
577
- }
578
- } else {
559
+ if (allowFiltering !== false && needToFilter) {
560
+ const trimmedRows = [];
561
+ this.hot.batchExecution(() => {
579
562
  this.filtersRowsMap.clear();
563
+ visibleVisualRows = arrayMap(dataFilter.filter(), rowData => rowData.meta.visualRow);
564
+ const visibleVisualRowsAssertion = createArrayAssertion(visibleVisualRows);
565
+ rangeEach(this.hot.countSourceRows() - 1, row => {
566
+ if (!visibleVisualRowsAssertion(row)) {
567
+ trimmedRows.push(row);
568
+ }
569
+ });
570
+ arrayEach(trimmedRows, physicalRow => {
571
+ this.filtersRowsMap.setValueAtIndex(physicalRow, true);
572
+ });
573
+ }, true);
574
+ if (!navigableHeaders && !visibleVisualRows.length) {
575
+ this.hot.deselectCell();
580
576
  }
581
577
  _classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
582
- this.hot.runHooks('afterFilter', conditions);
583
- this.hot.view.adjustElementsSize();
584
- this.hot.render();
578
+ } else if (allowFiltering !== false && !needToFilter) {
579
+ _classPrivateFieldSet(_previousConditionStack, this, this.exportConditions());
580
+ this.filtersRowsMap.clear();
585
581
  } else {
586
582
  this.importConditions(_classPrivateFieldGet(_previousConditionStack, this));
587
583
  }
588
584
  if (this.hot.selection.isSelected()) {
589
585
  this.hot.selectCell(navigableHeaders ? -1 : 0, this.hot.getSelectedRangeLast().highlight.col);
590
586
  }
587
+ if (allowFiltering !== false) {
588
+ this.hot.runHooks('afterFilter', conditions);
589
+ this.hot.view.adjustElementsSize();
590
+ this.hot.render();
591
+ }
591
592
  }
592
593
 
593
594
  /**
@@ -253,7 +253,13 @@ class MultipleSelectUI extends _base.BaseUI {
253
253
  beforeOnCellMouseUp: () => {
254
254
  _classPrivateFieldGet(_itemsBox, this).listen();
255
255
  },
256
- colWidths: () => _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument),
256
+ modifyColWidth: width => {
257
+ const minWidth = _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - (0, _element.getScrollbarWidth)(rootDocument);
258
+ if (width !== undefined && width < minWidth) {
259
+ return minWidth;
260
+ }
261
+ return width;
262
+ },
257
263
  maxCols: 1,
258
264
  autoWrapCol: true,
259
265
  height: 110,
@@ -248,7 +248,13 @@ export class MultipleSelectUI extends BaseUI {
248
248
  beforeOnCellMouseUp: () => {
249
249
  _classPrivateFieldGet(_itemsBox, this).listen();
250
250
  },
251
- colWidths: () => _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - getScrollbarWidth(rootDocument),
251
+ modifyColWidth: width => {
252
+ const minWidth = _classPrivateFieldGet(_itemsBox, this).container.scrollWidth - getScrollbarWidth(rootDocument);
253
+ if (width !== undefined && width < minWidth) {
254
+ return minWidth;
255
+ }
256
+ return width;
257
+ },
252
258
  maxCols: 1,
253
259
  autoWrapCol: true,
254
260
  height: 110,
@@ -231,8 +231,8 @@ class HiddenColumns extends _base.BasePlugin {
231
231
  * Disables the plugin functionality for this Handsontable instance.
232
232
  */
233
233
  disablePlugin() {
234
- this.hot.columnIndexMapper.unregisterMap(this.pluginName);
235
234
  super.disablePlugin();
235
+ this.hot.columnIndexMapper.unregisterMap(this.pluginName);
236
236
  this.resetCellsMeta();
237
237
  }
238
238
 
@@ -227,8 +227,8 @@ export class HiddenColumns extends BasePlugin {
227
227
  * Disables the plugin functionality for this Handsontable instance.
228
228
  */
229
229
  disablePlugin() {
230
- this.hot.columnIndexMapper.unregisterMap(this.pluginName);
231
230
  super.disablePlugin();
231
+ this.hot.columnIndexMapper.unregisterMap(this.pluginName);
232
232
  this.resetCellsMeta();
233
233
  }
234
234
 
@@ -231,8 +231,8 @@ class HiddenRows extends _base.BasePlugin {
231
231
  * Disables the plugin functionality for this Handsontable instance.
232
232
  */
233
233
  disablePlugin() {
234
- this.hot.rowIndexMapper.unregisterMap(this.pluginName);
235
234
  super.disablePlugin();
235
+ this.hot.rowIndexMapper.unregisterMap(this.pluginName);
236
236
  this.resetCellsMeta();
237
237
  }
238
238
 
@@ -227,8 +227,8 @@ export class HiddenRows extends BasePlugin {
227
227
  * Disables the plugin functionality for this Handsontable instance.
228
228
  */
229
229
  disablePlugin() {
230
- this.hot.rowIndexMapper.unregisterMap(this.pluginName);
231
230
  super.disablePlugin();
231
+ this.hot.rowIndexMapper.unregisterMap(this.pluginName);
232
232
  this.resetCellsMeta();
233
233
  }
234
234
 
@@ -341,12 +341,12 @@ class ManualColumnResize extends _base.BasePlugin {
341
341
  setupGuidePosition() {
342
342
  const handleHeight = parseInt((0, _element.outerHeight)(_classPrivateFieldGet(_handle, this)), 10);
343
343
  const handleBottomPosition = parseInt(_classPrivateFieldGet(_handle, this).style.top, 10) + handleHeight;
344
- const maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10);
344
+ const tableHeight = this.hot.view.getTableHeight();
345
345
  (0, _element.addClass)(_classPrivateFieldGet(_handle, this), 'active');
346
346
  (0, _element.addClass)(_classPrivateFieldGet(_guide, this), 'active');
347
347
  _classPrivateFieldGet(_guide, this).style.top = `${handleBottomPosition}px`;
348
348
  this.refreshGuidePosition();
349
- _classPrivateFieldGet(_guide, this).style.height = `${maximumVisibleElementHeight - handleHeight}px`;
349
+ _classPrivateFieldGet(_guide, this).style.height = `${tableHeight - handleHeight}px`;
350
350
  this.hot.rootElement.appendChild(_classPrivateFieldGet(_guide, this));
351
351
  }
352
352
 
@@ -417,8 +417,7 @@ class ManualColumnResize extends _base.BasePlugin {
417
417
  */
418
418
  afterMouseDownTimeout() {
419
419
  const render = () => {
420
- this.hot.forceFullRender = true;
421
- this.hot.view.render(); // updates all
420
+ this.hot.render();
422
421
  this.hot.view.adjustElementsSize();
423
422
  };
424
423
  const resize = (column, forceRender) => {
@@ -578,8 +577,7 @@ function _onMouseMove(event) {
578
577
  */
579
578
  function _onMouseUp() {
580
579
  const render = () => {
581
- this.hot.forceFullRender = true;
582
- this.hot.view.render(); // updates all
580
+ this.hot.render();
583
581
  this.hot.view.adjustElementsSize();
584
582
  };
585
583
  const resize = (column, forceRender) => {
@@ -336,12 +336,12 @@ export class ManualColumnResize extends BasePlugin {
336
336
  setupGuidePosition() {
337
337
  const handleHeight = parseInt(outerHeight(_classPrivateFieldGet(_handle, this)), 10);
338
338
  const handleBottomPosition = parseInt(_classPrivateFieldGet(_handle, this).style.top, 10) + handleHeight;
339
- const maximumVisibleElementHeight = parseInt(this.hot.view.maximumVisibleElementHeight(0), 10);
339
+ const tableHeight = this.hot.view.getTableHeight();
340
340
  addClass(_classPrivateFieldGet(_handle, this), 'active');
341
341
  addClass(_classPrivateFieldGet(_guide, this), 'active');
342
342
  _classPrivateFieldGet(_guide, this).style.top = `${handleBottomPosition}px`;
343
343
  this.refreshGuidePosition();
344
- _classPrivateFieldGet(_guide, this).style.height = `${maximumVisibleElementHeight - handleHeight}px`;
344
+ _classPrivateFieldGet(_guide, this).style.height = `${tableHeight - handleHeight}px`;
345
345
  this.hot.rootElement.appendChild(_classPrivateFieldGet(_guide, this));
346
346
  }
347
347
 
@@ -412,8 +412,7 @@ export class ManualColumnResize extends BasePlugin {
412
412
  */
413
413
  afterMouseDownTimeout() {
414
414
  const render = () => {
415
- this.hot.forceFullRender = true;
416
- this.hot.view.render(); // updates all
415
+ this.hot.render();
417
416
  this.hot.view.adjustElementsSize();
418
417
  };
419
418
  const resize = (column, forceRender) => {
@@ -572,8 +571,7 @@ function _onMouseMove(event) {
572
571
  */
573
572
  function _onMouseUp() {
574
573
  const render = () => {
575
- this.hot.forceFullRender = true;
576
- this.hot.view.render(); // updates all
574
+ this.hot.render();
577
575
  this.hot.view.adjustElementsSize();
578
576
  };
579
577
  const resize = (column, forceRender) => {
@@ -328,12 +328,12 @@ class ManualRowResize extends _base.BasePlugin {
328
328
  setupGuidePosition() {
329
329
  const handleWidth = parseInt((0, _element.outerWidth)(_classPrivateFieldGet(_handle, this)), 10);
330
330
  const handleEndPosition = parseInt(_classPrivateFieldGet(_handle, this).style[this.inlineDir], 10) + handleWidth;
331
- const maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10);
331
+ const tableWidth = this.hot.view.getTableWidth();
332
332
  (0, _element.addClass)(_classPrivateFieldGet(_handle, this), 'active');
333
333
  (0, _element.addClass)(_classPrivateFieldGet(_guide, this), 'active');
334
334
  _classPrivateFieldGet(_guide, this).style.top = _classPrivateFieldGet(_handle, this).style.top;
335
335
  _classPrivateFieldGet(_guide, this).style[this.inlineDir] = `${handleEndPosition}px`;
336
- _classPrivateFieldGet(_guide, this).style.width = `${maximumVisibleElementWidth - handleWidth}px`;
336
+ _classPrivateFieldGet(_guide, this).style.width = `${tableWidth - handleWidth}px`;
337
337
  this.hot.rootElement.appendChild(_classPrivateFieldGet(_guide, this));
338
338
  }
339
339
 
@@ -414,8 +414,7 @@ class ManualRowResize extends _base.BasePlugin {
414
414
  */
415
415
  afterMouseDownTimeout() {
416
416
  const render = () => {
417
- this.hot.forceFullRender = true;
418
- this.hot.view.render(); // updates all
417
+ this.hot.render();
419
418
  this.hot.view.adjustElementsSize();
420
419
  };
421
420
  const resize = (row, forceRender) => {
@@ -543,8 +542,7 @@ function _onMouseMove(event) {
543
542
  */
544
543
  function _onMouseUp() {
545
544
  const render = () => {
546
- this.hot.forceFullRender = true;
547
- this.hot.view.render(); // updates all
545
+ this.hot.render();
548
546
  this.hot.view.adjustElementsSize();
549
547
  };
550
548
  const runHooks = (row, forceRender) => {
@@ -323,12 +323,12 @@ export class ManualRowResize extends BasePlugin {
323
323
  setupGuidePosition() {
324
324
  const handleWidth = parseInt(outerWidth(_classPrivateFieldGet(_handle, this)), 10);
325
325
  const handleEndPosition = parseInt(_classPrivateFieldGet(_handle, this).style[this.inlineDir], 10) + handleWidth;
326
- const maximumVisibleElementWidth = parseInt(this.hot.view.maximumVisibleElementWidth(0), 10);
326
+ const tableWidth = this.hot.view.getTableWidth();
327
327
  addClass(_classPrivateFieldGet(_handle, this), 'active');
328
328
  addClass(_classPrivateFieldGet(_guide, this), 'active');
329
329
  _classPrivateFieldGet(_guide, this).style.top = _classPrivateFieldGet(_handle, this).style.top;
330
330
  _classPrivateFieldGet(_guide, this).style[this.inlineDir] = `${handleEndPosition}px`;
331
- _classPrivateFieldGet(_guide, this).style.width = `${maximumVisibleElementWidth - handleWidth}px`;
331
+ _classPrivateFieldGet(_guide, this).style.width = `${tableWidth - handleWidth}px`;
332
332
  this.hot.rootElement.appendChild(_classPrivateFieldGet(_guide, this));
333
333
  }
334
334
 
@@ -409,8 +409,7 @@ export class ManualRowResize extends BasePlugin {
409
409
  */
410
410
  afterMouseDownTimeout() {
411
411
  const render = () => {
412
- this.hot.forceFullRender = true;
413
- this.hot.view.render(); // updates all
412
+ this.hot.render();
414
413
  this.hot.view.adjustElementsSize();
415
414
  };
416
415
  const resize = (row, forceRender) => {
@@ -537,8 +536,7 @@ function _onMouseMove(event) {
537
536
  */
538
537
  function _onMouseUp() {
539
538
  const render = () => {
540
- this.hot.forceFullRender = true;
541
- this.hot.view.render(); // updates all
539
+ this.hot.render();
542
540
  this.hot.view.adjustElementsSize();
543
541
  };
544
542
  const runHooks = (row, forceRender) => {
@@ -30,6 +30,7 @@ var _element = require("../../helpers/dom/element");
30
30
  var _browser = require("../../helpers/browser");
31
31
  var _focusOrder2 = require("./focusOrder");
32
32
  var _renderer = require("./renderer");
33
+ var _utils = require("./utils");
33
34
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
34
35
  function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
35
36
  function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
@@ -666,8 +667,12 @@ class MergeCells extends _base.BasePlugin {
666
667
  * @param {CellRange} cellRange The cell range to merge or unmerged.
667
668
  */
668
669
  toggleMerge(cellRange) {
669
- const mergedCell = this.mergedCellsCollection.get(cellRange.from.row, cellRange.from.col);
670
- const mergedCellCoversWholeRange = mergedCell.row === cellRange.from.row && mergedCell.col === cellRange.from.col && mergedCell.row + mergedCell.rowspan - 1 === cellRange.to.row && mergedCell.col + mergedCell.colspan - 1 === cellRange.to.col;
670
+ const {
671
+ from,
672
+ to
673
+ } = cellRange.clone().normalize();
674
+ const mergedCell = this.mergedCellsCollection.get(from.row, from.col);
675
+ const mergedCellCoversWholeRange = mergedCell.row === from.row && mergedCell.col === from.col && mergedCell.row + mergedCell.rowspan - 1 === to.row && mergedCell.col + mergedCell.colspan - 1 === to.col;
671
676
  if (mergedCellCoversWholeRange) {
672
677
  this.unmergeRange(cellRange);
673
678
  } else {
@@ -1479,33 +1484,7 @@ function _onModifyRowHeightByOverlayName(height, row, overlayType) {
1479
1484
  } else {
1480
1485
  rowspanAfterCorrection = rowspan - rowspanCorrection;
1481
1486
  }
1482
- height = Math.max(height !== null && height !== void 0 ? height : 0, _assertClassBrand(_MergeCells_brand, this, _sumCellsHeights).call(this, row, rowspanAfterCorrection));
1487
+ height = Math.max(height !== null && height !== void 0 ? height : 0, (0, _utils.sumCellsHeights)(this.hot, row, rowspanAfterCorrection));
1483
1488
  });
1484
1489
  return height;
1485
- }
1486
- /**
1487
- * Sums the heights of the all cells that the merge cell consists of.
1488
- *
1489
- * @param {number} row The visual row index of the merged cell.
1490
- * @param {number} rowspan The rowspan value of the merged cell.
1491
- * @returns {number}
1492
- */
1493
- function _sumCellsHeights(row, rowspan) {
1494
- const {
1495
- view,
1496
- rowIndexMapper
1497
- } = this.hot;
1498
- const stylesHandler = view.getStylesHandler();
1499
- const defaultHeight = view.getDefaultRowHeight();
1500
- let height = 0;
1501
- for (let i = row; i < row + rowspan; i++) {
1502
- if (!rowIndexMapper.isHidden(i)) {
1503
- var _this$hot$getRowHeigh;
1504
- height += (_this$hot$getRowHeigh = this.hot.getRowHeight(i)) !== null && _this$hot$getRowHeigh !== void 0 ? _this$hot$getRowHeigh : defaultHeight;
1505
- if (i === 0 && !stylesHandler.isClassicTheme()) {
1506
- height += 1; // border-top-width
1507
- }
1508
- }
1509
- }
1510
- return height;
1511
1490
  }
@@ -36,6 +36,7 @@ import { getStyle } from "../../helpers/dom/element.mjs";
36
36
  import { isChrome } from "../../helpers/browser.mjs";
37
37
  import { FocusOrder } from "./focusOrder.mjs";
38
38
  import { createMergeCellRenderer } from "./renderer.mjs";
39
+ import { sumCellsHeights } from "./utils.mjs";
39
40
  Hooks.getSingleton().register('beforeMergeCells');
40
41
  Hooks.getSingleton().register('afterMergeCells');
41
42
  Hooks.getSingleton().register('beforeUnmergeCells');
@@ -662,8 +663,12 @@ export class MergeCells extends BasePlugin {
662
663
  * @param {CellRange} cellRange The cell range to merge or unmerged.
663
664
  */
664
665
  toggleMerge(cellRange) {
665
- const mergedCell = this.mergedCellsCollection.get(cellRange.from.row, cellRange.from.col);
666
- const mergedCellCoversWholeRange = mergedCell.row === cellRange.from.row && mergedCell.col === cellRange.from.col && mergedCell.row + mergedCell.rowspan - 1 === cellRange.to.row && mergedCell.col + mergedCell.colspan - 1 === cellRange.to.col;
666
+ const {
667
+ from,
668
+ to
669
+ } = cellRange.clone().normalize();
670
+ const mergedCell = this.mergedCellsCollection.get(from.row, from.col);
671
+ const mergedCellCoversWholeRange = mergedCell.row === from.row && mergedCell.col === from.col && mergedCell.row + mergedCell.rowspan - 1 === to.row && mergedCell.col + mergedCell.colspan - 1 === to.col;
667
672
  if (mergedCellCoversWholeRange) {
668
673
  this.unmergeRange(cellRange);
669
674
  } else {
@@ -1474,33 +1479,7 @@ function _onModifyRowHeightByOverlayName(height, row, overlayType) {
1474
1479
  } else {
1475
1480
  rowspanAfterCorrection = rowspan - rowspanCorrection;
1476
1481
  }
1477
- height = Math.max(height !== null && height !== void 0 ? height : 0, _assertClassBrand(_MergeCells_brand, this, _sumCellsHeights).call(this, row, rowspanAfterCorrection));
1482
+ height = Math.max(height !== null && height !== void 0 ? height : 0, sumCellsHeights(this.hot, row, rowspanAfterCorrection));
1478
1483
  });
1479
1484
  return height;
1480
- }
1481
- /**
1482
- * Sums the heights of the all cells that the merge cell consists of.
1483
- *
1484
- * @param {number} row The visual row index of the merged cell.
1485
- * @param {number} rowspan The rowspan value of the merged cell.
1486
- * @returns {number}
1487
- */
1488
- function _sumCellsHeights(row, rowspan) {
1489
- const {
1490
- view,
1491
- rowIndexMapper
1492
- } = this.hot;
1493
- const stylesHandler = view.getStylesHandler();
1494
- const defaultHeight = view.getDefaultRowHeight();
1495
- let height = 0;
1496
- for (let i = row; i < row + rowspan; i++) {
1497
- if (!rowIndexMapper.isHidden(i)) {
1498
- var _this$hot$getRowHeigh;
1499
- height += (_this$hot$getRowHeigh = this.hot.getRowHeight(i)) !== null && _this$hot$getRowHeigh !== void 0 ? _this$hot$getRowHeigh : defaultHeight;
1500
- if (i === 0 && !stylesHandler.isClassicTheme()) {
1501
- height += 1; // border-top-width
1502
- }
1503
- }
1504
- }
1505
- return height;
1506
1485
  }
@@ -3,6 +3,8 @@
3
3
  exports.__esModule = true;
4
4
  exports.createMergeCellRenderer = createMergeCellRenderer;
5
5
  var _object = require("../../helpers/object");
6
+ var _browser = require("../../helpers/browser");
7
+ var _utils = require("./utils");
6
8
  /**
7
9
  * Creates a renderer object for the `MergeCells` plugin.
8
10
  *
@@ -18,6 +20,7 @@ function createMergeCellRenderer(plugin) {
18
20
  rowIndexMapper: rowMapper,
19
21
  columnIndexMapper: columnMapper
20
22
  } = hot;
23
+ const updateNextCellsHeight = new Map();
21
24
 
22
25
  /**
23
26
  * Runs before the cell is rendered.
@@ -39,6 +42,10 @@ function createMergeCellRenderer(plugin) {
39
42
  if (!(0, _object.isObject)(mergedCell)) {
40
43
  TD.removeAttribute('rowspan');
41
44
  TD.removeAttribute('colspan');
45
+ if ((0, _browser.isSafari)() && updateNextCellsHeight.has(row) && !hot.getSettings().rowHeaders) {
46
+ TD.style.height = `${updateNextCellsHeight.get(row)}px`;
47
+ updateNextCellsHeight.delete(row);
48
+ }
42
49
  TD.style.display = '';
43
50
  return;
44
51
  }
@@ -50,6 +57,14 @@ function createMergeCellRenderer(plugin) {
50
57
  } = mergedCell;
51
58
  const [lastMergedRowIndex, lastMergedColumnIndex] = plugin.translateMergedCellToRenderable(origRow, origRowspan, origColumn, origColspan);
52
59
  const isVirtualRenderingEnabled = plugin.getSetting('virtualized');
60
+
61
+ // Safari bug fix - the height of the cells next to the merged cell must be defined
62
+ // so that their height is proportional to the height of the merged cell
63
+ // (this emulates default behavior in Chrome, FF etc.)
64
+ if ((0, _browser.isSafari)() && origColumn === 0 && !hot.getSettings().rowHeaders) {
65
+ const height = (0, _utils.sumCellsHeights)(hot, origRow, origRowspan);
66
+ updateNextCellsHeight.set(row, height / origRowspan);
67
+ }
53
68
  const renderedRowIndex = rowMapper.getRenderableFromVisualIndex(row);
54
69
  const renderedColumnIndex = columnMapper.getRenderableFromVisualIndex(col);
55
70
  const maxRowSpan = lastMergedRowIndex - renderedRowIndex + 1; // Number of rendered columns.