@odoo/o-spreadsheet 18.0.13 → 18.0.14
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 +160 -123
- package/dist/o-spreadsheet.d.ts +11 -14
- package/dist/o-spreadsheet.esm.js +160 -123
- package/dist/o-spreadsheet.iife.js +160 -123
- package/dist/o-spreadsheet.iife.min.js +4 -4
- 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 18.0.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.14
|
|
6
|
+
* @date 2025-02-05T06:47:33.041Z
|
|
7
|
+
* @hash 90f2af4
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -18382,19 +18382,20 @@ const HLOOKUP = {
|
|
|
18382
18382
|
description: _t("Horizontal lookup"),
|
|
18383
18383
|
args: [
|
|
18384
18384
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18385
|
-
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.")),
|
|
18385
|
+
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.")),
|
|
18386
18386
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18387
18387
|
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.")),
|
|
18388
18388
|
],
|
|
18389
18389
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18390
18390
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18391
|
-
|
|
18391
|
+
const _range = toMatrix(range);
|
|
18392
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18392
18393
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18393
18394
|
const _isSorted = toBoolean(isSorted.value);
|
|
18394
18395
|
const colIndex = _isSorted
|
|
18395
|
-
? dichotomicSearch(
|
|
18396
|
-
: linearSearch(range, searchKey, "wildcard",
|
|
18397
|
-
const col =
|
|
18396
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18397
|
+
: linearSearch(range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
|
|
18398
|
+
const col = _range[colIndex];
|
|
18398
18399
|
if (col === undefined) {
|
|
18399
18400
|
return valueNotAvailable(searchKey);
|
|
18400
18401
|
}
|
|
@@ -18486,35 +18487,37 @@ const LOOKUP = {
|
|
|
18486
18487
|
description: _t("Look up a value."),
|
|
18487
18488
|
args: [
|
|
18488
18489
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18489
|
-
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.")),
|
|
18490
|
-
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.")),
|
|
18490
|
+
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.")),
|
|
18491
|
+
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.")),
|
|
18491
18492
|
],
|
|
18492
18493
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18493
|
-
|
|
18494
|
-
|
|
18494
|
+
const _searchArray = toMatrix(searchArray);
|
|
18495
|
+
const _resultRange = toMatrix(resultRange);
|
|
18496
|
+
let nbCol = _searchArray.length;
|
|
18497
|
+
let nbRow = _searchArray[0].length;
|
|
18495
18498
|
const verticalSearch = nbRow >= nbCol;
|
|
18496
18499
|
const getElement = verticalSearch
|
|
18497
18500
|
? (range, index) => range[0][index].value
|
|
18498
18501
|
: (range, index) => range[index][0].value;
|
|
18499
18502
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18500
|
-
const index = dichotomicSearch(
|
|
18503
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18501
18504
|
if (index === -1 ||
|
|
18502
|
-
(verticalSearch &&
|
|
18503
|
-
(!verticalSearch &&
|
|
18505
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18506
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18504
18507
|
return valueNotAvailable(searchKey);
|
|
18505
18508
|
}
|
|
18506
|
-
if (
|
|
18507
|
-
return verticalSearch ?
|
|
18509
|
+
if (_resultRange[0].length === 0) {
|
|
18510
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18508
18511
|
}
|
|
18509
|
-
nbCol =
|
|
18510
|
-
nbRow =
|
|
18512
|
+
nbCol = _resultRange.length;
|
|
18513
|
+
nbRow = _resultRange[0].length;
|
|
18511
18514
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18512
18515
|
if (nbCol > 1) {
|
|
18513
18516
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18514
|
-
return
|
|
18517
|
+
return _resultRange[index][0];
|
|
18515
18518
|
}
|
|
18516
18519
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18517
|
-
return
|
|
18520
|
+
return _resultRange[0][index];
|
|
18518
18521
|
},
|
|
18519
18522
|
isExported: true,
|
|
18520
18523
|
};
|
|
@@ -18531,28 +18534,29 @@ const MATCH = {
|
|
|
18531
18534
|
],
|
|
18532
18535
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18533
18536
|
let _searchType = toNumber(searchType, this.locale);
|
|
18534
|
-
const
|
|
18535
|
-
const
|
|
18537
|
+
const _range = toMatrix(range);
|
|
18538
|
+
const nbCol = _range.length;
|
|
18539
|
+
const nbRow = _range[0].length;
|
|
18536
18540
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18537
18541
|
let index = -1;
|
|
18538
18542
|
const getElement = nbCol === 1
|
|
18539
|
-
? (
|
|
18540
|
-
: (
|
|
18541
|
-
const rangeLen = nbCol === 1 ?
|
|
18543
|
+
? (_range, index) => _range[0][index].value
|
|
18544
|
+
: (_range, index) => _range[index][0].value;
|
|
18545
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18542
18546
|
_searchType = Math.sign(_searchType);
|
|
18543
18547
|
switch (_searchType) {
|
|
18544
18548
|
case 1:
|
|
18545
|
-
index = dichotomicSearch(
|
|
18549
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18546
18550
|
break;
|
|
18547
18551
|
case 0:
|
|
18548
|
-
index = linearSearch(
|
|
18552
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
|
|
18549
18553
|
break;
|
|
18550
18554
|
case -1:
|
|
18551
|
-
index = dichotomicSearch(
|
|
18555
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18552
18556
|
break;
|
|
18553
18557
|
}
|
|
18554
|
-
if ((nbCol === 1 &&
|
|
18555
|
-
(nbCol !== 1 &&
|
|
18558
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18559
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18556
18560
|
return valueNotAvailable(searchKey);
|
|
18557
18561
|
}
|
|
18558
18562
|
return index + 1;
|
|
@@ -18607,13 +18611,14 @@ const VLOOKUP = {
|
|
|
18607
18611
|
],
|
|
18608
18612
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18609
18613
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18610
|
-
|
|
18614
|
+
const _range = toMatrix(range);
|
|
18615
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18611
18616
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18612
18617
|
const _isSorted = toBoolean(isSorted.value);
|
|
18613
18618
|
const rowIndex = _isSorted
|
|
18614
|
-
? dichotomicSearch(
|
|
18615
|
-
: linearSearch(
|
|
18616
|
-
const value =
|
|
18619
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18620
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
|
|
18621
|
+
const value = _range[_index - 1][rowIndex];
|
|
18617
18622
|
if (value === undefined) {
|
|
18618
18623
|
return valueNotAvailable(searchKey);
|
|
18619
18624
|
}
|
|
@@ -18650,27 +18655,29 @@ const XLOOKUP = {
|
|
|
18650
18655
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18651
18656
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18652
18657
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18653
|
-
|
|
18658
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18659
|
+
const _returnRange = toMatrix(returnRange);
|
|
18660
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18654
18661
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18655
18662
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18656
|
-
const lookupDirection =
|
|
18663
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18657
18664
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18658
18665
|
assert(() => lookupDirection === "col"
|
|
18659
|
-
?
|
|
18660
|
-
:
|
|
18666
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18667
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18661
18668
|
const getElement = lookupDirection === "col"
|
|
18662
18669
|
? (range, index) => range[0][index].value
|
|
18663
18670
|
: (range, index) => range[index][0].value;
|
|
18664
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18671
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18665
18672
|
const mode = MATCH_MODE[_matchMode];
|
|
18666
18673
|
const reverseSearch = _searchMode === -1;
|
|
18667
18674
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18668
|
-
? dichotomicSearch(
|
|
18669
|
-
: linearSearch(
|
|
18675
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18676
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
|
|
18670
18677
|
if (index !== -1) {
|
|
18671
18678
|
return lookupDirection === "col"
|
|
18672
|
-
?
|
|
18673
|
-
: [
|
|
18679
|
+
? _returnRange.map((col) => [col[index]])
|
|
18680
|
+
: [_returnRange[index]];
|
|
18674
18681
|
}
|
|
18675
18682
|
if (defaultValue === undefined) {
|
|
18676
18683
|
return valueNotAvailable(searchKey);
|
|
@@ -48476,11 +48483,10 @@ class GridRenderer {
|
|
|
48476
48483
|
switch (layer) {
|
|
48477
48484
|
case "Background":
|
|
48478
48485
|
this.drawGlobalBackground(renderingContext);
|
|
48479
|
-
for (const zone of this.getters.
|
|
48486
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
48480
48487
|
const { ctx } = renderingContext;
|
|
48481
48488
|
ctx.save();
|
|
48482
48489
|
ctx.beginPath();
|
|
48483
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
48484
48490
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
48485
48491
|
ctx.clip();
|
|
48486
48492
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -48756,10 +48762,8 @@ class GridRenderer {
|
|
|
48756
48762
|
const { ctx, thinLineWidth } = renderingContext;
|
|
48757
48763
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
48758
48764
|
const left = visibleCols[0];
|
|
48759
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
48760
48765
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
48761
48766
|
const top = visibleRows[0];
|
|
48762
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
48763
48767
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
48764
48768
|
const selection = this.getters.getSelectedZones();
|
|
48765
48769
|
const selectedCols = getZonesCols(selection);
|
|
@@ -48775,7 +48779,7 @@ class GridRenderer {
|
|
|
48775
48779
|
ctx.lineWidth = thinLineWidth;
|
|
48776
48780
|
ctx.strokeStyle = "#333";
|
|
48777
48781
|
// Columns headers background
|
|
48778
|
-
for (
|
|
48782
|
+
for (const col of visibleCols) {
|
|
48779
48783
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
48780
48784
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
48781
48785
|
const isColActive = activeCols.has(col);
|
|
@@ -48792,7 +48796,7 @@ class GridRenderer {
|
|
|
48792
48796
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
48793
48797
|
}
|
|
48794
48798
|
// Rows headers background
|
|
48795
|
-
for (
|
|
48799
|
+
for (const row of visibleRows) {
|
|
48796
48800
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
48797
48801
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
48798
48802
|
const isRowActive = activeRows.has(row);
|
|
@@ -48818,21 +48822,21 @@ class GridRenderer {
|
|
|
48818
48822
|
ctx.stroke();
|
|
48819
48823
|
ctx.beginPath();
|
|
48820
48824
|
// column text + separator
|
|
48821
|
-
for (const
|
|
48822
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
48823
|
-
const colName = numberToLetters(
|
|
48824
|
-
ctx.fillStyle = activeCols.has(
|
|
48825
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
48825
|
+
for (const col of visibleCols) {
|
|
48826
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
48827
|
+
const colName = numberToLetters(col);
|
|
48828
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
48829
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
48826
48830
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
48827
48831
|
ctx.moveTo(colStart + colSize, 0);
|
|
48828
48832
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
48829
48833
|
}
|
|
48830
48834
|
// row text + separator
|
|
48831
|
-
for (const
|
|
48832
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
48833
|
-
ctx.fillStyle = activeRows.has(
|
|
48834
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
48835
|
-
ctx.fillText(String(
|
|
48835
|
+
for (const row of visibleRows) {
|
|
48836
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
48837
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
48838
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
48839
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
48836
48840
|
ctx.moveTo(0, rowStart + rowSize);
|
|
48837
48841
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
48838
48842
|
}
|
|
@@ -49132,6 +49136,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
49132
49136
|
canvas.width = width * dpr;
|
|
49133
49137
|
canvas.height = height * dpr;
|
|
49134
49138
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
49139
|
+
if (width === 0 || height === 0) {
|
|
49140
|
+
return;
|
|
49141
|
+
}
|
|
49135
49142
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
49136
49143
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
49137
49144
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -50703,7 +50710,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
50703
50710
|
getCommonSides(border1, border2) {
|
|
50704
50711
|
const commonBorder = {};
|
|
50705
50712
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
50706
|
-
if (border1[side] && border1[side]
|
|
50713
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
50707
50714
|
commonBorder[side] = border1[side];
|
|
50708
50715
|
}
|
|
50709
50716
|
}
|
|
@@ -64973,8 +64980,17 @@ class InternalViewport {
|
|
|
64973
64980
|
this.getters = getters;
|
|
64974
64981
|
this.sheetId = sheetId;
|
|
64975
64982
|
this.boundaries = boundaries;
|
|
64976
|
-
|
|
64977
|
-
|
|
64983
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
64984
|
+
throw new Error("Viewport size cannot be negative");
|
|
64985
|
+
}
|
|
64986
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
64987
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
64988
|
+
this.top = boundaries.top;
|
|
64989
|
+
this.bottom = boundaries.bottom;
|
|
64990
|
+
this.left = boundaries.left;
|
|
64991
|
+
this.right = boundaries.right;
|
|
64992
|
+
this.offsetX = offsets.x;
|
|
64993
|
+
this.offsetY = offsets.y;
|
|
64978
64994
|
this.offsetScrollbarX = offsets.x;
|
|
64979
64995
|
this.offsetScrollbarY = offsets.y;
|
|
64980
64996
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -65017,9 +65033,9 @@ class InternalViewport {
|
|
|
65017
65033
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
65018
65034
|
);
|
|
65019
65035
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
65020
|
-
|
|
65021
|
-
|
|
65022
|
-
|
|
65036
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
65037
|
+
height += FOOTER_HEIGHT;
|
|
65038
|
+
}
|
|
65023
65039
|
}
|
|
65024
65040
|
return { width, height };
|
|
65025
65041
|
}
|
|
@@ -65160,6 +65176,9 @@ class InternalViewport {
|
|
|
65160
65176
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
65161
65177
|
}
|
|
65162
65178
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
65179
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
65180
|
+
return -1;
|
|
65181
|
+
}
|
|
65163
65182
|
const sheetId = this.sheetId;
|
|
65164
65183
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
65165
65184
|
// using a binary search:
|
|
@@ -65196,7 +65215,7 @@ class InternalViewport {
|
|
|
65196
65215
|
this.adjustViewportZoneY();
|
|
65197
65216
|
}
|
|
65198
65217
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
65199
|
-
* To make sure that at least
|
|
65218
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
65200
65219
|
*/
|
|
65201
65220
|
adjustViewportOffsetX() {
|
|
65202
65221
|
if (this.canScrollHorizontally) {
|
|
@@ -65208,7 +65227,7 @@ class InternalViewport {
|
|
|
65208
65227
|
this.adjustViewportZoneX();
|
|
65209
65228
|
}
|
|
65210
65229
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
65211
|
-
* To make sure that at least
|
|
65230
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
65212
65231
|
*/
|
|
65213
65232
|
adjustViewportOffsetY() {
|
|
65214
65233
|
if (this.canScrollVertically) {
|
|
@@ -65225,11 +65244,14 @@ class InternalViewport {
|
|
|
65225
65244
|
const sheetId = this.sheetId;
|
|
65226
65245
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
65227
65246
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
65247
|
+
if (!this.viewportWidth) {
|
|
65248
|
+
return;
|
|
65249
|
+
}
|
|
65228
65250
|
if (this.left === -1) {
|
|
65229
65251
|
this.left = this.boundaries.left;
|
|
65230
65252
|
}
|
|
65231
65253
|
if (this.right === -1) {
|
|
65232
|
-
this.right = this.
|
|
65254
|
+
this.right = this.boundaries.right;
|
|
65233
65255
|
}
|
|
65234
65256
|
this.offsetX =
|
|
65235
65257
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -65241,11 +65263,14 @@ class InternalViewport {
|
|
|
65241
65263
|
const sheetId = this.sheetId;
|
|
65242
65264
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
65243
65265
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
65266
|
+
if (!this.viewportHeight) {
|
|
65267
|
+
return;
|
|
65268
|
+
}
|
|
65244
65269
|
if (this.top === -1) {
|
|
65245
65270
|
this.top = this.boundaries.top;
|
|
65246
65271
|
}
|
|
65247
65272
|
if (this.bottom === -1) {
|
|
65248
|
-
this.bottom = this.
|
|
65273
|
+
this.bottom = this.boundaries.bottom;
|
|
65249
65274
|
}
|
|
65250
65275
|
this.offsetY =
|
|
65251
65276
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -65319,7 +65344,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65319
65344
|
"isPositionVisible",
|
|
65320
65345
|
"getColDimensionsInViewport",
|
|
65321
65346
|
"getRowDimensionsInViewport",
|
|
65322
|
-
"
|
|
65347
|
+
"getAllActiveViewportsZonesAndRect",
|
|
65323
65348
|
"getRect",
|
|
65324
65349
|
];
|
|
65325
65350
|
viewports = {};
|
|
@@ -65552,12 +65577,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65552
65577
|
const sheetId = this.getters.getActiveSheetId();
|
|
65553
65578
|
const viewports = this.getSubViewports(sheetId);
|
|
65554
65579
|
//TODO ake another commit to eimprove this
|
|
65555
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
65580
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
65556
65581
|
}
|
|
65557
65582
|
getSheetViewVisibleRows() {
|
|
65558
65583
|
const sheetId = this.getters.getActiveSheetId();
|
|
65559
65584
|
const viewports = this.getSubViewports(sheetId);
|
|
65560
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
65585
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
65561
65586
|
}
|
|
65562
65587
|
/**
|
|
65563
65588
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -65600,19 +65625,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65600
65625
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
65601
65626
|
};
|
|
65602
65627
|
}
|
|
65603
|
-
getColRowOffsetInViewport(dimension,
|
|
65604
|
-
|
|
65605
|
-
|
|
65606
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
65607
|
-
if (index < referenceIndex) {
|
|
65608
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
65628
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
65629
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
65630
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
65609
65631
|
}
|
|
65632
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
65633
|
+
const visibleHeaders = dimension === "COL"
|
|
65634
|
+
? this.getters.getSheetViewVisibleCols()
|
|
65635
|
+
: this.getters.getSheetViewVisibleRows();
|
|
65636
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
65637
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
65638
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
65610
65639
|
let offset = 0;
|
|
65611
|
-
const
|
|
65612
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
65613
|
-
if (!visibleIndexes.includes(i)) {
|
|
65614
|
-
continue;
|
|
65615
|
-
}
|
|
65640
|
+
for (const i of relevantIndexes) {
|
|
65616
65641
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
65617
65642
|
}
|
|
65618
65643
|
return offset;
|
|
@@ -65659,7 +65684,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65659
65684
|
}
|
|
65660
65685
|
return { canEdgeScroll, direction, delay };
|
|
65661
65686
|
}
|
|
65662
|
-
getEdgeScrollRow(y, previousY,
|
|
65687
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
65663
65688
|
let canEdgeScroll = false;
|
|
65664
65689
|
let direction = 0;
|
|
65665
65690
|
let delay = 0;
|
|
@@ -65680,7 +65705,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65680
65705
|
delay = scrollDelay(y - height);
|
|
65681
65706
|
direction = 1;
|
|
65682
65707
|
}
|
|
65683
|
-
else if (y < offsetCorrectionY &&
|
|
65708
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
65684
65709
|
// 2
|
|
65685
65710
|
canEdgeScroll = true;
|
|
65686
65711
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -65706,13 +65731,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65706
65731
|
*/
|
|
65707
65732
|
getVisibleRectWithoutHeaders(zone) {
|
|
65708
65733
|
const sheetId = this.getters.getActiveSheetId();
|
|
65709
|
-
|
|
65710
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
65711
|
-
.filter(isDefined);
|
|
65712
|
-
if (viewportRects.length === 0) {
|
|
65713
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
65714
|
-
}
|
|
65715
|
-
return this.recomposeRect(viewportRects);
|
|
65734
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
65716
65735
|
}
|
|
65717
65736
|
/**
|
|
65718
65737
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -65720,13 +65739,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65720
65739
|
*/
|
|
65721
65740
|
getRect(zone) {
|
|
65722
65741
|
const sheetId = this.getters.getActiveSheetId();
|
|
65723
|
-
const
|
|
65724
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
65725
|
-
.filter(isDefined);
|
|
65726
|
-
if (viewportRects.length === 0) {
|
|
65727
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
65728
|
-
}
|
|
65729
|
-
const rect = this.recomposeRect(viewportRects);
|
|
65742
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
65730
65743
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
65731
65744
|
}
|
|
65732
65745
|
/**
|
|
@@ -65771,9 +65784,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65771
65784
|
end: start + (isRowHidden ? 0 : size),
|
|
65772
65785
|
};
|
|
65773
65786
|
}
|
|
65774
|
-
|
|
65787
|
+
getAllActiveViewportsZonesAndRect() {
|
|
65775
65788
|
const sheetId = this.getters.getActiveSheetId();
|
|
65776
|
-
return this.getSubViewports(sheetId)
|
|
65789
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
65790
|
+
return {
|
|
65791
|
+
zone: viewport,
|
|
65792
|
+
rect: {
|
|
65793
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
65794
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
65795
|
+
...viewport.getMaxSize(),
|
|
65796
|
+
},
|
|
65797
|
+
};
|
|
65798
|
+
});
|
|
65777
65799
|
}
|
|
65778
65800
|
// ---------------------------------------------------------------------------
|
|
65779
65801
|
// Private
|
|
@@ -65832,12 +65854,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65832
65854
|
}
|
|
65833
65855
|
/** gets rid of deprecated sheetIds */
|
|
65834
65856
|
cleanViewports() {
|
|
65835
|
-
const
|
|
65836
|
-
for (
|
|
65837
|
-
|
|
65838
|
-
delete this.viewports[sheetId];
|
|
65839
|
-
}
|
|
65857
|
+
const newViewport = {};
|
|
65858
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
65859
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
65840
65860
|
}
|
|
65861
|
+
this.viewports = newViewport;
|
|
65841
65862
|
}
|
|
65842
65863
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
65843
65864
|
this.sheetViewHeight = height;
|
|
@@ -65847,7 +65868,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65847
65868
|
this.recomputeViewports();
|
|
65848
65869
|
}
|
|
65849
65870
|
recomputeViewports() {
|
|
65850
|
-
for (
|
|
65871
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
65851
65872
|
this.resetViewports(sheetId);
|
|
65852
65873
|
}
|
|
65853
65874
|
}
|
|
@@ -65869,8 +65890,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65869
65890
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
65870
65891
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
65871
65892
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
65872
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
65873
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
65893
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
65894
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
65895
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
65896
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
65874
65897
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
65875
65898
|
const canScrollHorizontally = xRatio < 1.0;
|
|
65876
65899
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -65881,14 +65904,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65881
65904
|
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 })) ||
|
|
65882
65905
|
undefined,
|
|
65883
65906
|
topRight: (ySplit &&
|
|
65884
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
65907
|
+
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 })) ||
|
|
65885
65908
|
undefined,
|
|
65886
65909
|
bottomLeft: (xSplit &&
|
|
65887
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
65910
|
+
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 })) ||
|
|
65888
65911
|
undefined,
|
|
65889
65912
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
65890
|
-
width:
|
|
65891
|
-
height:
|
|
65913
|
+
width: unfrozenWidth,
|
|
65914
|
+
height: unfrozenHeight,
|
|
65892
65915
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
65893
65916
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
65894
65917
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -65965,12 +65988,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
65965
65988
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
65966
65989
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
65967
65990
|
}
|
|
65968
|
-
|
|
65969
|
-
|
|
65970
|
-
|
|
65971
|
-
|
|
65972
|
-
|
|
65973
|
-
|
|
65991
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
65992
|
+
let x = Infinity;
|
|
65993
|
+
let y = Infinity;
|
|
65994
|
+
let width = 0;
|
|
65995
|
+
let height = 0;
|
|
65996
|
+
let hasViewports = false;
|
|
65997
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
65998
|
+
const rect = rectCallBack(viewport);
|
|
65999
|
+
if (rect) {
|
|
66000
|
+
hasViewports = true;
|
|
66001
|
+
x = Math.min(x, rect.x);
|
|
66002
|
+
y = Math.min(y, rect.y);
|
|
66003
|
+
width = Math.max(width, rect.x + rect.width);
|
|
66004
|
+
height = Math.max(height, rect.y + rect.height);
|
|
66005
|
+
}
|
|
66006
|
+
}
|
|
66007
|
+
if (!hasViewports) {
|
|
66008
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
66009
|
+
}
|
|
66010
|
+
return { x, y, width: width - x, height: height - y };
|
|
65974
66011
|
}
|
|
65975
66012
|
}
|
|
65976
66013
|
|
|
@@ -73088,6 +73125,6 @@ const constants = {
|
|
|
73088
73125
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, 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 };
|
|
73089
73126
|
|
|
73090
73127
|
|
|
73091
|
-
__info__.version = "18.0.
|
|
73092
|
-
__info__.date = "2025-
|
|
73093
|
-
__info__.hash = "
|
|
73128
|
+
__info__.version = "18.0.14";
|
|
73129
|
+
__info__.date = "2025-02-05T06:47:33.041Z";
|
|
73130
|
+
__info__.hash = "90f2af4";
|