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