handsontable 0.0.0-next-8951d31-20250210 → 0.0.0-next-508ffe1-20250211

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 (47) hide show
  1. package/3rdparty/walkontable/src/calculator/viewportColumns.js +5 -1
  2. package/3rdparty/walkontable/src/calculator/viewportColumns.mjs +5 -1
  3. package/3rdparty/walkontable/src/calculator/viewportRows.js +5 -1
  4. package/3rdparty/walkontable/src/calculator/viewportRows.mjs +5 -1
  5. package/3rdparty/walkontable/src/overlay/inlineStart.js +8 -1
  6. package/3rdparty/walkontable/src/overlay/inlineStart.mjs +8 -1
  7. package/3rdparty/walkontable/src/overlay/top.js +9 -1
  8. package/3rdparty/walkontable/src/overlay/top.mjs +9 -1
  9. package/3rdparty/walkontable/src/renderer/cells.js +1 -4
  10. package/3rdparty/walkontable/src/renderer/cells.mjs +1 -4
  11. package/3rdparty/walkontable/src/renderer/columnHeaders.js +1 -4
  12. package/3rdparty/walkontable/src/renderer/columnHeaders.mjs +1 -4
  13. package/3rdparty/walkontable/src/renderer/rowHeaders.js +0 -3
  14. package/3rdparty/walkontable/src/renderer/rowHeaders.mjs +0 -3
  15. package/3rdparty/walkontable/src/table.js +146 -5
  16. package/3rdparty/walkontable/src/table.mjs +146 -5
  17. package/3rdparty/walkontable/src/utils/column.js +25 -4
  18. package/3rdparty/walkontable/src/utils/column.mjs +25 -4
  19. package/3rdparty/walkontable/src/utils/row.js +12 -2
  20. package/3rdparty/walkontable/src/utils/row.mjs +12 -2
  21. package/3rdparty/walkontable/src/viewport.js +36 -2
  22. package/3rdparty/walkontable/src/viewport.mjs +36 -2
  23. package/base.js +2 -2
  24. package/base.mjs +2 -2
  25. package/core.js +54 -4
  26. package/core.mjs +54 -4
  27. package/dist/handsontable.css +2 -2
  28. package/dist/handsontable.full.css +2 -2
  29. package/dist/handsontable.full.js +333 -56
  30. package/dist/handsontable.full.min.css +2 -2
  31. package/dist/handsontable.full.min.js +9 -9
  32. package/dist/handsontable.js +322 -51
  33. package/dist/handsontable.min.css +2 -2
  34. package/dist/handsontable.min.js +15 -15
  35. package/helpers/mixed.js +1 -1
  36. package/helpers/mixed.mjs +1 -1
  37. package/package.json +1 -1
  38. package/plugins/copyPaste/copyPaste.js +12 -6
  39. package/plugins/copyPaste/copyPaste.mjs +12 -6
  40. package/renderers/textRenderer/textRenderer.js +3 -8
  41. package/renderers/textRenderer/textRenderer.mjs +3 -8
  42. package/styles/handsontable.css +2 -2
  43. package/styles/handsontable.min.css +2 -2
  44. package/styles/ht-theme-horizon.css +2 -2
  45. package/styles/ht-theme-horizon.min.css +2 -2
  46. package/styles/ht-theme-main.css +2 -2
  47. package/styles/ht-theme-main.min.css +2 -2
@@ -85,7 +85,11 @@ class ViewportColumnsCalculator extends _viewportBase.ViewportBaseCalculator {
85
85
  * @returns {number}
86
86
  */
87
87
  getColumnWidth(column) {
88
- return this.columnWidthFn(column);
88
+ const width = this.columnWidthFn(column);
89
+ if (isNaN(width)) {
90
+ return DEFAULT_WIDTH;
91
+ }
92
+ return width;
89
93
  }
90
94
  }
91
95
  exports.ViewportColumnsCalculator = ViewportColumnsCalculator;
@@ -82,6 +82,10 @@ export class ViewportColumnsCalculator extends ViewportBaseCalculator {
82
82
  * @returns {number}
83
83
  */
84
84
  getColumnWidth(column) {
85
- return this.columnWidthFn(column);
85
+ const width = this.columnWidthFn(column);
86
+ if (isNaN(width)) {
87
+ return DEFAULT_WIDTH;
88
+ }
89
+ return width;
86
90
  }
87
91
  }
