@odoo/o-spreadsheet 17.0.47 → 17.0.48

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 17.0.47
6
- * @date 2025-01-31T07:56:50.980Z
7
- * @hash a22bce2
5
+ * @version 17.0.48
6
+ * @date 2025-02-05T07:18:39.331Z
7
+ * @hash aea9101
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -18558,20 +18558,21 @@
18558
18558
  description: _t("Horizontal lookup"),
18559
18559
  args: [
18560
18560
  arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
18561
- 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.")),
18561
+ 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.")),
18562
18562
  arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
18563
18563
  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.")),
18564
18564
  ],
18565
18565
  returns: ["ANY"],
18566
18566
  computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18567
18567
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18568
- assert(() => 1 <= _index && _index <= range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18568
+ const _range = toMatrix(range);
18569
+ assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18569
18570
  const getValueFromRange = (range, index) => range[index][0].value;
18570
18571
  const _isSorted = toBoolean(isSorted.value);
18571
18572
  const colIndex = _isSorted
18572
- ? dichotomicSearch(range, searchKey?.value, "nextSmaller", "asc", range.length, getValueFromRange)
18573
- : linearSearch(range, searchKey?.value, "strict", range.length, getValueFromRange);
18574
- const col = range[colIndex];
18573
+ ? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range.length, getValueFromRange)
18574
+ : linearSearch(_range, searchKey?.value, "strict", _range.length, getValueFromRange);
18575
+ const col = _range[colIndex];
18575
18576
  assertAvailable(col, searchKey?.value);
18576
18577
  return col[_index - 1];
18577
18578
  },
@@ -18616,36 +18617,38 @@
18616
18617
  description: _t("Look up a value."),
18617
18618
  args: [
18618
18619
  arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
18619
- 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.")),
18620
- 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.")),
18620
+ 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.")),
18621
+ 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.")),
18621
18622
  ],
18622
18623
  returns: ["ANY"],
18623
18624
  computeValueAndFormat: function (searchKey, searchArray, resultRange) {
18624
- let nbCol = searchArray.length;
18625
- let nbRow = searchArray[0].length;
18625
+ const _searchArray = toMatrix(searchArray);
18626
+ const _resultRange = toMatrix(resultRange);
18627
+ let nbCol = _searchArray.length;
18628
+ let nbRow = _searchArray[0].length;
18626
18629
  const verticalSearch = nbRow >= nbCol;
18627
18630
  const getElement = verticalSearch
18628
18631
  ? (range, index) => range[0][index].value
18629
18632
  : (range, index) => range[index][0].value;
18630
18633
  const rangeLength = verticalSearch ? nbRow : nbCol;
18631
- const index = dichotomicSearch(searchArray, searchKey?.value, "nextSmaller", "asc", rangeLength, getElement);
18634
+ const index = dichotomicSearch(_searchArray, searchKey?.value, "nextSmaller", "asc", rangeLength, getElement);
18632
18635
  if (index === -1)
18633
18636
  assertAvailable(undefined, searchKey?.value);
18634
18637
  verticalSearch
18635
- ? assertAvailable(searchArray[0][index], searchKey?.value)
18636
- : assertAvailable(searchArray[index][nbRow - 1], searchKey?.value);
18637
- if (resultRange === undefined) {
18638
- return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
18638
+ ? assertAvailable(_searchArray[0][index], searchKey?.value)
18639
+ : assertAvailable(_searchArray[index][nbRow - 1], searchKey?.value);
18640
+ if (_resultRange[0].length === 0) {
18641
+ return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
18639
18642
  }
18640
- nbCol = resultRange.length;
18641
- nbRow = resultRange[0].length;
18643
+ nbCol = _resultRange.length;
18644
+ nbRow = _resultRange[0].length;
18642
18645
  assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
18643
18646
  if (nbCol > 1) {
18644
18647
  assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
18645
- return resultRange[index][0];
18648
+ return _resultRange[index][0];
18646
18649
  }
18647
18650
  assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
18648
- return resultRange[0][index];
18651
+ return _resultRange[0][index];
18649
18652
  },
18650
18653
  isExported: true,
18651
18654
  };
