handsontable 0.0.0-next-f52ab71-20250121 → 0.0.0-next-5cb0a2b-20250129

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 (43) hide show
  1. package/3rdparty/walkontable/src/core/_base.js +19 -0
  2. package/3rdparty/walkontable/src/core/_base.mjs +19 -0
  3. package/3rdparty/walkontable/src/overlay/_base.js +44 -8
  4. package/3rdparty/walkontable/src/overlay/_base.mjs +44 -8
  5. package/3rdparty/walkontable/src/overlay/bottom.js +0 -1
  6. package/3rdparty/walkontable/src/overlay/bottom.mjs +0 -1
  7. package/3rdparty/walkontable/src/overlay/bottomInlineStartCorner.js +0 -1
  8. package/3rdparty/walkontable/src/overlay/bottomInlineStartCorner.mjs +0 -1
  9. package/3rdparty/walkontable/src/overlay/inlineStart.js +0 -1
  10. package/3rdparty/walkontable/src/overlay/inlineStart.mjs +0 -1
  11. package/3rdparty/walkontable/src/overlay/top.js +0 -1
  12. package/3rdparty/walkontable/src/overlay/top.mjs +0 -1
  13. package/3rdparty/walkontable/src/overlay/topInlineStartCorner.js +0 -1
  14. package/3rdparty/walkontable/src/overlay/topInlineStartCorner.mjs +0 -1
  15. package/3rdparty/walkontable/src/overlays.js +355 -45
  16. package/3rdparty/walkontable/src/overlays.mjs +355 -45
  17. package/3rdparty/walkontable/src/table.js +94 -99
  18. package/3rdparty/walkontable/src/table.mjs +94 -99
  19. package/base.js +2 -2
  20. package/base.mjs +2 -2
  21. package/dist/handsontable.css +20 -4
  22. package/dist/handsontable.full.css +20 -4
  23. package/dist/handsontable.full.js +522 -166
  24. package/dist/handsontable.full.min.css +3 -3
  25. package/dist/handsontable.full.min.js +108 -108
  26. package/dist/handsontable.js +522 -166
  27. package/dist/handsontable.min.css +3 -3
  28. package/dist/handsontable.min.js +15 -15
  29. package/editors/baseEditor/baseEditor.js +2 -1
  30. package/editors/baseEditor/baseEditor.mjs +2 -1
  31. package/helpers/mixed.js +1 -1
  32. package/helpers/mixed.mjs +1 -1
  33. package/package.json +1 -1
  34. package/plugins/dragToScroll/dragToScroll.js +1 -1
  35. package/plugins/dragToScroll/dragToScroll.mjs +1 -1
  36. package/styles/handsontable.css +8 -3
  37. package/styles/handsontable.min.css +3 -3
  38. package/styles/ht-theme-horizon.css +2 -2
  39. package/styles/ht-theme-horizon.min.css +2 -2
  40. package/styles/ht-theme-main.css +2 -2
  41. package/styles/ht-theme-main.min.css +2 -2
  42. package/tableView.js +2 -2
  43. package/tableView.mjs +2 -2
@@ -25,8 +25,8 @@
25
25
  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER ARISING FROM
26
26
  * USE OR INABILITY TO USE THIS SOFTWARE.
27
27
  *
28
- * Version: 0.0.0-next-f52ab71-20250121
29
- * Release date: 16/12/2024 (built at 21/01/2025 09:22:54)
28
+ * Version: 0.0.0-next-5cb0a2b-20250129
29
+ * Release date: 16/12/2024 (built at 29/01/2025 13:38:31)
30
30
  */