@@ -87,7 +87,11 @@ class ViewportRowsCalculator extends _viewportBase.ViewportBaseCalculator {
87
87
  * @returns {number}
88
88
  */
89
89
  getRowHeight(row) {
90
- return this.rowHeightFn(row);
90
+ const rowHeight = this.rowHeightFn(row);
91
+ if (isNaN(rowHeight)) {
92
+ return this.defaultHeight;
93
+ }
94
+ return rowHeight;
91
95
  }
92
96
  }
93
97
  exports.ViewportRowsCalculator = ViewportRowsCalculator;
@@ -84,6 +84,10 @@ export class ViewportRowsCalculator extends ViewportBaseCalculator {
84
84
  * @returns {number}
85
85
  */
86
86
  getRowHeight(row) {
87
- return this.rowHeightFn(row);
87
+ const rowHeight = this.rowHeightFn(row);
88
+ if (isNaN(rowHeight)) {
89
+ return this.defaultHeight;
90
+ }
91
+ return rowHeight;
88
92
  }
89
93
  }
@@ -115,7 +115,14 @@ class InlineStartOverlay extends _base.Overlay {
115
115
  * @returns {number} Width sum.
116
116
  */
117
117
  sumCellSizes(from, to) {
118
- return (to - from) * 80;
118
+ const defaultColumnWidth = this.wtSettings.getSetting('defaultColumnWidth');
119
+ let column = from;
120
+ let sum = 0;
121
+ while (column < to) {
122
+ sum += this.wot.wtTable.getColumnWidth(column) || defaultColumnWidth;
123
+ column += 1;
124
+ }
125
+ return sum;
119
126
  }
120
127
 
121
128
  /**
@@ -111,7 +111,14 @@ export class InlineStartOverlay extends Overlay {
111
111
  * @returns {number} Width sum.
112
112
  */
113
113
  sumCellSizes(from, to) {
114
- return (to - from) * 80;
114
+ const defaultColumnWidth = this.wtSettings.getSetting('defaultColumnWidth');
115
+ let column = from;
116
+ let sum = 0;
117
+ while (column < to) {
118
+ sum += this.wot.wtTable.getColumnWidth(column) || defaultColumnWidth;
119
+ column += 1;
120
+ }
121
+ return sum;
115
122
  }
116
123
 
117
124
  /**
@@ -138,7 +138,15 @@ class TopOverlay extends _base.Overlay {
138
138
  * @returns {number} Height sum.
139
139
  */
140
140
  sumCellSizes(from, to) {
141
- return (to - from) * 29;
141
+ const defaultRowHeight = this.wot.stylesHandler.getDefaultRowHeight();
142
+ let row = from;
143
+ let sum = 0;
144
+ while (row < to) {
145
+ const height = this.wot.wtTable.getRowHeight(row);
146
+ sum += height === undefined ? defaultRowHeight : height;
147
+ row += 1;
148
+ }
149
+ return sum;
142
150
  }
143
151
 
144
152
  /**
@@ -134,7 +134,15 @@ export class TopOverlay extends Overlay {
134
134
  * @returns {number} Height sum.
135
135
  */
136
136
  sumCellSizes(from, to) {
137
- return (to - from) * 29;
137
+ const defaultRowHeight = this.wot.stylesHandler.getDefaultRowHeight();
138
+ let row = from;
139
+ let sum = 0;
140
+ while (row < to) {
141
+ const height = this.wot.wtTable.getRowHeight(row);
142
+ sum += height === undefined ? defaultRowHeight : height;
143
+ row += 1;
144
+ }
145
+ return sum;
138
146
  }
139
147
 
140
148
  /**
@@ -72,14 +72,11 @@ class CellsRenderer extends _base.BaseRenderer {
72
72
  this.sourceRowIndex = sourceRowIndex;
73
73
  const orderView = this.obtainOrderView(TR);
74
74
  const rowHeadersView = rowHeaders.obtainOrderView(TR);
75
- orderView.prependView(rowHeadersView).setSize(columnsToRender).setOffset(this.table.renderedColumnToSource(0)).start();
75
+ orderView.prependView(rowHeadersView).setSize(columnsToRender).setOffset(0).start();
76
76
  for (let visibleColumnIndex = 0; visibleColumnIndex < columnsToRender; visibleColumnIndex++) {
77
77
  orderView.render();
78
78
  const sourceColumnIndex = this.table.renderedColumnToSource(visibleColumnIndex);
79
79
  const TD = orderView.getCurrentNode();
80
- if (TD.innerHTML !== '') {
81
- continue;
82
- }
83
80
  if (!(0, _element.hasClass)(TD, 'hide')) {
84
81
  // Workaround for hidden columns plugin
85
82
  TD.className = '';
@@ -69,14 +69,11 @@ export class CellsRenderer extends BaseRenderer {
69
69
  this.sourceRowIndex = sourceRowIndex;
70
70
  const orderView = this.obtainOrderView(TR);
71
71
  const rowHeadersView = rowHeaders.obtainOrderView(TR);
72
- orderView.prependView(rowHeadersView).setSize(columnsToRender).setOffset(this.table.renderedColumnToSource(0)).start();
72
+ orderView.prependView(rowHeadersView).setSize(columnsToRender).setOffset(0).start();
73
73
  for (let visibleColumnIndex = 0; visibleColumnIndex < columnsToRender; visibleColumnIndex++) {
74
74
  orderView.render();
75
75
  const sourceColumnIndex = this.table.renderedColumnToSource(visibleColumnIndex);
76
76
  const TD = orderView.getCurrentNode();
77
- if (TD.innerHTML !== '') {
78
- continue;
79
- }
80
77
  if (!hasClass(TD, 'hide')) {
81
78
  // Workaround for hidden columns plugin
82
79
  TD.className = '';
@@ -18,7 +18,7 @@ var _a11y = require("../../../../helpers/a11y");
18
18
  */
19
19
  class ColumnHeadersRenderer extends _base.BaseRenderer {
20
20
  constructor(rootNode) {
21
- super('TR', rootNode); // NodePool is not implemented for this renderer yet
21
+ super(null, rootNode); // NodePool is not implemented for this renderer yet
22
22
  }
23
23
 
24
24
  /**
@@ -86,9 +86,6 @@ class ColumnHeadersRenderer extends _base.BaseRenderer {
86
86
  // eslint-disable-line max-len
87
87
  const sourceColumnIndex = this.table.renderedColumnToSource(renderedColumnIndex);
88
88
  const TH = TR.childNodes[renderedColumnIndex + rowHeadersCount];
89
- if (TH.innerHTML !== '') {
90
- continue;
91
- }
92
89
  TH.className = '';
93
90
  TH.removeAttribute('style');
94
91
 
@@ -15,7 +15,7 @@ import { A11Y_COLINDEX, A11Y_COLUMNHEADER, A11Y_ROW, A11Y_ROWGROUP, A11Y_ROWINDE
15
15
  */
16
16
  export class ColumnHeadersRenderer extends BaseRenderer {
17
17
  constructor(rootNode) {
18
- super('TR', rootNode); // NodePool is not implemented for this renderer yet
18
+ super(null, rootNode); // NodePool is not implemented for this renderer yet
19
19
  }
20
20
 
21
21
  /**
@@ -83,9 +83,6 @@ export class ColumnHeadersRenderer extends BaseRenderer {
83
83
  // eslint-disable-line max-len
84
84
  const sourceColumnIndex = this.table.renderedColumnToSource(renderedColumnIndex);
85
85
  const TH = TR.childNodes[renderedColumnIndex + rowHeadersCount];
86
- if (TH.innerHTML !== '') {
87
- continue;
88
- }
89
86
  TH.className = '';
90
87
  TH.removeAttribute('style');
91
88
 
@@ -77,9 +77,6 @@ class RowHeadersRenderer extends _base.BaseRenderer {
77
77
  for (let visibleColumnIndex = 0; visibleColumnIndex < rowHeadersCount; visibleColumnIndex++) {
78
78
  orderView.render();
79
79
  const TH = orderView.getCurrentNode();
80
- if (TH.innerHTML !== '') {
81
- continue;
82
- }
83
80
  TH.className = '';
84
81
  TH.removeAttribute('style');
85
82
 
@@ -74,9 +74,6 @@ export class RowHeadersRenderer extends BaseRenderer {
74
74
  for (let visibleColumnIndex = 0; visibleColumnIndex < rowHeadersCount; visibleColumnIndex++) {
75
75
  orderView.render();
76
76
  const TH = orderView.getCurrentNode();
77
- if (TH.innerHTML !== '') {
78
- continue;
79
- }
80
77
  TH.className = '';
81
78
  TH.removeAttribute('style');
82
79
 
@@ -300,6 +300,16 @@ class Table {
300
300
  this.resetOversizedRows();
301
301
  this.tableRenderer.setActiveOverlayName(this.name).setViewportSize(this.getRenderedRowsCount(), this.getRenderedColumnsCount()).setFilters(this.rowFilter, this.columnFilter).render();
302
302
  if (this.isMaster) {
303
+ this.markOversizedColumnHeaders();
304
+ }
305
+ this.adjustColumnHeaderHeights();
306
+ if (this.isMaster || this.is(_overlay.CLONE_BOTTOM)) {
307
+ this.markOversizedRows();
308
+ }
309
+ if (this.isMaster) {
310
+ if (!this.wtSettings.getSetting('externalRowCalculator')) {
311
+ wtViewport.createVisibleCalculators();
312
+ }
303
313
  wtOverlays.refresh(false);
304
314
  wtOverlays.applyToDOM();
305
315
  this.wtSettings.getSetting('onDraw', true);
@@ -341,18 +351,85 @@ class Table {
341
351
  /**
342
352
  * @param {number} col The visual column index.
343
353
  */
344
- markIfOversizedColumnHeader(col) {}
354
+ markIfOversizedColumnHeader(col) {
355
+ const sourceColIndex = this.columnFilter.renderedToSource(col);
356
+ let level = this.wtSettings.getSetting('columnHeaders').length;
357
+ const defaultRowHeight = this.dataAccessObject.stylesHandler.getDefaultRowHeight();
358
+ let previousColHeaderHeight;
359
+ let currentHeader;
360
+ let currentHeaderHeight;
361
+ const columnHeaderHeightSetting = this.wtSettings.getSetting('columnHeaderHeight') || [];
362
+ while (level) {
363
+ level -= 1;
364
+ previousColHeaderHeight = this.getColumnHeaderHeight(level);
365
+ currentHeader = this.getColumnHeader(sourceColIndex, level);
366
+ if (!currentHeader) {
367
+ /* eslint-disable no-continue */
368
+ continue;
369
+ }
370
+ currentHeaderHeight = (0, _element.innerHeight)(currentHeader);
371
+ if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) {
372
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight;
373
+ }
374
+ if (Array.isArray(columnHeaderHeightSetting)) {
375
+ if (columnHeaderHeightSetting[level] !== null && columnHeaderHeightSetting[level] !== undefined) {
376
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level];
377
+ }
378
+ } else if (!isNaN(columnHeaderHeightSetting)) {
379
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting;
380
+ }
381
+ if (this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) {
382
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting; // eslint-disable-line max-len
383
+ }
384
+ }
385
+ }
345
386
 
346
387
  /**
347
388
  *
348
389
  */
349
- adjustColumnHeaderHeights() {}
390
+ adjustColumnHeaderHeights() {
391
+ const {
392
+ wtSettings
393
+ } = this;
394
+ const children = this.THEAD.childNodes;
395
+ const oversizedColumnHeaders = this.dataAccessObject.wtViewport.oversizedColumnHeaders;
396
+ const columnHeaders = wtSettings.getSetting('columnHeaders');
397
+ for (let i = 0, len = columnHeaders.length; i < len; i++) {
398
+ if (oversizedColumnHeaders[i]) {
399
+ if (!children[i] || children[i].childNodes.length === 0) {
400
+ return;
401
+ }
402
+ children[i].childNodes[0].style.height = `${oversizedColumnHeaders[i]}px`;
403
+ }
404
+ }
405
+ }
350
406
 
351
407
  /**
352
408
  * Resets cache of row heights. The cache should be cached for each render cycle in a case
353
409
  * when new cell values have content which increases/decreases cell height.
354
410
  */
355
- resetOversizedRows() {}
411
+ resetOversizedRows() {
412
+ const {
413
+ wtSettings
414
+ } = this;
415
+ const {
416
+ wtViewport
417
+ } = this.dataAccessObject;
418
+ if (!this.isMaster && !this.is(_overlay.CLONE_BOTTOM)) {
419
+ return;
420
+ }
421
+ if (!wtSettings.getSetting('externalRowCalculator')) {
422
+ const rowsToRender = this.getRenderedRowsCount();
423
+
424
+ // Reset the oversized row cache for rendered rows
425
+ for (let visibleRowIndex = 0; visibleRowIndex < rowsToRender; visibleRowIndex++) {
426
+ const sourceRow = this.rowFilter.renderedToSource(visibleRowIndex);
427
+ if (wtViewport.oversizedRows && wtViewport.oversizedRows[sourceRow]) {
428
+ wtViewport.oversizedRows[sourceRow] = undefined;
429
+ }
430
+ }
431
+ }
432
+ }
356
433
 
357
434
  /**
358
435
  * Get cell element at coords.
@@ -550,7 +627,46 @@ class Table {
550
627
  /**
551
628
  * Check if any of the rendered rows is higher than expected, and if so, cache them.
552
629
  */
553
- markOversizedRows() {}
630
+ markOversizedRows() {
631
+ if (this.wtSettings.getSetting('externalRowCalculator')) {
632
+ return;
633
+ }
634
+ let rowCount = this.TBODY.childNodes.length;
635
+ const expectedTableHeight = rowCount * this.dataAccessObject.stylesHandler.getDefaultRowHeight();
636
+ const actualTableHeight = (0, _element.innerHeight)(this.TBODY) - 1;
637
+ const borderBoxSizing = this.wot.stylesHandler.areCellsBorderBox();
638
+ const rowHeightFn = borderBoxSizing ? _element.outerHeight : _element.innerHeight;
639
+ const borderCompensation = borderBoxSizing ? 0 : 1;
640
+ const firstRowBorderCompensation = borderBoxSizing ? 1 : 0;
641
+ let previousRowHeight;
642
+ let rowCurrentHeight;
643
+ let sourceRowIndex;
644
+ let currentTr;
645
+ let rowHeader;
646
+ if (expectedTableHeight === actualTableHeight && !this.wtSettings.getSetting('fixedRowsBottom')) {
647
+ // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them
648
+ return;
649
+ }
650
+ while (rowCount) {
651
+ rowCount -= 1;
652
+ sourceRowIndex = this.rowFilter.renderedToSource(rowCount);
653
+ previousRowHeight = this.getRowHeight(sourceRowIndex);
654
+ currentTr = this.getTrForRow(sourceRowIndex);
655
+ rowHeader = currentTr.querySelector('th');
656
+ const topBorderCompensation = sourceRowIndex === 0 ? firstRowBorderCompensation : 0;
657
+ if (rowHeader) {
658
+ rowCurrentHeight = rowHeightFn(rowHeader);
659
+ } else {
660
+ rowCurrentHeight = rowHeightFn(currentTr) - borderCompensation;
661
+ }
662
+ if (!previousRowHeight && this.dataAccessObject.stylesHandler.getDefaultRowHeight() < rowCurrentHeight - topBorderCompensation || previousRowHeight < rowCurrentHeight) {
663
+ if (!borderBoxSizing) {
664
+ rowCurrentHeight += 1;
665
+ }
666
+ this.dataAccessObject.wtViewport.oversizedRows[sourceRowIndex] = rowCurrentHeight;
667
+ }
668
+ }
669
+ }
554
670
 
555
671
  /**
556
672
  * @param {number} row The visual row index.
@@ -865,7 +981,32 @@ class Table {
865
981
  * @returns {number}
866
982
  */
867
983
  _modifyRowHeaderWidth(rowHeaderWidthFactory) {
868
- return 50;
984
+ let widths = (0, _function.isFunction)(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null;
985
+ if (Array.isArray(widths)) {
986
+ widths = [...widths];
987
+ widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]);
988
+ } else {
989
+ widths = this._correctRowHeaderWidth(widths);
990
+ }
991
+ return widths;
992
+ }
993
+
994
+ /**
995
+ * Correct row header width if necessary.
996
+ *
997
+ * @private
998
+ * @param {number} width The width to process.
999
+ * @returns {number}
1000
+ */
1001
+ _correctRowHeaderWidth(width) {
1002
+ let rowHeaderWidth = width;
1003
+ if (typeof width !== 'number') {
1004
+ rowHeaderWidth = this.wtSettings.getSetting('defaultColumnWidth');
1005
+ }
1006
+ if (this.correctHeaderWidth) {
1007
+ rowHeaderWidth += 1;
1008
+ }
1009
+ return rowHeaderWidth;
869
1010
  }
