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