31
31
  (function webpackUniversalModuleDefinition(root, factory) {
32
32
  if(typeof exports === 'object' && typeof module === 'object')
@@ -104,8 +104,8 @@ Handsontable.hooks = _hooks.Hooks.getSingleton();
104
104
  Handsontable.CellCoords = _src.CellCoords;
105
105
  Handsontable.CellRange = _src.CellRange;
106
106
  Handsontable.packageName = 'handsontable';
107
- Handsontable.buildDate = "21/01/2025 09:22:54";
108
- Handsontable.version = "0.0.0-next-f52ab71-20250121";
107
+ Handsontable.buildDate = "29/01/2025 13:38:31";
108
+ Handsontable.version = "0.0.0-next-5cb0a2b-20250129";
109
109
  Handsontable.languages = {
110
110
  dictionaryKeys: _registry.dictionaryKeys,
111
111
  getLanguageDictionary: _registry.getLanguageDictionary,
@@ -10104,7 +10104,7 @@ const domMessages = {
10104
10104
  function _injectProductInfo(key, element) {
10105
10105
  const hasValidType = !isEmpty(key);
10106
10106
  const isNonCommercial = typeof key === 'string' && key.toLowerCase() === 'non-commercial-and-evaluation';
10107
- const hotVersion = "0.0.0-next-f52ab71-20250121";
10107
+ const hotVersion = "0.0.0-next-5cb0a2b-20250129";
10108
10108
  let keyValidityDate;
10109
10109
  let consoleMessageState = 'invalid';
10110
10110
  let domMessageState = 'invalid';
@@ -17909,7 +17909,7 @@ class TableView {
17909
17909
  if (this.hot.isRenderSuspended()) {
17910
17910
  this.postponedAdjustElementsSize = true;
17911
17911
  } else {
17912
- // this._wt.wtOverlays.adjustElementsSize();
17912
+ this._wt.wtOverlays.adjustElementsSize();
17913
17913
  }
17914
17914
  }
17915
17915
 
@@ -18990,7 +18990,7 @@ class TableView {
18990
18990
  updateCellHeader(element, index, content) {
18991
18991
  let headerLevel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
18992
18992
  let renderedIndex = index;
18993
- const parentOverlay = this._wt;
18993
+ const parentOverlay = this._wt.wtOverlays.getParentOverlay(element) || this._wt;
18994
18994
 
18995
18995
  // prevent wrong calculations from SampleGenerator
18996
18996
  if (element.parentNode) {
@@ -22431,6 +22431,9 @@ var _interopRequireDefault = __webpack_require__(1);
22431
22431
  exports.__esModule = true;
22432
22432
  __webpack_require__(5);
22433
22433
  __webpack_require__(87);
22434
+ __webpack_require__(115);
22435
+ __webpack_require__(133);
22436
+ __webpack_require__(196);
22434
22437
  var _defineProperty2 = _interopRequireDefault(__webpack_require__(170));
22435
22438
  var _element = __webpack_require__(155);
22436
22439
  var _feature = __webpack_require__(168);
@@ -22448,6 +22451,7 @@ function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.h
22448
22451
  * @class Overlays
22449
22452
  */
22450
22453
  var _overlays = /*#__PURE__*/new WeakMap();
22454
+ var _hasRenderingStateChanged = /*#__PURE__*/new WeakMap();
22451
22455
  var _containerDomResizeCount = /*#__PURE__*/new WeakMap();
22452
22456
  var _containerDomResizeCountTimeout = /*#__PURE__*/new WeakMap();
22453
22457
  class Overlays {
@@ -22522,6 +22526,12 @@ class Overlays {
22522
22526
  * @type {Settings}
22523
22527
  */
22524
22528
  (0, _defineProperty2.default)(this, "wtSettings", null);
22529
+ /**
22530
+ * Indicates whether the rendering state has changed for one of the overlays.
22531
+ *
22532
+ * @type {boolean}
22533
+ */
22534
+ _classPrivateFieldInitSpec(this, _hasRenderingStateChanged, false);
22525
22535
  /**
22526
22536
  * The amount of times the ResizeObserver callback was fired in direct succession.
22527
22537
  *
@@ -22568,16 +22578,32 @@ class Overlays {
22568
22578
  this.domBindings = domBindings;
22569
22579
  this.facadeGetter = facadeGetter;
22570
22580
  this.wtTable = wtTable;
22571
- this.eventManager = eventManager;
22572
- this.destroyed = false;
22573
22581
  const {
22582
+ rootDocument,
22574
22583
  rootWindow
22575
22584
  } = this.domBindings;
22585
+
22586
+ // legacy support
22587
+ this.instance = this.wot; // todo refactoring: move to facade
22588
+ this.eventManager = eventManager;
22589
+
22590
+ // TODO refactoring: probably invalid place to this logic
22591
+ this.scrollbarSize = (0, _element.getScrollbarWidth)(rootDocument);
22576
22592
  const isOverflowHidden = rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden';
22577
22593
  this.scrollableElement = isOverflowHidden ? wtTable.holder : (0, _element.getScrollableElement)(wtTable.TABLE);
22578
22594
  this.initOverlays();
22595
+ this.destroyed = false;
22596
+ this.keyPressed = false;
22597
+ this.spreaderLastSize = {
22598
+ width: null,
22599
+ height: null
22600
+ };
22601
+ this.verticalScrolling = false;
22602
+ this.horizontalScrolling = false;
22579
22603
  this.initBrowserLineHeight();
22580
22604
  this.registerListeners();
22605
+ this.lastScrollX = rootWindow.scrollX;
22606
+ this.lastScrollY = rootWindow.scrollY;
22581
22607
  }
22582
22608
 
22583
22609
  /**
@@ -22612,8 +22638,8 @@ class Overlays {
22612
22638
  * Https://developer.mozilla.org/pl/docs/Web/CSS/line-height#Values.
22613
22639
  */
22614
22640
  const lineHeight = parseInt(computedStyle.lineHeight, 10);
22615
- const lineHeightFallback = parseInt(computedStyle.fontSize, 10) * 1.2;
22616
- this.browserLineHeight = lineHeight || lineHeightFallback;
22641
+ const lineHeightFalback = parseInt(computedStyle.fontSize, 10) * 1.2;
22642
+ this.browserLineHeight = lineHeight || lineHeightFalback;
22617
22643
  }
22618
22644
 
22619
22645
  /**
@@ -22623,9 +22649,15 @@ class Overlays {
22623
22649
  */
22624
22650
  initOverlays() {
22625
22651
  const args = [this.wot, this.facadeGetter, this.wtSettings, this.domBindings];
22652
+
22653
+ // todo refactoring: IOC, collection or factories.
22654
+ // TODO refactoring, conceive about using generic collection of overlays.
22626
22655
  this.topOverlay = new _overlay.TopOverlay(...args);
22627
22656
  this.bottomOverlay = new _overlay.BottomOverlay(...args);
22628
22657
  this.inlineStartOverlay = new _overlay.InlineStartOverlay(...args);
22658
+
22659
+ // TODO discuss, the controversial here would be removing the lazy creation mechanism for corners.
22660
+ // TODO cond. Has no any visual impact. They're initially hidden in same way like left, top, and bottom overlays.
22629
22661
  this.topInlineStartCornerOverlay = new _overlay.TopInlineStartCornerOverlay(...args, this.topOverlay, this.inlineStartOverlay);
22630
22662
  this.bottomInlineStartCornerOverlay = new _overlay.BottomInlineStartCornerOverlay(...args, this.bottomOverlay, this.inlineStartOverlay);
22631
22663
  _classPrivateFieldSet(_overlays, this, [this.topOverlay, this.bottomOverlay, this.inlineStartOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay]);
@@ -22634,20 +22666,48 @@ class Overlays {
22634
22666
  /**
22635
22667
  * Runs logic for the overlays before the table is drawn.
22636
22668
  */
22637
- beforeDraw() {}
22669
+ beforeDraw() {
22670
+ _classPrivateFieldSet(_hasRenderingStateChanged, this, _classPrivateFieldGet(_overlays, this).reduce((acc, overlay) => {
22671
+ return overlay.hasRenderingStateChanged() || acc;
22672
+ }, false));
22673
+ _classPrivateFieldGet(_overlays, this).forEach(overlay => overlay.updateStateOfRendering('before'));
22674
+ }
22638
22675
 
22639
22676
  /**
22640
22677
  * Runs logic for the overlays after the table is drawn.
22641
22678
  */
22642
- afterDraw() {}
22679
+ afterDraw() {
22680
+ this.syncScrollWithMaster();
22681
+ _classPrivateFieldGet(_overlays, this).forEach(overlay => {
22682
+ const hasRenderingStateChanged = overlay.hasRenderingStateChanged();
22683
+ overlay.updateStateOfRendering('after');
22684
+ if (hasRenderingStateChanged && !overlay.needFullRender) {
22685
+ overlay.reset();
22686
+ }
22687
+ });
22688
+ }
22643
22689
 
22644
22690
  /**
22645
22691
  * Refresh and redraw table.
22646
22692
  */
22647
- draw(fastDraw) {
22648
- (0, _array.arrayEach)(_classPrivateFieldGet(_overlays, this), overlay => {
22649
- overlay.adjustRootElementSize();
22650
- });
22693
+ refreshAll() {
22694
+ if (!this.wot.drawn) {
22695
+ return;
22696
+ }
22697
+ if (!this.wtTable.holder.parentNode) {
22698
+ // Walkontable was detached from DOM, but this handler was not removed
22699
+ this.destroy();
22700
+ return;
22701
+ }
22702
+ this.wot.draw(true);
22703
+ if (this.verticalScrolling) {
22704
+ this.inlineStartOverlay.onScroll(); // todo the inlineStartOverlay.onScroll() fires hook. Why is it needed there, not in any another place?
22705
+ }
22706
+ if (this.horizontalScrolling) {
22707
+ this.topOverlay.onScroll();
22708
+ }
22709
+ this.verticalScrolling = false;
22710
+ this.horizontalScrolling = false;
22651
22711
  }
22652
22712
 
22653
22713
  /**
@@ -22655,22 +22715,39 @@ class Overlays {
22655
22715
  */
22656
22716
  registerListeners() {
22657
22717
  const {
22718
+ rootDocument,
22658
22719
  rootWindow
22659
22720
  } = this.domBindings;
22721
+ const {
22722
+ mainTableScrollableElement: topOverlayScrollableElement
22723
+ } = this.topOverlay;
22724
+ const {
22725
+ mainTableScrollableElement: inlineStartOverlayScrollableElement
22726
+ } = this.inlineStartOverlay;
22727
+ this.eventManager.addEventListener(rootDocument.documentElement, 'keydown', event => this.onKeyDown(event));
22728
+ this.eventManager.addEventListener(rootDocument.documentElement, 'keyup', () => this.onKeyUp());
22729
+ this.eventManager.addEventListener(rootDocument, 'visibilitychange', () => this.onKeyUp());
22730
+ this.eventManager.addEventListener(topOverlayScrollableElement, 'scroll', event => this.onTableScroll(event), {
22731
+ passive: true
22732
+ });
22733
+ if (topOverlayScrollableElement !== inlineStartOverlayScrollableElement) {
22734
+ this.eventManager.addEventListener(inlineStartOverlayScrollableElement, 'scroll', event => this.onTableScroll(event), {
22735
+ passive: true
22736
+ });
22737
+ }
22660
22738
  const isHighPixelRatio = rootWindow.devicePixelRatio && rootWindow.devicePixelRatio > 1;
22661
22739
  const isScrollOnWindow = this.scrollableElement === rootWindow;
22662
22740
  const preventWheel = this.wtSettings.getSetting('preventWheel');
22663
22741
  const wheelEventOptions = {
22664
22742
  passive: isScrollOnWindow
22665
22743
  };
22666
- this.eventManager.addEventListener(this.scrollableElement, 'scroll', event => {
22667
- this.wot.draw(true);
22668
- }, {
22669
- passive: true
22670
- });
22671
22744
  if (preventWheel || isHighPixelRatio || !(0, _browser.isChrome)()) {
22672
22745
  this.eventManager.addEventListener(this.wtTable.wtRootElement, 'wheel', event => this.onCloneWheel(event, preventWheel), wheelEventOptions);
22673
22746
  }
22747
+ const overlays = [this.topOverlay, this.bottomOverlay, this.inlineStartOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
22748
+ overlays.forEach(overlay => {
22749
+ this.eventManager.addEventListener(overlay.clone.wtTable.holder, 'wheel', event => this.onCloneWheel(event, preventWheel), wheelEventOptions);
22750
+ });
22674
22751
  let resizeTimeout;
22675
22752
  this.eventManager.addEventListener(rootWindow, 'resize', () => {
22676
22753
  (0, _feature.requestAnimationFrame)(() => {
@@ -22687,6 +22764,29 @@ class Overlays {
22687
22764
  }
22688
22765
  }
22689
22766
 
22767
+ /**
22768
+ * Scroll listener.
22769
+ *
22770
+ * @param {Event} event The mouse event object.
22771
+ */
22772
+ onTableScroll(event) {
22773
+ // There was if statement which controlled flow of this function. It avoided the execution of the next lines
22774
+ // on mobile devices. It was changed. Broader description of this case is included within issue #4856.
22775
+ const rootWindow = this.domBindings.rootWindow;
22776
+ const masterHorizontal = this.inlineStartOverlay.mainTableScrollableElement;
22777
+ const masterVertical = this.topOverlay.mainTableScrollableElement;
22778
+ const target = event.target;
22779
+
22780
+ // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
22781
+ // by hot.refreshBorder
22782
+ if (this.keyPressed) {
22783
+ if (masterVertical !== rootWindow && target !== rootWindow && !event.target.contains(masterVertical) || masterHorizontal !== rootWindow && target !== rootWindow && !event.target.contains(masterHorizontal)) {
22784
+ return;
22785
+ }
22786
+ }
22787
+ this.syncScrollPositions(event);
22788
+ }
22789
+
22690
22790
  /**
22691
22791
  * Wheel listener for cloned overlays.
22692
22792
  *
@@ -22697,12 +22797,43 @@ class Overlays {
22697
22797
  const {
22698
22798
  rootWindow
22699
22799
  } = this.domBindings;
22800
+
22801
+ // There was if statement which controlled flow of this function. It avoided the execution of the next lines
22802
+ // on mobile devices. It was changed. Broader description of this case is included within issue #4856.
22803
+
22804
+ const masterHorizontal = this.inlineStartOverlay.mainTableScrollableElement;
22805
+ const masterVertical = this.topOverlay.mainTableScrollableElement;
22806
+ const target = event.target;
22807
+
22808
+ // For key press, sync only master -> overlay position because while pressing Walkontable.render is triggered
22809
+ // by hot.refreshBorder
22810
+ const shouldNotWheelVertically = masterVertical !== rootWindow && target !== rootWindow && !target.contains(masterVertical);
22811
+ const shouldNotWheelHorizontally = masterHorizontal !== rootWindow && target !== rootWindow && !target.contains(masterHorizontal);
22812
+ if (this.keyPressed && (shouldNotWheelVertically || shouldNotWheelHorizontally) || this.scrollableElement === rootWindow) {
22813
+ return;
22814
+ }
22700
22815
  const isScrollPossible = this.translateMouseWheelToScroll(event);
22701
22816
  if (preventDefault || this.scrollableElement !== rootWindow && isScrollPossible) {
22702
22817
  event.preventDefault();
22703
22818
  }
22704
22819
  }
22705
22820
 
22821
+ /**
22822
+ * Key down listener.
22823
+ *
22824
+ * @param {Event} event The keyboard event object.
22825
+ */
22826
+ onKeyDown(event) {
22827
+ this.keyPressed = (0, _unicode.isKey)(event.keyCode, 'ARROW_UP|ARROW_RIGHT|ARROW_DOWN|ARROW_LEFT');
22828
+ }
22829
+
22830
+ /**
22831
+ * Key up listener.
22832
+ */
22833
+ onKeyUp() {
22834
+ this.keyPressed = false;
22835
+ }
22836
+
22706
22837
  /**
22707
22838
  * Translate wheel event into scroll event and sync scroll overlays position.
22708
22839
  *
@@ -22745,6 +22876,130 @@ class Overlays {
22745
22876
  this.scrollableElement.scrollLeft += delta;
22746
22877
  return previousScroll !== this.scrollableElement.scrollLeft;
22747
22878
  }
22879
+
22880
+ /**
22881
+ * Synchronize scroll position between master table and overlay table.
22882
+ *
22883
+ * @private
22884
+ */
22885
+ syncScrollPositions() {
22886
+ if (this.destroyed) {
22887
+ return;
22888
+ }
22889
+ const {
22890
+ rootWindow
22891
+ } = this.domBindings;
22892
+ const topHolder = this.topOverlay.clone.wtTable.holder; // todo rethink
22893
+ const leftHolder = this.inlineStartOverlay.clone.wtTable.holder; // todo rethink
22894
+
22895
+ const [scrollLeft, scrollTop] = [this.scrollableElement.scrollLeft, this.scrollableElement.scrollTop];
22896
+ this.horizontalScrolling = topHolder.scrollLeft !== scrollLeft || this.lastScrollX !== rootWindow.scrollX;
22897
+ this.verticalScrolling = leftHolder.scrollTop !== scrollTop || this.lastScrollY !== rootWindow.scrollY;
22898
+ this.lastScrollX = rootWindow.scrollX;
22899
+ this.lastScrollY = rootWindow.scrollY;
22900
+ if (this.horizontalScrolling) {
22901
+ topHolder.scrollLeft = scrollLeft;
22902
+ const bottomHolder = this.bottomOverlay.needFullRender ? this.bottomOverlay.clone.wtTable.holder : null; // todo rethink
22903
+
22904
+ if (bottomHolder) {
22905
+ bottomHolder.scrollLeft = scrollLeft;
22906
+ }
22907
+ }
22908
+ if (this.verticalScrolling) {
22909
+ leftHolder.scrollTop = scrollTop;
22910
+ }
22911
+ this.refreshAll();
22912
+ }
22913
+
22914
+ /**
22915
+ * Synchronize overlay scrollbars with the master scrollbar.
22916
+ */
22917
+ syncScrollWithMaster() {
22918
+ if (!_classPrivateFieldGet(_hasRenderingStateChanged, this)) {
22919
+ return;
22920
+ }
22921
+ const master = this.topOverlay.mainTableScrollableElement;
22922
+ const {
22923
+ scrollLeft,
22924
+ scrollTop
22925
+ } = master;
22926
+ if (this.topOverlay.needFullRender) {
22927
+ this.topOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; // todo rethink, *overlay.setScroll*()
22928
+ }
22929
+ if (this.bottomOverlay.needFullRender) {
22930
+ this.bottomOverlay.clone.wtTable.holder.scrollLeft = scrollLeft; // todo rethink, *overlay.setScroll*()
22931
+ }
22932
+ if (this.inlineStartOverlay.needFullRender) {
22933
+ this.inlineStartOverlay.clone.wtTable.holder.scrollTop = scrollTop; // todo rethink, *overlay.setScroll*()
22934
+ }
22935
+ _classPrivateFieldSet(_hasRenderingStateChanged, this, false);
22936
+ }
22937
+
22938
+ /**
22939
+ *
22940
+ */
22941
+ destroy() {
22942
+ this.resizeObserver.disconnect();
22943
+ this.eventManager.destroy();
22944
+ // todo, probably all below `destroy` calls has no sense. To analyze
22945
+ this.topOverlay.destroy();
22946
+ if (this.bottomOverlay.clone) {
22947
+ this.bottomOverlay.destroy();
22948
+ }
22949
+ this.inlineStartOverlay.destroy();
22950
+ if (this.topInlineStartCornerOverlay) {
22951
+ this.topInlineStartCornerOverlay.destroy();
22952
+ }
22953
+ if (this.bottomInlineStartCornerOverlay && this.bottomInlineStartCornerOverlay.clone) {
22954
+ this.bottomInlineStartCornerOverlay.destroy();
22955
+ }
22956
+ this.destroyed = true;
22957
+ }
22958
+
22959
+ /**
22960
+ * @param {boolean} [fastDraw=false] When `true`, try to refresh only the positions of borders without rerendering
22961
+ * the data. It will only work if Table.draw() does not force
22962
+ * rendering anyway.
22963
+ */
22964
+ refresh() {
22965
+ let fastDraw = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
22966
+ const wasSpreaderSizeUpdated = this.updateLastSpreaderSize();
22967
+ if (wasSpreaderSizeUpdated) {
22968
+ this.adjustElementsSize();
22969
+ }
22970
+ if (this.bottomOverlay.clone) {
22971
+ this.bottomOverlay.refresh(fastDraw);
22972
+ }
22973
+ this.inlineStartOverlay.refresh(fastDraw);
22974
+ this.topOverlay.refresh(fastDraw);
22975
+ if (this.topInlineStartCornerOverlay) {
22976
+ this.topInlineStartCornerOverlay.refresh(fastDraw);
22977
+ }
22978
+ if (this.bottomInlineStartCornerOverlay && this.bottomInlineStartCornerOverlay.clone) {
22979
+ this.bottomInlineStartCornerOverlay.refresh(fastDraw);
22980
+ }
22981
+ }
22982
+
22983
+ /**
22984
+ * Update the last cached spreader size with the current size.
22985
+ *
22986
+ * @returns {boolean} `true` if the lastSpreaderSize cache was updated, `false` otherwise.
22987
+ */
22988
+ updateLastSpreaderSize() {
22989
+ const spreader = this.wtTable.spreader;
22990
+ const width = spreader.clientWidth;
22991
+ const height = spreader.clientHeight;
22992
+ const needsUpdating = width !== this.spreaderLastSize.width || height !== this.spreaderLastSize.height;
22993
+ if (needsUpdating) {
22994
+ this.spreaderLastSize.width = width;
22995
+ this.spreaderLastSize.height = height;
22996
+ }
22997
+ return needsUpdating;
22998
+ }
22999
+
23000
+ /**
23001
+ * Adjust overlays elements size and master table size.
23002
+ */
22748
23003
  adjustElementsSize() {
22749
23004
  const {
22750
23005
  wtViewport
@@ -22764,44 +23019,99 @@ class Overlays {
22764
23019
  const proposedHiderWidth = headerRowSize + this.inlineStartOverlay.sumCellSizes(0, totalColumns);
22765
23020
  const hiderElement = wtTable.hider;
22766
23021
  const hiderStyle = hiderElement.style;
22767
- hiderStyle.width = `${proposedHiderWidth}px`;
22768
- hiderStyle.height = `${proposedHiderHeight}px`;
22769
- const styleProperty = this.wtSettings.getSetting('rtlMode') ? 'right' : 'left';
22770
- if (typeof this.wot.wtViewport.columnsRenderCalculator.startPosition === 'number') {
22771
- wtTable.spreader.style[styleProperty] = `${this.wot.wtViewport.columnsRenderCalculator.startPosition}px`;
22772
- } else if (totalColumns === 0) {
22773
- wtTable.spreader.style[styleProperty] = '0';
22774
- } else {
22775
- throw new Error('Incorrect value of the columnsRenderCalculator');
22776
- }
22777
- if (typeof this.wot.wtViewport.rowsRenderCalculator.startPosition === 'number') {
22778
- wtTable.spreader.style.top = `${this.wot.wtViewport.rowsRenderCalculator.startPosition}px`;
22779
- } else if (totalRows === 0) {
22780
- wtTable.spreader.style.top = '0';
22781
- } else {
22782
- throw new Error('Incorrect value of the rowsRenderCalculator');
22783
- }
23022
+ const isScrolledBeyondHiderHeight = () => {
23023
+ return isWindowScrolled ? false : this.scrollableElement.scrollTop > Math.max(0, proposedHiderHeight - wtTable.holder.clientHeight);
23024
+ };
23025
+ const isScrolledBeyondHiderWidth = () => {
23026
+ return isWindowScrolled ? false : this.scrollableElement.scrollLeft > Math.max(0, proposedHiderWidth - wtTable.holder.clientWidth);
23027
+ };
23028
+ const columnHeaderBorderCompensation = isScrolledBeyondHiderHeight() ? 1 : 0;
23029
+ const rowHeaderBorderCompensation = isScrolledBeyondHiderWidth() ? 1 : 0;
23030
+
23031
+ // If the elements are being adjusted after scrolling the table from the very beginning to the very end,
23032
+ // we need to adjust the hider dimensions by the header border size. (https://github.com/handsontable/dev-handsontable/issues/1772)
23033
+ hiderStyle.width = `${proposedHiderWidth + rowHeaderBorderCompensation}px`;
23034
+ hiderStyle.height = `${proposedHiderHeight + columnHeaderBorderCompensation}px`;
23035
+ this.topOverlay.adjustElementsSize();
23036
+ this.inlineStartOverlay.adjustElementsSize();
23037
+ this.bottomOverlay.adjustElementsSize();
22784
23038
  }
22785
23039
 
22786
23040
  /**
23041
+ * Expand the hider vertically element by the provided delta value.
22787
23042
  *
23043
+ * @param {number} heightDelta The delta value to expand the hider element by.
22788
23044
  */
22789
- destroy() {
22790
- this.resizeObserver.disconnect();
22791
- this.eventManager.destroy();
22792
- // todo, probably all below `destroy` calls has no sense. To analyze
22793
- this.topOverlay.destroy();
22794
- if (this.bottomOverlay.clone) {
22795
- this.bottomOverlay.destroy();
23045
+ expandHiderVerticallyBy(heightDelta) {
23046
+ const {
23047
+ wtTable
23048
+ } = this;
23049
+ wtTable.hider.style.height = `${parseInt(wtTable.hider.style.height, 10) + heightDelta}px`;
23050
+ }
23051
+
23052
+ /**
23053
+ * Expand the hider horizontally element by the provided delta value.
23054
+ *
23055
+ * @param {number} widthDelta The delta value to expand the hider element by.
23056
+ */
23057
+ expandHiderHorizontallyBy(widthDelta) {
23058
+ const {
23059
+ wtTable
23060
+ } = this;
23061
+ wtTable.hider.style.width = `${parseInt(wtTable.hider.style.width, 10) + widthDelta}px`;
23062
+ }
23063
+
23064
+ /**
23065
+ *
23066
+ */
23067
+ applyToDOM() {
23068
+ if (!this.wtTable.isVisible()) {
23069
+ return;
22796
23070
  }
22797
- this.inlineStartOverlay.destroy();
22798
- if (this.topInlineStartCornerOverlay) {
22799
- this.topInlineStartCornerOverlay.destroy();
23071
+ this.topOverlay.applyToDOM();
23072
+ if (this.bottomOverlay.clone) {
23073
+ this.bottomOverlay.applyToDOM();
22800
23074
  }
22801
- if (this.bottomInlineStartCornerOverlay && this.bottomInlineStartCornerOverlay.clone) {
22802
- this.bottomInlineStartCornerOverlay.destroy();
23075
+ this.inlineStartOverlay.applyToDOM();
23076
+ }
23077
+
23078
+ /**
23079
+ * Get the parent overlay of the provided element.
23080
+ *
23081
+ * @param {HTMLElement} element An element to process.
23082
+ * @returns {object|null}
23083
+ */
23084
+ getParentOverlay(element) {
23085
+ if (!element) {
23086
+ return null;
22803
23087
  }
22804
- this.destroyed = true;
23088
+ const overlays = [this.topOverlay, this.inlineStartOverlay, this.bottomOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
23089
+ let result = null;
23090
+ (0, _array.arrayEach)(overlays, overlay => {
23091
+ if (!overlay) {
23092
+ return;
23093
+ }
23094
+ if (overlay.clone && overlay.clone.wtTable.TABLE.contains(element)) {
23095
+ // todo demeter
23096
+ result = overlay.clone;
23097
+ }
23098
+ });
23099
+ return result;
23100
+ }
23101
+
23102
+ /**
23103
+ * Synchronize the class names between the main overlay table and the tables on the other overlays.
23104
+ *
23105
+ */
23106
+ syncOverlayTableClassNames() {
23107
+ const masterTable = this.wtTable.TABLE;
23108
+ const overlays = [this.topOverlay, this.inlineStartOverlay, this.bottomOverlay, this.topInlineStartCornerOverlay, this.bottomInlineStartCornerOverlay];
23109
+ (0, _array.arrayEach)(overlays, elem => {
23110
+ if (!elem) {
23111
+ return;
23112
+ }
23113
+ elem.clone.wtTable.TABLE.className = masterTable.className; // todo demeter
23114
+ });
22805
23115
  }
22806
23116
  }
22807
23117
  var _default = exports["default"] = Overlays;
@@ -22897,7 +23207,6 @@ class BottomInlineStartCornerOverlay extends _base.Overlay {
22897
23207
  shouldBeRendered() {
22898
23208
  return this.wtSettings.getSetting('shouldRenderBottomOverlay') && this.wtSettings.getSetting('shouldRenderInlineStartOverlay');
22899
23209
  }
22900
- draw() {}
22901
23210
 
22902
23211
  /**
22903
23212
  * Updates the corner overlay position.
@@ -23007,7 +23316,6 @@ __webpack_require__(5);
23007
23316
  __webpack_require__(87);
23008
23317
  __webpack_require__(115);
23009
23318
  __webpack_require__(133);
23010
- __webpack_require__(142);
23011
23319
  var _defineProperty2 = _interopRequireDefault(__webpack_require__(170));
23012
23320
  var _element = __webpack_require__(155);
23013
23321
  var _function = __webpack_require__(163);
@@ -23021,6 +23329,7 @@ var _a11y = __webpack_require__(162);
23021
23329
  /**
23022
23330
  * @todo These mixes are never added to the class Table, however their members are used here.
23023
23331
  * @todo Continue: Potentially it works only, because some of these mixes are added to every inherited class.
23332
+ * @todo Refactoring, move code from `if(this.isMaster)` into MasterTable, and others like that.
23024
23333
  * @mixes stickyColumnsStart
23025
23334
  * @mixes stickyRowsBottom
23026
23335
  * @mixes stickyRowsTop
@@ -23077,6 +23386,7 @@ class Table {
23077
23386
  *
23078
23387
  * @type {boolean}
23079
23388
  */
23389
+ this.isMaster = name === 'master';
23080
23390
  this.name = name;
23081
23391
  this.dataAccessObject = dataAccessObject;
23082
23392
  this.facadeGetter = facadeGetter;
@@ -23093,7 +23403,9 @@ class Table {
23093
23403
  this.hider = this.createHider(this.spreader);
23094
23404
  this.holder = this.createHolder(this.hider);
23095
23405
  this.wtRootElement = this.holder.parentNode;
23096
- this.alignOverlaysWithTrimmingContainer(); // todo wow, It calls method from child class (MasterTable).
23406
+ if (this.isMaster) {
23407
+ this.alignOverlaysWithTrimmingContainer(); // todo wow, It calls method from child class (MasterTable).
23408
+ }
23097
23409
  this.fixTableDomTree();
23098
23410
  this.rowFilter = null; // TODO refactoring, eliminate all (re)creations of this object, then updates state when needed.
23099
23411
  this.columnFilter = null; // TODO refactoring, eliminate all (re)creations of this object, then updates state when needed.
@@ -23113,31 +23425,7 @@ class Table {
23113
23425
  TBODY: this.TBODY,
23114
23426
  rowUtils: this.rowUtils,
23115
23427
  columnUtils: this.columnUtils,
23116
- cellRenderer: (row, column, TD) => {
23117
- const fixedColumnsStart = this.wtSettings.getSetting('fixedColumnsStart');
23118
- const fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
23119
- this.wtSettings.getSettingPure('cellRenderer')(row, column, TD);
23120
- if (column < fixedColumnsStart) {
23121
- const left = this.dataAccessObject.wtViewport.getRowHeaderWidth() + this.dataAccessObject.wtOverlays.inlineStartOverlay.sumCellSizes(0, column);
23122
- TD.style.position = 'sticky';
23123
- TD.style.left = `${left}px`;
23124
- if (row < fixedRowsTop) {
23125
- TD.style.zIndex = '9';
23126
- } else {
23127
- TD.style.zIndex = '5';
23128
- }
23129
- }
23130
- if (row < fixedRowsTop) {
23131
- const top = this.dataAccessObject.wtViewport.getColumnHeaderHeight() + this.dataAccessObject.wtOverlays.topOverlay.sumCellSizes(0, row);
23132
- TD.style.position = 'sticky';
23133
- TD.style.top = `${top}px`;
23134
- if (column < fixedColumnsStart) {
23135
- TD.style.zIndex = '10';
23136
- } else {
23137
- TD.style.zIndex = '6';
23138
- }
23139
- }
23140
- },
23428
+ cellRenderer: this.wtSettings.getSettingPure('cellRenderer'),
23141
23429
  stylesHandler: this.dataAccessObject.stylesHandler
23142
23430
  });
23143
23431
  }
@@ -23237,10 +23525,12 @@ class Table {
23237
23525
  // if TABLE is detached (e.g. in Jasmine test), it has no parentNode so we cannot attach holder to it
23238
23526
  parent.insertBefore(holder, hider);
23239
23527
  }
23240
- holder.parentNode.className += 'ht_master handsontable';
23241
- holder.parentNode.setAttribute('dir', this.wtSettings.getSettingPure('rtlMode') ? 'rtl' : 'ltr');
23242
- if (this.wtSettings.getSetting('ariaTags')) {
23243
- (0, _element.setAttribute)(holder.parentNode, [(0, _a11y.A11Y_PRESENTATION)()]);
23528
+ if (this.isMaster) {
23529
+ holder.parentNode.className += 'ht_master handsontable';
23530
+ holder.parentNode.setAttribute('dir', this.wtSettings.getSettingPure('rtlMode') ? 'rtl' : 'ltr');
23531
+ if (this.wtSettings.getSetting('ariaTags')) {
23532
+ (0, _element.setAttribute)(holder.parentNode, [(0, _a11y.A11Y_PRESENTATION)()]);
23533
+ }
23244
23534
  }
23245
23535
  holder.appendChild(hider);
23246
23536
  }
@@ -23268,89 +23558,100 @@ class Table {
23268
23558
  } = this.dataAccessObject;
23269
23559
  const totalRows = wtSettings.getSetting('totalRows');
23270
23560
  const totalColumns = wtSettings.getSetting('totalColumns');
23271
- const rowHeaders = wtSettings.getSetting('rowHeaders').map(origRowRenderer => {
23272
- return (row, TH, column) => {
23273
- const fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
23274
- const fixedColumnsStart = this.wtSettings.getSetting('fixedColumnsStart');
23275
- if (row < fixedRowsTop) {
23276
- let top = 0;
23277
- if (row >= 0) {
23278
- top = this.dataAccessObject.wtViewport.getColumnHeaderHeight() + this.dataAccessObject.wtOverlays.topOverlay.sumCellSizes(0, row);
23279
- }
23280
- TH.style.top = `${top}px`;
23281
- if (column < fixedColumnsStart) {
23282
- TH.style.zIndex = '20';
23283
- } else {
23284
- TH.style.zIndex = '10';
23285
- }
23286
- } else {
23287
- TH.style.top = '0px';
23288
- TH.style.zIndex = '3';
23289
- }
23290
- origRowRenderer(row, TH, column);
23291
- TH.style.position = 'sticky';
23292
- TH.style.left = '0px';
23293
- };
23294
- });
23561
+ const rowHeaders = wtSettings.getSetting('rowHeaders');
23295
23562
  const rowHeadersCount = rowHeaders.length;
23296
- const columnHeaders = wtSettings.getSetting('columnHeaders').map(origColumnRenderer => {
23297
- return (column, TH, row) => {
23298
- const fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
23299
- const fixedColumnsStart = this.wtSettings.getSetting('fixedColumnsStart');
23300
- if (column < fixedColumnsStart) {
23301
- let left = 0;
23302
- if (column >= 0) {
23303
- left = this.dataAccessObject.wtViewport.getRowHeaderWidth() + this.dataAccessObject.wtOverlays.inlineStartOverlay.sumCellSizes(0, column);
23304
- }
23305
- TH.style.left = `${left}px`;
23306
- if (row < fixedRowsTop) {
23307
- TH.style.zIndex = '20';
23308
- } else {
23309
- TH.style.zIndex = '10';
23310
- }
23311
- } else {
23312
- TH.style.zIndex = '3';
23313
- TH.style.left = '0px';
23314
- }
23315
- origColumnRenderer(column, TH, row);
23316
- TH.style.position = 'sticky';
23317
- TH.style.top = '0px';
23318
- };
23319
- });
23563
+ const columnHeaders = wtSettings.getSetting('columnHeaders');
23320
23564
  const columnHeadersCount = columnHeaders.length;
23321
23565
  let runFastDraw = fastDraw;
23322
- wtOverlays.beforeDraw();
23323
- this.holderOffset = (0, _element.offset)(this.holder);
23324
- runFastDraw = wtViewport.createCalculators(runFastDraw);
23325
- if (!runFastDraw) {
23326
- this.tableOffset = (0, _element.offset)(this.TABLE);
23566
+ if (this.isMaster) {
23567
+ wtOverlays.beforeDraw();
23568
+ this.holderOffset = (0, _element.offset)(this.holder);
23569
+ runFastDraw = wtViewport.createCalculators(runFastDraw);
23570
+ if (rowHeadersCount && !wtSettings.getSetting('fixedColumnsStart')) {
23571
+ const leftScrollPos = wtOverlays.inlineStartOverlay.getScrollPosition();
23572
+ const previousState = this.correctHeaderWidth;
23573
+ this.correctHeaderWidth = leftScrollPos !== 0;
23574
+ if (previousState !== this.correctHeaderWidth) {
23575
+ runFastDraw = false;
23576
+ }
23577
+ }
23578
+ }
23579
+ if (runFastDraw) {
23580
+ if (this.isMaster) {
23581
+ wtOverlays.refresh(true);
23582
+ }
23583
+ } else {
23584
+ if (this.isMaster) {
23585
+ this.tableOffset = (0, _element.offset)(this.TABLE);
23586
+ } else {
23587
+ this.tableOffset = this.dataAccessObject.parentTableOffset;
23588
+ }
23327
23589
  const startRow = totalRows > 0 ? this.getFirstRenderedRow() : 0;
23328
23590
  const startColumn = totalColumns > 0 ? this.getFirstRenderedColumn() : 0;
23329
23591
  this.rowFilter = new _row.default(startRow, totalRows, columnHeadersCount);
23330
23592
  this.columnFilter = new _column.default(startColumn, totalColumns, rowHeadersCount);
23331
23593
  let performRedraw = true;
23332
- this.alignOverlaysWithTrimmingContainer(); // todo It calls method from child class (MasterTable).
23333
- const skipRender = {};
23334
- this.wtSettings.getSetting('beforeDraw', true, skipRender);
23335
- performRedraw = skipRender.skipRender !== true;
23594
+
23595
+ // Only master table rendering can be skipped
23596
+ if (this.isMaster) {
23597
+ this.alignOverlaysWithTrimmingContainer(); // todo It calls method from child class (MasterTable).
23598
+ const skipRender = {};
23599
+ this.wtSettings.getSetting('beforeDraw', true, skipRender);
23600
+ performRedraw = skipRender.skipRender !== true;
23601
+ }
23336
23602
  if (performRedraw) {
23337
23603
  this.tableRenderer.setHeaderContentRenderers(rowHeaders, columnHeaders);
23604
+ if (this.is(_overlay.CLONE_BOTTOM) || this.is(_overlay.CLONE_BOTTOM_INLINE_START_CORNER)) {
23605
+ // do NOT render headers on the bottom or bottom-left corner overlay
23606
+ this.tableRenderer.setHeaderContentRenderers(rowHeaders, []);
23607
+ }
23338
23608
  this.resetOversizedRows();
23339
23609
  this.tableRenderer.setActiveOverlayName(this.name).setViewportSize(this.getRenderedRowsCount(), this.getRenderedColumnsCount()).setFilters(this.rowFilter, this.columnFilter).render();
23340
- this.markOversizedColumnHeaders();
23610
+ if (this.isMaster) {
23611
+ this.markOversizedColumnHeaders();
23612
+ }
23341
23613
  this.adjustColumnHeaderHeights();
23342
- this.markOversizedRows();
23343
- if (!this.wtSettings.getSetting('externalRowCalculator')) {
23344
- wtViewport.createVisibleCalculators();
23614
+ if (this.isMaster || this.is(_overlay.CLONE_BOTTOM)) {
23615
+ this.markOversizedRows();
23345
23616
  }
23346
- wtOverlays.adjustElementsSize();
23347
- // wtOverlays.draw(fastDraw);
23348
-
23349
- this.wtSettings.getSetting('onDraw', true);
23617
+ if (this.isMaster) {
23618
+ if (!this.wtSettings.getSetting('externalRowCalculator')) {
23619
+ wtViewport.createVisibleCalculators();
23620
+ }
23621
+ wtOverlays.refresh(false);
23622
+ wtOverlays.applyToDOM();
23623
+ this.wtSettings.getSetting('onDraw', true);
23624
+ } else if (this.is(_overlay.CLONE_BOTTOM)) {
23625
+ this.dataAccessObject.cloneSource.wtOverlays.adjustElementsSize();
23626
+ }
23627
+ }
23628
+ }
23629
+ let positionChanged = false;
23630
+ if (this.isMaster) {
23631
+ positionChanged = wtOverlays.topOverlay.resetFixedPosition();
23632
+ if (wtOverlays.bottomOverlay.clone) {
23633
+ positionChanged = wtOverlays.bottomOverlay.resetFixedPosition() || positionChanged;
23634
+ }
23635
+ positionChanged = wtOverlays.inlineStartOverlay.resetFixedPosition() || positionChanged;
23636
+ if (wtOverlays.topInlineStartCornerOverlay) {
23637
+ wtOverlays.topInlineStartCornerOverlay.resetFixedPosition();
23350
23638
  }
23639
+ if (wtOverlays.bottomInlineStartCornerOverlay && wtOverlays.bottomInlineStartCornerOverlay.clone) {
23640
+ wtOverlays.bottomInlineStartCornerOverlay.resetFixedPosition();
23641
+ }
23642
+ }
23643
+ if (positionChanged) {
23644
+ // It refreshes the cells borders caused by a 1px shift (introduced by overlays which add or
23645
+ // remove `innerBorderTop` and `innerBorderInlineStart` CSS classes to the DOM element. This happens
23646
+ // when there is a switch between rendering from 0 to N rows/columns and vice versa).
23647
+ wtOverlays.refreshAll(); // `refreshAll()` internally already calls `refreshSelections()` method
23648
+ wtOverlays.adjustElementsSize();
23649
+ } else {
23650
+ this.dataAccessObject.selectionManager.setActiveOverlay(this.facadeGetter()).render(runFastDraw);
23651
+ }
23652
+ if (this.isMaster) {
23653
+ wtOverlays.afterDraw();
23351
23654
  }
23352
- this.dataAccessObject.selectionManager.setActiveOverlay(this.facadeGetter()).render(runFastDraw);
23353
- wtOverlays.afterDraw();
23354
23655
  this.dataAccessObject.drawn = true;
23355
23656
  return this;
23356
23657
  }
@@ -23422,6 +23723,9 @@ class Table {
23422
23723
  const {
23423
23724
  wtViewport
23424
23725
  } = this.dataAccessObject;
23726
+ if (!this.isMaster && !this.is(_overlay.CLONE_BOTTOM)) {
23727
+ return;
23728
+ }
23425
23729
  if (!wtSettings.getSetting('externalRowCalculator')) {
23426
23730
  const rowsToRender = this.getRenderedRowsCount();
23427
23731
 
@@ -23457,7 +23761,7 @@ class Table {
23457
23761
  getCell(coords) {
23458
23762
  let row = coords.row;
23459
23763
  let column = coords.col;
23460
- const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column, false, 'render');
23764
+ const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column, !this.isMaster, 'render');
23461
23765
  if (hookResult && Array.isArray(hookResult)) {
23462
23766
  [row, column] = hookResult;
23463
23767
  }
@@ -26566,14 +26870,33 @@ class Overlay {
26566
26870
  this.wtRootElement = wtRootElement;
26567
26871
  this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
26568
26872
  this.needFullRender = this.shouldBeRendered();
26569
- const preventOverflow = this.wtSettings.getSetting('preventOverflow');
26570
- const tableParent = this.wot.wtTable.wtRootElement.parentNode;
26571
- if (preventOverflow === true || preventOverflow === 'horizontal' && this.type === _constants.CLONE_TOP || preventOverflow === 'vertical' && this.type === _constants.CLONE_INLINE_START) {
26572
- this.mainTableScrollableElement = domBindings.rootWindow;
26573
- } else if (domBindings.rootWindow.getComputedStyle(tableParent).getPropertyValue('overflow') === 'hidden') {
26574
- this.mainTableScrollableElement = holder;
26575
- } else {
26576
- this.mainTableScrollableElement = (0, _element.getScrollableElement)(TABLE);
26873
+ this.clone = this.makeClone();
26874
+ }
26875
+
26876
+ /**
26877
+ * Checks if the overlay rendering state has changed.
26878
+ *
26879
+ * @returns {boolean}
26880
+ */
26881
+ hasRenderingStateChanged() {
26882
+ return this.needFullRender !== this.shouldBeRendered();
26883
+ }
26884
+
26885
+ /**
26886
+ * Updates internal state with an information about the need of full rendering of the overlay in the next draw cycles.
26887
+ *
26888
+ * If the state is changed to render the overlay, the `needFullRender` property is set to `true` which means that
26889
+ * the overlay will be fully rendered in the current draw cycle. If the state is changed to not render the overlay,
26890
+ * the `needFullRender` property is set to `false` which means that the overlay will be fully rendered in the
26891
+ * current draw cycle but it will not be rendered in the next draw cycles.
26892
+ *
26893
+ * @param {'before' | 'after'} drawPhase The phase of the rendering process.
26894
+ */
26895
+ updateStateOfRendering(drawPhase) {
26896
+ if (drawPhase === 'before' && this.shouldBeRendered()) {
26897
+ this.needFullRender = true;
26898
+ } else if (drawPhase === 'after' && !this.shouldBeRendered()) {
26899
+ this.needFullRender = false;
26577
26900
  }
26578
26901
  }
26579
26902
 
@@ -26593,6 +26916,23 @@ class Overlay {
26593
26916
  this.trimmingContainer = (0, _element.getTrimmingContainer)(this.hider.parentNode.parentNode);
26594
26917
  }
26595
26918
 
26919
+ /**
26920
+ * Update the main scrollable element.
26921
+ */
26922
+ updateMainScrollableElement() {
26923
+ const {
26924
+ wtTable
26925
+ } = this.wot;
26926
+ const {
26927
+ rootWindow
26928
+ } = this.domBindings;
26929
+ if (rootWindow.getComputedStyle(wtTable.wtRootElement.parentNode).getPropertyValue('overflow') === 'hidden') {
26930
+ this.mainTableScrollableElement = this.wot.wtTable.holder;
26931
+ } else {
26932
+ this.mainTableScrollableElement = (0, _element.getScrollableElement)(wtTable.TABLE);
26933
+ }
26934
+ }
26935
+
26596
26936
  /**
26597
26937
  * Calculates coordinates of the provided element, relative to the root Handsontable element.
26598
26938
  * NOTE: The element needs to be a child of the overlay in order for the method to work correctly.
@@ -27039,6 +27379,25 @@ class CoreAbstract {
27039
27379
  if (!topmost) {
27040
27380
  return this.wtTable.getCell(coords);
27041
27381
  }
27382
+ const totalRows = this.wtSettings.getSetting('totalRows');
27383
+ const fixedRowsTop = this.wtSettings.getSetting('fixedRowsTop');
27384
+ const fixedRowsBottom = this.wtSettings.getSetting('fixedRowsBottom');
27385
+ const fixedColumnsStart = this.wtSettings.getSetting('fixedColumnsStart');
27386
+ if (coords.row < fixedRowsTop && coords.col < fixedColumnsStart) {
27387
+ return this.wtOverlays.topInlineStartCornerOverlay.clone.wtTable.getCell(coords);
27388
+ } else if (coords.row < fixedRowsTop) {
27389
+ return this.wtOverlays.topOverlay.clone.wtTable.getCell(coords);
27390
+ } else if (coords.col < fixedColumnsStart && coords.row >= totalRows - fixedRowsBottom) {
27391
+ if (this.wtOverlays.bottomInlineStartCornerOverlay && this.wtOverlays.bottomInlineStartCornerOverlay.clone) {
27392
+ return this.wtOverlays.bottomInlineStartCornerOverlay.clone.wtTable.getCell(coords);
27393
+ }
27394
+ } else if (coords.col < fixedColumnsStart) {
27395
+ return this.wtOverlays.inlineStartOverlay.clone.wtTable.getCell(coords);
27396
+ } else if (coords.row < totalRows && coords.row >= totalRows - fixedRowsBottom) {
27397
+ if (this.wtOverlays.bottomOverlay && this.wtOverlays.bottomOverlay.clone) {
27398
+ return this.wtOverlays.bottomOverlay.clone.wtTable.getCell(coords);
27399
+ }
27400
+ }
27042
27401
  return this.wtTable.getCell(coords);
27043
27402
  }
27044
27403
 
@@ -27613,7 +27972,6 @@ class BottomOverlay extends _base.Overlay {
27613
27972
  shouldBeRendered() {
27614
27973
  return this.wtSettings.getSetting('shouldRenderBottomOverlay');
27615
27974
  }
27616
- draw() {}
27617
27975
 
27618
27976
  /**
27619
27977
  * Updates the top overlay position.
@@ -28124,7 +28482,6 @@ class InlineStartOverlay extends _base.Overlay {
28124
28482
  shouldBeRendered() {
28125
28483
  return this.wtSettings.getSetting('shouldRenderInlineStartOverlay');
28126
28484
  }
28127
- draw() {}
28128
28485
 
28129
28486
  /**
28130
28487
  * Updates the left overlay position.
@@ -30257,7 +30614,6 @@ class TopInlineStartCornerOverlay extends _base.Overlay {
30257
30614
  shouldBeRendered() {
30258
30615
  return this.wtSettings.getSetting('shouldRenderTopOverlay') && this.wtSettings.getSetting('shouldRenderInlineStartOverlay');
30259
30616
  }
30260
- draw() {}
30261
30617
 
30262
30618
  /**
30263
30619
  * Updates the corner overlay position.
@@ -30504,7 +30860,6 @@ class TopOverlay extends _base.Overlay {
30504
30860
  shouldBeRendered() {
30505
30861
  return this.wtSettings.getSetting('shouldRenderTopOverlay');
30506
30862
  }
30507
- draw() {}
30508
30863
 
30509
30864
  /**
30510
30865
  * Updates the top overlay position.
@@ -47057,6 +47412,7 @@ class BaseEditor {
47057
47412
  * @returns {{top: number, start: number, width: number, maxWidth: number, height: number, maxHeight: number} | undefined}
47058
47413
  */
47059
47414
  getEditedCellRect() {
47415
+ var _wtOverlays$getParent;
47060
47416
  const TD = this.getEditedCell();
47061
47417
 
47062
47418
  // TD is outside of the viewport.
@@ -47079,7 +47435,7 @@ class BaseEditor {
47079
47435
  const gridMostRightPos = rootWindow.innerWidth - containerOffset.left - containerWidth;
47080
47436
  const {
47081
47437
  wtTable: overlayTable
47082
- } = this.hot.view._wt;
47438
+ } = (_wtOverlays$getParent = wtOverlays.getParentOverlay(TD)) !== null && _wtOverlays$getParent !== void 0 ? _wtOverlays$getParent : this.hot.view._wt;
47083
47439
  const overlayName = overlayTable.name;
47084
47440
  const scrollTop = ['master', 'inline_start'].includes(overlayName) ? containerScrollTop : 0;
47085
47441
  const scrollLeft = ['master', 'top', 'bottom'].includes(overlayName) ? containerScrollLeft : 0;
@@ -68568,7 +68924,7 @@ function _setupListening(event) {
68568
68924
  if ((0, _event.isRightClick)(event)) {
68569
68925
  return;
68570
68926
  }
68571
- const scrollHandler = this.hot.view._wt.wtOverlays.scrollableElement;
68927
+ const scrollHandler = this.hot.view._wt.wtOverlays.topOverlay.mainTableScrollableElement;
68572
68928
  this.setBoundaries(scrollHandler !== this.hot.rootWindow ? scrollHandler.getBoundingClientRect() : undefined);
68573
68929
  this.setCallback((scrollX, scrollY) => {
68574
68930
  var _scrollHandler$scroll, _scrollHandler$scroll2;