handsontable 0.0.0-next-c8116f8-20240920 → 0.0.0-next-fad35d5-20240924

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of handsontable might be problematic. Click here for more details.

Files changed (113) hide show
  1. package/3rdparty/walkontable/src/calculator/calculationType/renderedColumns.js +23 -0
  2. package/3rdparty/walkontable/src/calculator/calculationType/renderedColumns.mjs +23 -0
  3. package/3rdparty/walkontable/src/calculator/calculationType/renderedRows.js +23 -0
  4. package/3rdparty/walkontable/src/calculator/calculationType/renderedRows.mjs +23 -0
  5. package/3rdparty/walkontable/src/core/_base.js +7 -0
  6. package/3rdparty/walkontable/src/core/_base.mjs +7 -0
  7. package/3rdparty/walkontable/src/facade/core.js +3 -0
  8. package/3rdparty/walkontable/src/facade/core.mjs +3 -0
  9. package/3rdparty/walkontable/src/overlay/_base.js +3 -0
  10. package/3rdparty/walkontable/src/overlay/_base.mjs +3 -0
  11. package/3rdparty/walkontable/src/selection/border/border.js +32 -44
  12. package/3rdparty/walkontable/src/selection/border/border.mjs +32 -44
  13. package/3rdparty/walkontable/src/selection/scanner.js +46 -11
  14. package/3rdparty/walkontable/src/selection/scanner.mjs +46 -11
  15. package/3rdparty/walkontable/src/settings.js +8 -0
  16. package/3rdparty/walkontable/src/settings.mjs +8 -0
  17. package/3rdparty/walkontable/src/table.js +6 -3
  18. package/3rdparty/walkontable/src/table.mjs +6 -3
  19. package/3rdparty/walkontable/src/viewport.js +26 -4
  20. package/3rdparty/walkontable/src/viewport.mjs +26 -4
  21. package/base.js +4 -4
  22. package/base.mjs +3 -3
  23. package/core/hooks/bucket.js +180 -0
  24. package/core/hooks/bucket.mjs +176 -0
  25. package/{pluginHooks.mjs → core/hooks/constants.js} +20 -486
  26. package/{pluginHooks.js → core/hooks/constants.mjs} +16 -489
  27. package/{pluginHooks.d.ts → core/hooks/index.d.ts} +17 -21
  28. package/core/hooks/index.js +385 -0
  29. package/core/hooks/index.mjs +381 -0
  30. package/core.d.ts +1 -1
  31. package/core.js +13 -12
  32. package/core.mjs +5 -4
  33. package/dataMap/metaManager/metaSchema.js +68 -2
  34. package/dataMap/metaManager/metaSchema.mjs +68 -2
  35. package/dataMap/metaManager/mods/dynamicCellMeta.js +2 -3
  36. package/dataMap/metaManager/mods/dynamicCellMeta.mjs +1 -1
  37. package/dist/handsontable.css +2 -2
  38. package/dist/handsontable.full.css +2 -2
  39. package/dist/handsontable.full.js +3009 -2582
  40. package/dist/handsontable.full.min.css +2 -2
  41. package/dist/handsontable.full.min.js +60 -60
  42. package/dist/handsontable.js +3011 -2584
  43. package/dist/handsontable.min.css +2 -2
  44. package/dist/handsontable.min.js +18 -18
  45. package/editorManager.js +2 -2
  46. package/editorManager.mjs +2 -2
  47. package/editors/baseEditor/baseEditor.js +23 -16
  48. package/editors/baseEditor/baseEditor.mjs +23 -16
  49. package/editors/dropdownEditor/dropdownEditor.js +2 -3
  50. package/editors/dropdownEditor/dropdownEditor.mjs +1 -1
  51. package/editors/registry.js +2 -2
  52. package/editors/registry.mjs +1 -1
  53. package/helpers/mixed.js +1 -1
  54. package/helpers/mixed.mjs +1 -1
  55. package/index.d.ts +2 -1
  56. package/package.json +1 -1
  57. package/plugins/autoColumnSize/autoColumnSize.js +18 -27
  58. package/plugins/autoColumnSize/autoColumnSize.mjs +18 -27
  59. package/plugins/autoRowSize/autoRowSize.js +16 -22
  60. package/plugins/autoRowSize/autoRowSize.mjs +17 -23
  61. package/plugins/autofill/autofill.js +4 -5
  62. package/plugins/autofill/autofill.mjs +1 -1
  63. package/plugins/base/base.d.ts +1 -1
  64. package/plugins/base/base.js +39 -0
  65. package/plugins/base/base.mjs +40 -1
  66. package/plugins/base/index.js +2 -1
  67. package/plugins/base/index.mjs +1 -1
  68. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.js +2 -5
  69. package/plugins/bindRowsWithHeaders/bindRowsWithHeaders.mjs +2 -5
  70. package/plugins/columnSorting/columnSorting.js +3 -4
  71. package/plugins/columnSorting/columnSorting.mjs +1 -1
  72. package/plugins/comments/comments.js +7 -15
  73. package/plugins/comments/comments.mjs +8 -16
  74. package/plugins/contextMenu/contextMenu.js +6 -7
  75. package/plugins/contextMenu/contextMenu.mjs +1 -1
  76. package/plugins/copyPaste/copyPaste.js +29 -23
  77. package/plugins/copyPaste/copyPaste.mjs +21 -15
  78. package/plugins/dropdownMenu/dropdownMenu.js +6 -7
  79. package/plugins/dropdownMenu/dropdownMenu.mjs +1 -1
  80. package/plugins/formulas/formulas.js +7 -7
  81. package/plugins/formulas/formulas.mjs +1 -1
  82. package/plugins/hiddenColumns/hiddenColumns.js +19 -30
  83. package/plugins/hiddenColumns/hiddenColumns.mjs +15 -26
  84. package/plugins/hiddenRows/hiddenRows.js +18 -29
  85. package/plugins/hiddenRows/hiddenRows.mjs +14 -25
  86. package/plugins/manualColumnFreeze/manualColumnFreeze.js +5 -5
  87. package/plugins/manualColumnFreeze/manualColumnFreeze.mjs +1 -1
  88. package/plugins/manualColumnMove/manualColumnMove.js +3 -3
  89. package/plugins/manualColumnMove/manualColumnMove.mjs +1 -1
  90. package/plugins/manualRowMove/manualRowMove.js +5 -5
  91. package/plugins/manualRowMove/manualRowMove.mjs +3 -3
  92. package/plugins/mergeCells/cellsCollection.js +15 -3
  93. package/plugins/mergeCells/cellsCollection.mjs +16 -4
  94. package/plugins/mergeCells/mergeCells.d.ts +6 -2
  95. package/plugins/mergeCells/mergeCells.js +78 -55
  96. package/plugins/mergeCells/mergeCells.mjs +76 -53
  97. package/plugins/mergeCells/renderer.js +13 -3
  98. package/plugins/mergeCells/renderer.mjs +13 -3
  99. package/plugins/persistentState/persistentState.js +4 -4
  100. package/plugins/persistentState/persistentState.mjs +1 -1
  101. package/plugins/undoRedo/undoRedo.js +4 -5
  102. package/plugins/undoRedo/undoRedo.mjs +3 -3
  103. package/renderers/checkboxRenderer/checkboxRenderer.js +2 -2
  104. package/renderers/checkboxRenderer/checkboxRenderer.mjs +1 -1
  105. package/settings.d.ts +3 -1
  106. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.js +1 -1
  107. package/shortcutContexts/commands/extendCellsSelection/downByViewportHeight.mjs +1 -1
  108. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.js +1 -1
  109. package/shortcutContexts/commands/extendCellsSelection/upByViewportHeight.mjs +1 -1
  110. package/shortcutContexts/commands/scrollToFocusedCell.js +4 -4
  111. package/shortcutContexts/commands/scrollToFocusedCell.mjs +4 -4
  112. package/tableView.js +40 -9
  113. package/tableView.mjs +40 -9
