@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
|
'use strict';
|
|
@@ -688,9 +688,16 @@ function deepEquals(o1, o2) {
|
|
|
688
688
|
}
|
|
689
689
|
return true;
|
|
690
690
|
}
|
|
691
|
-
/**
|
|
691
|
+
/**
|
|
692
|
+
* Check if the given array contains all the values of the other array.
|
|
693
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
694
|
+
*/
|
|
692
695
|
function includesAll(arr, values) {
|
|
693
|
-
|
|
696
|
+
if (arr.length < values.length) {
|
|
697
|
+
return false;
|
|
698
|
+
}
|
|
699
|
+
const set = new Set(arr);
|
|
700
|
+
return values.every((value) => set.has(value));
|
|
694
701
|
}
|
|
695
702
|
/**
|
|
696
703
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -18559,20 +18566,21 @@ const HLOOKUP = {
|
|
|
18559
18566
|
description: _t("Horizontal lookup"),
|
|
18560
18567
|
args: [
|
|
18561
18568
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18562
|
-
arg("range (range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18569
|
+
arg("range (any, range)", _t("The range to consider for the search. The first row in the range is searched for the key specified in search_key.")),
|
|
18563
18570
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18564
18571
|
arg(`is_sorted (boolean, default=${DEFAULT_IS_SORTED})`, _t("Indicates whether the row to be searched (the first row of the specified range) is sorted, in which case the closest match for search_key will be returned.")),
|
|
18565
18572
|
],
|
|
18566
18573
|
returns: ["ANY"],
|
|
18567
18574
|
computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18568
18575
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18569
|
-
|
|
18576
|
+
const _range = toMatrix(range);
|
|
18577
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18570
18578
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18571
18579
|
const _isSorted = toBoolean(isSorted.value);
|
|
18572
18580
|
const colIndex = _isSorted
|
|
18573
|
-
? dichotomicSearch(
|
|
18574
|
-
: linearSearch(
|
|
18575
|
-
const col =
|
|
18581
|
+
? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18582
|
+
: linearSearch(_range, searchKey?.value, "strict", _range.length, getValueFromRange);
|
|
18583
|
+
const col = _range[colIndex];
|
|
18576
18584
|
assertAvailable(col, searchKey?.value);
|
|
18577
18585
|
return col[_index - 1];
|
|
18578
18586
|
},
|
|
@@ -18617,36 +18625,38 @@ const LOOKUP = {
|
|
|
18617
18625
|
description: _t("Look up a value."),
|
|
18618
18626
|
args: [
|
|
18619
18627
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18620
|
-
arg("search_array (range)", _t("One method of using this function is to provide a single sorted row or column search_array to look through for the search_key with a second argument result_range. The other way is to combine these two arguments into one search_array where the first row or column is searched and a value is returned from the last row or column in the array. If search_key is not found, a non-exact match may be returned.")),
|
|
18621
|
-
arg("result_range (range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18628
|
+
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.")),
|
|
18629
|
+
arg("result_range (any, range, optional)", _t("The range from which to return a result. The value returned corresponds to the location where search_key is found in search_range. This range must be only a single row or column and should not be used if using the search_result_array method.")),
|
|
18622
18630
|
],
|
|
18623
18631
|
returns: ["ANY"],
|
|
18624
18632
|
computeValueAndFormat: function (searchKey, searchArray, resultRange) {
|
|
18625
|
-
|
|
18626
|
-
|
|
18633
|
+
const _searchArray = toMatrix(searchArray);
|
|
18634
|
+
const _resultRange = toMatrix(resultRange);
|
|
18635
|
+
let nbCol = _searchArray.length;
|
|
18636
|
+
let nbRow = _searchArray[0].length;
|
|
18627
18637
|
const verticalSearch = nbRow >= nbCol;
|
|
18628
18638
|
const getElement = verticalSearch
|
|
18629
18639
|
? (range, index) => range[0][index].value
|
|
18630
18640
|
: (range, index) => range[index][0].value;
|
|
18631
18641
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18632
|
-
const index = dichotomicSearch(
|
|
18642
|
+
const index = dichotomicSearch(_searchArray, searchKey?.value, "nextSmaller", "asc", rangeLength, getElement);
|
|
18633
18643
|
if (index === -1)
|
|
18634
18644
|
assertAvailable(undefined, searchKey?.value);
|
|
18635
18645
|
verticalSearch
|
|
18636
|
-
? assertAvailable(
|
|
18637
|
-
: assertAvailable(
|
|
18638
|
-
if (
|
|
18639
|
-
return verticalSearch ?
|
|
18646
|
+
? assertAvailable(_searchArray[0][index], searchKey?.value)
|
|
18647
|
+
: assertAvailable(_searchArray[index][nbRow - 1], searchKey?.value);
|
|
18648
|
+
if (_resultRange[0].length === 0) {
|
|
18649
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18640
18650
|
}
|
|
18641
|
-
nbCol =
|
|
18642
|
-
nbRow =
|
|
18651
|
+
nbCol = _resultRange.length;
|
|
18652
|
+
nbRow = _resultRange[0].length;
|
|
18643
18653
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18644
18654
|
if (nbCol > 1) {
|
|
18645
18655
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18646
|
-
return
|
|
18656
|
+
return _resultRange[index][0];
|
|
18647
18657
|
}
|
|
18648
18658
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18649
|
-
return
|
|
18659
|
+
return _resultRange[0][index];
|
|
18650
18660
|
},
|
|
18651
18661
|
isExported: true,
|
|
18652
18662
|
};
|
|
@@ -18664,27 +18674,28 @@ const MATCH = {
|
|
|
18664
18674
|
returns: ["NUMBER"],
|
|
18665
18675
|
compute: function (searchKey, range, searchType = DEFAULT_SEARCH_TYPE) {
|
|
18666
18676
|
let _searchType = toNumber(searchType, this.locale);
|
|
18667
|
-
const
|
|
18668
|
-
const
|
|
18677
|
+
const _range = toMatrix(range);
|
|
18678
|
+
const nbCol = _range.length;
|
|
18679
|
+
const nbRow = _range[0].length;
|
|
18669
18680
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18670
18681
|
let index = -1;
|
|
18671
18682
|
const getElement = nbCol === 1
|
|
18672
|
-
? (
|
|
18673
|
-
: (
|
|
18674
|
-
const rangeLen = nbCol === 1 ?
|
|
18683
|
+
? (_range, index) => _range[0][index]
|
|
18684
|
+
: (_range, index) => _range[index][0];
|
|
18685
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18675
18686
|
_searchType = Math.sign(_searchType);
|
|
18676
18687
|
switch (_searchType) {
|
|
18677
18688
|
case 1:
|
|
18678
|
-
index = dichotomicSearch(
|
|
18689
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18679
18690
|
break;
|
|
18680
18691
|
case 0:
|
|
18681
|
-
index = linearSearch(
|
|
18692
|
+
index = linearSearch(_range, searchKey, "strict", rangeLen, getElement);
|
|
18682
18693
|
break;
|
|
18683
18694
|
case -1:
|
|
18684
|
-
index = dichotomicSearch(
|
|
18695
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18685
18696
|
break;
|
|
18686
18697
|
}
|
|
18687
|
-
assertAvailable(nbCol === 1 ?
|
|
18698
|
+
assertAvailable(nbCol === 1 ? _range[0][index] : _range[index], searchKey);
|
|
18688
18699
|
return index + 1;
|
|
18689
18700
|
},
|
|
18690
18701
|
isExported: true,
|
|
@@ -18733,13 +18744,14 @@ const VLOOKUP = {
|
|
|
18733
18744
|
returns: ["ANY"],
|
|
18734
18745
|
computeValueAndFormat: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18735
18746
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18736
|
-
|
|
18747
|
+
const _range = toMatrix(range);
|
|
18748
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18737
18749
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18738
18750
|
const _isSorted = toBoolean(isSorted.value);
|
|
18739
18751
|
const rowIndex = _isSorted
|
|
18740
|
-
? dichotomicSearch(
|
|
18741
|
-
: linearSearch(
|
|
18742
|
-
const value =
|
|
18752
|
+
? dichotomicSearch(_range, searchKey?.value, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18753
|
+
: linearSearch(_range, searchKey?.value, "strict", _range[0].length, getValueFromRange);
|
|
18754
|
+
const value = _range[_index - 1][rowIndex];
|
|
18743
18755
|
assertAvailable(value, searchKey?.value);
|
|
18744
18756
|
return value;
|
|
18745
18757
|
},
|
|
@@ -18766,26 +18778,28 @@ const XLOOKUP = {
|
|
|
18766
18778
|
computeValueAndFormat: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18767
18779
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18768
18780
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18769
|
-
|
|
18781
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18782
|
+
const _returnRange = toMatrix(returnRange);
|
|
18783
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18770
18784
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("searchMode should be a value in [-1, 1, -2, 2]."));
|
|
18771
18785
|
assert(() => [-1, 0, 1].includes(_matchMode), _t("matchMode should be a value in [-1, 0, 1]."));
|
|
18772
|
-
const lookupDirection =
|
|
18786
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18773
18787
|
assert(() => lookupDirection === "col"
|
|
18774
|
-
?
|
|
18775
|
-
:
|
|
18788
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18789
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18776
18790
|
const getElement = lookupDirection === "col"
|
|
18777
18791
|
? (range, index) => range[0][index].value
|
|
18778
18792
|
: (range, index) => range[index][0].value;
|
|
18779
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18793
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18780
18794
|
const mode = _matchMode === 0 ? "strict" : _matchMode === 1 ? "nextGreater" : "nextSmaller";
|
|
18781
18795
|
const reverseSearch = _searchMode === -1;
|
|
18782
18796
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18783
|
-
? dichotomicSearch(
|
|
18784
|
-
: linearSearch(
|
|
18797
|
+
? dichotomicSearch(_lookupRange, searchKey?.value, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18798
|
+
: linearSearch(_lookupRange, searchKey?.value, mode, rangeLen, getElement, reverseSearch);
|
|
18785
18799
|
if (index !== -1) {
|
|
18786
18800
|
return lookupDirection === "col"
|
|
18787
|
-
?
|
|
18788
|
-
: [
|
|
18801
|
+
? _returnRange.map((col) => [col[index]])
|
|
18802
|
+
: [_returnRange[index]];
|
|
18789
18803
|
}
|
|
18790
18804
|
const _defaultValue = defaultValue?.();
|
|
18791
18805
|
assertAvailable(_defaultValue, searchKey?.value);
|
|
@@ -29243,6 +29257,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
29243
29257
|
canvas.width = width * dpr;
|
|
29244
29258
|
canvas.height = height * dpr;
|
|
29245
29259
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
29260
|
+
if (width === 0 || height === 0) {
|
|
29261
|
+
return;
|
|
29262
|
+
}
|
|
29246
29263
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
29247
29264
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
29248
29265
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -34723,7 +34740,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
34723
34740
|
getCommonSides(border1, border2) {
|
|
34724
34741
|
const commonBorder = {};
|
|
34725
34742
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
34726
|
-
if (border1[side] && border1[side]
|
|
34743
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
34727
34744
|
commonBorder[side] = border1[side];
|
|
34728
34745
|
}
|
|
34729
34746
|
}
|
|
@@ -46269,11 +46286,10 @@ class RendererPlugin extends UIPlugin {
|
|
|
46269
46286
|
switch (layer) {
|
|
46270
46287
|
case 0 /* LAYERS.Background */:
|
|
46271
46288
|
this.drawGlobalBackground(renderingContext);
|
|
46272
|
-
for (const zone of this.getters.
|
|
46289
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
46273
46290
|
const { ctx } = renderingContext;
|
|
46274
46291
|
ctx.save();
|
|
46275
46292
|
ctx.beginPath();
|
|
46276
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
46277
46293
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
46278
46294
|
ctx.clip();
|
|
46279
46295
|
this.boxes = this.getGridBoxes(zone);
|
|
@@ -46543,10 +46559,8 @@ class RendererPlugin extends UIPlugin {
|
|
|
46543
46559
|
const { ctx, thinLineWidth } = renderingContext;
|
|
46544
46560
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
46545
46561
|
const left = visibleCols[0];
|
|
46546
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
46547
46562
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
46548
46563
|
const top = visibleRows[0];
|
|
46549
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
46550
46564
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
46551
46565
|
const selection = this.getters.getSelectedZones();
|
|
46552
46566
|
const selectedCols = getZonesCols(selection);
|
|
@@ -46562,7 +46576,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
46562
46576
|
ctx.lineWidth = thinLineWidth;
|
|
46563
46577
|
ctx.strokeStyle = "#333";
|
|
46564
46578
|
// Columns headers background
|
|
46565
|
-
for (
|
|
46579
|
+
for (const col of visibleCols) {
|
|
46566
46580
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
46567
46581
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
46568
46582
|
const colHasFilter = this.getters.doesZonesContainFilter(sheetId, [colZone]);
|
|
@@ -46582,7 +46596,7 @@ class RendererPlugin extends UIPlugin {
|
|
|
46582
46596
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
46583
46597
|
}
|
|
46584
46598
|
// Rows headers background
|
|
46585
|
-
for (
|
|
46599
|
+
for (const row of visibleRows) {
|
|
46586
46600
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
46587
46601
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
46588
46602
|
const rowHasFilter = this.getters.doesZonesContainFilter(sheetId, [rowZone]);
|
|
@@ -46611,21 +46625,21 @@ class RendererPlugin extends UIPlugin {
|
|
|
46611
46625
|
ctx.stroke();
|
|
46612
46626
|
ctx.beginPath();
|
|
46613
46627
|
// column text + separator
|
|
46614
|
-
for (const
|
|
46615
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
46616
|
-
const colName = numberToLetters(
|
|
46617
|
-
ctx.fillStyle = activeCols.has(
|
|
46618
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
46628
|
+
for (const col of visibleCols) {
|
|
46629
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
46630
|
+
const colName = numberToLetters(col);
|
|
46631
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
46632
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
46619
46633
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
46620
46634
|
ctx.moveTo(colStart + colSize, 0);
|
|
46621
46635
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
46622
46636
|
}
|
|
46623
46637
|
// row text + separator
|
|
46624
|
-
for (const
|
|
46625
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
46626
|
-
ctx.fillStyle = activeRows.has(
|
|
46627
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
46628
|
-
ctx.fillText(String(
|
|
46638
|
+
for (const row of visibleRows) {
|
|
46639
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
46640
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
46641
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
46642
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
46629
46643
|
ctx.moveTo(0, rowStart + rowSize);
|
|
46630
46644
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
46631
46645
|
}
|
|
@@ -50516,8 +50530,17 @@ class InternalViewport {
|
|
|
50516
50530
|
this.getters = getters;
|
|
50517
50531
|
this.sheetId = sheetId;
|
|
50518
50532
|
this.boundaries = boundaries;
|
|
50519
|
-
|
|
50520
|
-
|
|
50533
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
50534
|
+
throw new Error("Viewport size cannot be negative");
|
|
50535
|
+
}
|
|
50536
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
50537
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
50538
|
+
this.top = boundaries.top;
|
|
50539
|
+
this.bottom = boundaries.bottom;
|
|
50540
|
+
this.left = boundaries.left;
|
|
50541
|
+
this.right = boundaries.right;
|
|
50542
|
+
this.offsetX = offsets.x;
|
|
50543
|
+
this.offsetY = offsets.y;
|
|
50521
50544
|
this.offsetScrollbarX = offsets.x;
|
|
50522
50545
|
this.offsetScrollbarY = offsets.y;
|
|
50523
50546
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -50560,9 +50583,9 @@ class InternalViewport {
|
|
|
50560
50583
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
50561
50584
|
);
|
|
50562
50585
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
50563
|
-
|
|
50564
|
-
|
|
50565
|
-
|
|
50586
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
50587
|
+
height += FOOTER_HEIGHT;
|
|
50588
|
+
}
|
|
50566
50589
|
}
|
|
50567
50590
|
return { width, height };
|
|
50568
50591
|
}
|
|
@@ -50709,6 +50732,9 @@ class InternalViewport {
|
|
|
50709
50732
|
}
|
|
50710
50733
|
// PRIVATE
|
|
50711
50734
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
50735
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
50736
|
+
return -1;
|
|
50737
|
+
}
|
|
50712
50738
|
const sheetId = this.sheetId;
|
|
50713
50739
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
50714
50740
|
// using a binary search:
|
|
@@ -50748,7 +50774,7 @@ class InternalViewport {
|
|
|
50748
50774
|
this.adjustViewportZoneY();
|
|
50749
50775
|
}
|
|
50750
50776
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
50751
|
-
* To make sure that at least
|
|
50777
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
50752
50778
|
*/
|
|
50753
50779
|
adjustViewportOffsetX() {
|
|
50754
50780
|
if (this.canScrollHorizontally) {
|
|
@@ -50765,7 +50791,7 @@ class InternalViewport {
|
|
|
50765
50791
|
this.adjustViewportZoneX();
|
|
50766
50792
|
}
|
|
50767
50793
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
50768
|
-
* To make sure that at least
|
|
50794
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
50769
50795
|
*/
|
|
50770
50796
|
adjustViewportOffsetY() {
|
|
50771
50797
|
if (this.canScrollVertically) {
|
|
@@ -50787,11 +50813,14 @@ class InternalViewport {
|
|
|
50787
50813
|
const sheetId = this.sheetId;
|
|
50788
50814
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
50789
50815
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
50816
|
+
if (!this.viewportWidth) {
|
|
50817
|
+
return;
|
|
50818
|
+
}
|
|
50790
50819
|
if (this.left === -1) {
|
|
50791
50820
|
this.left = this.boundaries.left;
|
|
50792
50821
|
}
|
|
50793
50822
|
if (this.right === -1) {
|
|
50794
|
-
this.right = this.
|
|
50823
|
+
this.right = this.boundaries.right;
|
|
50795
50824
|
}
|
|
50796
50825
|
this.offsetX =
|
|
50797
50826
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -50803,11 +50832,14 @@ class InternalViewport {
|
|
|
50803
50832
|
const sheetId = this.sheetId;
|
|
50804
50833
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
50805
50834
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
50835
|
+
if (!this.viewportHeight) {
|
|
50836
|
+
return;
|
|
50837
|
+
}
|
|
50806
50838
|
if (this.top === -1) {
|
|
50807
50839
|
this.top = this.boundaries.top;
|
|
50808
50840
|
}
|
|
50809
50841
|
if (this.bottom === -1) {
|
|
50810
|
-
this.bottom = this.
|
|
50842
|
+
this.bottom = this.boundaries.bottom;
|
|
50811
50843
|
}
|
|
50812
50844
|
this.offsetY =
|
|
50813
50845
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -50879,7 +50911,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
50879
50911
|
"getSheetViewVisibleRows",
|
|
50880
50912
|
"getFrozenSheetViewRatio",
|
|
50881
50913
|
"isPositionVisible",
|
|
50882
|
-
"
|
|
50914
|
+
"getAllActiveViewportsZonesAndRect",
|
|
50883
50915
|
"getRect",
|
|
50884
50916
|
];
|
|
50885
50917
|
viewports = {};
|
|
@@ -51113,12 +51145,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51113
51145
|
const sheetId = this.getters.getActiveSheetId();
|
|
51114
51146
|
const viewports = this.getSubViewports(sheetId);
|
|
51115
51147
|
//TODO ake another commit to eimprove this
|
|
51116
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
51148
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
51117
51149
|
}
|
|
51118
51150
|
getSheetViewVisibleRows() {
|
|
51119
51151
|
const sheetId = this.getters.getActiveSheetId();
|
|
51120
51152
|
const viewports = this.getSubViewports(sheetId);
|
|
51121
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
51153
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
51122
51154
|
}
|
|
51123
51155
|
/**
|
|
51124
51156
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -51161,19 +51193,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51161
51193
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
51162
51194
|
};
|
|
51163
51195
|
}
|
|
51164
|
-
getColRowOffsetInViewport(dimension,
|
|
51165
|
-
|
|
51166
|
-
|
|
51167
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
51168
|
-
if (index < referenceIndex) {
|
|
51169
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
51196
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
51197
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
51198
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
51170
51199
|
}
|
|
51200
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
51201
|
+
const visibleHeaders = dimension === "COL"
|
|
51202
|
+
? this.getters.getSheetViewVisibleCols()
|
|
51203
|
+
: this.getters.getSheetViewVisibleRows();
|
|
51204
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
51205
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
51206
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
51171
51207
|
let offset = 0;
|
|
51172
|
-
const
|
|
51173
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
51174
|
-
if (!visibleIndexes.includes(i)) {
|
|
51175
|
-
continue;
|
|
51176
|
-
}
|
|
51208
|
+
for (const i of relevantIndexes) {
|
|
51177
51209
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
51178
51210
|
}
|
|
51179
51211
|
return offset;
|
|
@@ -51220,7 +51252,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51220
51252
|
}
|
|
51221
51253
|
return { canEdgeScroll, direction, delay };
|
|
51222
51254
|
}
|
|
51223
|
-
getEdgeScrollRow(y, previousY,
|
|
51255
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
51224
51256
|
let canEdgeScroll = false;
|
|
51225
51257
|
let direction = 0;
|
|
51226
51258
|
let delay = 0;
|
|
@@ -51241,7 +51273,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51241
51273
|
delay = scrollDelay(y - height);
|
|
51242
51274
|
direction = 1;
|
|
51243
51275
|
}
|
|
51244
|
-
else if (y < offsetCorrectionY &&
|
|
51276
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
51245
51277
|
// 2
|
|
51246
51278
|
canEdgeScroll = true;
|
|
51247
51279
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -51267,13 +51299,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51267
51299
|
*/
|
|
51268
51300
|
getVisibleRectWithoutHeaders(zone) {
|
|
51269
51301
|
const sheetId = this.getters.getActiveSheetId();
|
|
51270
|
-
|
|
51271
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
51272
|
-
.filter(isDefined$1);
|
|
51273
|
-
if (viewportRects.length === 0) {
|
|
51274
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51275
|
-
}
|
|
51276
|
-
return this.recomposeRect(viewportRects);
|
|
51302
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
51277
51303
|
}
|
|
51278
51304
|
/**
|
|
51279
51305
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -51281,13 +51307,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51281
51307
|
*/
|
|
51282
51308
|
getRect(zone) {
|
|
51283
51309
|
const sheetId = this.getters.getActiveSheetId();
|
|
51284
|
-
const
|
|
51285
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
51286
|
-
.filter(isDefined$1);
|
|
51287
|
-
if (viewportRects.length === 0) {
|
|
51288
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51289
|
-
}
|
|
51290
|
-
const rect = this.recomposeRect(viewportRects);
|
|
51310
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
51291
51311
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
51292
51312
|
}
|
|
51293
51313
|
/**
|
|
@@ -51302,9 +51322,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51302
51322
|
const y = this.getters.getRowDimensions(sheetId, ySplit).start;
|
|
51303
51323
|
return { x, y };
|
|
51304
51324
|
}
|
|
51305
|
-
|
|
51325
|
+
getAllActiveViewportsZonesAndRect() {
|
|
51306
51326
|
const sheetId = this.getters.getActiveSheetId();
|
|
51307
|
-
return this.getSubViewports(sheetId)
|
|
51327
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
51328
|
+
return {
|
|
51329
|
+
zone: viewport,
|
|
51330
|
+
rect: {
|
|
51331
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
51332
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
51333
|
+
...viewport.getMaxSize(),
|
|
51334
|
+
},
|
|
51335
|
+
};
|
|
51336
|
+
});
|
|
51308
51337
|
}
|
|
51309
51338
|
// ---------------------------------------------------------------------------
|
|
51310
51339
|
// Private
|
|
@@ -51357,12 +51386,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51357
51386
|
}
|
|
51358
51387
|
/** gets rid of deprecated sheetIds */
|
|
51359
51388
|
cleanViewports() {
|
|
51360
|
-
const
|
|
51361
|
-
for (
|
|
51362
|
-
|
|
51363
|
-
delete this.viewports[sheetId];
|
|
51364
|
-
}
|
|
51389
|
+
const newViewport = {};
|
|
51390
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
51391
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
51365
51392
|
}
|
|
51393
|
+
this.viewports = newViewport;
|
|
51366
51394
|
}
|
|
51367
51395
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
51368
51396
|
this.sheetViewHeight = height;
|
|
@@ -51372,14 +51400,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51372
51400
|
this.recomputeViewports();
|
|
51373
51401
|
}
|
|
51374
51402
|
recomputeViewports() {
|
|
51375
|
-
for (
|
|
51403
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
51376
51404
|
this.resetViewports(sheetId);
|
|
51377
51405
|
}
|
|
51378
51406
|
}
|
|
51379
51407
|
setSheetViewOffset(offsetX, offsetY) {
|
|
51380
51408
|
const sheetId = this.getters.getActiveSheetId();
|
|
51381
51409
|
const { maxOffsetX, maxOffsetY } = this.getMaximumSheetOffset();
|
|
51382
|
-
|
|
51410
|
+
this.getSubViewports(sheetId).forEach((viewport) => viewport.setViewportOffset(clip(offsetX, 0, maxOffsetX), clip(offsetY, 0, maxOffsetY)));
|
|
51383
51411
|
}
|
|
51384
51412
|
getViewportOffset(sheetId) {
|
|
51385
51413
|
return {
|
|
@@ -51394,8 +51422,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51394
51422
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
51395
51423
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
51396
51424
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
51397
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
51398
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
51425
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
51426
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
51427
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
51428
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
51399
51429
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
51400
51430
|
const canScrollHorizontally = xRatio < 1.0;
|
|
51401
51431
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -51406,14 +51436,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51406
51436
|
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 })) ||
|
|
51407
51437
|
undefined,
|
|
51408
51438
|
topRight: (ySplit &&
|
|
51409
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
51439
|
+
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 })) ||
|
|
51410
51440
|
undefined,
|
|
51411
51441
|
bottomLeft: (xSplit &&
|
|
51412
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
51442
|
+
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 })) ||
|
|
51413
51443
|
undefined,
|
|
51414
51444
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
51415
|
-
width:
|
|
51416
|
-
height:
|
|
51445
|
+
width: unfrozenWidth,
|
|
51446
|
+
height: unfrozenHeight,
|
|
51417
51447
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
51418
51448
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
51419
51449
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -51425,7 +51455,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51425
51455
|
* Adjust the viewport such that the anchor position is visible
|
|
51426
51456
|
*/
|
|
51427
51457
|
refreshViewport(sheetId, anchorPosition) {
|
|
51428
|
-
|
|
51458
|
+
this.getSubViewports(sheetId).forEach((viewport) => {
|
|
51429
51459
|
viewport.adjustViewportZone();
|
|
51430
51460
|
viewport.adjustPosition(anchorPosition);
|
|
51431
51461
|
});
|
|
@@ -51490,12 +51520,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
51490
51520
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
51491
51521
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
51492
51522
|
}
|
|
51493
|
-
|
|
51494
|
-
|
|
51495
|
-
|
|
51496
|
-
|
|
51497
|
-
|
|
51498
|
-
|
|
51523
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
51524
|
+
let x = Infinity;
|
|
51525
|
+
let y = Infinity;
|
|
51526
|
+
let width = 0;
|
|
51527
|
+
let height = 0;
|
|
51528
|
+
let hasViewports = false;
|
|
51529
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
51530
|
+
const rect = rectCallBack(viewport);
|
|
51531
|
+
if (rect) {
|
|
51532
|
+
hasViewports = true;
|
|
51533
|
+
x = Math.min(x, rect.x);
|
|
51534
|
+
y = Math.min(y, rect.y);
|
|
51535
|
+
width = Math.max(width, rect.x + rect.width);
|
|
51536
|
+
height = Math.max(height, rect.y + rect.height);
|
|
51537
|
+
}
|
|
51538
|
+
}
|
|
51539
|
+
if (!hasViewports) {
|
|
51540
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
51541
|
+
}
|
|
51542
|
+
return { x, y, width: width - x, height: height - y };
|
|
51499
51543
|
}
|
|
51500
51544
|
}
|
|
51501
51545
|
|
|
@@ -57804,6 +57848,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57804
57848
|
exports.tokenize = tokenize;
|
|
57805
57849
|
|
|
57806
57850
|
|
|
57807
|
-
__info__.version = "17.0.
|
|
57808
|
-
__info__.date = "2025-
|
|
57809
|
-
__info__.hash = "
|
|
57851
|
+
__info__.version = "17.0.49";
|
|
57852
|
+
__info__.date = "2025-02-10T08:55:47.771Z";
|
|
57853
|
+
__info__.hash = "1049319";
|