@odoo/o-spreadsheet 17.2.33 → 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.
- package/dist/o-spreadsheet.cjs.js +170 -135
- package/dist/o-spreadsheet.d.ts +11 -14
- package/dist/o-spreadsheet.esm.js +170 -135
- package/dist/o-spreadsheet.iife.js +170 -135
- package/dist/o-spreadsheet.iife.min.js +4 -4
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -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.
|
|
7
|
-
* @date 2025-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.35
|
|
7
|
+
* @date 2025-02-05T07:12:34.721Z
|
|
8
|
+
* @hash 76b12a1
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -1782,11 +1782,11 @@ const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(l
|
|
|
1782
1782
|
* number from the point of view of the isNumber function.
|
|
1783
1783
|
*/
|
|
1784
1784
|
function parseNumber(str, locale) {
|
|
1785
|
+
// remove invaluable characters
|
|
1786
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
1785
1787
|
if (locale.decimalSeparator !== ".") {
|
|
1786
1788
|
str = str.replace(locale.decimalSeparator, ".");
|
|
1787
1789
|
}
|
|
1788
|
-
// remove invaluable characters
|
|
1789
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
1790
1790
|
let n = Number(str);
|
|
1791
1791
|
if (isNaN(n) && str.includes("%")) {
|
|
1792
1792
|
n = Number(str.split("%")[0]);
|
|
@@ -17751,23 +17751,24 @@ const HLOOKUP = {
|
|
|
17751
17751
|
description: _t("Horizontal lookup"),
|
|
17752
17752
|
args: [
|
|
17753
17753
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
17754
|
-
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.")),
|
|
17754
|
+
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.")),
|
|
17755
17755
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
17756
17756
|
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.")),
|
|
17757
17757
|
],
|
|
17758
17758
|
returns: ["ANY"],
|
|
17759
17759
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
17760
17760
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
17761
|
-
|
|
17761
|
+
const _range = toMatrix(range);
|
|
17762
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
17762
17763
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
17763
17764
|
return searchKey;
|
|
17764
17765
|
}
|
|
17765
17766
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
17766
17767
|
const _isSorted = toBoolean(isSorted.value);
|
|
17767
17768
|
const colIndex = _isSorted
|
|
17768
|
-
? dichotomicSearch(
|
|
17769
|
-
: linearSearch(
|
|
17770
|
-
const col =
|
|
17769
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
17770
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
17771
|
+
const col = _range[colIndex];
|
|
17771
17772
|
if (col === undefined) {
|
|
17772
17773
|
return valueNotAvailable(searchKey);
|
|
17773
17774
|
}
|
|
@@ -17876,36 +17877,38 @@ const LOOKUP = {
|
|
|
17876
17877
|
description: _t("Look up a value."),
|
|
17877
17878
|
args: [
|
|
17878
17879
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
17879
|
-
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.")),
|
|
17880
|
-
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.")),
|
|
17880
|
+
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.")),
|
|
17881
|
+
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.")),
|
|
17881
17882
|
],
|
|
17882
17883
|
returns: ["ANY"],
|
|
17883
17884
|
compute: function (searchKey, searchArray, resultRange) {
|
|
17884
|
-
|
|
17885
|
-
|
|
17885
|
+
const _searchArray = toMatrix(searchArray);
|
|
17886
|
+
const _resultRange = toMatrix(resultRange);
|
|
17887
|
+
let nbCol = _searchArray.length;
|
|
17888
|
+
let nbRow = _searchArray[0].length;
|
|
17886
17889
|
const verticalSearch = nbRow >= nbCol;
|
|
17887
17890
|
const getElement = verticalSearch
|
|
17888
17891
|
? (range, index) => range[0][index].value
|
|
17889
17892
|
: (range, index) => range[index][0].value;
|
|
17890
17893
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
17891
|
-
const index = dichotomicSearch(
|
|
17894
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
17892
17895
|
if (index === -1 ||
|
|
17893
|
-
(verticalSearch &&
|
|
17894
|
-
(!verticalSearch &&
|
|
17896
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
17897
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
17895
17898
|
return valueNotAvailable(searchKey);
|
|
17896
17899
|
}
|
|
17897
|
-
if (
|
|
17898
|
-
return verticalSearch ?
|
|
17900
|
+
if (_resultRange[0].length === 0) {
|
|
17901
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
17899
17902
|
}
|
|
17900
|
-
nbCol =
|
|
17901
|
-
nbRow =
|
|
17903
|
+
nbCol = _resultRange.length;
|
|
17904
|
+
nbRow = _resultRange[0].length;
|
|
17902
17905
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
17903
17906
|
if (nbCol > 1) {
|
|
17904
17907
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
17905
|
-
return
|
|
17908
|
+
return _resultRange[index][0];
|
|
17906
17909
|
}
|
|
17907
17910
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
17908
|
-
return
|
|
17911
|
+
return _resultRange[0][index];
|
|
17909
17912
|
},
|
|
17910
17913
|
isExported: true,
|
|
17911
17914
|
};
|
|
@@ -17923,28 +17926,29 @@ const MATCH = {
|
|
|
17923
17926
|
returns: ["NUMBER"],
|
|
17924
17927
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
17925
17928
|
let _searchType = toNumber(searchType, this.locale);
|
|
17926
|
-
const
|
|
17927
|
-
const
|
|
17929
|
+
const _range = toMatrix(range);
|
|
17930
|
+
const nbCol = _range.length;
|
|
17931
|
+
const nbRow = _range[0].length;
|
|
17928
17932
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
17929
17933
|
let index = -1;
|
|
17930
17934
|
const getElement = nbCol === 1
|
|
17931
|
-
? (
|
|
17932
|
-
: (
|
|
17933
|
-
const rangeLen = nbCol === 1 ?
|
|
17935
|
+
? (_range, index) => _range[0][index].value
|
|
17936
|
+
: (_range, index) => _range[index][0].value;
|
|
17937
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
17934
17938
|
_searchType = Math.sign(_searchType);
|
|
17935
17939
|
switch (_searchType) {
|
|
17936
17940
|
case 1:
|
|
17937
|
-
index = dichotomicSearch(
|
|
17941
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
17938
17942
|
break;
|
|
17939
17943
|
case 0:
|
|
17940
|
-
index = linearSearch(
|
|
17944
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
17941
17945
|
break;
|
|
17942
17946
|
case -1:
|
|
17943
|
-
index = dichotomicSearch(
|
|
17947
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
17944
17948
|
break;
|
|
17945
17949
|
}
|
|
17946
|
-
if ((nbCol === 1 &&
|
|
17947
|
-
(nbCol !== 1 &&
|
|
17950
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
17951
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
17948
17952
|
return valueNotAvailable(searchKey);
|
|
17949
17953
|
}
|
|
17950
17954
|
return index + 1;
|
|
@@ -17995,16 +17999,17 @@ const VLOOKUP = {
|
|
|
17995
17999
|
returns: ["ANY"],
|
|
17996
18000
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
17997
18001
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
17998
|
-
|
|
18002
|
+
const _range = toMatrix(range);
|
|
18003
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
17999
18004
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18000
18005
|
return searchKey;
|
|
18001
18006
|
}
|
|
18002
18007
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18003
18008
|
const _isSorted = toBoolean(isSorted.value);
|
|
18004
18009
|
const rowIndex = _isSorted
|
|
18005
|
-
? dichotomicSearch(
|
|
18006
|
-
: linearSearch(
|
|
18007
|
-
const value =
|
|
18010
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18011
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18012
|
+
const value = _range[_index - 1][rowIndex];
|
|
18008
18013
|
if (value === undefined) {
|
|
18009
18014
|
return valueNotAvailable(searchKey);
|
|
18010
18015
|
}
|
|
@@ -18042,30 +18047,32 @@ const XLOOKUP = {
|
|
|
18042
18047
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18043
18048
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18044
18049
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18045
|
-
|
|
18050
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18051
|
+
const _returnRange = toMatrix(returnRange);
|
|
18052
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18046
18053
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18047
18054
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18048
|
-
const lookupDirection =
|
|
18055
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18049
18056
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18050
18057
|
assert(() => lookupDirection === "col"
|
|
18051
|
-
?
|
|
18052
|
-
:
|
|
18058
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18059
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18053
18060
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18054
18061
|
return [[searchKey]];
|
|
18055
18062
|
}
|
|
18056
18063
|
const getElement = lookupDirection === "col"
|
|
18057
18064
|
? (range, index) => range[0][index].value
|
|
18058
18065
|
: (range, index) => range[index][0].value;
|
|
18059
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18066
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18060
18067
|
const mode = MATCH_MODE[_matchMode];
|
|
18061
18068
|
const reverseSearch = _searchMode === -1;
|
|
18062
18069
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18063
|
-
? dichotomicSearch(
|
|
18064
|
-
: linearSearch(
|
|
18070
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18071
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18065
18072
|
if (index !== -1) {
|
|
18066
18073
|
return lookupDirection === "col"
|
|
18067
|
-
?
|
|
18068
|
-
: [
|
|
18074
|
+
? _returnRange.map((col) => [col[index]])
|
|
18075
|
+
: [_returnRange[index]];
|
|
18069
18076
|
}
|
|
18070
18077
|
if (defaultValue === undefined) {
|
|
18071
18078
|
return valueNotAvailable(searchKey);
|
|
@@ -34695,11 +34702,10 @@ class GridRenderer {
|
|
|
34695
34702
|
switch (layer) {
|
|
34696
34703
|
case "Background":
|
|
34697
34704
|
this.drawGlobalBackground(renderingContext);
|
|
34698
|
-
for (const zone of this.getters.
|
|
34705
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
34699
34706
|
const { ctx } = renderingContext;
|
|
34700
34707
|
ctx.save();
|
|
34701
34708
|
ctx.beginPath();
|
|
34702
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
34703
34709
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
34704
34710
|
ctx.clip();
|
|
34705
34711
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -34969,10 +34975,8 @@ class GridRenderer {
|
|
|
34969
34975
|
const { ctx, thinLineWidth } = renderingContext;
|
|
34970
34976
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
34971
34977
|
const left = visibleCols[0];
|
|
34972
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
34973
34978
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
34974
34979
|
const top = visibleRows[0];
|
|
34975
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
34976
34980
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
34977
34981
|
const selection = this.getters.getSelectedZones();
|
|
34978
34982
|
const selectedCols = getZonesCols(selection);
|
|
@@ -34988,7 +34992,7 @@ class GridRenderer {
|
|
|
34988
34992
|
ctx.lineWidth = thinLineWidth;
|
|
34989
34993
|
ctx.strokeStyle = "#333";
|
|
34990
34994
|
// Columns headers background
|
|
34991
|
-
for (
|
|
34995
|
+
for (const col of visibleCols) {
|
|
34992
34996
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
34993
34997
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
34994
34998
|
const isColActive = activeCols.has(col);
|
|
@@ -35005,7 +35009,7 @@ class GridRenderer {
|
|
|
35005
35009
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
35006
35010
|
}
|
|
35007
35011
|
// Rows headers background
|
|
35008
|
-
for (
|
|
35012
|
+
for (const row of visibleRows) {
|
|
35009
35013
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
35010
35014
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
35011
35015
|
const isRowActive = activeRows.has(row);
|
|
@@ -35031,21 +35035,21 @@ class GridRenderer {
|
|
|
35031
35035
|
ctx.stroke();
|
|
35032
35036
|
ctx.beginPath();
|
|
35033
35037
|
// column text + separator
|
|
35034
|
-
for (const
|
|
35035
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
35036
|
-
const colName = numberToLetters(
|
|
35037
|
-
ctx.fillStyle = activeCols.has(
|
|
35038
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
35038
|
+
for (const col of visibleCols) {
|
|
35039
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
35040
|
+
const colName = numberToLetters(col);
|
|
35041
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
35042
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
35039
35043
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
35040
35044
|
ctx.moveTo(colStart + colSize, 0);
|
|
35041
35045
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
35042
35046
|
}
|
|
35043
35047
|
// row text + separator
|
|
35044
|
-
for (const
|
|
35045
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
35046
|
-
ctx.fillStyle = activeRows.has(
|
|
35047
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
35048
|
-
ctx.fillText(String(
|
|
35048
|
+
for (const row of visibleRows) {
|
|
35049
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
35050
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
35051
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
35052
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
35049
35053
|
ctx.moveTo(0, rowStart + rowSize);
|
|
35050
35054
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
35051
35055
|
}
|
|
@@ -35337,6 +35341,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
35337
35341
|
canvas.width = width * dpr;
|
|
35338
35342
|
canvas.height = height * dpr;
|
|
35339
35343
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
35344
|
+
if (width === 0 || height === 0) {
|
|
35345
|
+
return;
|
|
35346
|
+
}
|
|
35340
35347
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
35341
35348
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
35342
35349
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -40894,7 +40901,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
40894
40901
|
getCommonSides(border1, border2) {
|
|
40895
40902
|
const commonBorder = {};
|
|
40896
40903
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
40897
|
-
if (border1[side] && border1[side]
|
|
40904
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
40898
40905
|
commonBorder[side] = border1[side];
|
|
40899
40906
|
}
|
|
40900
40907
|
}
|
|
@@ -51463,14 +51470,12 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
51463
51470
|
}
|
|
51464
51471
|
break;
|
|
51465
51472
|
case "AUTORESIZE_ROWS":
|
|
51466
|
-
|
|
51467
|
-
|
|
51468
|
-
|
|
51469
|
-
|
|
51470
|
-
|
|
51471
|
-
|
|
51472
|
-
});
|
|
51473
|
-
}
|
|
51473
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
51474
|
+
elements: cmd.rows,
|
|
51475
|
+
dimension: "ROW",
|
|
51476
|
+
size: null,
|
|
51477
|
+
sheetId: cmd.sheetId,
|
|
51478
|
+
});
|
|
51474
51479
|
break;
|
|
51475
51480
|
}
|
|
51476
51481
|
}
|
|
@@ -53807,8 +53812,17 @@ class InternalViewport {
|
|
|
53807
53812
|
this.getters = getters;
|
|
53808
53813
|
this.sheetId = sheetId;
|
|
53809
53814
|
this.boundaries = boundaries;
|
|
53810
|
-
|
|
53811
|
-
|
|
53815
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
53816
|
+
throw new Error("Viewport size cannot be negative");
|
|
53817
|
+
}
|
|
53818
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
53819
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
53820
|
+
this.top = boundaries.top;
|
|
53821
|
+
this.bottom = boundaries.bottom;
|
|
53822
|
+
this.left = boundaries.left;
|
|
53823
|
+
this.right = boundaries.right;
|
|
53824
|
+
this.offsetX = offsets.x;
|
|
53825
|
+
this.offsetY = offsets.y;
|
|
53812
53826
|
this.offsetScrollbarX = offsets.x;
|
|
53813
53827
|
this.offsetScrollbarY = offsets.y;
|
|
53814
53828
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -53851,9 +53865,9 @@ class InternalViewport {
|
|
|
53851
53865
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
53852
53866
|
);
|
|
53853
53867
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
53854
|
-
|
|
53855
|
-
|
|
53856
|
-
|
|
53868
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
53869
|
+
height += FOOTER_HEIGHT;
|
|
53870
|
+
}
|
|
53857
53871
|
}
|
|
53858
53872
|
return { width, height };
|
|
53859
53873
|
}
|
|
@@ -53990,6 +54004,9 @@ class InternalViewport {
|
|
|
53990
54004
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
53991
54005
|
}
|
|
53992
54006
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
54007
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
54008
|
+
return -1;
|
|
54009
|
+
}
|
|
53993
54010
|
const sheetId = this.sheetId;
|
|
53994
54011
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
53995
54012
|
// using a binary search:
|
|
@@ -54026,7 +54043,7 @@ class InternalViewport {
|
|
|
54026
54043
|
this.adjustViewportZoneY();
|
|
54027
54044
|
}
|
|
54028
54045
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
54029
|
-
* To make sure that at least
|
|
54046
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
54030
54047
|
*/
|
|
54031
54048
|
adjustViewportOffsetX() {
|
|
54032
54049
|
if (this.canScrollHorizontally) {
|
|
@@ -54038,7 +54055,7 @@ class InternalViewport {
|
|
|
54038
54055
|
this.adjustViewportZoneX();
|
|
54039
54056
|
}
|
|
54040
54057
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
54041
|
-
* To make sure that at least
|
|
54058
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
54042
54059
|
*/
|
|
54043
54060
|
adjustViewportOffsetY() {
|
|
54044
54061
|
if (this.canScrollVertically) {
|
|
@@ -54055,11 +54072,14 @@ class InternalViewport {
|
|
|
54055
54072
|
const sheetId = this.sheetId;
|
|
54056
54073
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
54057
54074
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
54075
|
+
if (!this.viewportWidth) {
|
|
54076
|
+
return;
|
|
54077
|
+
}
|
|
54058
54078
|
if (this.left === -1) {
|
|
54059
54079
|
this.left = this.boundaries.left;
|
|
54060
54080
|
}
|
|
54061
54081
|
if (this.right === -1) {
|
|
54062
|
-
this.right = this.
|
|
54082
|
+
this.right = this.boundaries.right;
|
|
54063
54083
|
}
|
|
54064
54084
|
this.offsetX =
|
|
54065
54085
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -54071,11 +54091,14 @@ class InternalViewport {
|
|
|
54071
54091
|
const sheetId = this.sheetId;
|
|
54072
54092
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
54073
54093
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
54094
|
+
if (!this.viewportHeight) {
|
|
54095
|
+
return;
|
|
54096
|
+
}
|
|
54074
54097
|
if (this.top === -1) {
|
|
54075
54098
|
this.top = this.boundaries.top;
|
|
54076
54099
|
}
|
|
54077
54100
|
if (this.bottom === -1) {
|
|
54078
|
-
this.bottom = this.
|
|
54101
|
+
this.bottom = this.boundaries.bottom;
|
|
54079
54102
|
}
|
|
54080
54103
|
this.offsetY =
|
|
54081
54104
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -54149,7 +54172,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54149
54172
|
"isPositionVisible",
|
|
54150
54173
|
"getColDimensionsInViewport",
|
|
54151
54174
|
"getRowDimensionsInViewport",
|
|
54152
|
-
"
|
|
54175
|
+
"getAllActiveViewportsZonesAndRect",
|
|
54153
54176
|
"getRect",
|
|
54154
54177
|
];
|
|
54155
54178
|
viewports = {};
|
|
@@ -54383,12 +54406,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54383
54406
|
const sheetId = this.getters.getActiveSheetId();
|
|
54384
54407
|
const viewports = this.getSubViewports(sheetId);
|
|
54385
54408
|
//TODO ake another commit to eimprove this
|
|
54386
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
54409
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
54387
54410
|
}
|
|
54388
54411
|
getSheetViewVisibleRows() {
|
|
54389
54412
|
const sheetId = this.getters.getActiveSheetId();
|
|
54390
54413
|
const viewports = this.getSubViewports(sheetId);
|
|
54391
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
54414
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
54392
54415
|
}
|
|
54393
54416
|
/**
|
|
54394
54417
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -54431,19 +54454,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54431
54454
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
54432
54455
|
};
|
|
54433
54456
|
}
|
|
54434
|
-
getColRowOffsetInViewport(dimension,
|
|
54435
|
-
|
|
54436
|
-
|
|
54437
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
54438
|
-
if (index < referenceIndex) {
|
|
54439
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
54457
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
54458
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
54459
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
54440
54460
|
}
|
|
54461
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
54462
|
+
const visibleHeaders = dimension === "COL"
|
|
54463
|
+
? this.getters.getSheetViewVisibleCols()
|
|
54464
|
+
: this.getters.getSheetViewVisibleRows();
|
|
54465
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
54466
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
54467
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
54441
54468
|
let offset = 0;
|
|
54442
|
-
const
|
|
54443
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
54444
|
-
if (!visibleIndexes.includes(i)) {
|
|
54445
|
-
continue;
|
|
54446
|
-
}
|
|
54469
|
+
for (const i of relevantIndexes) {
|
|
54447
54470
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
54448
54471
|
}
|
|
54449
54472
|
return offset;
|
|
@@ -54490,7 +54513,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54490
54513
|
}
|
|
54491
54514
|
return { canEdgeScroll, direction, delay };
|
|
54492
54515
|
}
|
|
54493
|
-
getEdgeScrollRow(y, previousY,
|
|
54516
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
54494
54517
|
let canEdgeScroll = false;
|
|
54495
54518
|
let direction = 0;
|
|
54496
54519
|
let delay = 0;
|
|
@@ -54511,7 +54534,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54511
54534
|
delay = scrollDelay(y - height);
|
|
54512
54535
|
direction = 1;
|
|
54513
54536
|
}
|
|
54514
|
-
else if (y < offsetCorrectionY &&
|
|
54537
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
54515
54538
|
// 2
|
|
54516
54539
|
canEdgeScroll = true;
|
|
54517
54540
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -54537,13 +54560,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54537
54560
|
*/
|
|
54538
54561
|
getVisibleRectWithoutHeaders(zone) {
|
|
54539
54562
|
const sheetId = this.getters.getActiveSheetId();
|
|
54540
|
-
|
|
54541
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
54542
|
-
.filter(isDefined$1);
|
|
54543
|
-
if (viewportRects.length === 0) {
|
|
54544
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54545
|
-
}
|
|
54546
|
-
return this.recomposeRect(viewportRects);
|
|
54563
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
54547
54564
|
}
|
|
54548
54565
|
/**
|
|
54549
54566
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -54551,13 +54568,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54551
54568
|
*/
|
|
54552
54569
|
getRect(zone) {
|
|
54553
54570
|
const sheetId = this.getters.getActiveSheetId();
|
|
54554
|
-
const
|
|
54555
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
54556
|
-
.filter(isDefined$1);
|
|
54557
|
-
if (viewportRects.length === 0) {
|
|
54558
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54559
|
-
}
|
|
54560
|
-
const rect = this.recomposeRect(viewportRects);
|
|
54571
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
54561
54572
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
54562
54573
|
}
|
|
54563
54574
|
/**
|
|
@@ -54602,9 +54613,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54602
54613
|
end: start + (isRowHidden ? 0 : size),
|
|
54603
54614
|
};
|
|
54604
54615
|
}
|
|
54605
|
-
|
|
54616
|
+
getAllActiveViewportsZonesAndRect() {
|
|
54606
54617
|
const sheetId = this.getters.getActiveSheetId();
|
|
54607
|
-
return this.getSubViewports(sheetId)
|
|
54618
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
54619
|
+
return {
|
|
54620
|
+
zone: viewport,
|
|
54621
|
+
rect: {
|
|
54622
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
54623
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
54624
|
+
...viewport.getMaxSize(),
|
|
54625
|
+
},
|
|
54626
|
+
};
|
|
54627
|
+
});
|
|
54608
54628
|
}
|
|
54609
54629
|
// ---------------------------------------------------------------------------
|
|
54610
54630
|
// Private
|
|
@@ -54657,12 +54677,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54657
54677
|
}
|
|
54658
54678
|
/** gets rid of deprecated sheetIds */
|
|
54659
54679
|
cleanViewports() {
|
|
54660
|
-
const
|
|
54661
|
-
for (
|
|
54662
|
-
|
|
54663
|
-
delete this.viewports[sheetId];
|
|
54664
|
-
}
|
|
54680
|
+
const newViewport = {};
|
|
54681
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
54682
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
54665
54683
|
}
|
|
54684
|
+
this.viewports = newViewport;
|
|
54666
54685
|
}
|
|
54667
54686
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
54668
54687
|
this.sheetViewHeight = height;
|
|
@@ -54672,14 +54691,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54672
54691
|
this.recomputeViewports();
|
|
54673
54692
|
}
|
|
54674
54693
|
recomputeViewports() {
|
|
54675
|
-
for (
|
|
54694
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
54676
54695
|
this.resetViewports(sheetId);
|
|
54677
54696
|
}
|
|
54678
54697
|
}
|
|
54679
54698
|
setSheetViewOffset(offsetX, offsetY) {
|
|
54680
54699
|
const sheetId = this.getters.getActiveSheetId();
|
|
54681
54700
|
const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
|
|
54682
|
-
|
|
54701
|
+
this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
|
|
54683
54702
|
}
|
|
54684
54703
|
getViewportOffset(sheetId) {
|
|
54685
54704
|
return {
|
|
@@ -54694,8 +54713,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54694
54713
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
54695
54714
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
54696
54715
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
54697
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
54698
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
54716
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
54717
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
54718
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
54719
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
54699
54720
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
54700
54721
|
const canScrollHorizontally = xRatio < 1.0;
|
|
54701
54722
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -54706,14 +54727,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54706
54727
|
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 })) ||
|
|
54707
54728
|
undefined,
|
|
54708
54729
|
topRight: (ySplit &&
|
|
54709
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
54730
|
+
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 })) ||
|
|
54710
54731
|
undefined,
|
|
54711
54732
|
bottomLeft: (xSplit &&
|
|
54712
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
54733
|
+
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 })) ||
|
|
54713
54734
|
undefined,
|
|
54714
54735
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
54715
|
-
width:
|
|
54716
|
-
height:
|
|
54736
|
+
width: unfrozenWidth,
|
|
54737
|
+
height: unfrozenHeight,
|
|
54717
54738
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
54718
54739
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
54719
54740
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -54725,7 +54746,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54725
54746
|
* Adjust the viewport such that the anchor position is visible
|
|
54726
54747
|
*/
|
|
54727
54748
|
refreshViewport(sheetId, anchorPosition) {
|
|
54728
|
-
|
|
54749
|
+
this.getSubViewports(sheetId).forEach((viewport) => {
|
|
54729
54750
|
viewport.adjustViewportZone();
|
|
54730
54751
|
viewport.adjustPosition(anchorPosition);
|
|
54731
54752
|
});
|
|
@@ -54790,12 +54811,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54790
54811
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
54791
54812
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
54792
54813
|
}
|
|
54793
|
-
|
|
54794
|
-
|
|
54795
|
-
|
|
54796
|
-
|
|
54797
|
-
|
|
54798
|
-
|
|
54814
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
54815
|
+
let x = Infinity;
|
|
54816
|
+
let y = Infinity;
|
|
54817
|
+
let width = 0;
|
|
54818
|
+
let height = 0;
|
|
54819
|
+
let hasViewports = false;
|
|
54820
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
54821
|
+
const rect = rectCallBack(viewport);
|
|
54822
|
+
if (rect) {
|
|
54823
|
+
hasViewports = true;
|
|
54824
|
+
x = Math.min(x, rect.x);
|
|
54825
|
+
y = Math.min(y, rect.y);
|
|
54826
|
+
width = Math.max(width, rect.x + rect.width);
|
|
54827
|
+
height = Math.max(height, rect.y + rect.height);
|
|
54828
|
+
}
|
|
54829
|
+
}
|
|
54830
|
+
if (!hasViewports) {
|
|
54831
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54832
|
+
}
|
|
54833
|
+
return { x, y, width: width - x, height: height - y };
|
|
54799
54834
|
}
|
|
54800
54835
|
}
|
|
54801
54836
|
|
|
@@ -61093,6 +61128,6 @@ const constants = {
|
|
|
61093
61128
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
61094
61129
|
|
|
61095
61130
|
|
|
61096
|
-
__info__.version = "17.2.
|
|
61097
|
-
__info__.date = "2025-
|
|
61098
|
-
__info__.hash = "
|
|
61131
|
+
__info__.version = "17.2.35";
|
|
61132
|
+
__info__.date = "2025-02-05T07:12:34.721Z";
|
|
61133
|
+
__info__.hash = "76b12a1";
|