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