870
1011
  }
871
1012
  var _default = exports.default = Table;
@@ -296,6 +296,16 @@ class Table {
296
296
  this.resetOversizedRows();
297
297
  this.tableRenderer.setActiveOverlayName(this.name).setViewportSize(this.getRenderedRowsCount(), this.getRenderedColumnsCount()).setFilters(this.rowFilter, this.columnFilter).render();
298
298
  if (this.isMaster) {
299
+ this.markOversizedColumnHeaders();
300
+ }
301
+ this.adjustColumnHeaderHeights();
302
+ if (this.isMaster || this.is(CLONE_BOTTOM)) {
303
+ this.markOversizedRows();
304
+ }
305
+ if (this.isMaster) {
306
+ if (!this.wtSettings.getSetting('externalRowCalculator')) {
307
+ wtViewport.createVisibleCalculators();
308
+ }
299
309
  wtOverlays.refresh(false);
300
310
  wtOverlays.applyToDOM();
301
311
  this.wtSettings.getSetting('onDraw', true);
@@ -337,18 +347,85 @@ class Table {
337
347
  /**
338
348
  * @param {number} col The visual column index.
339
349
  */
340
- markIfOversizedColumnHeader(col) {}
350
+ markIfOversizedColumnHeader(col) {
351
+ const sourceColIndex = this.columnFilter.renderedToSource(col);
352
+ let level = this.wtSettings.getSetting('columnHeaders').length;
353
+ const defaultRowHeight = this.dataAccessObject.stylesHandler.getDefaultRowHeight();
354
+ let previousColHeaderHeight;
355
+ let currentHeader;
356
+ let currentHeaderHeight;
357
+ const columnHeaderHeightSetting = this.wtSettings.getSetting('columnHeaderHeight') || [];
358
+ while (level) {
359
+ level -= 1;
360
+ previousColHeaderHeight = this.getColumnHeaderHeight(level);
361
+ currentHeader = this.getColumnHeader(sourceColIndex, level);
362
+ if (!currentHeader) {
363
+ /* eslint-disable no-continue */
364
+ continue;
365
+ }
366
+ currentHeaderHeight = innerHeight(currentHeader);
367
+ if (!previousColHeaderHeight && defaultRowHeight < currentHeaderHeight || previousColHeaderHeight < currentHeaderHeight) {
368
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = currentHeaderHeight;
369
+ }
370
+ if (Array.isArray(columnHeaderHeightSetting)) {
371
+ if (columnHeaderHeightSetting[level] !== null && columnHeaderHeightSetting[level] !== undefined) {
372
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level];
373
+ }
374
+ } else if (!isNaN(columnHeaderHeightSetting)) {
375
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting;
376
+ }
377
+ if (this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] < (columnHeaderHeightSetting[level] || columnHeaderHeightSetting)) {
378
+ this.dataAccessObject.wtViewport.oversizedColumnHeaders[level] = columnHeaderHeightSetting[level] || columnHeaderHeightSetting; // eslint-disable-line max-len
379
+ }
380
+ }
381
+ }
341
382
 
342
383
  /**
343
384
  *
344
385
  */
345
- adjustColumnHeaderHeights() {}
386
+ adjustColumnHeaderHeights() {
387
+ const {
388
+ wtSettings
389
+ } = this;
390
+ const children = this.THEAD.childNodes;
391
+ const oversizedColumnHeaders = this.dataAccessObject.wtViewport.oversizedColumnHeaders;
392
+ const columnHeaders = wtSettings.getSetting('columnHeaders');
393
+ for (let i = 0, len = columnHeaders.length; i < len; i++) {
394
+ if (oversizedColumnHeaders[i]) {
395
+ if (!children[i] || children[i].childNodes.length === 0) {
396
+ return;
397
+ }
398
+ children[i].childNodes[0].style.height = `${oversizedColumnHeaders[i]}px`;
399
+ }
400
+ }
401
+ }
346
402
 
347
403
  /**
348
404
  * Resets cache of row heights. The cache should be cached for each render cycle in a case
349
405
  * when new cell values have content which increases/decreases cell height.
350
406
  */
351
- resetOversizedRows() {}
407
+ resetOversizedRows() {
408
+ const {
409
+ wtSettings
410
+ } = this;
411
+ const {
412
+ wtViewport
413
+ } = this.dataAccessObject;
414
+ if (!this.isMaster && !this.is(CLONE_BOTTOM)) {
415
+ return;
416
+ }
417
+ if (!wtSettings.getSetting('externalRowCalculator')) {
418
+ const rowsToRender = this.getRenderedRowsCount();
419
+
420
+ // Reset the oversized row cache for rendered rows
421
+ for (let visibleRowIndex = 0; visibleRowIndex < rowsToRender; visibleRowIndex++) {
422
+ const sourceRow = this.rowFilter.renderedToSource(visibleRowIndex);
423
+ if (wtViewport.oversizedRows && wtViewport.oversizedRows[sourceRow]) {
424
+ wtViewport.oversizedRows[sourceRow] = undefined;
425
+ }
426
+ }
427
+ }
428
+ }
352
429
 
353
430
  /**
354
431
  * Get cell element at coords.
@@ -546,7 +623,46 @@ class Table {
546
623
  /**
547
624
  * Check if any of the rendered rows is higher than expected, and if so, cache them.
548
625
  */
549
- markOversizedRows() {}
626
+ markOversizedRows() {
627
+ if (this.wtSettings.getSetting('externalRowCalculator')) {
628
+ return;
629
+ }
630
+ let rowCount = this.TBODY.childNodes.length;
631
+ const expectedTableHeight = rowCount * this.dataAccessObject.stylesHandler.getDefaultRowHeight();
632
+ const actualTableHeight = innerHeight(this.TBODY) - 1;
633
+ const borderBoxSizing = this.wot.stylesHandler.areCellsBorderBox();
634
+ const rowHeightFn = borderBoxSizing ? outerHeight : innerHeight;
635
+ const borderCompensation = borderBoxSizing ? 0 : 1;
636
+ const firstRowBorderCompensation = borderBoxSizing ? 1 : 0;
637
+ let previousRowHeight;
638
+ let rowCurrentHeight;
639
+ let sourceRowIndex;
640
+ let currentTr;
641
+ let rowHeader;
642
+ if (expectedTableHeight === actualTableHeight && !this.wtSettings.getSetting('fixedRowsBottom')) {
643
+ // If the actual table height equals rowCount * default single row height, no row is oversized -> no need to iterate over them
644
+ return;
645
+ }
646
+ while (rowCount) {
647
+ rowCount -= 1;
648
+ sourceRowIndex = this.rowFilter.renderedToSource(rowCount);
649
+ previousRowHeight = this.getRowHeight(sourceRowIndex);
650
+ currentTr = this.getTrForRow(sourceRowIndex);
651
+ rowHeader = currentTr.querySelector('th');
652
+ const topBorderCompensation = sourceRowIndex === 0 ? firstRowBorderCompensation : 0;
653
+ if (rowHeader) {
654
+ rowCurrentHeight = rowHeightFn(rowHeader);
655
+ } else {
656
+ rowCurrentHeight = rowHeightFn(currentTr) - borderCompensation;
657
+ }
658
+ if (!previousRowHeight && this.dataAccessObject.stylesHandler.getDefaultRowHeight() < rowCurrentHeight - topBorderCompensation || previousRowHeight < rowCurrentHeight) {
659
+ if (!borderBoxSizing) {
660
+ rowCurrentHeight += 1;
661
+ }
662
+ this.dataAccessObject.wtViewport.oversizedRows[sourceRowIndex] = rowCurrentHeight;
663
+ }
664
+ }
665
+ }
550
666
 
551
667
  /**
552
668
  * @param {number} row The visual row index.
@@ -861,7 +977,32 @@ class Table {
861
977
  * @returns {number}
862
978
  */
863
979
  _modifyRowHeaderWidth(rowHeaderWidthFactory) {
864
- return 50;
980
+ let widths = isFunction(rowHeaderWidthFactory) ? rowHeaderWidthFactory() : null;
981
+ if (Array.isArray(widths)) {
982
+ widths = [...widths];
983
+ widths[widths.length - 1] = this._correctRowHeaderWidth(widths[widths.length - 1]);
984
+ } else {
985
+ widths = this._correctRowHeaderWidth(widths);
986
+ }
987
+ return widths;
988
+ }
989
+
990
+ /**
991
+ * Correct row header width if necessary.
992
+ *
993
+ * @private
994
+ * @param {number} width The width to process.
995
+ * @returns {number}
996
+ */
997
+ _correctRowHeaderWidth(width) {
998
+ let rowHeaderWidth = width;
999
+ if (typeof width !== 'number') {
1000
+ rowHeaderWidth = this.wtSettings.getSetting('defaultColumnWidth');
1001
+ }
1002
+ if (this.correctHeaderWidth) {
1003
+ rowHeaderWidth += 1;
1004
+ }
1005
+ return rowHeaderWidth;
865
1006
  }
866
1007
  }