@@ -18663,27 +18666,28 @@
18663
18666
  returns: ["NUMBER"],
18664
18667
  compute: function (searchKey, range, searchType = DEFAULT_SEARCH_TYPE) {
18665
18668
  let _searchType = toNumber(searchType, this.locale);
18666
- const nbCol = range.length;
18667
- const nbRow = range[0].length;
18669
+ const _range = toMatrix(range);
18670
+ const nbCol = _range.length;
18671
+ const nbRow = _range[0].length;
18668
18672
  assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
18669
18673
  let index = -1;
18670
18674
  const getElement = nbCol === 1
18671
- ? (range, index) => range[0][index]
18672
- : (range, index) => range[index][0];
18673
- const rangeLen = nbCol === 1 ? range[0].length : range.length;
18675
+ ? (_range, index) => _range[0][index]
18676
+ : (_range, index) => _range[index][0];
18677
+ const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
18674
18678
  _searchType = Math.sign(_searchType);
18675
18679
  switch (_searchType) {
18676
18680
  case 1:
18677
- index = dichotomicSearch(range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
18681
+ index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
18678
18682
  break;
18679
18683
  case 0:
18680
- index = linearSearch(range, searchKey, "strict", rangeLen, getElement);
18684
+ index = linearSearch(_range, searchKey, "strict", rangeLen, getElement);
18681
18685
  break;
18682
18686
  case -1:
18683
- index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
18687
+ index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
18684
18688
  break;
18685
18689
  }
18686
- assertAvailable(nbCol === 1 ? range[0][index] : range[index], searchKey);
18690
+ assertAvailable(nbCol === 1 ? _range[0][index] : _range[index], searchKey);
18687
18691
  return index + 1;
18688
18692
  },
18689
18693
  isExported: true,
@@ -18732,13 +18736,14 @@
18732
18736
  returns: ["ANY"],
18733
18737
  computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18734
18738
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18735
- assert(() => 1 <= _index && _index <= range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18739
+ const _range = toMatrix(range);
18740
+ assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18736
18741
  const getValueFromRange = (range, index) => range[0][index].value;
18737
18742
  const _isSorted = toBoolean(isSorted.value);
18738
18743
  const rowIndex = _isSorted
18739
- ? dichotomicSearch(range, searchKey?.value, "nextSmaller", "asc", range[0].length, getValueFromRange)
18740
- : linearSearch(range, searchKey?.value, "strict", range[0].length, getValueFromRange);
18741
- const value = range[_index - 1][rowIndex];
18744
+ ? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range[0].length, getValueFromRange)
18745
+ : linearSearch(_range, searchKey?.value, "strict", _range[0].length, getValueFromRange);
18746
+ const value = _range[_index - 1][rowIndex];
18742
18747
  assertAvailable(value, searchKey?.value);
18743
18748
  return value;
18744
18749
  },
@@ -18765,26 +18770,28 @@
18765
18770
  computeValueAndFormat: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
18766
18771
  const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
18767
18772
  const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
18768
- assert(() => lookupRange.length === 1 || lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18773
+ const _lookupRange = toMatrix(lookupRange);
18774
+ const _returnRange = toMatrix(returnRange);
18775
+ assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
18769
18776
  assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("searchMode should be a value in [-1, 1, -2, 2]."));
18770
18777
  assert(() => [-1, 0, 1].includes(_matchMode), _t("matchMode should be a value in [-1, 0, 1]."));
