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