@odoo/o-spreadsheet 17.2.34 → 17.2.35

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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.34
7
- * @date 2025-01-31T07:58:03.953Z
8
- * @hash 0bffee9
6
+ * @version 17.2.35
7
+ * @date 2025-02-05T07:12:34.721Z
8
+ * @hash 76b12a1
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -17752,23 +17752,24 @@ stores.inject(MyMetaStore, storeInstance);
17752
17752
  description: _t("Horizontal lookup"),
17753
17753
  args: [
17754
17754
  arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
17755
- 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.")),
17755
+ 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.")),
17756
17756
  arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
17757
17757
  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.")),
17758
17758
  ],
17759
17759
  returns: ["ANY"],
17760
17760
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
17761
17761
  const _index = Math.trunc(toNumber(index?.value, this.locale));
17762
- assert(() => 1 <= _index && _index <= range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
17762
+ const _range = toMatrix(range);
17763
+ assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
17763
17764
  if (searchKey && isEvaluationError(searchKey.value)) {
17764
17765
  return searchKey;
17765
17766
  }
17766
17767
  const getValueFromRange = (range, index) => range[index][0].value;
17767
17768
  const _isSorted = toBoolean(isSorted.value);
17768
17769
  const colIndex = _isSorted
17769
- ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range.length, getValueFromRange)
17770
- : linearSearch(range, searchKey, "wildcard", range.length, getValueFromRange);
17771
- const col = range[colIndex];
17770
+ ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
17771
+ : linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
17772
+ const col = _range[colIndex];
17772
17773
  if (col === undefined) {
17773
17774
  return valueNotAvailable(searchKey);
17774
17775
  }
@@ -17877,36 +17878,38 @@ stores.inject(MyMetaStore, storeInstance);
17877
17878
  description: _t("Look up a value."),
17878
17879
  args: [
17879
17880
  arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
17880
- 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.")),
17881
- 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.")),
17881
+ 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.")),
17882
+ 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.")),
17882
17883
  ],
17883
17884
  returns: ["ANY"],
