@odoo/o-spreadsheet 17.4.19 → 17.4.21
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 +180 -133
- package/dist/o-spreadsheet.d.ts +12 -14
- package/dist/o-spreadsheet.esm.js +180 -133
- package/dist/o-spreadsheet.iife.js +180 -133
- package/dist/o-spreadsheet.iife.min.js +6 -6
- 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.4.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.21
|
|
6
|
+
* @date 2025-02-05T06:46:54.366Z
|
|
7
|
+
* @hash 0c55e18
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -1952,11 +1952,11 @@ const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(l
|
|
|
1952
1952
|
* number from the point of view of the isNumber function.
|
|
1953
1953
|
*/
|
|
1954
1954
|
function parseNumber(str, locale) {
|
|
1955
|
+
// remove invaluable characters
|
|
1956
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
1955
1957
|
if (locale.decimalSeparator !== ".") {
|
|
1956
1958
|
str = str.replace(locale.decimalSeparator, ".");
|
|
1957
1959
|
}
|
|
1958
|
-
// remove invaluable characters
|
|
1959
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
1960
1960
|
let n = Number(str);
|
|
1961
1961
|
if (isNaN(n) && str.includes("%")) {
|
|
1962
1962
|
n = Number(str.split("%")[0]);
|
|
@@ -18881,22 +18881,23 @@ const HLOOKUP = {
|
|
|
18881
18881
|
description: _t("Horizontal lookup"),
|
|
18882
18882
|
args: [
|
|
18883
18883
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18884
|
-
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.")),
|
|
18884
|
+
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.")),
|
|
18885
18885
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18886
18886
|
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.")),
|
|
18887
18887
|
],
|
|
18888
18888
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18889
18889
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18890
|
-
|
|
18890
|
+
const _range = toMatrix(range);
|
|
18891
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18891
18892
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18892
18893
|
return searchKey;
|
|
18893
18894
|
}
|
|
18894
18895
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18895
18896
|
const _isSorted = toBoolean(isSorted.value);
|
|
18896
18897
|
const colIndex = _isSorted
|
|
18897
|
-
? dichotomicSearch(
|
|
18898
|
-
: linearSearch(
|
|
18899
|
-
const col =
|
|
18898
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18899
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18900
|
+
const col = _range[colIndex];
|
|
18900
18901
|
if (col === undefined) {
|
|
18901
18902
|
return valueNotAvailable(searchKey);
|
|
18902
18903
|
}
|
|
@@ -18995,35 +18996,37 @@ const LOOKUP = {
|
|
|
18995
18996
|
description: _t("Look up a value."),
|
|
18996
18997
|
args: [
|
|
18997
18998
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18998
|
-
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.")),
|
|
18999
|
-
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.")),
|
|
18999
|
+
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.")),
|
|
19000
|
+
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.")),
|
|
19000
19001
|
],
|
|
19001
19002
|
compute: function (searchKey, searchArray, resultRange) {
|
|
19002
|
-
|
|
19003
|
-
|
|
19003
|
+
const _searchArray = toMatrix(searchArray);
|
|
19004
|
+
const _resultRange = toMatrix(resultRange);
|
|
19005
|
+
let nbCol = _searchArray.length;
|
|
19006
|
+
let nbRow = _searchArray[0].length;
|
|
19004
19007
|
const verticalSearch = nbRow >= nbCol;
|
|
19005
19008
|
const getElement = verticalSearch
|
|
19006
19009
|
? (range, index) => range[0][index].value
|
|
19007
19010
|
: (range, index) => range[index][0].value;
|
|
19008
19011
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
19009
|
-
const index = dichotomicSearch(
|
|
19012
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
19010
19013
|
if (index === -1 ||
|
|
19011
|
-
(verticalSearch &&
|
|
19012
|
-
(!verticalSearch &&
|
|
19014
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
19015
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
19013
19016
|
return valueNotAvailable(searchKey);
|
|
19014
19017
|
}
|
|
19015
|
-
if (
|
|
19016
|
-
return verticalSearch ?
|
|
19018
|
+
if (_resultRange[0].length === 0) {
|
|
19019
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
19017
19020
|
}
|
|
19018
|
-
nbCol =
|
|
19019
|
-
nbRow =
|
|
19021
|
+
nbCol = _resultRange.length;
|
|
19022
|
+
nbRow = _resultRange[0].length;
|
|
19020
19023
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
19021
19024
|
if (nbCol > 1) {
|
|
19022
19025
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
19023
|
-
return
|
|
19026
|
+
return _resultRange[index][0];
|
|
19024
19027
|
}
|
|
19025
19028
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
19026
|
-
return
|
|
19029
|
+
return _resultRange[0][index];
|
|
19027
19030
|
},
|
|
19028
19031
|
isExported: true,
|
|
19029
19032
|
};
|
|
@@ -19040,28 +19043,29 @@ const MATCH = {
|
|
|
19040
19043
|
],
|
|
19041
19044
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
19042
19045
|
let _searchType = toNumber(searchType, this.locale);
|
|
19043
|
-
const
|
|
19044
|
-
const
|
|
19046
|
+
const _range = toMatrix(range);
|
|
19047
|
+
const nbCol = _range.length;
|
|
19048
|
+
const nbRow = _range[0].length;
|
|
19045
19049
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
19046
19050
|
let index = -1;
|
|
19047
19051
|
const getElement = nbCol === 1
|
|
19048
|
-
? (
|
|
19049
|
-
: (
|
|
19050
|
-
const rangeLen = nbCol === 1 ?
|
|
19052
|
+
? (_range, index) => _range[0][index].value
|
|
19053
|
+
: (_range, index) => _range[index][0].value;
|
|
19054
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
19051
19055
|
_searchType = Math.sign(_searchType);
|
|
19052
19056
|
switch (_searchType) {
|
|
19053
19057
|
case 1:
|
|
19054
|
-
index = dichotomicSearch(
|
|
19058
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
19055
19059
|
break;
|
|
19056
19060
|
case 0:
|
|
19057
|
-
index = linearSearch(
|
|
19061
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
19058
19062
|
break;
|
|
19059
19063
|
case -1:
|
|
19060
|
-
index = dichotomicSearch(
|
|
19064
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
19061
19065
|
break;
|
|
19062
19066
|
}
|
|
19063
|
-
if ((nbCol === 1 &&
|
|
19064
|
-
(nbCol !== 1 &&
|
|
19067
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
19068
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
19065
19069
|
return valueNotAvailable(searchKey);
|
|
19066
19070
|
}
|
|
19067
19071
|
return index + 1;
|
|
@@ -19115,16 +19119,17 @@ const VLOOKUP = {
|
|
|
19115
19119
|
],
|
|
19116
19120
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
19117
19121
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
19118
|
-
|
|
19122
|
+
const _range = toMatrix(range);
|
|
19123
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
19119
19124
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
19120
19125
|
return searchKey;
|
|
19121
19126
|
}
|
|
19122
19127
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
19123
19128
|
const _isSorted = toBoolean(isSorted.value);
|
|
19124
19129
|
const rowIndex = _isSorted
|
|
19125
|
-
? dichotomicSearch(
|
|
19126
|
-
: linearSearch(
|
|
19127
|
-
const value =
|
|
19130
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
19131
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
19132
|
+
const value = _range[_index - 1][rowIndex];
|
|
19128
19133
|
if (value === undefined) {
|
|
19129
19134
|
return valueNotAvailable(searchKey);
|
|
19130
19135
|
}
|
|
@@ -19161,30 +19166,32 @@ const XLOOKUP = {
|
|
|
19161
19166
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
19162
19167
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
19163
19168
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
19164
|
-
|
|
19169
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
19170
|
+
const _returnRange = toMatrix(returnRange);
|
|
19171
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
19165
19172
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
19166
19173
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
19167
|
-
const lookupDirection =
|
|
19174
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
19168
19175
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
19169
19176
|
assert(() => lookupDirection === "col"
|
|
19170
|
-
?
|
|
19171
|
-
:
|
|
19177
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
19178
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
19172
19179
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
19173
19180
|
return [[searchKey]];
|
|
19174
19181
|
}
|
|
19175
19182
|
const getElement = lookupDirection === "col"
|
|
19176
19183
|
? (range, index) => range[0][index].value
|
|
19177
19184
|
: (range, index) => range[index][0].value;
|
|
19178
|
-
const rangeLen = lookupDirection === "col" ?
|
|
19185
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
19179
19186
|
const mode = MATCH_MODE[_matchMode];
|
|
19180
19187
|
const reverseSearch = _searchMode === -1;
|
|
19181
19188
|
const index = _searchMode === 2 || _searchMode === -2
|
|
19182
|
-
? dichotomicSearch(
|
|
19183
|
-
: linearSearch(
|
|
19189
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
19190
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
19184
19191
|
if (index !== -1) {
|
|
19185
19192
|
return lookupDirection === "col"
|
|
19186
|
-
?
|
|
19187
|
-
: [
|
|
19193
|
+
? _returnRange.map((col) => [col[index]])
|
|
19194
|
+
: [_returnRange[index]];
|
|
19188
19195
|
}
|
|
19189
19196
|
if (defaultValue === undefined) {
|
|
19190
19197
|
return valueNotAvailable(searchKey);
|
|
@@ -21614,6 +21621,12 @@ class Composer extends Component {
|
|
|
21614
21621
|
}
|
|
21615
21622
|
this.contentHelper.updateEl(el);
|
|
21616
21623
|
});
|
|
21624
|
+
this.env.model.selection.observe(this, {
|
|
21625
|
+
handleEvent: () => this.autoCompleteState.hide(),
|
|
21626
|
+
});
|
|
21627
|
+
onWillUnmount(() => {
|
|
21628
|
+
this.env.model.selection.detachObserver(this);
|
|
21629
|
+
});
|
|
21617
21630
|
useEffect(() => {
|
|
21618
21631
|
this.processContent();
|
|
21619
21632
|
});
|
|
@@ -41212,11 +41225,10 @@ class GridRenderer {
|
|
|
41212
41225
|
switch (layer) {
|
|
41213
41226
|
case "Background":
|
|
41214
41227
|
this.drawGlobalBackground(renderingContext);
|
|
41215
|
-
for (const zone of this.getters.
|
|
41228
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
41216
41229
|
const { ctx } = renderingContext;
|
|
41217
41230
|
ctx.save();
|
|
41218
41231
|
ctx.beginPath();
|
|
41219
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
41220
41232
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
41221
41233
|
ctx.clip();
|
|
41222
41234
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -41486,10 +41498,8 @@ class GridRenderer {
|
|
|
41486
41498
|
const { ctx, thinLineWidth } = renderingContext;
|
|
41487
41499
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
41488
41500
|
const left = visibleCols[0];
|
|
41489
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
41490
41501
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
41491
41502
|
const top = visibleRows[0];
|
|
41492
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
41493
41503
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
41494
41504
|
const selection = this.getters.getSelectedZones();
|
|
41495
41505
|
const selectedCols = getZonesCols(selection);
|
|
@@ -41505,7 +41515,7 @@ class GridRenderer {
|
|
|
41505
41515
|
ctx.lineWidth = thinLineWidth;
|
|
41506
41516
|
ctx.strokeStyle = "#333";
|
|
41507
41517
|
// Columns headers background
|
|
41508
|
-
for (
|
|
41518
|
+
for (const col of visibleCols) {
|
|
41509
41519
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
41510
41520
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
41511
41521
|
const isColActive = activeCols.has(col);
|
|
@@ -41522,7 +41532,7 @@ class GridRenderer {
|
|
|
41522
41532
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
41523
41533
|
}
|
|
41524
41534
|
// Rows headers background
|
|
41525
|
-
for (
|
|
41535
|
+
for (const row of visibleRows) {
|
|
41526
41536
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
41527
41537
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
41528
41538
|
const isRowActive = activeRows.has(row);
|
|
@@ -41548,21 +41558,21 @@ class GridRenderer {
|
|
|
41548
41558
|
ctx.stroke();
|
|
41549
41559
|
ctx.beginPath();
|
|
41550
41560
|
// column text + separator
|
|
41551
|
-
for (const
|
|
41552
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
41553
|
-
const colName = numberToLetters(
|
|
41554
|
-
ctx.fillStyle = activeCols.has(
|
|
41555
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
41561
|
+
for (const col of visibleCols) {
|
|
41562
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
41563
|
+
const colName = numberToLetters(col);
|
|
41564
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
41565
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
41556
41566
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
41557
41567
|
ctx.moveTo(colStart + colSize, 0);
|
|
41558
41568
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
41559
41569
|
}
|
|
41560
41570
|
// row text + separator
|
|
41561
|
-
for (const
|
|
41562
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
41563
|
-
ctx.fillStyle = activeRows.has(
|
|
41564
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
41565
|
-
ctx.fillText(String(
|
|
41571
|
+
for (const row of visibleRows) {
|
|
41572
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
41573
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
41574
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
41575
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
41566
41576
|
ctx.moveTo(0, rowStart + rowSize);
|
|
41567
41577
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
41568
41578
|
}
|
|
@@ -41860,6 +41870,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
41860
41870
|
canvas.width = width * dpr;
|
|
41861
41871
|
canvas.height = height * dpr;
|
|
41862
41872
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
41873
|
+
if (width === 0 || height === 0) {
|
|
41874
|
+
return;
|
|
41875
|
+
}
|
|
41863
41876
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
41864
41877
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
41865
41878
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -47592,7 +47605,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
47592
47605
|
getCommonSides(border1, border2) {
|
|
47593
47606
|
const commonBorder = {};
|
|
47594
47607
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
47595
|
-
if (border1[side] && border1[side]
|
|
47608
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
47596
47609
|
commonBorder[side] = border1[side];
|
|
47597
47610
|
}
|
|
47598
47611
|
}
|
|
@@ -58533,14 +58546,12 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
58533
58546
|
}
|
|
58534
58547
|
break;
|
|
58535
58548
|
case "AUTORESIZE_ROWS":
|
|
58536
|
-
|
|
58537
|
-
|
|
58538
|
-
|
|
58539
|
-
|
|
58540
|
-
|
|
58541
|
-
|
|
58542
|
-
});
|
|
58543
|
-
}
|
|
58549
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
58550
|
+
elements: cmd.rows,
|
|
58551
|
+
dimension: "ROW",
|
|
58552
|
+
size: null,
|
|
58553
|
+
sheetId: cmd.sheetId,
|
|
58554
|
+
});
|
|
58544
58555
|
break;
|
|
58545
58556
|
}
|
|
58546
58557
|
}
|
|
@@ -60937,8 +60948,17 @@ class InternalViewport {
|
|
|
60937
60948
|
this.getters = getters;
|
|
60938
60949
|
this.sheetId = sheetId;
|
|
60939
60950
|
this.boundaries = boundaries;
|
|
60940
|
-
|
|
60941
|
-
|
|
60951
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
60952
|
+
throw new Error("Viewport size cannot be negative");
|
|
60953
|
+
}
|
|
60954
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
60955
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
60956
|
+
this.top = boundaries.top;
|
|
60957
|
+
this.bottom = boundaries.bottom;
|
|
60958
|
+
this.left = boundaries.left;
|
|
60959
|
+
this.right = boundaries.right;
|
|
60960
|
+
this.offsetX = offsets.x;
|
|
60961
|
+
this.offsetY = offsets.y;
|
|
60942
60962
|
this.offsetScrollbarX = offsets.x;
|
|
60943
60963
|
this.offsetScrollbarY = offsets.y;
|
|
60944
60964
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -60981,9 +61001,9 @@ class InternalViewport {
|
|
|
60981
61001
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
60982
61002
|
);
|
|
60983
61003
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
60984
|
-
|
|
60985
|
-
|
|
60986
|
-
|
|
61004
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
61005
|
+
height += FOOTER_HEIGHT;
|
|
61006
|
+
}
|
|
60987
61007
|
}
|
|
60988
61008
|
return { width, height };
|
|
60989
61009
|
}
|
|
@@ -61124,6 +61144,9 @@ class InternalViewport {
|
|
|
61124
61144
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
61125
61145
|
}
|
|
61126
61146
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
61147
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
61148
|
+
return -1;
|
|
61149
|
+
}
|
|
61127
61150
|
const sheetId = this.sheetId;
|
|
61128
61151
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
61129
61152
|
// using a binary search:
|
|
@@ -61160,7 +61183,7 @@ class InternalViewport {
|
|
|
61160
61183
|
this.adjustViewportZoneY();
|
|
61161
61184
|
}
|
|
61162
61185
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
61163
|
-
* To make sure that at least
|
|
61186
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
61164
61187
|
*/
|
|
61165
61188
|
adjustViewportOffsetX() {
|
|
61166
61189
|
if (this.canScrollHorizontally) {
|
|
@@ -61172,7 +61195,7 @@ class InternalViewport {
|
|
|
61172
61195
|
this.adjustViewportZoneX();
|
|
61173
61196
|
}
|
|
61174
61197
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
61175
|
-
* To make sure that at least
|
|
61198
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
61176
61199
|
*/
|
|
61177
61200
|
adjustViewportOffsetY() {
|
|
61178
61201
|
if (this.canScrollVertically) {
|
|
@@ -61189,11 +61212,14 @@ class InternalViewport {
|
|
|
61189
61212
|
const sheetId = this.sheetId;
|
|
61190
61213
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
61191
61214
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
61215
|
+
if (!this.viewportWidth) {
|
|
61216
|
+
return;
|
|
61217
|
+
}
|
|
61192
61218
|
if (this.left === -1) {
|
|
61193
61219
|
this.left = this.boundaries.left;
|
|
61194
61220
|
}
|
|
61195
61221
|
if (this.right === -1) {
|
|
61196
|
-
this.right = this.
|
|
61222
|
+
this.right = this.boundaries.right;
|
|
61197
61223
|
}
|
|
61198
61224
|
this.offsetX =
|
|
61199
61225
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -61205,11 +61231,14 @@ class InternalViewport {
|
|
|
61205
61231
|
const sheetId = this.sheetId;
|
|
61206
61232
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
61207
61233
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
61234
|
+
if (!this.viewportHeight) {
|
|
61235
|
+
return;
|
|
61236
|
+
}
|
|
61208
61237
|
if (this.top === -1) {
|
|
61209
61238
|
this.top = this.boundaries.top;
|
|
61210
61239
|
}
|
|
61211
61240
|
if (this.bottom === -1) {
|
|
61212
|
-
this.bottom = this.
|
|
61241
|
+
this.bottom = this.boundaries.bottom;
|
|
61213
61242
|
}
|
|
61214
61243
|
this.offsetY =
|
|
61215
61244
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -61283,7 +61312,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61283
61312
|
"isPositionVisible",
|
|
61284
61313
|
"getColDimensionsInViewport",
|
|
61285
61314
|
"getRowDimensionsInViewport",
|
|
61286
|
-
"
|
|
61315
|
+
"getAllActiveViewportsZonesAndRect",
|
|
61287
61316
|
"getRect",
|
|
61288
61317
|
];
|
|
61289
61318
|
viewports = {};
|
|
@@ -61516,12 +61545,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61516
61545
|
const sheetId = this.getters.getActiveSheetId();
|
|
61517
61546
|
const viewports = this.getSubViewports(sheetId);
|
|
61518
61547
|
//TODO ake another commit to eimprove this
|
|
61519
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
61548
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
61520
61549
|
}
|
|
61521
61550
|
getSheetViewVisibleRows() {
|
|
61522
61551
|
const sheetId = this.getters.getActiveSheetId();
|
|
61523
61552
|
const viewports = this.getSubViewports(sheetId);
|
|
61524
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
61553
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
61525
61554
|
}
|
|
61526
61555
|
/**
|
|
61527
61556
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -61564,19 +61593,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61564
61593
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
61565
61594
|
};
|
|
61566
61595
|
}
|
|
61567
|
-
getColRowOffsetInViewport(dimension,
|
|
61568
|
-
|
|
61569
|
-
|
|
61570
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
61571
|
-
if (index < referenceIndex) {
|
|
61572
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
61596
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
61597
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
61598
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
61573
61599
|
}
|
|
61600
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
61601
|
+
const visibleHeaders = dimension === "COL"
|
|
61602
|
+
? this.getters.getSheetViewVisibleCols()
|
|
61603
|
+
: this.getters.getSheetViewVisibleRows();
|
|
61604
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
61605
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
61606
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
61574
61607
|
let offset = 0;
|
|
61575
|
-
const
|
|
61576
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
61577
|
-
if (!visibleIndexes.includes(i)) {
|
|
61578
|
-
continue;
|
|
61579
|
-
}
|
|
61608
|
+
for (const i of relevantIndexes) {
|
|
61580
61609
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
61581
61610
|
}
|
|
61582
61611
|
return offset;
|
|
@@ -61623,7 +61652,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61623
61652
|
}
|
|
61624
61653
|
return { canEdgeScroll, direction, delay };
|
|
61625
61654
|
}
|
|
61626
|
-
getEdgeScrollRow(y, previousY,
|
|
61655
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
61627
61656
|
let canEdgeScroll = false;
|
|
61628
61657
|
let direction = 0;
|
|
61629
61658
|
let delay = 0;
|
|
@@ -61644,7 +61673,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61644
61673
|
delay = scrollDelay(y - height);
|
|
61645
61674
|
direction = 1;
|
|
61646
61675
|
}
|
|
61647
|
-
else if (y < offsetCorrectionY &&
|
|
61676
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
61648
61677
|
// 2
|
|
61649
61678
|
canEdgeScroll = true;
|
|
61650
61679
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -61670,13 +61699,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61670
61699
|
*/
|
|
61671
61700
|
getVisibleRectWithoutHeaders(zone) {
|
|
61672
61701
|
const sheetId = this.getters.getActiveSheetId();
|
|
61673
|
-
|
|
61674
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
61675
|
-
.filter(isDefined);
|
|
61676
|
-
if (viewportRects.length === 0) {
|
|
61677
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61678
|
-
}
|
|
61679
|
-
return this.recomposeRect(viewportRects);
|
|
61702
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
61680
61703
|
}
|
|
61681
61704
|
/**
|
|
61682
61705
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -61684,13 +61707,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61684
61707
|
*/
|
|
61685
61708
|
getRect(zone) {
|
|
61686
61709
|
const sheetId = this.getters.getActiveSheetId();
|
|
61687
|
-
const
|
|
61688
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
61689
|
-
.filter(isDefined);
|
|
61690
|
-
if (viewportRects.length === 0) {
|
|
61691
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61692
|
-
}
|
|
61693
|
-
const rect = this.recomposeRect(viewportRects);
|
|
61710
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
61694
61711
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
61695
61712
|
}
|
|
61696
61713
|
/**
|
|
@@ -61735,9 +61752,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61735
61752
|
end: start + (isRowHidden ? 0 : size),
|
|
61736
61753
|
};
|
|
61737
61754
|
}
|
|
61738
|
-
|
|
61755
|
+
getAllActiveViewportsZonesAndRect() {
|
|
61739
61756
|
const sheetId = this.getters.getActiveSheetId();
|
|
61740
|
-
return this.getSubViewports(sheetId)
|
|
61757
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
61758
|
+
return {
|
|
61759
|
+
zone: viewport,
|
|
61760
|
+
rect: {
|
|
61761
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
61762
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
61763
|
+
...viewport.getMaxSize(),
|
|
61764
|
+
},
|
|
61765
|
+
};
|
|
61766
|
+
});
|
|
61741
61767
|
}
|
|
61742
61768
|
// ---------------------------------------------------------------------------
|
|
61743
61769
|
// Private
|
|
@@ -61796,12 +61822,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61796
61822
|
}
|
|
61797
61823
|
/** gets rid of deprecated sheetIds */
|
|
61798
61824
|
cleanViewports() {
|
|
61799
|
-
const
|
|
61800
|
-
for (
|
|
61801
|
-
|
|
61802
|
-
delete this.viewports[sheetId];
|
|
61803
|
-
}
|
|
61825
|
+
const newViewport = {};
|
|
61826
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
61827
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
61804
61828
|
}
|
|
61829
|
+
this.viewports = newViewport;
|
|
61805
61830
|
}
|
|
61806
61831
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
61807
61832
|
this.sheetViewHeight = height;
|
|
@@ -61811,7 +61836,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61811
61836
|
this.recomputeViewports();
|
|
61812
61837
|
}
|
|
61813
61838
|
recomputeViewports() {
|
|
61814
|
-
for (
|
|
61839
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
61815
61840
|
this.resetViewports(sheetId);
|
|
61816
61841
|
}
|
|
61817
61842
|
}
|
|
@@ -61833,8 +61858,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61833
61858
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
61834
61859
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
61835
61860
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
61836
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
61837
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
61861
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
61862
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
61863
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
61864
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
61838
61865
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
61839
61866
|
const canScrollHorizontally = xRatio < 1.0;
|
|
61840
61867
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -61845,14 +61872,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61845
61872
|
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 })) ||
|
|
61846
61873
|
undefined,
|
|
61847
61874
|
topRight: (ySplit &&
|
|
61848
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
61875
|
+
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 })) ||
|
|
61849
61876
|
undefined,
|
|
61850
61877
|
bottomLeft: (xSplit &&
|
|
61851
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
61878
|
+
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 })) ||
|
|
61852
61879
|
undefined,
|
|
61853
61880
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
61854
|
-
width:
|
|
61855
|
-
height:
|
|
61881
|
+
width: unfrozenWidth,
|
|
61882
|
+
height: unfrozenHeight,
|
|
61856
61883
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
61857
61884
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
61858
61885
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -61929,12 +61956,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61929
61956
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
61930
61957
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
61931
61958
|
}
|
|
61932
|
-
|
|
61933
|
-
|
|
61934
|
-
|
|
61935
|
-
|
|
61936
|
-
|
|
61937
|
-
|
|
61959
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
61960
|
+
let x = Infinity;
|
|
61961
|
+
let y = Infinity;
|
|
61962
|
+
let width = 0;
|
|
61963
|
+
let height = 0;
|
|
61964
|
+
let hasViewports = false;
|
|
61965
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
61966
|
+
const rect = rectCallBack(viewport);
|
|
61967
|
+
if (rect) {
|
|
61968
|
+
hasViewports = true;
|
|
61969
|
+
x = Math.min(x, rect.x);
|
|
61970
|
+
y = Math.min(y, rect.y);
|
|
61971
|
+
width = Math.max(width, rect.x + rect.width);
|
|
61972
|
+
height = Math.max(height, rect.y + rect.height);
|
|
61973
|
+
}
|
|
61974
|
+
}
|
|
61975
|
+
if (!hasViewports) {
|
|
61976
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61977
|
+
}
|
|
61978
|
+
return { x, y, width: width - x, height: height - y };
|
|
61938
61979
|
}
|
|
61939
61980
|
}
|
|
61940
61981
|
|
|
@@ -65550,6 +65591,9 @@ class EventStream {
|
|
|
65550
65591
|
observe(owner, callbacks) {
|
|
65551
65592
|
this.observers.set(owner, { owner, callbacks });
|
|
65552
65593
|
}
|
|
65594
|
+
detachObserver(owner) {
|
|
65595
|
+
this.observers.delete(owner);
|
|
65596
|
+
}
|
|
65553
65597
|
/**
|
|
65554
65598
|
* Capture the stream for yourself
|
|
65555
65599
|
*/
|
|
@@ -65642,6 +65686,9 @@ class SelectionStreamProcessorImpl {
|
|
|
65642
65686
|
observe(owner, callbacks) {
|
|
65643
65687
|
this.stream.observe(owner, callbacks);
|
|
65644
65688
|
}
|
|
65689
|
+
detachObserver(owner) {
|
|
65690
|
+
this.stream.detachObserver(owner);
|
|
65691
|
+
}
|
|
65645
65692
|
release(owner) {
|
|
65646
65693
|
if (this.stream.isListening(owner)) {
|
|
65647
65694
|
this.stream.release(owner);
|
|
@@ -68818,6 +68865,6 @@ const constants = {
|
|
|
68818
68865
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
68819
68866
|
|
|
68820
68867
|
|
|
68821
|
-
__info__.version = "17.4.
|
|
68822
|
-
__info__.date = "2025-
|
|
68823
|
-
__info__.hash = "
|
|
68868
|
+
__info__.version = "17.4.21";
|
|
68869
|
+
__info__.date = "2025-02-05T06:46:54.366Z";
|
|
68870
|
+
__info__.hash = "0c55e18";
|