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