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