@odoo/o-spreadsheet 17.2.34 → 17.2.36
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 +171 -127
- package/dist/o-spreadsheet.d.ts +11 -14
- package/dist/o-spreadsheet.esm.js +171 -127
- package/dist/o-spreadsheet.iife.js +171 -127
- 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.36
|
|
7
|
+
* @date 2025-02-10T08:59:25.719Z
|
|
8
|
+
* @hash 5a942bd
|
|
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';
|
|
@@ -604,9 +604,16 @@ function deepEquals(o1, o2) {
|
|
|
604
604
|
}
|
|
605
605
|
return true;
|
|
606
606
|
}
|
|
607
|
-
/**
|
|
607
|
+
/**
|
|
608
|
+
* Check if the given array contains all the values of the other array.
|
|
609
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
610
|
+
*/
|
|
608
611
|
function includesAll(arr, values) {
|
|
609
|
-
|
|
612
|
+
if (arr.length < values.length) {
|
|
613
|
+
return false;
|
|
614
|
+
}
|
|
615
|
+
const set = new Set(arr);
|
|
616
|
+
return values.every((value) => set.has(value));
|
|
610
617
|
}
|
|
611
618
|
/**
|
|
612
619
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -17751,23 +17758,24 @@ const HLOOKUP = {
|
|
|
17751
17758
|
description: _t("Horizontal lookup"),
|
|
17752
17759
|
args: [
|
|
17753
17760
|
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.")),
|
|
17761
|
+
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
17762
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
17756
17763
|
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
17764
|
],
|
|
17758
17765
|
returns: ["ANY"],
|
|
17759
17766
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
17760
17767
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
17761
|
-
|
|
17768
|
+
const _range = toMatrix(range);
|
|
17769
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
17762
17770
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
17763
17771
|
return searchKey;
|
|
17764
17772
|
}
|
|
17765
17773
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
17766
17774
|
const _isSorted = toBoolean(isSorted.value);
|
|
17767
17775
|
const colIndex = _isSorted
|
|
17768
|
-
? dichotomicSearch(
|
|
17769
|
-
: linearSearch(
|
|
17770
|
-
const col =
|
|
17776
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
17777
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
17778
|
+
const col = _range[colIndex];
|
|
17771
17779
|
if (col === undefined) {
|
|
17772
17780
|
return valueNotAvailable(searchKey);
|
|
17773
17781
|
}
|
|
@@ -17876,36 +17884,38 @@ const LOOKUP = {
|
|
|
17876
17884
|
description: _t("Look up a value."),
|
|
17877
17885
|
args: [
|
|
17878
17886
|
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.")),
|
|
17887
|
+
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.")),
|
|
17888
|
+
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
17889
|
],
|
|
17882
17890
|
returns: ["ANY"],
|
|
17883
17891
|
compute: function (searchKey, searchArray, resultRange) {
|
|
17884
|
-
|
|
17885
|
-
|
|
17892
|
+
const _searchArray = toMatrix(searchArray);
|
|
17893
|
+
const _resultRange = toMatrix(resultRange);
|
|
17894
|
+
let nbCol = _searchArray.length;
|
|
17895
|
+
let nbRow = _searchArray[0].length;
|
|
17886
17896
|
const verticalSearch = nbRow >= nbCol;
|
|
17887
17897
|
const getElement = verticalSearch
|
|
17888
17898
|
? (range, index) => range[0][index].value
|
|
17889
17899
|
: (range, index) => range[index][0].value;
|
|
17890
17900
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
17891
|
-
const index = dichotomicSearch(
|
|
17901
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
17892
17902
|
if (index === -1 ||
|
|
17893
|
-
(verticalSearch &&
|
|
17894
|
-
(!verticalSearch &&
|
|
17903
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
17904
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
17895
17905
|
return valueNotAvailable(searchKey);
|
|
17896
17906
|
}
|
|
17897
|
-
if (
|
|
17898
|
-
return verticalSearch ?
|
|
17907
|
+
if (_resultRange[0].length === 0) {
|
|
17908
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
17899
17909
|
}
|
|
17900
|
-
nbCol =
|
|
17901
|
-
nbRow =
|
|
17910
|
+
nbCol = _resultRange.length;
|
|
17911
|
+
nbRow = _resultRange[0].length;
|
|
17902
17912
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
17903
17913
|
if (nbCol > 1) {
|
|
17904
17914
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
17905
|
-
return
|
|
17915
|
+
return _resultRange[index][0];
|
|
17906
17916
|
}
|
|
17907
17917
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
17908
|
-
return
|
|
17918
|
+
return _resultRange[0][index];
|
|
17909
17919
|
},
|
|
17910
17920
|
isExported: true,
|
|
17911
17921
|
};
|
|
@@ -17923,28 +17933,29 @@ const MATCH = {
|
|
|
17923
17933
|
returns: ["NUMBER"],
|
|
17924
17934
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
17925
17935
|
let _searchType = toNumber(searchType, this.locale);
|
|
17926
|
-
const
|
|
17927
|
-
const
|
|
17936
|
+
const _range = toMatrix(range);
|
|
17937
|
+
const nbCol = _range.length;
|
|
17938
|
+
const nbRow = _range[0].length;
|
|
17928
17939
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
17929
17940
|
let index = -1;
|
|
17930
17941
|
const getElement = nbCol === 1
|
|
17931
|
-
? (
|
|
17932
|
-
: (
|
|
17933
|
-
const rangeLen = nbCol === 1 ?
|
|
17942
|
+
? (_range, index) => _range[0][index].value
|
|
17943
|
+
: (_range, index) => _range[index][0].value;
|
|
17944
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
17934
17945
|
_searchType = Math.sign(_searchType);
|
|
17935
17946
|
switch (_searchType) {
|
|
17936
17947
|
case 1:
|
|
17937
|
-
index = dichotomicSearch(
|
|
17948
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
17938
17949
|
break;
|
|
17939
17950
|
case 0:
|
|
17940
|
-
index = linearSearch(
|
|
17951
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
17941
17952
|
break;
|
|
17942
17953
|
case -1:
|
|
17943
|
-
index = dichotomicSearch(
|
|
17954
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
17944
17955
|
break;
|
|
17945
17956
|
}
|
|
17946
|
-
if ((nbCol === 1 &&
|
|
17947
|
-
(nbCol !== 1 &&
|
|
17957
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
17958
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
17948
17959
|
return valueNotAvailable(searchKey);
|
|
17949
17960
|
}
|
|
17950
17961
|
return index + 1;
|
|
@@ -17995,16 +18006,17 @@ const VLOOKUP = {
|
|
|
17995
18006
|
returns: ["ANY"],
|
|
17996
18007
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
17997
18008
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
17998
|
-
|
|
18009
|
+
const _range = toMatrix(range);
|
|
18010
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
17999
18011
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18000
18012
|
return searchKey;
|
|
18001
18013
|
}
|
|
18002
18014
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18003
18015
|
const _isSorted = toBoolean(isSorted.value);
|
|
18004
18016
|
const rowIndex = _isSorted
|
|
18005
|
-
? dichotomicSearch(
|
|
18006
|
-
: linearSearch(
|
|
18007
|
-
const value =
|
|
18017
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18018
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18019
|
+
const value = _range[_index - 1][rowIndex];
|
|
18008
18020
|
if (value === undefined) {
|
|
18009
18021
|
return valueNotAvailable(searchKey);
|
|
18010
18022
|
}
|
|
@@ -18042,30 +18054,32 @@ const XLOOKUP = {
|
|
|
18042
18054
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18043
18055
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18044
18056
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18045
|
-
|
|
18057
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18058
|
+
const _returnRange = toMatrix(returnRange);
|
|
18059
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18046
18060
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18047
18061
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18048
|
-
const lookupDirection =
|
|
18062
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18049
18063
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18050
18064
|
assert(() => lookupDirection === "col"
|
|
18051
|
-
?
|
|
18052
|
-
:
|
|
18065
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18066
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18053
18067
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18054
18068
|
return [[searchKey]];
|
|
18055
18069
|
}
|
|
18056
18070
|
const getElement = lookupDirection === "col"
|
|
18057
18071
|
? (range, index) => range[0][index].value
|
|
18058
18072
|
: (range, index) => range[index][0].value;
|
|
18059
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18073
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18060
18074
|
const mode = MATCH_MODE[_matchMode];
|
|
18061
18075
|
const reverseSearch = _searchMode === -1;
|
|
18062
18076
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18063
|
-
? dichotomicSearch(
|
|
18064
|
-
: linearSearch(
|
|
18077
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18078
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18065
18079
|
if (index !== -1) {
|
|
18066
18080
|
return lookupDirection === "col"
|
|
18067
|
-
?
|
|
18068
|
-
: [
|
|
18081
|
+
? _returnRange.map((col) => [col[index]])
|
|
18082
|
+
: [_returnRange[index]];
|
|
18069
18083
|
}
|
|
18070
18084
|
if (defaultValue === undefined) {
|
|
18071
18085
|
return valueNotAvailable(searchKey);
|
|
@@ -34695,11 +34709,10 @@ class GridRenderer {
|
|
|
34695
34709
|
switch (layer) {
|
|
34696
34710
|
case "Background":
|
|
34697
34711
|
this.drawGlobalBackground(renderingContext);
|
|
34698
|
-
for (const zone of this.getters.
|
|
34712
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
34699
34713
|
const { ctx } = renderingContext;
|
|
34700
34714
|
ctx.save();
|
|
34701
34715
|
ctx.beginPath();
|
|
34702
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
34703
34716
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
34704
34717
|
ctx.clip();
|
|
34705
34718
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -34969,10 +34982,8 @@ class GridRenderer {
|
|
|
34969
34982
|
const { ctx, thinLineWidth } = renderingContext;
|
|
34970
34983
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
34971
34984
|
const left = visibleCols[0];
|
|
34972
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
34973
34985
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
34974
34986
|
const top = visibleRows[0];
|
|
34975
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
34976
34987
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
34977
34988
|
const selection = this.getters.getSelectedZones();
|
|
34978
34989
|
const selectedCols = getZonesCols(selection);
|
|
@@ -34988,7 +34999,7 @@ class GridRenderer {
|
|
|
34988
34999
|
ctx.lineWidth = thinLineWidth;
|
|
34989
35000
|
ctx.strokeStyle = "#333";
|
|
34990
35001
|
// Columns headers background
|
|
34991
|
-
for (
|
|
35002
|
+
for (const col of visibleCols) {
|
|
34992
35003
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
34993
35004
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
34994
35005
|
const isColActive = activeCols.has(col);
|
|
@@ -35005,7 +35016,7 @@ class GridRenderer {
|
|
|
35005
35016
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
35006
35017
|
}
|
|
35007
35018
|
// Rows headers background
|
|
35008
|
-
for (
|
|
35019
|
+
for (const row of visibleRows) {
|
|
35009
35020
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
35010
35021
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
35011
35022
|
const isRowActive = activeRows.has(row);
|
|
@@ -35031,21 +35042,21 @@ class GridRenderer {
|
|
|
35031
35042
|
ctx.stroke();
|
|
35032
35043
|
ctx.beginPath();
|
|
35033
35044
|
// 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,
|
|
35045
|
+
for (const col of visibleCols) {
|
|
35046
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
35047
|
+
const colName = numberToLetters(col);
|
|
35048
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
35049
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
35039
35050
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
35040
35051
|
ctx.moveTo(colStart + colSize, 0);
|
|
35041
35052
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
35042
35053
|
}
|
|
35043
35054
|
// 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(
|
|
35055
|
+
for (const row of visibleRows) {
|
|
35056
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
35057
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
35058
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
35059
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
35049
35060
|
ctx.moveTo(0, rowStart + rowSize);
|
|
35050
35061
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
35051
35062
|
}
|
|
@@ -35337,6 +35348,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
35337
35348
|
canvas.width = width * dpr;
|
|
35338
35349
|
canvas.height = height * dpr;
|
|
35339
35350
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
35351
|
+
if (width === 0 || height === 0) {
|
|
35352
|
+
return;
|
|
35353
|
+
}
|
|
35340
35354
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
35341
35355
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
35342
35356
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -40894,7 +40908,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
40894
40908
|
getCommonSides(border1, border2) {
|
|
40895
40909
|
const commonBorder = {};
|
|
40896
40910
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
40897
|
-
if (border1[side] && border1[side]
|
|
40911
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
40898
40912
|
commonBorder[side] = border1[side];
|
|
40899
40913
|
}
|
|
40900
40914
|
}
|
|
@@ -53805,8 +53819,17 @@ class InternalViewport {
|
|
|
53805
53819
|
this.getters = getters;
|
|
53806
53820
|
this.sheetId = sheetId;
|
|
53807
53821
|
this.boundaries = boundaries;
|
|
53808
|
-
|
|
53809
|
-
|
|
53822
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
53823
|
+
throw new Error("Viewport size cannot be negative");
|
|
53824
|
+
}
|
|
53825
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
53826
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
53827
|
+
this.top = boundaries.top;
|
|
53828
|
+
this.bottom = boundaries.bottom;
|
|
53829
|
+
this.left = boundaries.left;
|
|
53830
|
+
this.right = boundaries.right;
|
|
53831
|
+
this.offsetX = offsets.x;
|
|
53832
|
+
this.offsetY = offsets.y;
|
|
53810
53833
|
this.offsetScrollbarX = offsets.x;
|
|
53811
53834
|
this.offsetScrollbarY = offsets.y;
|
|
53812
53835
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -53849,9 +53872,9 @@ class InternalViewport {
|
|
|
53849
53872
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
53850
53873
|
);
|
|
53851
53874
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
53852
|
-
|
|
53853
|
-
|
|
53854
|
-
|
|
53875
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
53876
|
+
height += FOOTER_HEIGHT;
|
|
53877
|
+
}
|
|
53855
53878
|
}
|
|
53856
53879
|
return { width, height };
|
|
53857
53880
|
}
|
|
@@ -53988,6 +54011,9 @@ class InternalViewport {
|
|
|
53988
54011
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
53989
54012
|
}
|
|
53990
54013
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
54014
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
54015
|
+
return -1;
|
|
54016
|
+
}
|
|
53991
54017
|
const sheetId = this.sheetId;
|
|
53992
54018
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
53993
54019
|
// using a binary search:
|
|
@@ -54024,7 +54050,7 @@ class InternalViewport {
|
|
|
54024
54050
|
this.adjustViewportZoneY();
|
|
54025
54051
|
}
|
|
54026
54052
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
54027
|
-
* To make sure that at least
|
|
54053
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
54028
54054
|
*/
|
|
54029
54055
|
adjustViewportOffsetX() {
|
|
54030
54056
|
if (this.canScrollHorizontally) {
|
|
@@ -54036,7 +54062,7 @@ class InternalViewport {
|
|
|
54036
54062
|
this.adjustViewportZoneX();
|
|
54037
54063
|
}
|
|
54038
54064
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
54039
|
-
* To make sure that at least
|
|
54065
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
54040
54066
|
*/
|
|
54041
54067
|
adjustViewportOffsetY() {
|
|
54042
54068
|
if (this.canScrollVertically) {
|
|
@@ -54053,11 +54079,14 @@ class InternalViewport {
|
|
|
54053
54079
|
const sheetId = this.sheetId;
|
|
54054
54080
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
54055
54081
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
54082
|
+
if (!this.viewportWidth) {
|
|
54083
|
+
return;
|
|
54084
|
+
}
|
|
54056
54085
|
if (this.left === -1) {
|
|
54057
54086
|
this.left = this.boundaries.left;
|
|
54058
54087
|
}
|
|
54059
54088
|
if (this.right === -1) {
|
|
54060
|
-
this.right = this.
|
|
54089
|
+
this.right = this.boundaries.right;
|
|
54061
54090
|
}
|
|
54062
54091
|
this.offsetX =
|
|
54063
54092
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -54069,11 +54098,14 @@ class InternalViewport {
|
|
|
54069
54098
|
const sheetId = this.sheetId;
|
|
54070
54099
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
54071
54100
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
54101
|
+
if (!this.viewportHeight) {
|
|
54102
|
+
return;
|
|
54103
|
+
}
|
|
54072
54104
|
if (this.top === -1) {
|
|
54073
54105
|
this.top = this.boundaries.top;
|
|
54074
54106
|
}
|
|
54075
54107
|
if (this.bottom === -1) {
|
|
54076
|
-
this.bottom = this.
|
|
54108
|
+
this.bottom = this.boundaries.bottom;
|
|
54077
54109
|
}
|
|
54078
54110
|
this.offsetY =
|
|
54079
54111
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -54147,7 +54179,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54147
54179
|
"isPositionVisible",
|
|
54148
54180
|
"getColDimensionsInViewport",
|
|
54149
54181
|
"getRowDimensionsInViewport",
|
|
54150
|
-
"
|
|
54182
|
+
"getAllActiveViewportsZonesAndRect",
|
|
54151
54183
|
"getRect",
|
|
54152
54184
|
];
|
|
54153
54185
|
viewports = {};
|
|
@@ -54381,12 +54413,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54381
54413
|
const sheetId = this.getters.getActiveSheetId();
|
|
54382
54414
|
const viewports = this.getSubViewports(sheetId);
|
|
54383
54415
|
//TODO ake another commit to eimprove this
|
|
54384
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
54416
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
54385
54417
|
}
|
|
54386
54418
|
getSheetViewVisibleRows() {
|
|
54387
54419
|
const sheetId = this.getters.getActiveSheetId();
|
|
54388
54420
|
const viewports = this.getSubViewports(sheetId);
|
|
54389
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
54421
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
54390
54422
|
}
|
|
54391
54423
|
/**
|
|
54392
54424
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -54429,19 +54461,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54429
54461
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
54430
54462
|
};
|
|
54431
54463
|
}
|
|
54432
|
-
getColRowOffsetInViewport(dimension,
|
|
54433
|
-
|
|
54434
|
-
|
|
54435
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
54436
|
-
if (index < referenceIndex) {
|
|
54437
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
54464
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
54465
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
54466
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
54438
54467
|
}
|
|
54468
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
54469
|
+
const visibleHeaders = dimension === "COL"
|
|
54470
|
+
? this.getters.getSheetViewVisibleCols()
|
|
54471
|
+
: this.getters.getSheetViewVisibleRows();
|
|
54472
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
54473
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
54474
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
54439
54475
|
let offset = 0;
|
|
54440
|
-
const
|
|
54441
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
54442
|
-
if (!visibleIndexes.includes(i)) {
|
|
54443
|
-
continue;
|
|
54444
|
-
}
|
|
54476
|
+
for (const i of relevantIndexes) {
|
|
54445
54477
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
54446
54478
|
}
|
|
54447
54479
|
return offset;
|
|
@@ -54488,7 +54520,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54488
54520
|
}
|
|
54489
54521
|
return { canEdgeScroll, direction, delay };
|
|
54490
54522
|
}
|
|
54491
|
-
getEdgeScrollRow(y, previousY,
|
|
54523
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
54492
54524
|
let canEdgeScroll = false;
|
|
54493
54525
|
let direction = 0;
|
|
54494
54526
|
let delay = 0;
|
|
@@ -54509,7 +54541,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54509
54541
|
delay = scrollDelay(y - height);
|
|
54510
54542
|
direction = 1;
|
|
54511
54543
|
}
|
|
54512
|
-
else if (y < offsetCorrectionY &&
|
|
54544
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
54513
54545
|
// 2
|
|
54514
54546
|
canEdgeScroll = true;
|
|
54515
54547
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -54535,13 +54567,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54535
54567
|
*/
|
|
54536
54568
|
getVisibleRectWithoutHeaders(zone) {
|
|
54537
54569
|
const sheetId = this.getters.getActiveSheetId();
|
|
54538
|
-
|
|
54539
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
54540
|
-
.filter(isDefined$1);
|
|
54541
|
-
if (viewportRects.length === 0) {
|
|
54542
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54543
|
-
}
|
|
54544
|
-
return this.recomposeRect(viewportRects);
|
|
54570
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
54545
54571
|
}
|
|
54546
54572
|
/**
|
|
54547
54573
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -54549,13 +54575,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54549
54575
|
*/
|
|
54550
54576
|
getRect(zone) {
|
|
54551
54577
|
const sheetId = this.getters.getActiveSheetId();
|
|
54552
|
-
const
|
|
54553
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
54554
|
-
.filter(isDefined$1);
|
|
54555
|
-
if (viewportRects.length === 0) {
|
|
54556
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54557
|
-
}
|
|
54558
|
-
const rect = this.recomposeRect(viewportRects);
|
|
54578
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
54559
54579
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
54560
54580
|
}
|
|
54561
54581
|
/**
|
|
@@ -54600,9 +54620,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54600
54620
|
end: start + (isRowHidden ? 0 : size),
|
|
54601
54621
|
};
|
|
54602
54622
|
}
|
|
54603
|
-
|
|
54623
|
+
getAllActiveViewportsZonesAndRect() {
|
|
54604
54624
|
const sheetId = this.getters.getActiveSheetId();
|
|
54605
|
-
return this.getSubViewports(sheetId)
|
|
54625
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
54626
|
+
return {
|
|
54627
|
+
zone: viewport,
|
|
54628
|
+
rect: {
|
|
54629
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
54630
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
54631
|
+
...viewport.getMaxSize(),
|
|
54632
|
+
},
|
|
54633
|
+
};
|
|
54634
|
+
});
|
|
54606
54635
|
}
|
|
54607
54636
|
// ---------------------------------------------------------------------------
|
|
54608
54637
|
// Private
|
|
@@ -54655,12 +54684,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54655
54684
|
}
|
|
54656
54685
|
/** gets rid of deprecated sheetIds */
|
|
54657
54686
|
cleanViewports() {
|
|
54658
|
-
const
|
|
54659
|
-
for (
|
|
54660
|
-
|
|
54661
|
-
delete this.viewports[sheetId];
|
|
54662
|
-
}
|
|
54687
|
+
const newViewport = {};
|
|
54688
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
54689
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
54663
54690
|
}
|
|
54691
|
+
this.viewports = newViewport;
|
|
54664
54692
|
}
|
|
54665
54693
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
54666
54694
|
this.sheetViewHeight = height;
|
|
@@ -54670,14 +54698,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54670
54698
|
this.recomputeViewports();
|
|
54671
54699
|
}
|
|
54672
54700
|
recomputeViewports() {
|
|
54673
|
-
for (
|
|
54701
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
54674
54702
|
this.resetViewports(sheetId);
|
|
54675
54703
|
}
|
|
54676
54704
|
}
|
|
54677
54705
|
setSheetViewOffset(offsetX, offsetY) {
|
|
54678
54706
|
const sheetId = this.getters.getActiveSheetId();
|
|
54679
54707
|
const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
|
|
54680
|
-
|
|
54708
|
+
this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
|
|
54681
54709
|
}
|
|
54682
54710
|
getViewportOffset(sheetId) {
|
|
54683
54711
|
return {
|
|
@@ -54692,8 +54720,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54692
54720
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
54693
54721
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
54694
54722
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
54695
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
54696
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
54723
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
54724
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
54725
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
54726
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
54697
54727
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
54698
54728
|
const canScrollHorizontally = xRatio < 1.0;
|
|
54699
54729
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -54704,14 +54734,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54704
54734
|
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 })) ||
|
|
54705
54735
|
undefined,
|
|
54706
54736
|
topRight: (ySplit &&
|
|
54707
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
54737
|
+
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 })) ||
|
|
54708
54738
|
undefined,
|
|
54709
54739
|
bottomLeft: (xSplit &&
|
|
54710
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
54740
|
+
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 })) ||
|
|
54711
54741
|
undefined,
|
|
54712
54742
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
54713
|
-
width:
|
|
54714
|
-
height:
|
|
54743
|
+
width: unfrozenWidth,
|
|
54744
|
+
height: unfrozenHeight,
|
|
54715
54745
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
54716
54746
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
54717
54747
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -54723,7 +54753,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54723
54753
|
* Adjust the viewport such that the anchor position is visible
|
|
54724
54754
|
*/
|
|
54725
54755
|
refreshViewport(sheetId, anchorPosition) {
|
|
54726
|
-
|
|
54756
|
+
this.getSubViewports(sheetId).forEach((viewport) => {
|
|
54727
54757
|
viewport.adjustViewportZone();
|
|
54728
54758
|
viewport.adjustPosition(anchorPosition);
|
|
54729
54759
|
});
|
|
@@ -54788,12 +54818,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
54788
54818
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
54789
54819
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
54790
54820
|
}
|
|
54791
|
-
|
|
54792
|
-
|
|
54793
|
-
|
|
54794
|
-
|
|
54795
|
-
|
|
54796
|
-
|
|
54821
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
54822
|
+
let x = Infinity;
|
|
54823
|
+
let y = Infinity;
|
|
54824
|
+
let width = 0;
|
|
54825
|
+
let height = 0;
|
|
54826
|
+
let hasViewports = false;
|
|
54827
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
54828
|
+
const rect = rectCallBack(viewport);
|
|
54829
|
+
if (rect) {
|
|
54830
|
+
hasViewports = true;
|
|
54831
|
+
x = Math.min(x, rect.x);
|
|
54832
|
+
y = Math.min(y, rect.y);
|
|
54833
|
+
width = Math.max(width, rect.x + rect.width);
|
|
54834
|
+
height = Math.max(height, rect.y + rect.height);
|
|
54835
|
+
}
|
|
54836
|
+
}
|
|
54837
|
+
if (!hasViewports) {
|
|
54838
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
54839
|
+
}
|
|
54840
|
+
return { x, y, width: width - x, height: height - y };
|
|
54797
54841
|
}
|
|
54798
54842
|
}
|
|
54799
54843
|
|
|
@@ -61091,6 +61135,6 @@ const constants = {
|
|
|
61091
61135
|
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 };
|
|
61092
61136
|
|
|
61093
61137
|
|
|
61094
|
-
__info__.version = "17.2.
|
|
61095
|
-
__info__.date = "2025-
|
|
61096
|
-
__info__.hash = "
|
|
61138
|
+
__info__.version = "17.2.36";
|
|
61139
|
+
__info__.date = "2025-02-10T08:59:25.719Z";
|
|
61140
|
+
__info__.hash = "5a942bd";
|