18771
- const lookupDirection = lookupRange.length === 1 ? "col" : "row";
18778
+ const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
18772
18779
  assert(() => lookupDirection === "col"
18773
- ? returnRange[0].length === lookupRange[0].length
18774
- : returnRange.length === lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18780
+ ? _returnRange[0].length === _lookupRange[0].length
18781
+ : _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18775
18782
  const getElement = lookupDirection === "col"
18776
18783
  ? (range, index) => range[0][index].value
18777
18784
  : (range, index) => range[index][0].value;
18778
- const rangeLen = lookupDirection === "col" ? lookupRange[0].length : lookupRange.length;
18785
+ const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
18779
18786
  const mode = _matchMode === 0 ? "strict" : _matchMode === 1 ? "nextGreater" : "nextSmaller";
18780
18787
  const reverseSearch = _searchMode === -1;
18781
18788
  const index = _searchMode === 2 || _searchMode === -2
18782
- ? dichotomicSearch(lookupRange, searchKey?.value, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18783
- : linearSearch(lookupRange, searchKey?.value, mode, rangeLen, getElement, reverseSearch);
18789
+ ? dichotomicSearch(_lookupRange, searchKey?.value, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
18790
+ : linearSearch(_lookupRange, searchKey?.value, mode, rangeLen, getElement, reverseSearch);
18784
18791
  if (index !== -1) {
18785
18792
  return lookupDirection === "col"
18786
- ? returnRange.map((col) => [col[index]])
18787
- : [returnRange[index]];
18793
+ ? _returnRange.map((col) => [col[index]])
18794
+ : [_returnRange[index]];
18788
18795
  }
18789
18796
  const _defaultValue = defaultValue?.();
18790
18797
  assertAvailable(_defaultValue, searchKey?.value);
@@ -29242,6 +29249,9 @@
29242
29249
  canvas.width = width * dpr;
29243
29250
  canvas.height = height * dpr;
29244
29251
  canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
29252
+ if (width === 0 || height === 0) {
29253
+ return;
29254
+ }
29245
29255
  // Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
29246
29256
  // are the edges of the squares. If you draw a one-unit-wide line between whole-number
29247
29257
  // coordinates, it will overlap opposite sides of the pixel square, and the resulting
@@ -34722,7 +34732,7 @@
34722
34732
  getCommonSides(border1, border2) {
34723
34733
  const commonBorder = {};
34724
34734
  for (let side of ["top", "bottom", "left", "right"]) {
34725
- if (border1[side] && border1[side] === border2[side]) {
34735
+ if (border1[side] && deepEquals(border1[side], border2[side])) {
34726
34736
  commonBorder[side] = border1[side];
34727
34737
  }
34728
34738
  }
@@ -46268,11 +46278,10 @@
46268
46278
  switch (layer) {
46269
46279
  case 0 /* LAYERS.Background */:
46270
46280
  this.drawGlobalBackground(renderingContext);
46271
- for (const zone of this.getters.getAllActiveViewportsZones()) {
46281
+ for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
46272
46282
  const { ctx } = renderingContext;
46273
46283
  ctx.save();
46274
46284
  ctx.beginPath();
46275
- const rect = this.getters.getVisibleRect(zone);
46276
46285
  ctx.rect(rect.x, rect.y, rect.width, rect.height);
46277
46286
  ctx.clip();
46278
46287
  this.boxes = this.getGridBoxes(zone);
@@ -46542,10 +46551,8 @@
46542
46551
  const { ctx, thinLineWidth } = renderingContext;
46543
46552
  const visibleCols = this.getters.getSheetViewVisibleCols();
46544
46553
  const left = visibleCols[0];
46545
- const right = visibleCols[visibleCols.length - 1];
46546
46554
  const visibleRows = this.getters.getSheetViewVisibleRows();
46547
46555
  const top = visibleRows[0];
46548
- const bottom = visibleRows[visibleRows.length - 1];
46549
46556
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
46550
46557
  const selection = this.getters.getSelectedZones();
46551
46558
  const selectedCols = getZonesCols(selection);
@@ -46561,7 +46568,7 @@
46561
46568
  ctx.lineWidth = thinLineWidth;
46562
46569
  ctx.strokeStyle = "#333";
46563
46570
  // Columns headers background
46564
- for (let col = left; col <= right; col++) {
46571
+ for (const col of visibleCols) {
46565
46572
  const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
46566
46573
  const { x, width } = this.getters.getVisibleRect(colZone);
46567
46574
  const colHasFilter = this.getters.doesZonesContainFilter(sheetId, [colZone]);
@@ -46581,7 +46588,7 @@
46581
46588
  ctx.fillRect(x, 0, width, HEADER_HEIGHT);
46582
46589
  }
46583
46590
  // Rows headers background
46584
- for (let row = top; row <= bottom; row++) {
46591
+ for (const row of visibleRows) {
46585
46592
  const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
46586
46593
  const { y, height } = this.getters.getVisibleRect(rowZone);
46587
46594
  const rowHasFilter = this.getters.doesZonesContainFilter(sheetId, [rowZone]);
@@ -46610,21 +46617,21 @@
46610
46617
  ctx.stroke();
46611
46618
  ctx.beginPath();
46612
46619
  // column text + separator
46613
- for (const i of visibleCols) {
46614
- const colSize = this.getters.getColSize(sheetId, i);
46615
- const colName = numberToLetters(i);
46616
- ctx.fillStyle = activeCols.has(i) ? "#fff" : TEXT_HEADER_COLOR;
46617
- let colStart = this.getHeaderOffset("COL", left, i);
46620
+ for (const col of visibleCols) {
46621
+ const colSize = this.getters.getColSize(sheetId, col);
46622
+ const colName = numberToLetters(col);
46623
+ ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
46624
+ let colStart = this.getHeaderOffset("COL", left, col);
46618
46625
  ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
46619
46626
  ctx.moveTo(colStart + colSize, 0);
46620
46627
  ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
46621
46628
  }
46622
46629
  // row text + separator
46623
- for (const i of visibleRows) {
46624
- const rowSize = this.getters.getRowSize(sheetId, i);
46625
- ctx.fillStyle = activeRows.has(i) ? "#fff" : TEXT_HEADER_COLOR;
46626
- let rowStart = this.getHeaderOffset("ROW", top, i);
46627
- ctx.fillText(String(i + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
46630
+ for (const row of visibleRows) {
46631
+ const rowSize = this.getters.getRowSize(sheetId, row);
46632
+ ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
46633
+ let rowStart = this.getHeaderOffset("ROW", top, row);
46634
+ ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
46628
46635
  ctx.moveTo(0, rowStart + rowSize);
46629
46636
  ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
46630
46637
  }
@@ -50515,8 +50522,17 @@
50515
50522
  this.getters = getters;
50516
50523
  this.sheetId = sheetId;
50517
50524
  this.boundaries = boundaries;
50518
- this.viewportWidth = sizeInGrid.width;
50519
- this.viewportHeight = sizeInGrid.height;
50525
+ if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
50526
+ throw new Error("Viewport size cannot be negative");
50527
+ }
50528
+ this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
50529
+ this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
50530
+ this.top = boundaries.top;
50531
+ this.bottom = boundaries.bottom;
50532
+ this.left = boundaries.left;
50533
+ this.right = boundaries.right;
50534
+ this.offsetX = offsets.x;
50535
+ this.offsetY = offsets.y;
50520
50536
  this.offsetScrollbarX = offsets.x;
50521
50537
  this.offsetScrollbarY = offsets.y;
50522
50538
  this.canScrollVertically = options.canScrollVertically;
@@ -50559,9 +50575,9 @@
50559
50575
  Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
50560
50576
  );
50561
50577
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
50562
- }
50563
- if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
50564
- height += FOOTER_HEIGHT;
50578
+ if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
50579
+ height += FOOTER_HEIGHT;
50580
+ }
50565
50581
  }
50566
50582
  return { width, height };
50567
50583
  }
@@ -50708,6 +50724,9 @@
50708
50724
  }
50709
50725
  // PRIVATE
50710
50726
  searchHeaderIndex(dimension, position, startIndex = 0) {
50727
+ if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
50728
+ return -1;
50729
+ }
50711
50730
  const sheetId = this.sheetId;
50712
50731
  const headers = this.getters.getNumberHeaders(sheetId, dimension);
50713
50732
  // using a binary search:
@@ -50747,7 +50766,7 @@
50747
50766
  this.adjustViewportZoneY();
50748
50767
  }
50749
50768
  /** Corrects the viewport's horizontal offset based on the current structure
50750
- * To make sure that at least on column is visible inside the viewport.
50769
+ * To make sure that at least one column is visible inside the viewport.
50751
50770
  */
50752
50771
  adjustViewportOffsetX() {
50753
50772
  if (this.canScrollHorizontally) {
@@ -50764,7 +50783,7 @@
50764
50783
  this.adjustViewportZoneX();
50765
50784
  }
50766
50785
  /** Corrects the viewport's vertical offset based on the current structure
50767
- * To make sure that at least on row is visible inside the viewport.
50786
+ * To make sure that at least one row is visible inside the viewport.
50768
50787
  */
50769
50788
  adjustViewportOffsetY() {
50770
50789
  if (this.canScrollVertically) {
@@ -50786,11 +50805,14 @@
50786
50805
  const sheetId = this.sheetId;
50787
50806
  this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
50788
50807
  this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
50808
+ if (!this.viewportWidth) {
50809
+ return;
50810
+ }
50789
50811
  if (this.left === -1) {
50790
50812
  this.left = this.boundaries.left;
50791
50813
  }
50792
50814
  if (this.right === -1) {
50793
- this.right = this.getters.getNumberCols(sheetId) - 1;
50815
+ this.right = this.boundaries.right;
50794
50816
  }
50795
50817
  this.offsetX =
50796
50818
  this.getters.getColDimensions(sheetId, this.left).start -
@@ -50802,11 +50824,14 @@
50802
50824
  const sheetId = this.sheetId;
50803
50825
  this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
50804
50826
  this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
50827
+ if (!this.viewportHeight) {
50828
+ return;
50829
+ }
50805
50830
  if (this.top === -1) {
50806
50831
  this.top = this.boundaries.top;
50807
50832
  }
50808
50833
  if (this.bottom === -1) {
50809
- this.bottom = this.getters.getNumberRows(sheetId) - 1;
50834
+ this.bottom = this.boundaries.bottom;
50810
50835
  }
50811
50836
  this.offsetY =
50812
50837
  this.getters.getRowDimensions(sheetId, this.top).start -
@@ -50878,7 +50903,7 @@
50878
50903
  "getSheetViewVisibleRows",
50879
50904
  "getFrozenSheetViewRatio",
50880
50905
  "isPositionVisible",
50881
- "getAllActiveViewportsZones",
50906
+ "getAllActiveViewportsZonesAndRect",
50882
50907
  "getRect",
50883
50908
  ];
50884
50909
  viewports = {};
@@ -51112,12 +51137,12 @@
51112
51137
  const sheetId = this.getters.getActiveSheetId();
51113
51138
  const viewports = this.getSubViewports(sheetId);
51114
51139
  //TODO ake another commit to eimprove this
51115
- return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
51140
+ return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
51116
51141
  }
51117
51142
  getSheetViewVisibleRows() {
51118
51143
  const sheetId = this.getters.getActiveSheetId();
51119
51144
  const viewports = this.getSubViewports(sheetId);
51120
- return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
51145
+ return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
51121
51146
  }
51122
51147
  /**
51123
51148
  * Get the positions of all the cells that are visible in the viewport, taking merges into account.
@@ -51160,19 +51185,19 @@
51160
51185
  maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
51161
51186
  };
51162
51187
  }
51163
- getColRowOffsetInViewport(dimension, referenceIndex, index) {
51164
- const sheetId = this.getters.getActiveSheetId();
51165
- const visibleCols = this.getters.getSheetViewVisibleCols();
51166
- const visibleRows = this.getters.getSheetViewVisibleRows();
51167
- if (index < referenceIndex) {
51168
- return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
51188
+ getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
51189
+ if (targetHeaderIndex < referenceHeaderIndex) {
51190
+ return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
51169
51191
  }
51192
+ const sheetId = this.getters.getActiveSheetId();
51193
+ const visibleHeaders = dimension === "COL"
51194
+ ? this.getters.getSheetViewVisibleCols()
51195
+ : this.getters.getSheetViewVisibleRows();
51196
+ const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
51197
+ const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
51198
+ const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
51170
51199
  let offset = 0;
51171
- const visibleIndexes = dimension === "COL" ? visibleCols : visibleRows;
51172
- for (let i = referenceIndex; i < index; i++) {
51173
- if (!visibleIndexes.includes(i)) {
51174
- continue;
51175
- }
51200
+ for (const i of relevantIndexes) {
51176
51201
  offset += this.getters.getHeaderSize(sheetId, dimension, i);
51177
51202
  }
51178
51203
  return offset;
@@ -51219,7 +51244,7 @@
51219
51244
  }
51220
51245
  return { canEdgeScroll, direction, delay };
51221
51246
  }
51222
- getEdgeScrollRow(y, previousY, tartingY) {
51247
+ getEdgeScrollRow(y, previousY, startingY) {
51223
51248
  let canEdgeScroll = false;
51224
51249
  let direction = 0;
51225
51250
  let delay = 0;
@@ -51240,7 +51265,7 @@
51240
51265
  delay = scrollDelay(y - height);
51241
51266
  direction = 1;
51242
51267
  }
51243
- else if (y < offsetCorrectionY && tartingY >= offsetCorrectionY && currentOffsetY > 0) {
51268
+ else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
51244
51269
  // 2
51245
51270
  canEdgeScroll = true;
51246
51271
  delay = scrollDelay(offsetCorrectionY - y);
@@ -51266,13 +51291,7 @@
51266
51291
  */
51267
51292
  getVisibleRectWithoutHeaders(zone) {
51268
51293
  const sheetId = this.getters.getActiveSheetId();
51269
- const viewportRects = this.getSubViewports(sheetId)
51270
- .map((viewport) => viewport.getVisibleRect(zone))
51271
- .filter(isDefined$1);
51272
- if (viewportRects.length === 0) {
51273
- return { x: 0, y: 0, width: 0, height: 0 };
51274
- }
51275
- return this.recomposeRect(viewportRects);
51294
+ return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
51276
51295
  }
51277
51296
  /**
51278
51297
  * Computes the actual size and position (:Rect) of the zone on the canvas
@@ -51280,13 +51299,7 @@
51280
51299
  */
51281
51300
  getRect(zone) {
51282
51301
  const sheetId = this.getters.getActiveSheetId();
51283
- const viewportRects = this.getSubViewports(sheetId)
51284
- .map((viewport) => viewport.getFullRect(zone))
51285
- .filter(isDefined$1);
51286
- if (viewportRects.length === 0) {
51287
- return { x: 0, y: 0, width: 0, height: 0 };
51288
- }
51289
- const rect = this.recomposeRect(viewportRects);
51302
+ const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
51290
51303
  return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
51291
51304
  }
51292
51305
  /**
@@ -51301,9 +51314,18 @@
51301
51314
  const y = this.getters.getRowDimensions(sheetId, ySplit).start;
51302
51315
  return { x, y };
51303
51316
  }
51304
- getAllActiveViewportsZones() {
51317
+ getAllActiveViewportsZonesAndRect() {
51305
51318
  const sheetId = this.getters.getActiveSheetId();
51306
- return this.getSubViewports(sheetId);
51319
+ return this.getSubViewports(sheetId).map((viewport) => {
51320
+ return {
51321
+ zone: viewport,
51322
+ rect: {
51323
+ x: viewport.offsetCorrectionX + this.gridOffsetX,
51324
+ y: viewport.offsetCorrectionY + this.gridOffsetY,
51325
+ ...viewport.getMaxSize(),
51326
+ },
51327
+ };
51328
+ });
51307
51329
  }
51308
51330
  // ---------------------------------------------------------------------------
51309
51331
  // Private
@@ -51356,12 +51378,11 @@
51356
51378
  }
51357
51379
  /** gets rid of deprecated sheetIds */
51358
51380
  cleanViewports() {
51359
- const sheetIds = this.getters.getSheetIds();
51360
- for (let sheetId of Object.keys(this.viewports)) {
51361
- if (!sheetIds.includes(sheetId)) {
51362
- delete this.viewports[sheetId];
51363
- }
51381
+ const newViewport = {};
51382
+ for (const sheetId of this.getters.getSheetIds()) {
51383
+ newViewport[sheetId] = this.viewports[sheetId];
51364
51384
  }
51385
+ this.viewports = newViewport;
51365
51386
  }
51366
51387
  resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
51367
51388
  this.sheetViewHeight = height;
@@ -51371,14 +51392,14 @@
51371
51392
  this.recomputeViewports();
51372
51393
  }
51373
51394
  recomputeViewports() {
51374
- for (let sheetId of Object.keys(this.viewports)) {
51395
+ for (const sheetId of this.getters.getSheetIds()) {
51375
51396
  this.resetViewports(sheetId);
51376
51397
  }
51377
51398
  }
51378
51399
  setSheetViewOffset(offsetX, offsetY) {
51379
51400
  const sheetId = this.getters.getActiveSheetId();
51380
51401
  const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
51381
- Object.values(this.getSubViewports(sheetId)).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
51402
+ this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
51382
51403
  }
51383
51404
  getViewportOffset(sheetId) {
51384
51405
  return {
@@ -51393,8 +51414,10 @@
51393
51414
  const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
51394
51415
  const nCols = this.getters.getNumberCols(sheetId);
51395
51416
  const nRows = this.getters.getNumberRows(sheetId);
51396
- const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
51397
- const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
51417
+ const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
51418
+ const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
51419
+ const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
51420
+ const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
51398
51421
  const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
51399
51422
  const canScrollHorizontally = xRatio < 1.0;
51400
51423
  const canScrollVertically = yRatio < 1.0;
@@ -51405,14 +51428,14 @@
51405
51428
  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 })) ||
51406
51429
  undefined,
51407
51430
  topRight: (ySplit &&
51408
- 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 })) ||
51431
+ 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 })) ||
51409
51432
  undefined,
51410
51433
  bottomLeft: (xSplit &&
51411
- 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 })) ||
51434
+ 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 })) ||
51412
51435
  undefined,
