@odoo/o-spreadsheet 18.0.13 → 18.0.14

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.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.0.13
6
- * @date 2025-01-31T07:59:17.481Z
7
- * @hash f505971
5
+ * @version 18.0.14
6
+ * @date 2025-02-05T06:47:33.041Z
7
+ * @hash 90f2af4
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -18383,19 +18383,20 @@ stores.inject(MyMetaStore, storeInstance);
18383
18383
  description: _t("Horizontal lookup"),
18384
18384
  args: [
18385
18385
  arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
18386
- arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
18386
+ arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
18387
18387
  arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
18388
18388
  arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
18389
18389
  ],
18390
18390
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18391
18391
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18392
- assert(() => 1 <= _index && _index <= range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18392
+ const _range = toMatrix(range);
18393
+ assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18393
18394
  const getValueFromRange = (range, index) => range[index][0].value;
18394
18395
  const _isSorted = toBoolean(isSorted.value);
18395
18396
  const colIndex = _isSorted
18396
- ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range.length, getValueFromRange)
18397
- : linearSearch(range, searchKey, "wildcard", range.length, getValueFromRange, this.lookupCaches);
18398
- const col = range[colIndex];
18397
+ ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
18398
+ : linearSearch(range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
18399
+ const col = _range[colIndex];
18399
18400
  if (col === undefined) {
18400
18401
  return valueNotAvailable(searchKey);
18401
18402
  }
@@ -18487,35 +18488,37 @@ stores.inject(MyMetaStore, storeInstance);
18487
18488
  description: _t("Look up a value."),
18488
18489
  args: [
18489
18490
  arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
18490
- arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
18491
- arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
18491
+ arg("search_array (any, range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
18492
+ arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
18492
18493
  ],
18493
18494
  compute: function (searchKey, searchArray, resultRange) {
18494
- let nbCol = searchArray.length;
18495
- let nbRow = searchArray[0].length;
18495
+ const _searchArray = toMatrix(searchArray);
18496
+ const _resultRange = toMatrix(resultRange);
18497
+ let nbCol = _searchArray.length;
18498
+ let nbRow = _searchArray[0].length;
18496
18499
  const verticalSearch = nbRow >= nbCol;
18497
18500
  const getElement = verticalSearch
18498
18501
  ? (range, index) => range[0][index].value
18499
18502
  : (range, index) => range[index][0].value;
18500
18503
  const rangeLength = verticalSearch ? nbRow : nbCol;
18501
- const index = dichotomicSearch(searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
18504
+ const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
18502
18505
  if (index === -1 ||
18503
- (verticalSearch && searchArray[0][index] === undefined) ||
18504
- (!verticalSearch && searchArray[index][nbRow - 1] === undefined)) {
18506
+ (verticalSearch && _searchArray[0][index] === undefined) ||
18507
+ (!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
18505
18508
  return valueNotAvailable(searchKey);
18506
18509
  }
18507
- if (resultRange === undefined) {
18508
- return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
18510
+ if (_resultRange[0].length === 0) {
18511
+ return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
18509
18512
  }
18510
- nbCol = resultRange.length;
18511
- nbRow = resultRange[0].length;
18513
+ nbCol = _resultRange.length;
18514
+ nbRow = _resultRange[0].length;
18512
18515
  assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
18513
18516
  if (nbCol > 1) {
18514
18517
  assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
18515
- return resultRange[index][0];
18518
+ return _resultRange[index][0];
18516
18519
  }
18517
18520
  assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
18518
- return resultRange[0][index];
18521
+ return _resultRange[0][index];
18519
18522
  },
18520
18523
  isExported: true,
18521
18524
  };
@@ -18532,28 +18535,29 @@ stores.inject(MyMetaStore, storeInstance);
18532
18535
  ],
18533
18536
  compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
18534
18537
  let _searchType = toNumber(searchType, this.locale);
18535
- const nbCol = range.length;
18536
- const nbRow = range[0].length;
18538
+ const _range = toMatrix(range);
18539
+ const nbCol = _range.length;
18540
+ const nbRow = _range[0].length;
18537
18541
  assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
18538
18542
  let index = -1;
18539
18543
  const getElement = nbCol === 1
18540
- ? (range, index) => range[0][index].value
18541
- : (range, index) => range[index][0].value;
18542
- const rangeLen = nbCol === 1 ? range[0].length : range.length;
18544
+ ? (_range, index) => _range[0][index].value
18545
+ : (_range, index) => _range[index][0].value;
18546
+ const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
18543
18547
  _searchType = Math.sign(_searchType);
18544
18548
  switch (_searchType) {
18545
18549
  case 1:
18546
- index = dichotomicSearch(range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
18550
+ index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
18547
18551
  break;
18548
18552
  case 0:
18549
- index = linearSearch(range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
18553
+ index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
18550
18554
  break;
18551
18555
  case -1:
18552
- index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
18556
+ index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
18553
18557
  break;
18554
18558
  }
18555
- if ((nbCol === 1 && range[0][index] === undefined) ||
18556
- (nbCol !== 1 && range[index] === undefined)) {
18559
+ if ((nbCol === 1 && _range[0][index] === undefined) ||
18560
+ (nbCol !== 1 && _range[index] === undefined)) {
18557
18561
  return valueNotAvailable(searchKey);
18558
18562
  }
18559
18563
  return index + 1;
@@ -18608,13 +18612,14 @@ stores.inject(MyMetaStore, storeInstance);
18608
18612
  ],
18609
18613
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18610
18614
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18611
- assert(() => 1 <= _index && _index <= range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18615
+ const _range = toMatrix(range);
18616
+ assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18612
18617
  const getValueFromRange = (range, index) => range[0][index].value;
18613
18618
  const _isSorted = toBoolean(isSorted.value);
18614
18619
  const rowIndex = _isSorted
18615
- ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range[0].length, getValueFromRange)
18616
- : linearSearch(range, searchKey, "wildcard", range[0].length, getValueFromRange, this.lookupCaches);
18617
- const value = range[_index - 1][rowIndex];
18620
+ ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
18621
+ : linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
18622
+ const value = _range[_index - 1][rowIndex];
18618
18623
  if (value === undefined) {
18619
18624
  return valueNotAvailable(searchKey);
18620
18625
  }
@@ -18651,27 +18656,29 @@ stores.inject(MyMetaStore, storeInstance);
18651
18656
  compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
18652
18657
  const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
18653
18658
  const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
18654
- assert(() => lookupRange.length === 1 || lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18659
+ const _lookupRange = toMatrix(lookupRange);
18660
+ const _returnRange = toMatrix(returnRange);
18661
+ assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18655
18662
  assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
18656
18663
  assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
18657
- const lookupDirection = lookupRange.length === 1 ? "col" : "row";
18664
+ const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
18658
18665
  assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
18659
18666
  assert(() => lookupDirection === "col"
18660
- ? returnRange[0].length === lookupRange[0].length
18661
- : returnRange.length === lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18667
+ ? _returnRange[0].length === _lookupRange[0].length
18668
+ : _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18662
18669
  const getElement = lookupDirection === "col"
18663
18670
  ? (range, index) => range[0][index].value
18664
18671
  : (range, index) => range[index][0].value;
18665
- const rangeLen = lookupDirection === "col" ? lookupRange[0].length : lookupRange.length;
18672
+ const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
18666
18673
  const mode = MATCH_MODE[_matchMode];
18667
18674
  const reverseSearch = _searchMode === -1;
18668
18675
  const index = _searchMode === 2 || _searchMode === -2
18669
- ? dichotomicSearch(lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18670
- : linearSearch(lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
18676
+ ? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18677
+ : linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
18671
18678
  if (index !== -1) {
18672
18679
  return lookupDirection === "col"
18673
- ? returnRange.map((col) => [col[index]])
18674
- : [returnRange[index]];
18680
+ ? _returnRange.map((col) => [col[index]])
18681
+ : [_returnRange[index]];
18675
18682
  }
18676
18683
  if (defaultValue === undefined) {
18677
18684
  return valueNotAvailable(searchKey);
@@ -48477,11 +48484,10 @@ stores.inject(MyMetaStore, storeInstance);
48477
48484
  switch (layer) {
48478
48485
  case "Background":
48479
48486
  this.drawGlobalBackground(renderingContext);
48480
- for (const zone of this.getters.getAllActiveViewportsZones()) {
48487
+ for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
48481
48488
  const { ctx } = renderingContext;
48482
48489
  ctx.save();
48483
48490
  ctx.beginPath();
48484
- const rect = this.getters.getVisibleRect(zone);
48485
48491
  ctx.rect(rect.x, rect.y, rect.width, rect.height);
48486
48492
  ctx.clip();
48487
48493
  const boxes = this.getGridBoxes(zone);
@@ -48757,10 +48763,8 @@ stores.inject(MyMetaStore, storeInstance);
48757
48763
  const { ctx, thinLineWidth } = renderingContext;
48758
48764
  const visibleCols = this.getters.getSheetViewVisibleCols();
48759
48765
  const left = visibleCols[0];
48760
- const right = visibleCols[visibleCols.length - 1];
48761
48766
  const visibleRows = this.getters.getSheetViewVisibleRows();
48762
48767
  const top = visibleRows[0];
48763
- const bottom = visibleRows[visibleRows.length - 1];
48764
48768
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
48765
48769
  const selection = this.getters.getSelectedZones();
48766
48770
  const selectedCols = getZonesCols(selection);
@@ -48776,7 +48780,7 @@ stores.inject(MyMetaStore, storeInstance);
48776
48780
  ctx.lineWidth = thinLineWidth;
48777
48781
  ctx.strokeStyle = "#333";
48778
48782
  // Columns headers background
48779
- for (let col = left; col <= right; col++) {
48783
+ for (const col of visibleCols) {
48780
48784
  const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
48781
48785
  const { x, width } = this.getters.getVisibleRect(colZone);
48782
48786
  const isColActive = activeCols.has(col);
@@ -48793,7 +48797,7 @@ stores.inject(MyMetaStore, storeInstance);
48793
48797
  ctx.fillRect(x, 0, width, HEADER_HEIGHT);
48794
48798
  }
48795
48799
  // Rows headers background
48796
- for (let row = top; row <= bottom; row++) {
48800
+ for (const row of visibleRows) {
48797
48801
  const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
48798
48802
  const { y, height } = this.getters.getVisibleRect(rowZone);
48799
48803
  const isRowActive = activeRows.has(row);
@@ -48819,21 +48823,21 @@ stores.inject(MyMetaStore, storeInstance);
48819
48823
  ctx.stroke();
48820
48824
  ctx.beginPath();
48821
48825
  // column text + separator
48822
- for (const i of visibleCols) {
48823
- const colSize = this.getters.getColSize(sheetId, i);
48824
- const colName = numberToLetters(i);
48825
- ctx.fillStyle = activeCols.has(i) ? "#fff" : TEXT_HEADER_COLOR;
48826
- let colStart = this.getHeaderOffset("COL", left, i);
48826
+ for (const col of visibleCols) {
48827
+ const colSize = this.getters.getColSize(sheetId, col);
48828
+ const colName = numberToLetters(col);
48829
+ ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
48830
+ let colStart = this.getHeaderOffset("COL", left, col);
48827
48831
  ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
48828
48832
  ctx.moveTo(colStart + colSize, 0);
48829
48833
  ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
48830
48834
  }
48831
48835
  // row text + separator
48832
- for (const i of visibleRows) {
48833
- const rowSize = this.getters.getRowSize(sheetId, i);
48834
- ctx.fillStyle = activeRows.has(i) ? "#fff" : TEXT_HEADER_COLOR;
48835
- let rowStart = this.getHeaderOffset("ROW", top, i);
48836
- ctx.fillText(String(i + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
48836
+ for (const row of visibleRows) {
48837
+ const rowSize = this.getters.getRowSize(sheetId, row);
48838
+ ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
48839
+ let rowStart = this.getHeaderOffset("ROW", top, row);
48840
+ ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
48837
48841
  ctx.moveTo(0, rowStart + rowSize);
48838
48842
  ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
48839
48843
  }
@@ -49133,6 +49137,9 @@ stores.inject(MyMetaStore, storeInstance);
49133
49137
  canvas.width = width * dpr;
49134
49138
  canvas.height = height * dpr;
49135
49139
  canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
49140
+ if (width === 0 || height === 0) {
49141
+ return;
49142
+ }
49136
49143
  // Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
49137
49144
  // are the edges of the squares. If you draw a one-unit-wide line between whole-number
49138
49145
  // coordinates, it will overlap opposite sides of the pixel square, and the resulting
@@ -50704,7 +50711,7 @@ stores.inject(MyMetaStore, storeInstance);
50704
50711
  getCommonSides(border1, border2) {
50705
50712
  const commonBorder = {};
50706
50713
  for (let side of ["top", "bottom", "left", "right"]) {
50707
- if (border1[side] && border1[side] === border2[side]) {
50714
+ if (border1[side] && deepEquals(border1[side], border2[side])) {
50708
50715
  commonBorder[side] = border1[side];
50709
50716
  }
50710
50717
  }
@@ -64974,8 +64981,17 @@ stores.inject(MyMetaStore, storeInstance);
64974
64981
  this.getters = getters;
64975
64982
  this.sheetId = sheetId;
64976
64983
  this.boundaries = boundaries;
64977
- this.viewportWidth = sizeInGrid.width;
64978
- this.viewportHeight = sizeInGrid.height;
64984
+ if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
64985
+ throw new Error("Viewport size cannot be negative");
64986
+ }
64987
+ this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
64988
+ this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
64989
+ this.top = boundaries.top;
64990
+ this.bottom = boundaries.bottom;
64991
+ this.left = boundaries.left;
64992
+ this.right = boundaries.right;
64993
+ this.offsetX = offsets.x;
64994
+ this.offsetY = offsets.y;
64979
64995
  this.offsetScrollbarX = offsets.x;
64980
64996
  this.offsetScrollbarY = offsets.y;
64981
64997
  this.canScrollVertically = options.canScrollVertically;
@@ -65018,9 +65034,9 @@ stores.inject(MyMetaStore, storeInstance);
65018
65034
  Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
65019
65035
  );
65020
65036
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
65021
- }
65022
- if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
65023
- height += FOOTER_HEIGHT;
65037
+ if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
65038
+ height += FOOTER_HEIGHT;
65039
+ }
65024
65040
  }
65025
65041
  return { width, height };
65026
65042
  }
@@ -65161,6 +65177,9 @@ stores.inject(MyMetaStore, storeInstance);
65161
65177
  !this.getters.isRowHidden(this.sheetId, row));
65162
65178
  }
65163
65179
  searchHeaderIndex(dimension, position, startIndex = 0) {
65180
+ if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
65181
+ return -1;
65182
+ }
65164
65183
  const sheetId = this.sheetId;
65165
65184
  const headers = this.getters.getNumberHeaders(sheetId, dimension);
65166
65185
  // using a binary search:
@@ -65197,7 +65216,7 @@ stores.inject(MyMetaStore, storeInstance);
65197
65216
  this.adjustViewportZoneY();
65198
65217
  }
65199
65218
  /** Corrects the viewport's horizontal offset based on the current structure
65200
- * To make sure that at least on column is visible inside the viewport.
65219
+ * To make sure that at least one column is visible inside the viewport.
65201
65220
  */
65202
65221
  adjustViewportOffsetX() {
65203
65222
  if (this.canScrollHorizontally) {
@@ -65209,7 +65228,7 @@ stores.inject(MyMetaStore, storeInstance);
65209
65228
  this.adjustViewportZoneX();
65210
65229
  }
65211
65230
  /** Corrects the viewport's vertical offset based on the current structure
65212
- * To make sure that at least on row is visible inside the viewport.
65231
+ * To make sure that at least one row is visible inside the viewport.
65213
65232
  */
65214
65233
  adjustViewportOffsetY() {
65215
65234
  if (this.canScrollVertically) {
@@ -65226,11 +65245,14 @@ stores.inject(MyMetaStore, storeInstance);
65226
65245
  const sheetId = this.sheetId;
65227
65246
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
65228
65247
  this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
65248
+ if (!this.viewportWidth) {
65249
+ return;
65250
+ }
65229
65251
  if (this.left === -1) {
65230
65252
  this.left = this.boundaries.left;
65231
65253
  }
65232
65254
  if (this.right === -1) {
65233
- this.right = this.getters.getNumberCols(sheetId) - 1;
65255
+ this.right = this.boundaries.right;
65234
65256
  }
65235
65257
  this.offsetX =
65236
65258
  this.getters.getColDimensions(sheetId, this.left).start -
@@ -65242,11 +65264,14 @@ stores.inject(MyMetaStore, storeInstance);
65242
65264
  const sheetId = this.sheetId;
65243
65265
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
65244
65266
  this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
65267
+ if (!this.viewportHeight) {
65268
+ return;
65269
+ }
65245
65270
  if (this.top === -1) {
65246
65271
  this.top = this.boundaries.top;
65247
65272
  }
65248
65273
  if (this.bottom === -1) {
65249
- this.bottom = this.getters.getNumberRows(sheetId) - 1;
65274
+ this.bottom = this.boundaries.bottom;
65250
65275
  }
65251
65276
  this.offsetY =
65252
65277
  this.getters.getRowDimensions(sheetId, this.top).start -
@@ -65320,7 +65345,7 @@ stores.inject(MyMetaStore, storeInstance);
65320
65345
  "isPositionVisible",
65321
65346
  "getColDimensionsInViewport",
65322
65347
  "getRowDimensionsInViewport",
65323
- "getAllActiveViewportsZones",
65348
+ "getAllActiveViewportsZonesAndRect",
65324
65349
  "getRect",
65325
65350
  ];
65326
65351
  viewports = {};
@@ -65553,12 +65578,12 @@ stores.inject(MyMetaStore, storeInstance);
65553
65578
  const sheetId = this.getters.getActiveSheetId();
65554
65579
  const viewports = this.getSubViewports(sheetId);
65555
65580
  //TODO ake another commit to eimprove this
65556
- return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
65581
+ return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
65557
65582
  }
65558
65583
  getSheetViewVisibleRows() {
65559
65584
  const sheetId = this.getters.getActiveSheetId();
65560
65585
  const viewports = this.getSubViewports(sheetId);
65561
- return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
65586
+ return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
65562
65587
  }
65563
65588
  /**
65564
65589
  * Get the positions of all the cells that are visible in the viewport, taking merges into account.
@@ -65601,19 +65626,19 @@ stores.inject(MyMetaStore, storeInstance);
65601
65626
  maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
65602
65627
  };
65603
65628
  }
65604
- getColRowOffsetInViewport(dimension, referenceIndex, index) {
65605
- const sheetId = this.getters.getActiveSheetId();
65606
- const visibleCols = this.getters.getSheetViewVisibleCols();
65607
- const visibleRows = this.getters.getSheetViewVisibleRows();
65608
- if (index < referenceIndex) {
65609
- return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
65629
+ getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
65630
+ if (targetHeaderIndex < referenceHeaderIndex) {
65631
+ return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
65610
65632
  }
65633
+ const sheetId = this.getters.getActiveSheetId();
65634
+ const visibleHeaders = dimension === "COL"
65635
+ ? this.getters.getSheetViewVisibleCols()
65636
+ : this.getters.getSheetViewVisibleRows();
65637
+ const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
65638
+ const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
65639
+ const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
65611
65640
  let offset = 0;
65612
- const visibleIndexes = dimension === "COL" ? visibleCols : visibleRows;
65613
- for (let i = referenceIndex; i < index; i++) {
65614
- if (!visibleIndexes.includes(i)) {
65615
- continue;
65616
- }
65641
+ for (const i of relevantIndexes) {
65617
65642
  offset += this.getters.getHeaderSize(sheetId, dimension, i);
65618
65643
  }
65619
65644
  return offset;
@@ -65660,7 +65685,7 @@ stores.inject(MyMetaStore, storeInstance);
65660
65685
  }
65661
65686
  return { canEdgeScroll, direction, delay };
65662
65687
  }
65663
- getEdgeScrollRow(y, previousY, tartingY) {
65688
+ getEdgeScrollRow(y, previousY, startingY) {
65664
65689
  let canEdgeScroll = false;
65665
65690
  let direction = 0;
65666
65691
  let delay = 0;
@@ -65681,7 +65706,7 @@ stores.inject(MyMetaStore, storeInstance);
65681
65706
  delay = scrollDelay(y - height);
65682
65707
  direction = 1;
65683
65708
  }
65684
- else if (y < offsetCorrectionY && tartingY >= offsetCorrectionY && currentOffsetY > 0) {
65709
+ else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
65685
65710
  // 2
65686
65711
  canEdgeScroll = true;
65687
65712
  delay = scrollDelay(offsetCorrectionY - y);
@@ -65707,13 +65732,7 @@ stores.inject(MyMetaStore, storeInstance);
65707
65732
  */
65708
65733
  getVisibleRectWithoutHeaders(zone) {
65709
65734
  const sheetId = this.getters.getActiveSheetId();
65710
- const viewportRects = this.getSubViewports(sheetId)
65711
- .map((viewport) => viewport.getVisibleRect(zone))
65712
- .filter(isDefined);
65713
- if (viewportRects.length === 0) {
65714
- return { x: 0, y: 0, width: 0, height: 0 };
65715
- }
65716
- return this.recomposeRect(viewportRects);
65735
+ return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
65717
65736
  }
65718
65737
  /**
65719
65738
  * Computes the actual size and position (:Rect) of the zone on the canvas
@@ -65721,13 +65740,7 @@ stores.inject(MyMetaStore, storeInstance);
65721
65740
  */
65722
65741
  getRect(zone) {
65723
65742
  const sheetId = this.getters.getActiveSheetId();
65724
- const viewportRects = this.getSubViewports(sheetId)
65725
- .map((viewport) => viewport.getFullRect(zone))
65726
- .filter(isDefined);
65727
- if (viewportRects.length === 0) {
65728
- return { x: 0, y: 0, width: 0, height: 0 };
65729
- }
65730
- const rect = this.recomposeRect(viewportRects);
65743
+ const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
65731
65744
  return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
65732
65745
  }
65733
65746
  /**
@@ -65772,9 +65785,18 @@ stores.inject(MyMetaStore, storeInstance);
65772
65785
  end: start + (isRowHidden ? 0 : size),
65773
65786
  };
65774
65787
  }
65775
- getAllActiveViewportsZones() {
65788
+ getAllActiveViewportsZonesAndRect() {
65776
65789
  const sheetId = this.getters.getActiveSheetId();
65777
- return this.getSubViewports(sheetId);
65790
+ return this.getSubViewports(sheetId).map((viewport) => {
65791
+ return {
65792
+ zone: viewport,
65793
+ rect: {
65794
+ x: viewport.offsetCorrectionX + this.gridOffsetX,
65795
+ y: viewport.offsetCorrectionY + this.gridOffsetY,
65796
+ ...viewport.getMaxSize(),
65797
+ },
65798
+ };
65799
+ });
65778
65800
  }
65779
65801
  // ---------------------------------------------------------------------------
65780
65802
  // Private
@@ -65833,12 +65855,11 @@ stores.inject(MyMetaStore, storeInstance);
65833
65855
  }
65834
65856
  /** gets rid of deprecated sheetIds */
65835
65857
  cleanViewports() {
65836
- const sheetIds = this.getters.getSheetIds();
65837
- for (let sheetId of Object.keys(this.viewports)) {
65838
- if (!sheetIds.includes(sheetId)) {
65839
- delete this.viewports[sheetId];
65840
- }
65858
+ const newViewport = {};
65859
+ for (const sheetId of this.getters.getSheetIds()) {
65860
+ newViewport[sheetId] = this.viewports[sheetId];
65841
65861
  }
65862
+ this.viewports = newViewport;
65842
65863
  }
65843
65864
  resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
65844
65865
  this.sheetViewHeight = height;
@@ -65848,7 +65869,7 @@ stores.inject(MyMetaStore, storeInstance);
65848
65869
  this.recomputeViewports();
65849
65870
  }
65850
65871
  recomputeViewports() {
65851
- for (let sheetId of Object.keys(this.viewports)) {
65872
+ for (const sheetId of this.getters.getSheetIds()) {
65852
65873
  this.resetViewports(sheetId);
65853
65874
  }
65854
65875
  }
@@ -65870,8 +65891,10 @@ stores.inject(MyMetaStore, storeInstance);
65870
65891
  const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
65871
65892
  const nCols = this.getters.getNumberCols(sheetId);
65872
65893
  const nRows = this.getters.getNumberRows(sheetId);
65873
- const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
65874
- const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
65894
+ const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
65895
+ const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
65896
+ const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
65897
+ const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
65875
65898
  const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
65876
65899
  const canScrollHorizontally = xRatio < 1.0;
65877
65900
  const canScrollVertically = yRatio < 1.0;
@@ -65882,14 +65905,14 @@ stores.inject(MyMetaStore, storeInstance);
65882
65905
  new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: 0, bottom: ySplit - 1 }, { width: colOffset, height: rowOffset }, { canScrollHorizontally: false, canScrollVertically: false }, { x: 0, y: 0 })) ||
65883
65906
  undefined,
65884
65907
  topRight: (ySplit &&
65885
- new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: this.sheetViewWidth - colOffset, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
65908
+ new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width: unfrozenWidth, height: rowOffset }, { canScrollHorizontally, canScrollVertically: false }, { x: canScrollHorizontally ? previousOffset.x : 0, y: 0 })) ||
65886
65909
  undefined,
65887
65910
  bottomLeft: (xSplit &&
65888
- new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: this.sheetViewHeight - rowOffset }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
65911
+ new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height: unfrozenHeight }, { canScrollHorizontally: false, canScrollVertically }, { x: 0, y: canScrollVertically ? previousOffset.y : 0 })) ||
65889
65912
  undefined,
65890
65913
  bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
65891
- width: this.sheetViewWidth - colOffset,
65892
- height: this.sheetViewHeight - rowOffset,
65914
+ width: unfrozenWidth,
65915
+ height: unfrozenHeight,
65893
65916
  }, { canScrollHorizontally, canScrollVertically }, {
65894
65917
  x: canScrollHorizontally ? previousOffset.x : 0,
65895
65918
  y: canScrollVertically ? previousOffset.y : 0,
@@ -65966,12 +65989,26 @@ stores.inject(MyMetaStore, storeInstance);
65966
65989
  const height = this.sheetViewHeight + this.gridOffsetY;
65967
65990
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
65968
65991
  }
65969
- recomposeRect(viewportRects) {
65970
- const x = Math.min(...viewportRects.map((rect) => rect.x));
65971
- const y = Math.min(...viewportRects.map((rect) => rect.y));
65972
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
65973
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
65974
- return { x, y, width, height };
65992
+ mapViewportsToRect(sheetId, rectCallBack) {
65993
+ let x = Infinity;
65994
+ let y = Infinity;
65995
+ let width = 0;
65996
+ let height = 0;
65997
+ let hasViewports = false;
65998
+ for (const viewport of this.getSubViewports(sheetId)) {
65999
+ const rect = rectCallBack(viewport);
66000
+ if (rect) {
66001
+ hasViewports = true;
66002
+ x = Math.min(x, rect.x);
66003
+ y = Math.min(y, rect.y);
66004
+ width = Math.max(width, rect.x + rect.width);
66005
+ height = Math.max(height, rect.y + rect.height);
66006
+ }
66007
+ }
66008
+ if (!hasViewports) {
66009
+ return { x: 0, y: 0, width: 0, height: 0 };
66010
+ }
66011
+ return { x, y, width: width - x, height: height - y };
65975
66012
  }
65976
66013
  }
65977
66014
 
@@ -73132,9 +73169,9 @@ stores.inject(MyMetaStore, storeInstance);
73132
73169
  exports.tokenize = tokenize;
73133
73170
 
73134
73171
 
73135
- __info__.version = "18.0.13";
73136
- __info__.date = "2025-01-31T07:59:17.481Z";
73137
- __info__.hash = "f505971";
73172
+ __info__.version = "18.0.14";
73173
+ __info__.date = "2025-02-05T06:47:33.041Z";
73174
+ __info__.hash = "90f2af4";
73138
73175
 
73139
73176
 
73140
73177
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);