17884
17885
  compute: function (searchKey, searchArray, resultRange) {
17885
- let nbCol = searchArray.length;
17886
- let nbRow = searchArray[0].length;
17886
+ const _searchArray = toMatrix(searchArray);
17887
+ const _resultRange = toMatrix(resultRange);
17888
+ let nbCol = _searchArray.length;
17889
+ let nbRow = _searchArray[0].length;
17887
17890
  const verticalSearch = nbRow >= nbCol;
17888
17891
  const getElement = verticalSearch
17889
17892
  ? (range, index) => range[0][index].value
17890
17893
  : (range, index) => range[index][0].value;
17891
17894
  const rangeLength = verticalSearch ? nbRow : nbCol;
17892
- const index = dichotomicSearch(searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
17895
+ const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
17893
17896
  if (index === -1 ||
17894
- (verticalSearch && searchArray[0][index] === undefined) ||
17895
- (!verticalSearch && searchArray[index][nbRow - 1] === undefined)) {
17897
+ (verticalSearch && _searchArray[0][index] === undefined) ||
17898
+ (!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
17896
17899
  return valueNotAvailable(searchKey);
17897
17900
  }
17898
- if (resultRange === undefined) {
17899
- return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
17901
+ if (_resultRange[0].length === 0) {
17902
+ return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
17900
17903
  }
17901
- nbCol = resultRange.length;
17902
- nbRow = resultRange[0].length;
17904
+ nbCol = _resultRange.length;
17905
+ nbRow = _resultRange[0].length;
17903
17906
  assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
17904
17907
  if (nbCol > 1) {
17905
17908
  assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
17906
- return resultRange[index][0];
17909
+ return _resultRange[index][0];
17907
17910
  }
17908
17911
  assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
17909
- return resultRange[0][index];
17912
+ return _resultRange[0][index];
17910
17913
  },
17911
17914
  isExported: true,
17912
17915
  };
@@ -17924,28 +17927,29 @@ stores.inject(MyMetaStore, storeInstance);
17924
17927
  returns: ["NUMBER"],
17925
17928
  compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
17926
17929
  let _searchType = toNumber(searchType, this.locale);
17927
- const nbCol = range.length;
17928
- const nbRow = range[0].length;
17930
+ const _range = toMatrix(range);
17931
+ const nbCol = _range.length;
17932
+ const nbRow = _range[0].length;
17929
17933
  assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
17930
17934
  let index = -1;
17931
17935
  const getElement = nbCol === 1
17932
- ? (range, index) => range[0][index].value
17933
- : (range, index) => range[index][0].value;
17934
- const rangeLen = nbCol === 1 ? range[0].length : range.length;
17936
+ ? (_range, index) => _range[0][index].value
17937
+ : (_range, index) => _range[index][0].value;
17938
+ const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
17935
17939
  _searchType = Math.sign(_searchType);
17936
17940
  switch (_searchType) {
17937
17941
  case 1:
17938
- index = dichotomicSearch(range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
17942
+ index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
17939
17943
  break;
17940
17944
  case 0:
17941
- index = linearSearch(range, searchKey, "wildcard", rangeLen, getElement);
17945
+ index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
17942
17946
  break;
17943
17947
  case -1:
17944
- index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
17948
+ index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
17945
17949
  break;
17946
17950
  }
17947
- if ((nbCol === 1 && range[0][index] === undefined) ||
17948
- (nbCol !== 1 && range[index] === undefined)) {
17951
+ if ((nbCol === 1 && _range[0][index] === undefined) ||
17952
+ (nbCol !== 1 && _range[index] === undefined)) {
17949
17953
  return valueNotAvailable(searchKey);
17950
17954
  }
17951
17955
  return index + 1;
@@ -17996,16 +18000,17 @@ stores.inject(MyMetaStore, storeInstance);
17996
18000
  returns: ["ANY"],
17997
18001
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
17998
18002
  const _index = Math.trunc(toNumber(index?.value, this.locale));
17999
- assert(() => 1 <= _index && _index <= range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18003
+ const _range = toMatrix(range);
18004
+ assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18000
18005
  if (searchKey && isEvaluationError(searchKey.value)) {
18001
18006
  return searchKey;
18002
18007
  }
18003
18008
  const getValueFromRange = (range, index) => range[0][index].value;
18004
18009
  const _isSorted = toBoolean(isSorted.value);
18005
18010
  const rowIndex = _isSorted
18006
- ? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range[0].length, getValueFromRange)
18007
- : linearSearch(range, searchKey, "wildcard", range[0].length, getValueFromRange);
18008
- const value = range[_index - 1][rowIndex];
18011
+ ? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
18012
+ : linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
18013
+ const value = _range[_index - 1][rowIndex];
18009
18014
  if (value === undefined) {
18010
18015
  return valueNotAvailable(searchKey);
18011
18016
  }
@@ -18043,30 +18048,32 @@ stores.inject(MyMetaStore, storeInstance);
18043
18048
  compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
18044
18049
  const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
18045
18050
  const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
18046
- assert(() => lookupRange.length === 1 || lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18051
+ const _lookupRange = toMatrix(lookupRange);
18052
+ const _returnRange = toMatrix(returnRange);
18053
+ assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18047
18054
  assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
18048
18055
  assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
18049
- const lookupDirection = lookupRange.length === 1 ? "col" : "row";
18056
+ const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
18050
18057
  assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
18051
18058
  assert(() => lookupDirection === "col"
18052
- ? returnRange[0].length === lookupRange[0].length
18053
- : returnRange.length === lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18059
+ ? _returnRange[0].length === _lookupRange[0].length
18060
+ : _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18054
18061
  if (searchKey && isEvaluationError(searchKey.value)) {
18055
18062
  return [[searchKey]];
18056
18063
  }
18057
18064
  const getElement = lookupDirection === "col"
18058
18065
  ? (range, index) => range[0][index].value
18059
18066
  : (range, index) => range[index][0].value;
18060
- const rangeLen = lookupDirection === "col" ? lookupRange[0].length : lookupRange.length;
18067
+ const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
18061
18068
  const mode = MATCH_MODE[_matchMode];
18062
18069
  const reverseSearch = _searchMode === -1;
18063
18070
  const index = _searchMode === 2 || _searchMode === -2
18064
- ? dichotomicSearch(lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18065
- : linearSearch(lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
18071
+ ? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18072
+ : linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
18066
18073
  if (index !== -1) {
18067
18074
  return lookupDirection === "col"
18068
- ? returnRange.map((col) => [col[index]])
18069
- : [returnRange[index]];
18075
+ ? _returnRange.map((col) => [col[index]])
18076
+ : [_returnRange[index]];
18070
18077
  }
18071
18078
  if (defaultValue === undefined) {
18072
18079
  return valueNotAvailable(searchKey);
@@ -34696,11 +34703,10 @@ stores.inject(MyMetaStore, storeInstance);
34696
34703
  switch (layer) {
34697
34704
  case "Background":
34698
34705
  this.drawGlobalBackground(renderingContext);
34699
- for (const zone of this.getters.getAllActiveViewportsZones()) {
34706
+ for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
34700
34707
  const { ctx } = renderingContext;
34701
34708
  ctx.save();
34702
34709
  ctx.beginPath();
34703
- const rect = this.getters.getVisibleRect(zone);
34704
34710
  ctx.rect(rect.x, rect.y, rect.width, rect.height);
34705
34711
  ctx.clip();
34706
34712
  const boxes = this.getGridBoxes(zone);
@@ -34970,10 +34976,8 @@ stores.inject(MyMetaStore, storeInstance);
34970
34976
  const { ctx, thinLineWidth } = renderingContext;
34971
34977
  const visibleCols = this.getters.getSheetViewVisibleCols();
34972
34978
  const left = visibleCols[0];
34973
- const right = visibleCols[visibleCols.length - 1];
34974
34979
  const visibleRows = this.getters.getSheetViewVisibleRows();
34975
34980
  const top = visibleRows[0];
34976
- const bottom = visibleRows[visibleRows.length - 1];
34977
34981
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
34978
34982
  const selection = this.getters.getSelectedZones();
34979
34983
  const selectedCols = getZonesCols(selection);
@@ -34989,7 +34993,7 @@ stores.inject(MyMetaStore, storeInstance);
34989
34993
  ctx.lineWidth = thinLineWidth;
34990
34994
  ctx.strokeStyle = "#333";
34991
34995
  // Columns headers background
34992
- for (let col = left; col <= right; col++) {
34996
+ for (const col of visibleCols) {
34993
34997
  const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
34994
34998
  const { x, width } = this.getters.getVisibleRect(colZone);
34995
34999
  const isColActive = activeCols.has(col);
@@ -35006,7 +35010,7 @@ stores.inject(MyMetaStore, storeInstance);
35006
35010
  ctx.fillRect(x, 0, width, HEADER_HEIGHT);
35007
35011
  }
35008
35012
  // Rows headers background
35009
- for (let row = top; row <= bottom; row++) {
35013
+ for (const row of visibleRows) {
35010
35014
  const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
35011
35015
  const { y, height } = this.getters.getVisibleRect(rowZone);
35012
35016
  const isRowActive = activeRows.has(row);
@@ -35032,21 +35036,21 @@ stores.inject(MyMetaStore, storeInstance);
35032
35036
  ctx.stroke();
35033
35037
  ctx.beginPath();
35034
35038
  // column text + separator
35035
- for (const i of visibleCols) {
35036
- const colSize = this.getters.getColSize(sheetId, i);
35037
- const colName = numberToLetters(i);
35038
- ctx.fillStyle = activeCols.has(i) ? "#fff" : TEXT_HEADER_COLOR;
35039
- let colStart = this.getHeaderOffset("COL", left, i);
35039
+ for (const col of visibleCols) {
35040
+ const colSize = this.getters.getColSize(sheetId, col);
35041
+ const colName = numberToLetters(col);
35042
+ ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
35043
+ let colStart = this.getHeaderOffset("COL", left, col);
35040
35044
  ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
35041
35045
  ctx.moveTo(colStart + colSize, 0);
35042
35046
  ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
35043
35047
  }
35044
35048
  // row text + separator
35045
- for (const i of visibleRows) {
35046
- const rowSize = this.getters.getRowSize(sheetId, i);
35047
- ctx.fillStyle = activeRows.has(i) ? "#fff" : TEXT_HEADER_COLOR;
35048
- let rowStart = this.getHeaderOffset("ROW", top, i);
35049
- ctx.fillText(String(i + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
35049
+ for (const row of visibleRows) {
35050
+ const rowSize = this.getters.getRowSize(sheetId, row);
35051
+ ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
35052
+ let rowStart = this.getHeaderOffset("ROW", top, row);
35053
+ ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
35050
35054
  ctx.moveTo(0, rowStart + rowSize);
35051
35055
  ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
35052
35056
  }
@@ -35338,6 +35342,9 @@ stores.inject(MyMetaStore, storeInstance);
35338
35342
  canvas.width = width * dpr;
35339
35343
  canvas.height = height * dpr;
35340
35344
  canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
35345
+ if (width === 0 || height === 0) {
35346
+ return;
35347
+ }
35341
35348
  // Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
35342
35349
  // are the edges of the squares. If you draw a one-unit-wide line between whole-number
35343
35350
  // coordinates, it will overlap opposite sides of the pixel square, and the resulting
@@ -40895,7 +40902,7 @@ stores.inject(MyMetaStore, storeInstance);
40895
40902
  getCommonSides(border1, border2) {
40896
40903
  const commonBorder = {};
40897
40904
  for (let side of ["top", "bottom", "left", "right"]) {
40898
- if (border1[side] && border1[side] === border2[side]) {
40905
+ if (border1[side] && deepEquals(border1[side], border2[side])) {
40899
40906
  commonBorder[side] = border1[side];
40900
40907
  }
40901
40908
  }
@@ -53806,8 +53813,17 @@ stores.inject(MyMetaStore, storeInstance);
53806
53813
  this.getters = getters;
53807
53814
  this.sheetId = sheetId;
53808
53815
  this.boundaries = boundaries;
53809
- this.viewportWidth = sizeInGrid.width;
53810
- this.viewportHeight = sizeInGrid.height;
53816
+ if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
53817
+ throw new Error("Viewport size cannot be negative");
53818
+ }
53819
+ this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
53820
+ this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
53821
+ this.top = boundaries.top;
53822
+ this.bottom = boundaries.bottom;
53823
+ this.left = boundaries.left;
53824
+ this.right = boundaries.right;
53825
+ this.offsetX = offsets.x;
53826
+ this.offsetY = offsets.y;
53811
53827
  this.offsetScrollbarX = offsets.x;
53812
53828
  this.offsetScrollbarY = offsets.y;
53813
53829
  this.canScrollVertically = options.canScrollVertically;
@@ -53850,9 +53866,9 @@ stores.inject(MyMetaStore, storeInstance);
53850
53866
  Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
53851
53867
  );
53852
53868
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
53853
- }
53854
- if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
53855
- height += FOOTER_HEIGHT;
53869
+ if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
53870
+ height += FOOTER_HEIGHT;
53871
+ }
53856
53872
  }
53857
53873
  return { width, height };
53858
53874
  }
@@ -53989,6 +54005,9 @@ stores.inject(MyMetaStore, storeInstance);
53989
54005
  !this.getters.isRowHidden(this.sheetId, row));
53990
54006
  }
53991
54007
  searchHeaderIndex(dimension, position, startIndex = 0) {
54008
+ if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
54009
+ return -1;
54010
+ }
53992
54011
  const sheetId = this.sheetId;
53993
54012
  const headers = this.getters.getNumberHeaders(sheetId, dimension);
53994
54013
  // using a binary search:
@@ -54025,7 +54044,7 @@ stores.inject(MyMetaStore, storeInstance);
54025
54044
  this.adjustViewportZoneY();
54026
54045
  }
54027
54046
  /** Corrects the viewport's horizontal offset based on the current structure
54028
- * To make sure that at least on column is visible inside the viewport.
54047
+ * To make sure that at least one column is visible inside the viewport.
54029
54048
  */
54030
54049
  adjustViewportOffsetX() {
54031
54050
  if (this.canScrollHorizontally) {
@@ -54037,7 +54056,7 @@ stores.inject(MyMetaStore, storeInstance);
54037
54056
  this.adjustViewportZoneX();
54038
54057
  }
54039
54058
  /** Corrects the viewport's vertical offset based on the current structure
54040
- * To make sure that at least on row is visible inside the viewport.
54059
+ * To make sure that at least one row is visible inside the viewport.
54041
54060
  */
54042
54061
  adjustViewportOffsetY() {
54043
54062
  if (this.canScrollVertically) {
@@ -54054,11 +54073,14 @@ stores.inject(MyMetaStore, storeInstance);
54054
54073
  const sheetId = this.sheetId;
54055
54074
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
54056
54075
  this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
54076
+ if (!this.viewportWidth) {
54077
+ return;
54078
+ }
54057
54079
  if (this.left === -1) {
54058
54080
  this.left = this.boundaries.left;
54059
54081
  }
54060
54082
  if (this.right === -1) {
54061
- this.right = this.getters.getNumberCols(sheetId) - 1;
54083
+ this.right = this.boundaries.right;
54062
54084
  }
54063
54085
  this.offsetX =
54064
54086
  this.getters.getColDimensions(sheetId, this.left).start -
@@ -54070,11 +54092,14 @@ stores.inject(MyMetaStore, storeInstance);
54070
54092
  const sheetId = this.sheetId;
54071
54093
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
54072
54094
  this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
54095
+ if (!this.viewportHeight) {
54096
+ return;
54097
+ }
54073
54098
  if (this.top === -1) {
54074
54099
  this.top = this.boundaries.top;
54075
54100
  }
54076
54101
  if (this.bottom === -1) {
54077
- this.bottom = this.getters.getNumberRows(sheetId) - 1;
54102
+ this.bottom = this.boundaries.bottom;
54078
54103
  }
54079
54104
  this.offsetY =
54080
54105
  this.getters.getRowDimensions(sheetId, this.top).start -
@@ -54148,7 +54173,7 @@ stores.inject(MyMetaStore, storeInstance);
54148
54173
  "isPositionVisible",
54149
54174
  "getColDimensionsInViewport",
54150
54175
  "getRowDimensionsInViewport",
54151
- "getAllActiveViewportsZones",
54176
+ "getAllActiveViewportsZonesAndRect",
54152
54177
  "getRect",
54153
54178
  ];
54154
54179
  viewports = {};
@@ -54382,12 +54407,12 @@ stores.inject(MyMetaStore, storeInstance);
54382
54407
  const sheetId = this.getters.getActiveSheetId();
54383
54408
  const viewports = this.getSubViewports(sheetId);
54384
54409
  //TODO ake another commit to eimprove this
54385
- return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
54410
+ return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
54386
54411
  }
54387
54412
  getSheetViewVisibleRows() {
54388
54413
  const sheetId = this.getters.getActiveSheetId();
54389
54414
  const viewports = this.getSubViewports(sheetId);
54390
- return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
54415
+ return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
54391
54416
  }
54392
54417
  /**
54393
54418
  * Get the positions of all the cells that are visible in the viewport, taking merges into account.
@@ -54430,19 +54455,19 @@ stores.inject(MyMetaStore, storeInstance);
54430
54455
  maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
54431
54456
  };
54432
54457
  }
54433
- getColRowOffsetInViewport(dimension, referenceIndex, index) {
54434
- const sheetId = this.getters.getActiveSheetId();
54435
- const visibleCols = this.getters.getSheetViewVisibleCols();
54436
- const visibleRows = this.getters.getSheetViewVisibleRows();
54437
- if (index < referenceIndex) {
54438
- return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
54458
+ getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
54459
+ if (targetHeaderIndex < referenceHeaderIndex) {
54460
+ return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
54439
54461
  }
54462
+ const sheetId = this.getters.getActiveSheetId();
54463
+ const visibleHeaders = dimension === "COL"
54464
+ ? this.getters.getSheetViewVisibleCols()
54465
+ : this.getters.getSheetViewVisibleRows();
54466
+ const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
54467
+ const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
54468
+ const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
54440
54469
  let offset = 0;
54441
- const visibleIndexes = dimension === "COL" ? visibleCols : visibleRows;
54442
- for (let i = referenceIndex; i < index; i++) {
54443
- if (!visibleIndexes.includes(i)) {
54444
- continue;
54445
- }
54470
+ for (const i of relevantIndexes) {
54446
54471
  offset += this.getters.getHeaderSize(sheetId, dimension, i);
54447
54472
  }
54448
54473
  return offset;
@@ -54489,7 +54514,7 @@ stores.inject(MyMetaStore, storeInstance);
54489
54514
  }
54490
54515
  return { canEdgeScroll, direction, delay };
54491
54516
  }
54492
- getEdgeScrollRow(y, previousY, tartingY) {
54517
+ getEdgeScrollRow(y, previousY, startingY) {
54493
54518
  let canEdgeScroll = false;
54494
54519
  let direction = 0;
54495
54520
  let delay = 0;
@@ -54510,7 +54535,7 @@ stores.inject(MyMetaStore, storeInstance);
54510
54535
  delay = scrollDelay(y - height);
54511
54536
  direction = 1;
54512
54537
  }
54513
- else if (y < offsetCorrectionY && tartingY >= offsetCorrectionY && currentOffsetY > 0) {
54538
+ else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
54514
54539
  // 2
54515
54540
  canEdgeScroll = true;
54516
54541
  delay = scrollDelay(offsetCorrectionY - y);
@@ -54536,13 +54561,7 @@ stores.inject(MyMetaStore, storeInstance);
54536
54561
  */
54537
54562
  getVisibleRectWithoutHeaders(zone) {
54538
54563
  const sheetId = this.getters.getActiveSheetId();
54539
- const viewportRects = this.getSubViewports(sheetId)
54540
- .map((viewport) => viewport.getVisibleRect(zone))
54541
- .filter(isDefined$1);
54542
- if (viewportRects.length === 0) {
54543
- return { x: 0, y: 0, width: 0, height: 0 };
54544
- }
54545
- return this.recomposeRect(viewportRects);
54564
+ return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
54546
54565
  }
54547
54566
  /**
54548
54567
  * Computes the actual size and position (:Rect) of the zone on the canvas
@@ -54550,13 +54569,7 @@ stores.inject(MyMetaStore, storeInstance);
54550
54569
  */
54551
54570
  getRect(zone) {
54552
54571
  const sheetId = this.getters.getActiveSheetId();
54553
- const viewportRects = this.getSubViewports(sheetId)
54554
- .map((viewport) => viewport.getFullRect(zone))
54555
- .filter(isDefined$1);
54556
- if (viewportRects.length === 0) {
54557
- return { x: 0, y: 0, width: 0, height: 0 };
54558
- }
54559
- const rect = this.recomposeRect(viewportRects);
54572
+ const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
54560
54573
  return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
54561
54574
  }
54562
54575
  /**
@@ -54601,9 +54614,18 @@ stores.inject(MyMetaStore, storeInstance);
54601
54614
  end: start + (isRowHidden ? 0 : size),
54602
54615
  };
54603
54616
  }
54604
- getAllActiveViewportsZones() {
54617
+ getAllActiveViewportsZonesAndRect() {
54605
54618
  const sheetId = this.getters.getActiveSheetId();
54606
- return this.getSubViewports(sheetId);
54619
+ return this.getSubViewports(sheetId).map((viewport) => {
54620
+ return {
54621
+ zone: viewport,
54622
+ rect: {
54623
+ x: viewport.offsetCorrectionX + this.gridOffsetX,
54624
+ y: viewport.offsetCorrectionY + this.gridOffsetY,
54625
+ ...viewport.getMaxSize(),
54626
+ },
54627
+ };
54628
+ });
54607
54629
  }
54608
54630
  // ---------------------------------------------------------------------------
54609
54631
  // Private
@@ -54656,12 +54678,11 @@ stores.inject(MyMetaStore, storeInstance);
54656
54678
  }
54657
54679
  /** gets rid of deprecated sheetIds */
54658
54680
  cleanViewports() {
54659
- const sheetIds = this.getters.getSheetIds();
54660
- for (let sheetId of Object.keys(this.viewports)) {
54661
- if (!sheetIds.includes(sheetId)) {
54662
- delete this.viewports[sheetId];
54663
- }
54681
+ const newViewport = {};
54682
+ for (const sheetId of this.getters.getSheetIds()) {
54683
+ newViewport[sheetId] = this.viewports[sheetId];
54664
54684
  }
54685
+ this.viewports = newViewport;
54665
54686
  }
54666
54687
  resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
54667
54688
  this.sheetViewHeight = height;
@@ -54671,14 +54692,14 @@ stores.inject(MyMetaStore, storeInstance);
54671
54692
  this.recomputeViewports();
54672
54693
  }
54673
54694
  recomputeViewports() {
54674
- for (let sheetId of Object.keys(this.viewports)) {
54695
+ for (const sheetId of this.getters.getSheetIds()) {
54675
54696
  this.resetViewports(sheetId);
54676
54697
  }
54677
54698
  }
54678
54699
  setSheetViewOffset(offsetX, offsetY) {
54679
54700
  const sheetId = this.getters.getActiveSheetId();
54680
54701
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
54681
- Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
54702
+ this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
54682
54703
  }
54683
54704
  getViewportOffset(sheetId) {
54684
54705
  return {
@@ -54693,8 +54714,10 @@ stores.inject(MyMetaStore, storeInstance);
54693
54714
  const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
54694
54715
  const nCols = this.getters.getNumberCols(sheetId);
54695
54716
  const nRows = this.getters.getNumberRows(sheetId);
54696
- const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
54697
- const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
54717
+ const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
54718
+ const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
54719
+ const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
54720
+ const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
54698
54721
  const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
54699
54722
  const canScrollHorizontally = xRatio < 1.0;
54700
54723
  const canScrollVertically = yRatio < 1.0;
@@ -54705,14 +54728,14 @@ stores.inject(MyMetaStore, storeInstance);
54705
54728
  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 })) ||
54706
54729
  undefined,
54707
54730
  topRight: (ySplit &&
54708
- 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 })) ||
54731
+ 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 })) ||
54709
54732
  undefined,
54710
54733
  bottomLeft: (xSplit &&
54711
- 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 })) ||
54734
+ 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 })) ||
54712
54735
  undefined,
54713
54736
  bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
54714
- width: this.sheetViewWidth - colOffset,
54715
- height: this.sheetViewHeight - rowOffset,
54737
+ width: unfrozenWidth,
54738
+ height: unfrozenHeight,
54716
54739
  }, { canScrollHorizontally, canScrollVertically }, {
54717
54740
  x: canScrollHorizontally ? previousOffset.x : 0,
54718
54741
  y: canScrollVertically ? previousOffset.y : 0,
@@ -54724,7 +54747,7 @@ stores.inject(MyMetaStore, storeInstance);
54724
54747
  * Adjust the viewport such that the anchor position is visible
54725
54748
  */
54726
54749
  refreshViewport(sheetId, anchorPosition) {
54727
- Object.values(this.getSubViewports(sheetId)).forEach((viewport) => {
54750
+ this.getSubViewports(sheetId).forEach((viewport) => {
54728
54751
  viewport.adjustViewportZone();
54729
54752
  viewport.adjustPosition(anchorPosition);
54730
54753
  });
@@ -54789,12 +54812,26 @@ stores.inject(MyMetaStore, storeInstance);
54789
54812
  const height = this.sheetViewHeight + this.gridOffsetY;
54790
54813
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
54791
54814
  }
54792
- recomposeRect(viewportRects) {
54793
- const x = Math.min(...viewportRects.map((rect) => rect.x));
54794
- const y = Math.min(...viewportRects.map((rect) => rect.y));
54795
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
54796
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
54797
- return { x, y, width, height };
54815
+ mapViewportsToRect(sheetId, rectCallBack) {
54816
+ let x = Infinity;
54817
+ let y = Infinity;
54818
+ let width = 0;
54819
+ let height = 0;
54820
+ let hasViewports = false;
54821
+ for (const viewport of this.getSubViewports(sheetId)) {
54822
+ const rect = rectCallBack(viewport);
54823
+ if (rect) {
54824
+ hasViewports = true;
54825
+ x = Math.min(x, rect.x);
54826
+ y = Math.min(y, rect.y);
54827
+ width = Math.max(width, rect.x + rect.width);
54828
+ height = Math.max(height, rect.y + rect.height);
54829
+ }
54830
+ }
54831
+ if (!hasViewports) {
54832
+ return { x: 0, y: 0, width: 0, height: 0 };
54833
+ }
54834
+ return { x, y, width: width - x, height: height - y };
54798
54835
  }
54799
54836
  }
54800
54837
 
@@ -61133,9 +61170,9 @@ stores.inject(MyMetaStore, storeInstance);
61133
61170
  exports.tokenize = tokenize;
61134
61171
 
61135
61172
 
61136
- __info__.version = "17.2.34";
61137
- __info__.date = "2025-01-31T07:58:03.953Z";
61138
- __info__.hash = "0bffee9";
61173
+ __info__.version = "17.2.35";
61174
+ __info__.date = "2025-02-05T07:12:34.721Z";
61175
+ __info__.hash = "76b12a1";
61139
61176
 
61140
61177
 
61141
61178
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);