867
1008
  export default Table;
@@ -39,7 +39,8 @@ class ColumnUtils {
39
39
  * @returns {number}
40
40
  */
41
41
  getWidth(sourceIndex) {
42
- return this.wtSettings.getSetting('columnWidth', sourceIndex);
42
+ const width = this.wtSettings.getSetting('columnWidth', sourceIndex) || this.wtSettings.getSetting('defaultColumnWidth');
43
+ return width;
43
44
  }
44
45
 
45
46
  /**
@@ -49,7 +50,12 @@ class ColumnUtils {
49
50
  * @returns {number}
50
51
  */
51
52
  getHeaderHeight(level) {
52
- return this.dataAccessObject.stylesHandler.getDefaultRowHeight();
53
+ let height = this.dataAccessObject.stylesHandler.getDefaultRowHeight();
54
+ const oversizedHeight = this.dataAccessObject.wtViewport.oversizedColumnHeaders[level];
55
+ if (oversizedHeight !== undefined) {
56
+ height = height ? Math.max(height, oversizedHeight) : oversizedHeight;
57
+ }
58
+ return height;
53
59
  }
54
60
 
55
61
  /**
@@ -59,12 +65,27 @@ class ColumnUtils {
59
65
  * @returns {number}
60
66
  */
61
67
  getHeaderWidth(sourceIndex) {
62
- return 50;
68
+ return this.headerWidths.get(this.dataAccessObject.wtTable.columnFilter.sourceToRendered(sourceIndex));
63
69
  }
64
70
 
65
71
  /**
66
72
  * Calculates column header widths that can be retrieved from the cache.
67
73
  */
68
- calculateWidths() {}
74
+ calculateWidths() {
75
+ const {
76
+ wtSettings
77
+ } = this;
78
+ let rowHeaderWidthSetting = wtSettings.getSetting('rowHeaderWidth');
79
+ rowHeaderWidthSetting = wtSettings.getSetting('onModifyRowHeaderWidth', rowHeaderWidthSetting);
80
+ if (rowHeaderWidthSetting !== null && rowHeaderWidthSetting !== undefined) {
81
+ const rowHeadersCount = wtSettings.getSetting('rowHeaders').length;
82
+ const defaultColumnWidth = wtSettings.getSetting('defaultColumnWidth');
83
+ for (let visibleColumnIndex = 0; visibleColumnIndex < rowHeadersCount; visibleColumnIndex++) {
84
+ let width = Array.isArray(rowHeaderWidthSetting) ? rowHeaderWidthSetting[visibleColumnIndex] : rowHeaderWidthSetting;
85
+ width = width === null || width === undefined ? defaultColumnWidth : width;
86
+ this.headerWidths.set(visibleColumnIndex, width);
87
+ }
88
+ }
89
+ }
69
90
  }
70
91
  exports.default = ColumnUtils;