@@ -193,21 +193,18 @@ export class SelectionScanner {
193
193
  * @param {function(HTMLTableElement): void} callback The callback function to trigger.
194
194
  */
195
195
  scanCellsRange(callback) {
196
- const [topRow, topColumn, bottomRow, bottomColumn] = _classPrivateFieldGet(_selection, this).getCorners();
197
196
  const {
198
197
  wtTable
199
198
  } = _classPrivateFieldGet(_activeOverlaysWot, this);
200
199
  _assertClassBrand(_SelectionScanner_brand, this, _scanCellsRange).call(this, (sourceRow, sourceColumn) => {
201
- if (sourceRow >= topRow && sourceRow <= bottomRow && sourceColumn >= topColumn && sourceColumn <= bottomColumn) {
202
- const cell = wtTable.getCell(_classPrivateFieldGet(_activeOverlaysWot, this).createCellCoords(sourceRow, sourceColumn));
200
+ const cell = wtTable.getCell(_classPrivateFieldGet(_activeOverlaysWot, this).createCellCoords(sourceRow, sourceColumn));
203
201
 
204
- // support for old API
205
- const additionalSelectionClass = _classPrivateFieldGet(_activeOverlaysWot, this).getSetting('onAfterDrawSelection', sourceRow, sourceColumn, _classPrivateFieldGet(_selection, this).settings.layerLevel);
206
- if (typeof additionalSelectionClass === 'string') {
207
- addClass(cell, additionalSelectionClass);
208
- }
209
- callback(cell);
202
+ // support for old API
203
+ const additionalSelectionClass = _classPrivateFieldGet(_activeOverlaysWot, this).getSetting('onAfterDrawSelection', sourceRow, sourceColumn, _classPrivateFieldGet(_selection, this).settings.layerLevel);
204
+ if (typeof additionalSelectionClass === 'string') {
205
+ addClass(cell, additionalSelectionClass);
210
206
  }
207
+ callback(cell);
211
208
  });
212
209
  }
213
210
 
@@ -223,7 +220,7 @@ export class SelectionScanner {
223
220
  const {
224
221
  wtTable
225
222
  } = _classPrivateFieldGet(_activeOverlaysWot, this);
226
- _assertClassBrand(_SelectionScanner_brand, this, _scanCellsRange).call(this, (sourceRow, sourceColumn) => {
223
+ _assertClassBrand(_SelectionScanner_brand, this, _scanViewportRange).call(this, (sourceRow, sourceColumn) => {
227
224
  if (sourceRow >= topRow && sourceRow <= bottomRow) {
228
225
  const cell = wtTable.getCell(_classPrivateFieldGet(_activeOverlaysWot, this).createCellCoords(sourceRow, sourceColumn));
229
226
  callback(cell);
@@ -242,7 +239,7 @@ export class SelectionScanner {
242
239
  const {
243
240
  wtTable
244
241
  } = _classPrivateFieldGet(_activeOverlaysWot, this);
245
- _assertClassBrand(_SelectionScanner_brand, this, _scanCellsRange).call(this, (sourceRow, sourceColumn) => {
242
+ _assertClassBrand(_SelectionScanner_brand, this, _scanViewportRange).call(this, (sourceRow, sourceColumn) => {
246
243
  if (sourceColumn >= topColumn && sourceColumn <= bottomColumn) {
247
244
  const cell = wtTable.getCell(_classPrivateFieldGet(_activeOverlaysWot, this).createCellCoords(sourceRow, sourceColumn));
248
245
  callback(cell);
@@ -251,6 +248,44 @@ export class SelectionScanner {
251
248
  }
252
249
  }
253
250
  function _scanCellsRange(callback) {
251
+ let [topRow, startColumn, bottomRow, endColumn] = _classPrivateFieldGet(_selection, this).getCorners();
252
+ if (topRow < 0 && bottomRow < 0 || startColumn < 0 && endColumn < 0) {
253
+ return;
254
+ }
255
+ const {
256
+ wtTable
257
+ } = _classPrivateFieldGet(_activeOverlaysWot, this);
258
+ const isMultiple = topRow !== bottomRow || startColumn !== endColumn;
259
+ startColumn = Math.max(startColumn, 0);
260
+ endColumn = Math.max(endColumn, 0);
261
+ topRow = Math.max(topRow, 0);
262
+ bottomRow = Math.max(bottomRow, 0);
263
+ if (isMultiple) {
264
+ startColumn = Math.max(startColumn, wtTable.getFirstRenderedColumn());
265
+ endColumn = Math.min(endColumn, wtTable.getLastRenderedColumn());
266
+ topRow = Math.max(topRow, wtTable.getFirstRenderedRow());
267
+ bottomRow = Math.min(bottomRow, wtTable.getLastRenderedRow());
268
+ if (endColumn < startColumn || bottomRow < topRow) {
269
+ return;
270
+ }
271
+ } else {
272
+ const cell = wtTable.getCell(_classPrivateFieldGet(_activeOverlaysWot, this).createCellCoords(topRow, startColumn));
273
+ if (!(cell instanceof HTMLElement)) {
274
+ return;
275
+ }
276
+ }
277
+ for (let row = topRow; row <= bottomRow; row += 1) {
278
+ for (let column = startColumn; column <= endColumn; column += 1) {
279
+ callback(row, column);
280
+ }
281
+ }
282
+ }
283
+ /**
284
+ * The method triggers a callback for each rendered cell including headers.
285
+ *
286
+ * @param {function(number, number): void} callback The callback function to trigger.
287
+ */
288
+ function _scanViewportRange(callback) {
254
289
  const {
255
290
  wtTable
256
291
  } = _classPrivateFieldGet(_activeOverlaysWot, this);
@@ -66,6 +66,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
66
66
  * @property {?Option} onCellMouseUp Option `onCellMouseUp`.
67
67
  * @property {?Option} onDraw Option `onDraw`.
68
68
  * @property {?Option} onModifyGetCellCoords Option `onModifyGetCellCoords`.
69
+ * @property {?Option} onModifyGetCoordsElement Option `onModifyGetCoordsElement`.
70
+ * @property {?Option} onModifyGetCoords Option `onModifyGetCoords`.
69
71
  * @property {?Option} onModifyRowHeaderWidth Option `onModifyRowHeaderWidth`.
70
72
  * @property {?Option} onBeforeViewportScrollHorizontally Option `onBeforeViewportScrollHorizontally`.
71
73
  * @property {?Option} onBeforeViewportScrollVertically Option `onBeforeViewportScrollVertically`.
@@ -76,6 +78,8 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
76
78
  * @property {?Option} selections Option `selections`.
77
79
  * @property {?Option} viewportColumnCalculatorOverride Option `viewportColumnCalculatorOverride`.
78
80
  * @property {?Option} viewportRowCalculatorOverride Option `viewportRowCalculatorOverride`.
81
+ * @property {?Option} viewportColumnRenderingThreshold Option `viewportColumnRenderingThreshold`.
82
+ * @property {?Option} viewportRowRenderingThreshold Option `viewportRowRenderingThreshold`.
79
83
  */
80
84
 
81
85
  /**
@@ -193,6 +197,8 @@ class Settings {
193
197
  hideBorderOnMouseDownOver: false,
194
198
  viewportRowCalculatorOverride: null,
195
199
  viewportColumnCalculatorOverride: null,
200
+ viewportRowRenderingThreshold: null,
201
+ viewportColumnRenderingThreshold: null,
196
202
  // callbacks
197
203
  onCellMouseDown: null,
198
204
  onCellContextMenu: null,
@@ -220,6 +226,8 @@ class Settings {
220
226
  onBeforeStretchingColumnWidth: width => width,
221
227
  onModifyRowHeaderWidth: null,
222
228
  onModifyGetCellCoords: null,
229
+ onModifyGetCoordsElement: null,
230
+ onModifyGetCoords: null,
223
231
  onBeforeHighlightingRowHeader: sourceRow => sourceRow,
224
232
  onBeforeHighlightingColumnHeader: sourceCol => sourceCol,
225
233
  onWindowResize: null,
@@ -63,6 +63,8 @@ import { objectEach } from "../../../helpers/object.mjs";
63
63
  * @property {?Option} onCellMouseUp Option `onCellMouseUp`.
64
64
  * @property {?Option} onDraw Option `onDraw`.
65
65
  * @property {?Option} onModifyGetCellCoords Option `onModifyGetCellCoords`.
66
+ * @property {?Option} onModifyGetCoordsElement Option `onModifyGetCoordsElement`.
67
+ * @property {?Option} onModifyGetCoords Option `onModifyGetCoords`.
66
68
  * @property {?Option} onModifyRowHeaderWidth Option `onModifyRowHeaderWidth`.
67
69
  * @property {?Option} onBeforeViewportScrollHorizontally Option `onBeforeViewportScrollHorizontally`.
68
70
  * @property {?Option} onBeforeViewportScrollVertically Option `onBeforeViewportScrollVertically`.
@@ -73,6 +75,8 @@ import { objectEach } from "../../../helpers/object.mjs";
73
75
  * @property {?Option} selections Option `selections`.
74
76
  * @property {?Option} viewportColumnCalculatorOverride Option `viewportColumnCalculatorOverride`.
75
77
  * @property {?Option} viewportRowCalculatorOverride Option `viewportRowCalculatorOverride`.
78
+ * @property {?Option} viewportColumnRenderingThreshold Option `viewportColumnRenderingThreshold`.
79
+ * @property {?Option} viewportRowRenderingThreshold Option `viewportRowRenderingThreshold`.
76
80
  */
77
81
  /**
78
82
  * @template TValue.
@@ -188,6 +192,8 @@ export default class Settings {
188
192
  hideBorderOnMouseDownOver: false,
189
193
  viewportRowCalculatorOverride: null,
190
194
  viewportColumnCalculatorOverride: null,
195
+ viewportRowRenderingThreshold: null,
196
+ viewportColumnRenderingThreshold: null,
191
197
  // callbacks
192
198
  onCellMouseDown: null,
193
199
  onCellContextMenu: null,
@@ -215,6 +221,8 @@ export default class Settings {
215
221
  onBeforeStretchingColumnWidth: width => width,
216
222
  onModifyRowHeaderWidth: null,
217
223
  onModifyGetCellCoords: null,
224
+ onModifyGetCoordsElement: null,
225
+ onModifyGetCoords: null,
218
226
  onBeforeHighlightingRowHeader: sourceRow => sourceRow,
219
227
  onBeforeHighlightingColumnHeader: sourceCol => sourceCol,
220
228
  onWindowResize: null,
@@ -466,7 +466,7 @@ class Table {
466
466
  getCell(coords) {
467
467
  let row = coords.row;
468
468
  let column = coords.col;
469
- const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column);
469
+ const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column, !this.isMaster, 'render');
470
470
  if (hookResult && Array.isArray(hookResult)) {
471
471
  [row, column] = hookResult;
472
472
  }
@@ -519,9 +519,8 @@ class Table {
519
519
  } else {
520
520
  return parentElement.childNodes[renderedRowIndex];
521
521
  }
522
- } else {
523
- return false;
524
522
  }
523
+ return false;
525
524
  }
526
525
 
527
526
  /**
@@ -631,6 +630,10 @@ class Table {
631
630
  } else {
632
631
  col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col);
633
632
  }
633
+ const hookResult = this.wtSettings.getSetting('onModifyGetCoordsElement', row, col);
634
+ if (hookResult && Array.isArray(hookResult)) {
635
+ [row, col] = hookResult;
636
+ }
634
637
  return this.wot.createCellCoords(row, col);
635
638
  }
636
639
 
@@ -462,7 +462,7 @@ class Table {
462
462
  getCell(coords) {
463
463
  let row = coords.row;
464
464
  let column = coords.col;
465
- const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column);
465
+ const hookResult = this.wtSettings.getSetting('onModifyGetCellCoords', row, column, !this.isMaster, 'render');
466
466
  if (hookResult && Array.isArray(hookResult)) {
467
467
  [row, column] = hookResult;
468
468
  }
@@ -515,9 +515,8 @@ class Table {
515
515
  } else {
516
516
  return parentElement.childNodes[renderedRowIndex];
517
517
  }
518
- } else {
519
- return false;
520
518
  }
519
+ return false;
521
520
  }
522
521
 
523
522
  /**
@@ -627,6 +626,10 @@ class Table {
627
626
  } else {
628
627
  col = this.columnFilter.visibleRowHeadedColumnToSourceColumn(col);
629
628
  }
629
+ const hookResult = this.wtSettings.getSetting('onModifyGetCoordsElement', row, col);
630
+ if (hookResult && Array.isArray(hookResult)) {
631
+ [row, col] = hookResult;
632
+ }
630
633
  return this.wot.createCellCoords(row, col);
631
634
  }
632
635
 
@@ -403,11 +403,22 @@ class Viewport {
403
403
  }
404
404
  const {
405
405
  startRow: renderedStartRow,
406
- endRow: renderedEndRow
406
+ endRow: renderedEndRow,
407
+ rowStartOffset,
408
+ rowEndOffset
407
409
  } = this.rowsRenderCalculator;
410
+ const totalRows = this.wtSettings.getSetting('totalRows') - 1;
411
+ const renderingThreshold = this.wtSettings.getSetting('viewportRowRenderingThreshold');
412
+ if (Number.isInteger(renderingThreshold) && renderingThreshold > 0) {
413
+ startRow = Math.max(0, startRow - Math.min(rowStartOffset, renderingThreshold));
414
+ endRow = Math.min(totalRows, endRow + Math.min(rowEndOffset, renderingThreshold));
415
+ } else if (renderingThreshold === 'auto') {
416
+ startRow = Math.max(0, startRow - Math.ceil(rowStartOffset / 2));
417
+ endRow = Math.min(totalRows, endRow + Math.ceil(rowEndOffset / 2));
418
+ }
408
419
  if (startRow < renderedStartRow || startRow === renderedStartRow && startRow > 0) {
409
420
  return false;
410
- } else if (endRow > renderedEndRow || endRow === renderedEndRow && endRow < this.wtSettings.getSetting('totalRows') - 1) {
421
+ } else if (endRow > renderedEndRow || endRow === renderedEndRow && endRow < totalRows) {
411
422
  return false;
412
423
  }
413
424
  return true;
@@ -441,11 +452,22 @@ class Viewport {
441
452
  }
442
453
  const {
443
454
  startColumn: renderedStartColumn,
444
- endColumn: renderedEndColumn
455
+ endColumn: renderedEndColumn,
456
+ columnStartOffset,
457
+ columnEndOffset
445
458
  } = this.columnsRenderCalculator;
459
+ const totalColumns = this.wtSettings.getSetting('totalColumns') - 1;
460
+ const renderingThreshold = this.wtSettings.getSetting('viewportColumnRenderingThreshold');
461
+ if (Number.isInteger(renderingThreshold) && renderingThreshold > 0) {
462
+ startColumn = Math.max(0, startColumn - Math.min(columnStartOffset, renderingThreshold));
463
+ endColumn = Math.min(totalColumns, endColumn + Math.min(columnEndOffset, renderingThreshold));
464
+ } else if (renderingThreshold === 'auto') {
465
+ startColumn = Math.max(0, startColumn - Math.ceil(columnStartOffset / 2));
466
+ endColumn = Math.min(totalColumns, endColumn + Math.ceil(columnEndOffset / 2));
467
+ }
446
468
  if (startColumn < renderedStartColumn || startColumn === renderedStartColumn && startColumn > 0) {
447
469
  return false;
448
- } else if (endColumn > renderedEndColumn || endColumn === renderedEndColumn && endColumn < this.wtSettings.getSetting('totalColumns') - 1) {
470
+ } else if (endColumn > renderedEndColumn || endColumn === renderedEndColumn && endColumn < totalColumns) {
449
471
  return false;
450
472
  }
451
473
  return true;
@@ -400,11 +400,22 @@ class Viewport {
400
400
  }
401
401
  const {
402
402
  startRow: renderedStartRow,
403
- endRow: renderedEndRow
403
+ endRow: renderedEndRow,
404
+ rowStartOffset,
405
+ rowEndOffset
404
406
  } = this.rowsRenderCalculator;
407
+ const totalRows = this.wtSettings.getSetting('totalRows') - 1;
408
+ const renderingThreshold = this.wtSettings.getSetting('viewportRowRenderingThreshold');
409
+ if (Number.isInteger(renderingThreshold) && renderingThreshold > 0) {
410
+ startRow = Math.max(0, startRow - Math.min(rowStartOffset, renderingThreshold));
411
+ endRow = Math.min(totalRows, endRow + Math.min(rowEndOffset, renderingThreshold));
412
+ } else if (renderingThreshold === 'auto') {
413
+ startRow = Math.max(0, startRow - Math.ceil(rowStartOffset / 2));
414
+ endRow = Math.min(totalRows, endRow + Math.ceil(rowEndOffset / 2));
415
+ }
405
416
  if (startRow < renderedStartRow || startRow === renderedStartRow && startRow > 0) {
406
417
  return false;
407
- } else if (endRow > renderedEndRow || endRow === renderedEndRow && endRow < this.wtSettings.getSetting('totalRows') - 1) {
418
+ } else if (endRow > renderedEndRow || endRow === renderedEndRow && endRow < totalRows) {
408
419
  return false;
409
420
  }
410
421
  return true;
@@ -438,11 +449,22 @@ class Viewport {
438
449
  }
439
450
  const {
440
451
  startColumn: renderedStartColumn,
441
- endColumn: renderedEndColumn
452
+ endColumn: renderedEndColumn,
453
+ columnStartOffset,
454
+ columnEndOffset
442
455
  } = this.columnsRenderCalculator;
456
+ const totalColumns = this.wtSettings.getSetting('totalColumns') - 1;
457
+ const renderingThreshold = this.wtSettings.getSetting('viewportColumnRenderingThreshold');
458
+ if (Number.isInteger(renderingThreshold) && renderingThreshold > 0) {
459
+ startColumn = Math.max(0, startColumn - Math.min(columnStartOffset, renderingThreshold));
460
+ endColumn = Math.min(totalColumns, endColumn + Math.min(columnEndOffset, renderingThreshold));
461
+ } else if (renderingThreshold === 'auto') {
462
+ startColumn = Math.max(0, startColumn - Math.ceil(columnStartOffset / 2));
463
+ endColumn = Math.min(totalColumns, endColumn + Math.ceil(columnEndOffset / 2));
464
+ }
443
465
  if (startColumn < renderedStartColumn || startColumn === renderedStartColumn && startColumn > 0) {
444
466
  return false;
445
- } else if (endColumn > renderedEndColumn || endColumn === renderedEndColumn && endColumn < this.wtSettings.getSetting('totalColumns') - 1) {
467
+ } else if (endColumn > renderedEndColumn || endColumn === renderedEndColumn && endColumn < totalColumns) {
446
468
  return false;
447
469
  }
448
470
  return true;
package/base.js CHANGED
@@ -4,7 +4,7 @@ exports.__esModule = true;
4
4
  var _core = _interopRequireDefault(require("./core"));
5
5
  var _rootInstance = require("./utils/rootInstance");
6
6
  var _dataMap = require("./dataMap");
7
- var _pluginHooks = _interopRequireDefault(require("./pluginHooks"));
7
+ var _hooks = require("./core/hooks");
8
8
  var _registry = require("./i18n/registry");
9
9
  var _registry2 = require("./cellTypes/registry");
10
10
  var _textType = require("./cellTypes/textType");
@@ -41,12 +41,12 @@ Handsontable.Core = function (rootElement) {
41
41
  return new _core.default(rootElement, userSettings, _rootInstance.rootInstanceSymbol);
42
42
  };
43
43
  Handsontable.DefaultSettings = (0, _dataMap.metaSchemaFactory)();
44
- Handsontable.hooks = _pluginHooks.default.getSingleton();
44
+ Handsontable.hooks = _hooks.Hooks.getSingleton();
45
45
  Handsontable.CellCoords = _src.CellCoords;
46
46
  Handsontable.CellRange = _src.CellRange;
47
47
  Handsontable.packageName = 'handsontable';
48
- Handsontable.buildDate = "20/09/2024 09:23:42";
49
- Handsontable.version = "0.0.0-next-c8116f8-20240920";
48
+ Handsontable.buildDate = "24/09/2024 12:48:10";
49
+ Handsontable.version = "0.0.0-next-fad35d5-20240924";
50
50
  Handsontable.languages = {
51
51
  dictionaryKeys: _registry.dictionaryKeys,
52
52
  getLanguageDictionary: _registry.getLanguageDictionary,
package/base.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import Core from "./core.mjs";
2
2
  import { rootInstanceSymbol } from "./utils/rootInstance.mjs";
3
3
  import { metaSchemaFactory } from "./dataMap/index.mjs";
4
- import Hooks from "./pluginHooks.mjs"; // FIXME: Bug in eslint-plugin-import: https://github.com/benmosher/eslint-plugin-import/issues/1883
4
+ import { Hooks } from "./core/hooks/index.mjs"; // FIXME: Bug in eslint-plugin-import: https://github.com/benmosher/eslint-plugin-import/issues/1883
5
5
  /* eslint-disable import/named */
6
6
  import { dictionaryKeys, getTranslatedPhrase, registerLanguageDictionary, getLanguagesDictionaries, getLanguageDictionary } from "./i18n/registry.mjs";
7
7
  /* eslint-enable import/named */
@@ -35,8 +35,8 @@ Handsontable.hooks = Hooks.getSingleton();
35
35
  Handsontable.CellCoords = CellCoords;
36
36
  Handsontable.CellRange = CellRange;
37
37
  Handsontable.packageName = 'handsontable';
38
- Handsontable.buildDate = "20/09/2024 09:23:47";
39
- Handsontable.version = "0.0.0-next-c8116f8-20240920";
38
+ Handsontable.buildDate = "24/09/2024 12:48:16";
39
+ Handsontable.version = "0.0.0-next-fad35d5-20240924";
40
40
  Handsontable.languages = {
41
41
  dictionaryKeys,
42
42
  getLanguageDictionary,
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ require("core-js/modules/es.error.cause.js");
5
+ require("core-js/modules/es.array.push.js");
6
+ require("core-js/modules/es.array.to-sorted.js");
7
+ require("core-js/modules/esnext.set.difference.v2.js");
8
+ require("core-js/modules/esnext.set.intersection.v2.js");
9
+ require("core-js/modules/esnext.set.is-disjoint-from.v2.js");
10
+ require("core-js/modules/esnext.set.is-subset-of.v2.js");
11
+ require("core-js/modules/esnext.set.is-superset-of.v2.js");
12
+ require("core-js/modules/esnext.set.symmetric-difference.v2.js");
13
+ require("core-js/modules/esnext.set.union.v2.js");
14
+ var _constants = require("./constants");
15
+ function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
16
+ function _classPrivateFieldInitSpec(e, t, a) { _checkPrivateRedeclaration(e, t), t.set(e, a); }
17
+ function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
18
+ function _classPrivateFieldSet(s, a, r) { return s.set(_assertClassBrand(s, a), r), r; }
19
+ function _classPrivateFieldGet(s, a) { return s.get(_assertClassBrand(s, a)); }
20
+ function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
21
+ /**
22
+ * @typedef {object} HookEntry
23
+ * @property {Function} callback The callback function.
24
+ * @property {number} orderIndex The order index.
25
+ * @property {boolean} runOnce Indicates if the hook should run only once.
26
+ * @property {boolean} initialHook Indicates if it is an initial hook - which means that the hook
27
+ * always stays at the same index position even after update.
28
+ * @property {boolean} skip Indicates if the hook was removed.
29
+ */
30
+ /**
31
+ * The maximum number of hooks that can be skipped before the bucket is cleaned up.
32
+ */
33
+ const MAX_SKIPPED_HOOKS_COUNT = 100;
34
+
35
+ /**
36
+ * The class represents a collection that allows to manage hooks (add, remove).
37
+ *
38
+ * @class HooksBucket
39
+ */
40
+ var _hooks = /*#__PURE__*/new WeakMap();
41
+ var _skippedHooksCount = /*#__PURE__*/new WeakMap();
42
+ var _needsSort = /*#__PURE__*/new WeakMap();
43
+ var _HooksBucket_brand = /*#__PURE__*/new WeakSet();
44
+ class HooksBucket {
45
+ constructor() {
46
+ /**
47
+ * Creates a initial collection for the provided hook name.
48
+ *
49
+ * @param {string} hookName The name of the hook.
50
+ */
51
+ _classPrivateMethodInitSpec(this, _HooksBucket_brand);
52
+ /**
53
+ * A map that stores hooks.
54
+ *
55
+ * @type {Map<string, HookEntry>}
56
+ */
57
+ _classPrivateFieldInitSpec(this, _hooks, new Map());
58
+ /**
59
+ * A map that stores the number of skipped hooks.
60
+ */
61
+ _classPrivateFieldInitSpec(this, _skippedHooksCount, new Map());
62
+ /**
63
+ * A set that stores hook names that need to be re-sorted.
64
+ */
65
+ _classPrivateFieldInitSpec(this, _needsSort, new Set());
66
+ _constants.REGISTERED_HOOKS.forEach(hookName => _assertClassBrand(_HooksBucket_brand, this, _createHooksCollection).call(this, hookName));
67
+ }
68
+
69
+ /**
70
+ * Gets all hooks for the provided hook name.
71
+ *
72
+ * @param {string} hookName The name of the hook.
73
+ * @returns {HookEntry[]}
74
+ */
75
+ getHooks(hookName) {
76
+ var _classPrivateFieldGet2;
77
+ return (_classPrivateFieldGet2 = _classPrivateFieldGet(_hooks, this).get(hookName)) !== null && _classPrivateFieldGet2 !== void 0 ? _classPrivateFieldGet2 : [];
78
+ }
79
+
80
+ /**
81
+ * Adds a new hook to the collection.
82
+ *
83
+ * @param {string} hookName The name of the hook.
84
+ * @param {Function} callback The callback function to add.
85
+ * @param {{ orderIndex?: number, runOnce?: boolean, initialHook?: boolean }} options The options object.
86
+ */
87
+ add(hookName, callback) {
88
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
89
+ if (!_classPrivateFieldGet(_hooks, this).has(hookName)) {
90
+ _assertClassBrand(_HooksBucket_brand, this, _createHooksCollection).call(this, hookName);
91
+ _constants.REGISTERED_HOOKS.push(hookName);
92
+ }
93
+ const hooks = _classPrivateFieldGet(_hooks, this).get(hookName);
94
+ if (hooks.find(hook => hook.callback === callback)) {
95
+ // adding the same hook twice is now silently ignored
96
+ return;
97
+ }
98
+ const orderIndex = Number.isInteger(options.orderIndex) ? options.orderIndex : 0;
99
+ const runOnce = !!options.runOnce;
100
+ const initialHook = !!options.initialHook;
101
+ let foundInitialHook = false;
102
+ if (initialHook) {
103
+ const initialHookEntry = hooks.find(hook => hook.initialHook);
104
+ if (initialHookEntry) {
105
+ initialHookEntry.callback = callback;
106
+ foundInitialHook = true;
107
+ }
108
+ }
109
+ if (!foundInitialHook) {
110
+ hooks.push({
111
+ callback,
112
+ orderIndex,
113
+ runOnce,
114
+ initialHook,
115
+ skip: false
116
+ });
117
+ let needsSort = _classPrivateFieldGet(_needsSort, this).has(hookName);
118
+ if (!needsSort && orderIndex !== 0) {
119
+ needsSort = true;
120
+ _classPrivateFieldGet(_needsSort, this).add(hookName);
121
+ }
122
+ if (needsSort && hooks.length > 1) {
123
+ _classPrivateFieldGet(_hooks, this).set(hookName, hooks.toSorted((a, b) => a.orderIndex - b.orderIndex));
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Checks if there are any hooks for the provided hook name.
130
+ *
131
+ * @param {string} hookName The name of the hook.
132
+ * @returns {boolean}
133
+ */
134
+ has(hookName) {
135
+ return _classPrivateFieldGet(_hooks, this).has(hookName) && _classPrivateFieldGet(_hooks, this).get(hookName).length > 0;
136
+ }
137
+
138
+ /**
139
+ * Removes a hook from the collection. If the hook was found and removed,
140
+ * the method returns `true`, otherwise `false`.
141
+ *
142
+ * @param {string} hookName The name of the hook.
143
+ * @param {*} callback The callback function to remove.
144
+ * @returns {boolean}
145
+ */
146
+ remove(hookName, callback) {
147
+ if (!_classPrivateFieldGet(_hooks, this).has(hookName)) {
148
+ return false;
149
+ }
150
+ const hooks = _classPrivateFieldGet(_hooks, this).get(hookName);
151
+ const hookEntry = hooks.find(hook => hook.callback === callback);
152
+ if (hookEntry) {
153
+ let skippedHooksCount = _classPrivateFieldGet(_skippedHooksCount, this).get(hookName);
154
+ hookEntry.skip = true;
155
+ skippedHooksCount += 1;
156
+ if (skippedHooksCount > MAX_SKIPPED_HOOKS_COUNT) {
157
+ _classPrivateFieldGet(_hooks, this).set(hookName, hooks.filter(hook => !hook.skip));
158
+ skippedHooksCount = 0;
159
+ }
160
+ _classPrivateFieldGet(_skippedHooksCount, this).set(hookName, skippedHooksCount);
161
+ return true;
162
+ }
163
+ return false;
164
+ }
165
+
166
+ /**
167
+ * Destroys the bucket.
168
+ */
169
+ destroy() {
170
+ _classPrivateFieldGet(_hooks, this).clear();
171
+ _classPrivateFieldGet(_skippedHooksCount, this).clear();
172
+ _classPrivateFieldSet(_hooks, this, null);
173
+ _classPrivateFieldSet(_skippedHooksCount, this, null);
174
+ }
175
+ }
176
+ exports.HooksBucket = HooksBucket;
177
+ function _createHooksCollection(hookName) {
178
+ _classPrivateFieldGet(_hooks, this).set(hookName, []);
179
+ _classPrivateFieldGet(_skippedHooksCount, this).set(hookName, 0);
180
+ }