51413
51436
  bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
51414
- width: this.sheetViewWidth - colOffset,
51415
- height: this.sheetViewHeight - rowOffset,
51437
+ width: unfrozenWidth,
51438
+ height: unfrozenHeight,
51416
51439
  }, { canScrollHorizontally, canScrollVertically }, {
51417
51440
  x: canScrollHorizontally ? previousOffset.x : 0,
51418
51441
  y: canScrollVertically ? previousOffset.y : 0,
@@ -51424,7 +51447,7 @@
51424
51447
  * Adjust the viewport such that the anchor position is visible
51425
51448
  */
51426
51449
  refreshViewport(sheetId, anchorPosition) {
51427
- Object.values(this.getSubViewports(sheetId)).forEach((viewport) => {
51450
+ this.getSubViewports(sheetId).forEach((viewport) => {
51428
51451
  viewport.adjustViewportZone();
51429
51452
  viewport.adjustPosition(anchorPosition);
51430
51453
  });
@@ -51489,12 +51512,26 @@
51489
51512
  const height = this.sheetViewHeight + this.gridOffsetY;
51490
51513
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
51491
51514
  }
51492
- recomposeRect(viewportRects) {
51493
- const x = Math.min(...viewportRects.map((rect) => rect.x));
51494
- const y = Math.min(...viewportRects.map((rect) => rect.y));
51495
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
51496
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
51497
- return { x, y, width, height };
51515
+ mapViewportsToRect(sheetId, rectCallBack) {
51516
+ let x = Infinity;
51517
+ let y = Infinity;
51518
+ let width = 0;
51519
+ let height = 0;
51520
+ let hasViewports = false;
51521
+ for (const viewport of this.getSubViewports(sheetId)) {
51522
+ const rect = rectCallBack(viewport);
51523
+ if (rect) {
51524
+ hasViewports = true;
51525
+ x = Math.min(x, rect.x);
51526
+ y = Math.min(y, rect.y);
51527
+ width = Math.max(width, rect.x + rect.width);
51528
+ height = Math.max(height, rect.y + rect.height);
51529
+ }
51530
+ }
51531
+ if (!hasViewports) {
51532
+ return { x: 0, y: 0, width: 0, height: 0 };
51533
+ }
51534
+ return { x, y, width: width - x, height: height - y };
51498
51535
  }
51499
51536
  }
51500
51537
 
@@ -57803,9 +57840,9 @@
57803
57840
  exports.tokenize = tokenize;
57804
57841
 
57805
57842
 
57806
- __info__.version = "17.0.47";
57807
- __info__.date = "2025-01-31T07:56:50.980Z";
57808
- __info__.hash = "a22bce2";
57843
+ __info__.version = "17.0.48";
57844
+ __info__.date = "2025-02-05T07:18:39.331Z";
57845
+ __info__.hash = "aea9101";
57809
57846
 
57810
57847
 
57811
57848
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);