@odoo/o-spreadsheet 17.0.47 → 17.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/o-spreadsheet.cjs.js +170 -126
- package/dist/o-spreadsheet.d.ts +11 -14
- package/dist/o-spreadsheet.esm.js +170 -126
- package/dist/o-spreadsheet.iife.js +170 -126
- 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.49
|
|
6
|
+
* @date 2025-02-10T08:55:47.771Z
|
|
7
|
+
* @hash 1049319
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -686,9 +686,16 @@ function deepEquals(o1, o2) {
|
|
|
686
686
|
}
|
|
687
687
|
return true;
|
|
688
688
|
}
|
|
689
|
-
/**
|
|
689
|
+
/**
|
|
690
|
+
* Check if the given array contains all the values of the other array.
|
|
691
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
692
|
+
*/
|
|
690
693
|
function includesAll(arr, values) {
|
|
691
|
-
|
|
694
|
+
if (arr.length < values.length) {
|
|
695
|
+
return false;
|
|
696
|
+
}
|
|
697
|
+
const set = new Set(arr);
|
|
698
|
+
return values.every((value) => set.has(value));
|
|
692
699
|
}
|
|
693
700
|
/**
|
|
694
701
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -18557,20 +18564,21 @@ const HLOOKUP = {
|
|
|
18557
18564
|
description: _t("Horizontal lookup"),
|
|
18558
18565
|
args: [
|
|
18559
18566
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18560
|
-
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.")),
|
|
18567
|
+
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.")),
|
|
18561
18568
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18562
18569
|
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.")),
|
|
18563
18570
|
],
|
|
18564
18571
|
returns: ["ANY"],
|
|
18565
18572
|
computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18566
18573
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18567
|
-
|
|
18574
|
+
const _range = toMatrix(range);
|
|
18575
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18568
18576
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18569
18577
|
const _isSorted = toBoolean(isSorted.value);
|
|
18570
18578
|
const colIndex = _isSorted
|
|
18571
|
-
? dichotomicSearch(
|
|
18572
|
-
: linearSearch(
|
|
18573
|
-
const col =
|
|
18579
|
+
? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18580
|
+
: linearSearch(_range, searchKey?.value, "strict", _range.length, getValueFromRange);
|
|
18581
|
+
const col = _range[colIndex];
|
|
18574
18582
|
assertAvailable(col, searchKey?.value);
|
|
18575
18583
|
return col[_index - 1];
|
|
18576
18584
|
},
|
|
@@ -18615,36 +18623,38 @@ const LOOKUP = {
|
|
|
18615
18623
|
description: _t("Look up a value."),
|
|
18616
18624
|
args: [
|
|
18617
18625
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18618
|
-
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.")),
|
|
18619
|
-
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.")),
|
|
18626
|
+
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.")),
|
|
18627
|
+
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.")),
|
|
18620
18628
|
],
|
|
18621
18629
|
returns: ["ANY"],
|
|
18622
18630
|
computeValueAndFormat: function (searchKey, searchArray, resultRange) {
|
|
18623
|
-
|
|
18624
|
-
|
|
18631
|
+
const _searchArray = toMatrix(searchArray);
|
|
18632
|
+
const _resultRange = toMatrix(resultRange);
|
|
18633
|
+
let nbCol = _searchArray.length;
|
|
18634
|
+
let nbRow = _searchArray[0].length;
|
|
18625
18635
|
const verticalSearch = nbRow >= nbCol;
|
|
18626
18636
|
const getElement = verticalSearch
|
|
18627
18637
|
? (range, index) => range[0][index].value
|
|
18628
18638
|
: (range, index) => range[index][0].value;
|
|
18629
18639
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18630
|
-
const index = dichotomicSearch(
|
|
18640
|
+
const index = dichotomicSearch(_searchArray, searchKey?.value, "nextSmaller", "asc", rangeLength, getElement);
|
|
18631
18641
|
if (index === -1)
|
|
18632
18642
|
assertAvailable(undefined, searchKey?.value);
|
|
18633
18643
|
verticalSearch
|
|
18634
|
-
? assertAvailable(
|
|
18635
|
-
: assertAvailable(
|
|
18636
|
-
if (
|
|
18637
|
-
return verticalSearch ?
|
|
18644
|
+
? assertAvailable(_searchArray[0][index], searchKey?.value)
|
|
18645
|
+
: assertAvailable(_searchArray[index][nbRow - 1], searchKey?.value);
|
|
18646
|
+
if (_resultRange[0].length === 0) {
|
|
18647
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18638
18648
|
}
|
|
18639
|
-
nbCol =
|
|
18640
|
-
nbRow =
|
|
18649
|
+
nbCol = _resultRange.length;
|
|
18650
|
+
nbRow = _resultRange[0].length;
|
|
18641
18651
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18642
18652
|
if (nbCol > 1) {
|
|
18643
18653
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18644
|
-
return
|
|
18654
|
+
return _resultRange[index][0];
|
|
18645
18655
|
}
|
|
18646
18656
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18647
|
-
return
|
|
18657
|
+
return _resultRange[0][index];
|
|
18648
18658
|
},
|
|
18649
18659
|
isExported: true,
|
|
18650
18660
|
};
|
|
@@ -18662,27 +18672,28 @@ const MATCH = {
|
|
|
18662
18672
|
returns: ["NUMBER"],
|
|
18663
18673
|
compute: function (searchKey, range, searchType = DEFAULT_SEARCH_TYPE) {
|
|
18664
18674
|
let _searchType = toNumber(searchType, this.locale);
|
|
18665
|
-
const
|
|
18666
|
-
const
|
|
18675
|
+
const _range = toMatrix(range);
|
|
18676
|
+
const nbCol = _range.length;
|
|
18677
|
+
const nbRow = _range[0].length;
|
|
18667
18678
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18668
18679
|
let index = -1;
|
|
18669
18680
|
const getElement = nbCol === 1
|
|
18670
|
-
? (
|
|
18671
|
-
: (
|
|
18672
|
-
const rangeLen = nbCol === 1 ?
|
|
18681
|
+
? (_range, index) => _range[0][index]
|
|
18682
|
+
: (_range, index) => _range[index][0];
|
|
18683
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18673
18684
|
_searchType = Math.sign(_searchType);
|
|
18674
18685
|
switch (_searchType) {
|
|
18675
18686
|
case 1:
|
|
18676
|
-
index = dichotomicSearch(
|
|
18687
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18677
18688
|
break;
|
|
18678
18689
|
case 0:
|
|
18679
|
-
index = linearSearch(
|
|
18690
|
+
index = linearSearch(_range, searchKey, "strict", rangeLen, getElement);
|
|
18680
18691
|
break;
|
|
18681
18692
|
case -1:
|
|
18682
|
-
index = dichotomicSearch(
|
|
18693
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18683
18694
|
break;
|
|
18684
18695
|
}
|
|
18685
|
-
assertAvailable(nbCol === 1 ?
|
|
18696
|
+
assertAvailable(nbCol === 1 ? _range[0][index] : _range[index], searchKey);
|
|
18686
18697
|
return index + 1;
|
|
18687
18698
|
},
|
|
18688
18699
|
isExported: true,
|
|
@@ -18731,13 +18742,14 @@ const VLOOKUP = {
|
|
|
18731
18742
|
returns: ["ANY"],
|
|
18732
18743
|
computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18733
18744
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18734
|
-
|
|
18745
|
+
const _range = toMatrix(range);
|
|
18746
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18735
18747
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18736
18748
|
const _isSorted = toBoolean(isSorted.value);
|
|
18737
18749
|
const rowIndex = _isSorted
|
|
18738
|
-
? dichotomicSearch(
|
|
18739
|
-
: linearSearch(
|
|
18740
|
-
const value =
|
|
18750
|
+
? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18751
|
+
: linearSearch(_range, searchKey?.value, "strict", _range[0].length, getValueFromRange);
|
|
18752
|
+
const value = _range[_index - 1][rowIndex];
|
|
18741
18753
|
assertAvailable(value, searchKey?.value);
|
|
18742
18754
|
return value;
|
|
18743
18755
|
},
|
|
@@ -18764,26 +18776,28 @@ const XLOOKUP = {
|
|
|
18764
18776
|
computeValueAndFormat: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18765
18777
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18766
18778
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18767
|
-
|
|
18779
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18780
|
+
const _returnRange = toMatrix(returnRange);
|
|
18781
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18768
18782
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("searchMode should be a value in [-1, 1, -2, 2]."));
|
|
18769
18783
|
assert(() => [-1, 0, 1].includes(_matchMode), _t("matchMode should be a value in [-1, 0, 1]."));
|
|
18770
|
-
const lookupDirection =
|
|
18784
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18771
18785
|
assert(() => lookupDirection === "col"
|
|
18772
|
-
?
|
|
18773
|
-
:
|
|
18786
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18787
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18774
18788
|
const getElement = lookupDirection === "col"
|
|
18775
18789
|
? (range, index) => range[0][index].value
|
|
18776
18790
|
: (range, index) => range[index][0].value;
|
|
18777
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18791
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18778
18792
|
const mode = _matchMode === 0 ? "strict" : _matchMode === 1 ? "nextGreater" : "nextSmaller";
|
|
18779
18793
|
const reverseSearch = _searchMode === -1;
|
|
18780
18794
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18781
|
-
? dichotomicSearch(
|
|
18782
|
-
: linearSearch(
|
|
18795
|
+
? dichotomicSearch(_lookupRange, searchKey?.value, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18796
|
+
: linearSearch(_lookupRange, searchKey?.value, mode, rangeLen, getElement, reverseSearch);
|
|
18783
18797
|
if (index !== -1) {
|
|
18784
18798
|
return lookupDirection === "col"
|
|
18785
|
-
?
|
|
18786
|
-
: [
|
|
18799
|
+
? _returnRange.map((col) => [col[index]])
|
|
18800
|
+
: [_returnRange[index]];
|
|
18787
18801
|
}
|
|
18788
18802
|
const _defaultValue = defaultValue?.();
|
|
18789
18803
|
assertAvailable(_defaultValue, searchKey?.value);
|
|
@@ -29241,6 +29255,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
29241
29255
|
canvas.width = width * dpr;
|
|
29242
29256
|
canvas.height = height * dpr;
|
|
29243
29257
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
29258
|
+
if (width === 0 || height === 0) {
|
|
29259
|
+
return;
|
|
29260
|
+
}
|
|
29244
29261
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
29245
29262
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
29246
29263
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -34721,7 +34738,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
34721
34738
|
getCommonSides(border1, border2) {
|
|
34722
34739
|
const commonBorder = {};
|
|
34723
34740
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
34724
|
-
if (border1[side] && border1[side]
|
|
34741
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
34725
34742
|
commonBorder[side] = border1[side];
|
|
34726
34743
|
}
|
|
34727
34744
|
}
|
|
@@ -46267,11 +46284,10 @@ class RendererPlugin extends UIPlugin {
|
|
|
46267
46284
|
switch (layer) {
|
|
46268
46285
|
case 0 /* LAYERS.Background */:
|
|
46269
46286
|
this.drawGlobalBackground(renderingContext);
|
|
46270
|
-
for (const zone of this.getters.
|
|
46287
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
46271
46288
|
const { ctx } = renderingContext;
|
|
46272
46289
|
ctx.save();
|
|
46273
46290
|
ctx.beginPath();
|
|
46274
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
46275
46291
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
46276
46292
|
ctx.clip();
|
|
46277
46293
|
this.boxes = this.getGridBoxes(zone);
|
|
@@ -46541,10 +46557,8 @@ class RendererPlugin extends UIPlugin {
|
|
|
46541
46557
|
const { ctx, thinLineWidth } = renderingContext;
|
|
46542
46558
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
46543
46559
|
const left = visibleCols[0];
|
|
46544
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
46545
46560
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
46546
46561
|
const top = visibleRows[0];
|
|
46547
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
46548
46562
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
46549
46563
|
const selection = this.getters.getSelectedZones();
|
|
46550
46564
|
const selectedCols = getZonesCols(selection);
|
|
@@ -46560,7 +46574,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
46560
46574
|
ctx.lineWidth = thinLineWidth;
|
|
46561
46575
|
ctx.strokeStyle = "#333";
|
|
46562
46576
|
// Columns headers background
|
|
46563
|
-
for (
|
|
46577
|
+
for (const col of visibleCols) {
|
|
46564
46578
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
46565
46579
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
46566
46580
|
const colHasFilter = this.getters.doesZonesContainFilter(sheetId, [colZone]);
|
|
@@ -46580,7 +46594,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
46580
46594
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
46581
46595
|
}
|
|
46582
46596
|
// Rows headers background
|
|
46583
|
-
for (
|
|
46597
|
+
for (const row of visibleRows) {
|
|
46584
46598
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
46585
46599
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
46586
46600
|
const rowHasFilter = this.getters.doesZonesContainFilter(sheetId, [rowZone]);
|
|
@@ -46609,21 +46623,21 @@ class RendererPlugin extends UIPlugin {
|
|
|
46609
46623
|
ctx.stroke();
|
|
46610
46624
|
ctx.beginPath();
|
|
46611
46625
|
// column text + separator
|
|
46612
|
-
for (const
|
|
46613
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
46614
|
-
const colName = numberToLetters(
|
|
46615
|
-
ctx.fillStyle = activeCols.has(
|
|
46616
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
46626
|
+
for (const col of visibleCols) {
|
|
46627
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
46628
|
+
const colName = numberToLetters(col);
|
|
46629
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
46630
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
46617
46631
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
46618
46632
|
ctx.moveTo(colStart + colSize, 0);
|
|
46619
46633
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
46620
46634
|
}
|
|
46621
46635
|
// row text + separator
|
|
46622
|
-
for (const
|
|
46623
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
46624
|
-
ctx.fillStyle = activeRows.has(
|
|
46625
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
46626
|
-
ctx.fillText(String(
|
|
46636
|
+
for (const row of visibleRows) {
|
|
46637
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
46638
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
46639
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
46640
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
46627
46641
|
ctx.moveTo(0, rowStart + rowSize);
|
|
46628
46642
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
46629
46643
|
}
|
|
@@ -50514,8 +50528,17 @@ class InternalViewport {
|
|
|
50514
50528
|
this.getters = getters;
|
|
50515
50529
|
this.sheetId = sheetId;
|
|
50516
50530
|
this.boundaries = boundaries;
|
|
50517
|
-
|
|
50518
|
-
|
|
50531
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
50532
|
+
throw new Error("Viewport size cannot be negative");
|
|
50533
|
+
}
|
|
50534
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
50535
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
50536
|
+
this.top = boundaries.top;
|
|
50537
|
+
this.bottom = boundaries.bottom;
|
|
50538
|
+
this.left = boundaries.left;
|
|
50539
|
+
this.right = boundaries.right;
|
|
50540
|
+
this.offsetX = offsets.x;
|
|
50541
|
+
this.offsetY = offsets.y;
|
|
50519
50542
|
this.offsetScrollbarX = offsets.x;
|
|
50520
50543
|
this.offsetScrollbarY = offsets.y;
|
|
50521
50544
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -50558,9 +50581,9 @@ class InternalViewport {
|
|
|
50558
50581
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
50559
50582
|
);
|
|
50560
50583
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
50561
|
-
|
|
50562
|
-
|
|
50563
|
-
|
|
50584
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
50585
|
+
height += FOOTER_HEIGHT;
|
|
50586
|
+
}
|
|
50564
50587
|
}
|
|
50565
50588
|
return { width, height };
|
|
50566
50589
|
}
|
|
@@ -50707,6 +50730,9 @@ class InternalViewport {
|
|
|
50707
50730
|
}
|
|
50708
50731
|
// PRIVATE
|
|
50709
50732
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
50733
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
50734
|
+
return -1;
|
|
50735
|
+
}
|
|
50710
50736
|
const sheetId = this.sheetId;
|
|
50711
50737
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
50712
50738
|
// using a binary search:
|
|
@@ -50746,7 +50772,7 @@ class InternalViewport {
|
|
|
50746
50772
|
this.adjustViewportZoneY();
|
|
50747
50773
|
}
|
|
50748
50774
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
50749
|
-
* To make sure that at least
|
|
50775
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
50750
50776
|
*/
|
|
50751
50777
|
adjustViewportOffsetX() {
|
|
50752
50778
|
if (this.canScrollHorizontally) {
|
|
@@ -50763,7 +50789,7 @@ class InternalViewport {
|
|
|
50763
50789
|
this.adjustViewportZoneX();
|
|
50764
50790
|
}
|
|
50765
50791
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
50766
|
-
* To make sure that at least
|
|
50792
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
50767
50793
|
*/
|
|
50768
50794
|
adjustViewportOffsetY() {
|
|
50769
50795
|
if (this.canScrollVertically) {
|
|
@@ -50785,11 +50811,14 @@ class InternalViewport {
|
|
|
50785
50811
|
const sheetId = this.sheetId;
|
|
50786
50812
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
50787
50813
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
50814
|
+
if (!this.viewportWidth) {
|
|
50815
|
+
return;
|
|
50816
|
+
}
|
|
50788
50817
|
if (this.left === -1) {
|
|
50789
50818
|
this.left = this.boundaries.left;
|
|
50790
50819
|
}
|
|
50791
50820
|
if (this.right === -1) {
|
|
50792
|
-
this.right = this.
|
|
50821
|
+
this.right = this.boundaries.right;
|
|
50793
50822
|
}
|
|
50794
50823
|
this.offsetX =
|
|
50795
50824
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -50801,11 +50830,14 @@ class InternalViewport {
|
|
|
50801
50830
|
const sheetId = this.sheetId;
|
|
50802
50831
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
50803
50832
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
50833
|
+
if (!this.viewportHeight) {
|
|
50834
|
+
return;
|
|
50835
|
+
}
|
|
50804
50836
|
if (this.top === -1) {
|
|
50805
50837
|
this.top = this.boundaries.top;
|
|
50806
50838
|
}
|
|
50807
50839
|
if (this.bottom === -1) {
|
|
50808
|
-
this.bottom = this.
|
|
50840
|
+
this.bottom = this.boundaries.bottom;
|
|
50809
50841
|
}
|
|
50810
50842
|
this.offsetY =
|
|
50811
50843
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -50877,7 +50909,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
50877
50909
|
"getSheetViewVisibleRows",
|
|
50878
50910
|
"getFrozenSheetViewRatio",
|
|
50879
50911
|
"isPositionVisible",
|
|
50880
|
-
"
|
|
50912
|
+
"getAllActiveViewportsZonesAndRect",
|
|
50881
50913
|
"getRect",
|
|
50882
50914
|
];
|
|
50883
50915
|
viewports = {};
|
|
@@ -51111,12 +51143,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51111
51143
|
const sheetId = this.getters.getActiveSheetId();
|
|
51112
51144
|
const viewports = this.getSubViewports(sheetId);
|
|
51113
51145
|
//TODO ake another commit to eimprove this
|
|
51114
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
51146
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
51115
51147
|
}
|
|
51116
51148
|
getSheetViewVisibleRows() {
|
|
51117
51149
|
const sheetId = this.getters.getActiveSheetId();
|
|
51118
51150
|
const viewports = this.getSubViewports(sheetId);
|
|
51119
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
51151
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
51120
51152
|
}
|
|
51121
51153
|
/**
|
|
51122
51154
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -51159,19 +51191,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51159
51191
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
51160
51192
|
};
|
|
51161
51193
|
}
|
|
51162
|
-
getColRowOffsetInViewport(dimension,
|
|
51163
|
-
|
|
51164
|
-
|
|
51165
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
51166
|
-
if (index < referenceIndex) {
|
|
51167
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
51194
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
51195
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
51196
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
51168
51197
|
}
|
|
51198
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
51199
|
+
const visibleHeaders = dimension === "COL"
|
|
51200
|
+
? this.getters.getSheetViewVisibleCols()
|
|
51201
|
+
: this.getters.getSheetViewVisibleRows();
|
|
51202
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
51203
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
51204
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
51169
51205
|
let offset = 0;
|
|
51170
|
-
const
|
|
51171
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
51172
|
-
if (!visibleIndexes.includes(i)) {
|
|
51173
|
-
continue;
|
|
51174
|
-
}
|
|
51206
|
+
for (const i of relevantIndexes) {
|
|
51175
51207
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
51176
51208
|
}
|
|
51177
51209
|
return offset;
|
|
@@ -51218,7 +51250,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51218
51250
|
}
|
|
51219
51251
|
return { canEdgeScroll, direction, delay };
|
|
51220
51252
|
}
|
|
51221
|
-
getEdgeScrollRow(y, previousY,
|
|
51253
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
51222
51254
|
let canEdgeScroll = false;
|
|
51223
51255
|
let direction = 0;
|
|
51224
51256
|
let delay = 0;
|
|
@@ -51239,7 +51271,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51239
51271
|
delay = scrollDelay(y - height);
|
|
51240
51272
|
direction = 1;
|
|
51241
51273
|
}
|
|
51242
|
-
else if (y < offsetCorrectionY &&
|
|
51274
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
51243
51275
|
// 2
|
|
51244
51276
|
canEdgeScroll = true;
|
|
51245
51277
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -51265,13 +51297,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51265
51297
|
*/
|
|
51266
51298
|
getVisibleRectWithoutHeaders(zone) {
|
|
51267
51299
|
const sheetId = this.getters.getActiveSheetId();
|
|
51268
|
-
|
|
51269
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
51270
|
-
.filter(isDefined$1);
|
|
51271
|
-
if (viewportRects.length === 0) {
|
|
51272
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51273
|
-
}
|
|
51274
|
-
return this.recomposeRect(viewportRects);
|
|
51300
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
51275
51301
|
}
|
|
51276
51302
|
/**
|
|
51277
51303
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -51279,13 +51305,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51279
51305
|
*/
|
|
51280
51306
|
getRect(zone) {
|
|
51281
51307
|
const sheetId = this.getters.getActiveSheetId();
|
|
51282
|
-
const
|
|
51283
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
51284
|
-
.filter(isDefined$1);
|
|
51285
|
-
if (viewportRects.length === 0) {
|
|
51286
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51287
|
-
}
|
|
51288
|
-
const rect = this.recomposeRect(viewportRects);
|
|
51308
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
51289
51309
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
51290
51310
|
}
|
|
51291
51311
|
/**
|
|
@@ -51300,9 +51320,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51300
51320
|
const y = this.getters.getRowDimensions(sheetId, ySplit).start;
|
|
51301
51321
|
return { x, y };
|
|
51302
51322
|
}
|
|
51303
|
-
|
|
51323
|
+
getAllActiveViewportsZonesAndRect() {
|
|
51304
51324
|
const sheetId = this.getters.getActiveSheetId();
|
|
51305
|
-
return this.getSubViewports(sheetId)
|
|
51325
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
51326
|
+
return {
|
|
51327
|
+
zone: viewport,
|
|
51328
|
+
rect: {
|
|
51329
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
51330
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
51331
|
+
...viewport.getMaxSize(),
|
|
51332
|
+
},
|
|
51333
|
+
};
|
|
51334
|
+
});
|
|
51306
51335
|
}
|
|
51307
51336
|
// ---------------------------------------------------------------------------
|
|
51308
51337
|
// Private
|
|
@@ -51355,12 +51384,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51355
51384
|
}
|
|
51356
51385
|
/** gets rid of deprecated sheetIds */
|
|
51357
51386
|
cleanViewports() {
|
|
51358
|
-
const
|
|
51359
|
-
for (
|
|
51360
|
-
|
|
51361
|
-
delete this.viewports[sheetId];
|
|
51362
|
-
}
|
|
51387
|
+
const newViewport = {};
|
|
51388
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
51389
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
51363
51390
|
}
|
|
51391
|
+
this.viewports = newViewport;
|
|
51364
51392
|
}
|
|
51365
51393
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
51366
51394
|
this.sheetViewHeight = height;
|
|
@@ -51370,14 +51398,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51370
51398
|
this.recomputeViewports();
|
|
51371
51399
|
}
|
|
51372
51400
|
recomputeViewports() {
|
|
51373
|
-
for (
|
|
51401
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
51374
51402
|
this.resetViewports(sheetId);
|
|
51375
51403
|
}
|
|
51376
51404
|
}
|
|
51377
51405
|
setSheetViewOffset(offsetX, offsetY) {
|
|
51378
51406
|
const sheetId = this.getters.getActiveSheetId();
|
|
51379
51407
|
const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
|
|
51380
|
-
|
|
51408
|
+
this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
|
|
51381
51409
|
}
|
|
51382
51410
|
getViewportOffset(sheetId) {
|
|
51383
51411
|
return {
|
|
@@ -51392,8 +51420,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51392
51420
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
51393
51421
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
51394
51422
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
51395
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
51396
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
51423
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
51424
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
51425
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
51426
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
51397
51427
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
51398
51428
|
const canScrollHorizontally = xRatio < 1.0;
|
|
51399
51429
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -51404,14 +51434,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51404
51434
|
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 })) ||
|
|
51405
51435
|
undefined,
|
|
51406
51436
|
topRight: (ySplit &&
|
|
51407
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
51437
|
+
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 })) ||
|
|
51408
51438
|
undefined,
|
|
51409
51439
|
bottomLeft: (xSplit &&
|
|
51410
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
51440
|
+
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 })) ||
|
|
51411
51441
|
undefined,
|
|
51412
51442
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
51413
|
-
width:
|
|
51414
|
-
height:
|
|
51443
|
+
width: unfrozenWidth,
|
|
51444
|
+
height: unfrozenHeight,
|
|
51415
51445
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
51416
51446
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
51417
51447
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -51423,7 +51453,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51423
51453
|
* Adjust the viewport such that the anchor position is visible
|
|
51424
51454
|
*/
|
|
51425
51455
|
refreshViewport(sheetId, anchorPosition) {
|
|
51426
|
-
|
|
51456
|
+
this.getSubViewports(sheetId).forEach((viewport) => {
|
|
51427
51457
|
viewport.adjustViewportZone();
|
|
51428
51458
|
viewport.adjustPosition(anchorPosition);
|
|
51429
51459
|
});
|
|
@@ -51488,12 +51518,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51488
51518
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
51489
51519
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
51490
51520
|
}
|
|
51491
|
-
|
|
51492
|
-
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
|
|
51496
|
-
|
|
51521
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
51522
|
+
let x = Infinity;
|
|
51523
|
+
let y = Infinity;
|
|
51524
|
+
let width = 0;
|
|
51525
|
+
let height = 0;
|
|
51526
|
+
let hasViewports = false;
|
|
51527
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
51528
|
+
const rect = rectCallBack(viewport);
|
|
51529
|
+
if (rect) {
|
|
51530
|
+
hasViewports = true;
|
|
51531
|
+
x = Math.min(x, rect.x);
|
|
51532
|
+
y = Math.min(y, rect.y);
|
|
51533
|
+
width = Math.max(width, rect.x + rect.width);
|
|
51534
|
+
height = Math.max(height, rect.y + rect.height);
|
|
51535
|
+
}
|
|
51536
|
+
}
|
|
51537
|
+
if (!hasViewports) {
|
|
51538
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51539
|
+
}
|
|
51540
|
+
return { x, y, width: width - x, height: height - y };
|
|
51497
51541
|
}
|
|
51498
51542
|
}
|
|
51499
51543
|
|
|
@@ -57767,6 +57811,6 @@ const constants = {
|
|
|
57767
57811
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
57768
57812
|
|
|
57769
57813
|
|
|
57770
|
-
__info__.version = "17.0.
|
|
57771
|
-
__info__.date = "2025-
|
|
57772
|
-
__info__.hash = "
|
|
57814
|
+
__info__.version = "17.0.49";
|
|
57815
|
+
__info__.date = "2025-02-10T08:55:47.771Z";
|
|
57816
|
+
__info__.hash = "1049319";
|