@odoo/o-spreadsheet 17.4.20 → 17.4.22
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 +182 -133
- package/dist/o-spreadsheet.d.ts +17 -15
- package/dist/o-spreadsheet.esm.js +182 -133
- package/dist/o-spreadsheet.iife.js +182 -133
- package/dist/o-spreadsheet.iife.min.js +55 -55
- package/dist/o_spreadsheet.xml +5 -4
- 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.22
|
|
6
|
+
* @date 2025-02-10T09:14:48.889Z
|
|
7
|
+
* @hash 667f2b1
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -748,9 +748,16 @@ function deepEqualsArray(arr1, arr2) {
|
|
|
748
748
|
}
|
|
749
749
|
return true;
|
|
750
750
|
}
|
|
751
|
-
/**
|
|
751
|
+
/**
|
|
752
|
+
* Check if the given array contains all the values of the other array.
|
|
753
|
+
* It makes the assumption that both array do not contain duplicates.
|
|
754
|
+
*/
|
|
752
755
|
function includesAll(arr, values) {
|
|
753
|
-
|
|
756
|
+
if (arr.length < values.length) {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
const set = new Set(arr);
|
|
760
|
+
return values.every((value) => set.has(value));
|
|
754
761
|
}
|
|
755
762
|
/**
|
|
756
763
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
@@ -18883,22 +18890,23 @@ const HLOOKUP = {
|
|
|
18883
18890
|
description: _t("Horizontal lookup"),
|
|
18884
18891
|
args: [
|
|
18885
18892
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18886
|
-
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.")),
|
|
18893
|
+
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.")),
|
|
18887
18894
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18888
18895
|
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.")),
|
|
18889
18896
|
],
|
|
18890
18897
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18891
18898
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18892
|
-
|
|
18899
|
+
const _range = toMatrix(range);
|
|
18900
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18893
18901
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18894
18902
|
return searchKey;
|
|
18895
18903
|
}
|
|
18896
18904
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18897
18905
|
const _isSorted = toBoolean(isSorted.value);
|
|
18898
18906
|
const colIndex = _isSorted
|
|
18899
|
-
? dichotomicSearch(
|
|
18900
|
-
: linearSearch(
|
|
18901
|
-
const col =
|
|
18907
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18908
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18909
|
+
const col = _range[colIndex];
|
|
18902
18910
|
if (col === undefined) {
|
|
18903
18911
|
return valueNotAvailable(searchKey);
|
|
18904
18912
|
}
|
|
@@ -18997,35 +19005,37 @@ const LOOKUP = {
|
|
|
18997
19005
|
description: _t("Look up a value."),
|
|
18998
19006
|
args: [
|
|
18999
19007
|
arg("search_key (any)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
19000
|
-
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.")),
|
|
19001
|
-
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.")),
|
|
19008
|
+
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.")),
|
|
19009
|
+
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.")),
|
|
19002
19010
|
],
|
|
19003
19011
|
compute: function (searchKey, searchArray, resultRange) {
|
|
19004
|
-
|
|
19005
|
-
|
|
19012
|
+
const _searchArray = toMatrix(searchArray);
|
|
19013
|
+
const _resultRange = toMatrix(resultRange);
|
|
19014
|
+
let nbCol = _searchArray.length;
|
|
19015
|
+
let nbRow = _searchArray[0].length;
|
|
19006
19016
|
const verticalSearch = nbRow >= nbCol;
|
|
19007
19017
|
const getElement = verticalSearch
|
|
19008
19018
|
? (range, index) => range[0][index].value
|
|
19009
19019
|
: (range, index) => range[index][0].value;
|
|
19010
19020
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
19011
|
-
const index = dichotomicSearch(
|
|
19021
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
19012
19022
|
if (index === -1 ||
|
|
19013
|
-
(verticalSearch &&
|
|
19014
|
-
(!verticalSearch &&
|
|
19023
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
19024
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
19015
19025
|
return valueNotAvailable(searchKey);
|
|
19016
19026
|
}
|
|
19017
|
-
if (
|
|
19018
|
-
return verticalSearch ?
|
|
19027
|
+
if (_resultRange[0].length === 0) {
|
|
19028
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
19019
19029
|
}
|
|
19020
|
-
nbCol =
|
|
19021
|
-
nbRow =
|
|
19030
|
+
nbCol = _resultRange.length;
|
|
19031
|
+
nbRow = _resultRange[0].length;
|
|
19022
19032
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
19023
19033
|
if (nbCol > 1) {
|
|
19024
19034
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
19025
|
-
return
|
|
19035
|
+
return _resultRange[index][0];
|
|
19026
19036
|
}
|
|
19027
19037
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
19028
|
-
return
|
|
19038
|
+
return _resultRange[0][index];
|
|
19029
19039
|
},
|
|
19030
19040
|
isExported: true,
|
|
19031
19041
|
};
|
|
@@ -19042,28 +19052,29 @@ const MATCH = {
|
|
|
19042
19052
|
],
|
|
19043
19053
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
19044
19054
|
let _searchType = toNumber(searchType, this.locale);
|
|
19045
|
-
const
|
|
19046
|
-
const
|
|
19055
|
+
const _range = toMatrix(range);
|
|
19056
|
+
const nbCol = _range.length;
|
|
19057
|
+
const nbRow = _range[0].length;
|
|
19047
19058
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
19048
19059
|
let index = -1;
|
|
19049
19060
|
const getElement = nbCol === 1
|
|
19050
|
-
? (
|
|
19051
|
-
: (
|
|
19052
|
-
const rangeLen = nbCol === 1 ?
|
|
19061
|
+
? (_range, index) => _range[0][index].value
|
|
19062
|
+
: (_range, index) => _range[index][0].value;
|
|
19063
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
19053
19064
|
_searchType = Math.sign(_searchType);
|
|
19054
19065
|
switch (_searchType) {
|
|
19055
19066
|
case 1:
|
|
19056
|
-
index = dichotomicSearch(
|
|
19067
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
19057
19068
|
break;
|
|
19058
19069
|
case 0:
|
|
19059
|
-
index = linearSearch(
|
|
19070
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
19060
19071
|
break;
|
|
19061
19072
|
case -1:
|
|
19062
|
-
index = dichotomicSearch(
|
|
19073
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
19063
19074
|
break;
|
|
19064
19075
|
}
|
|
19065
|
-
if ((nbCol === 1 &&
|
|
19066
|
-
(nbCol !== 1 &&
|
|
19076
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
19077
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
19067
19078
|
return valueNotAvailable(searchKey);
|
|
19068
19079
|
}
|
|
19069
19080
|
return index + 1;
|
|
@@ -19117,16 +19128,17 @@ const VLOOKUP = {
|
|
|
19117
19128
|
],
|
|
19118
19129
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
19119
19130
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
19120
|
-
|
|
19131
|
+
const _range = toMatrix(range);
|
|
19132
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
19121
19133
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
19122
19134
|
return searchKey;
|
|
19123
19135
|
}
|
|
19124
19136
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
19125
19137
|
const _isSorted = toBoolean(isSorted.value);
|
|
19126
19138
|
const rowIndex = _isSorted
|
|
19127
|
-
? dichotomicSearch(
|
|
19128
|
-
: linearSearch(
|
|
19129
|
-
const value =
|
|
19139
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
19140
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
19141
|
+
const value = _range[_index - 1][rowIndex];
|
|
19130
19142
|
if (value === undefined) {
|
|
19131
19143
|
return valueNotAvailable(searchKey);
|
|
19132
19144
|
}
|
|
@@ -19163,30 +19175,32 @@ const XLOOKUP = {
|
|
|
19163
19175
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
19164
19176
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
19165
19177
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
19166
|
-
|
|
19178
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
19179
|
+
const _returnRange = toMatrix(returnRange);
|
|
19180
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
19167
19181
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
19168
19182
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
19169
|
-
const lookupDirection =
|
|
19183
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
19170
19184
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
19171
19185
|
assert(() => lookupDirection === "col"
|
|
19172
|
-
?
|
|
19173
|
-
:
|
|
19186
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
19187
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
19174
19188
|
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
19175
19189
|
return [[searchKey]];
|
|
19176
19190
|
}
|
|
19177
19191
|
const getElement = lookupDirection === "col"
|
|
19178
19192
|
? (range, index) => range[0][index].value
|
|
19179
19193
|
: (range, index) => range[index][0].value;
|
|
19180
|
-
const rangeLen = lookupDirection === "col" ?
|
|
19194
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
19181
19195
|
const mode = MATCH_MODE[_matchMode];
|
|
19182
19196
|
const reverseSearch = _searchMode === -1;
|
|
19183
19197
|
const index = _searchMode === 2 || _searchMode === -2
|
|
19184
|
-
? dichotomicSearch(
|
|
19185
|
-
: linearSearch(
|
|
19198
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
19199
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
19186
19200
|
if (index !== -1) {
|
|
19187
19201
|
return lookupDirection === "col"
|
|
19188
|
-
?
|
|
19189
|
-
: [
|
|
19202
|
+
? _returnRange.map((col) => [col[index]])
|
|
19203
|
+
: [_returnRange[index]];
|
|
19190
19204
|
}
|
|
19191
19205
|
if (defaultValue === undefined) {
|
|
19192
19206
|
return valueNotAvailable(searchKey);
|
|
@@ -33540,8 +33554,8 @@ function useDragAndDropListItems() {
|
|
|
33540
33554
|
document.body.style.cursor = "move";
|
|
33541
33555
|
state.draggedItemId = args.draggedItemId;
|
|
33542
33556
|
const container = direction === "horizontal"
|
|
33543
|
-
? new HorizontalContainer(args.
|
|
33544
|
-
: new VerticalContainer(args.
|
|
33557
|
+
? new HorizontalContainer(args.scrollableContainerEl)
|
|
33558
|
+
: new VerticalContainer(args.scrollableContainerEl);
|
|
33545
33559
|
dndHelper = new DOMDndHelper({
|
|
33546
33560
|
...args,
|
|
33547
33561
|
container,
|
|
@@ -33552,8 +33566,8 @@ function useDragAndDropListItems() {
|
|
|
33552
33566
|
const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
33553
33567
|
cleanupFns.push(stopListening);
|
|
33554
33568
|
const onScroll = dndHelper.onScroll.bind(dndHelper);
|
|
33555
|
-
args.
|
|
33556
|
-
cleanupFns.push(() => args.
|
|
33569
|
+
args.scrollableContainerEl.addEventListener("scroll", onScroll);
|
|
33570
|
+
cleanupFns.push(() => args.scrollableContainerEl.removeEventListener("scroll", onScroll));
|
|
33557
33571
|
cleanupFns.push(dndHelper.destroy.bind(dndHelper));
|
|
33558
33572
|
};
|
|
33559
33573
|
owl.onWillUnmount(() => {
|
|
@@ -34001,7 +34015,7 @@ class ConditionalFormatPreviewList extends owl.Component {
|
|
|
34001
34015
|
draggedItemId: cf.id,
|
|
34002
34016
|
initialMousePosition: event.clientY,
|
|
34003
34017
|
items: items,
|
|
34004
|
-
|
|
34018
|
+
scrollableContainerEl: this.cfListRef.el,
|
|
34005
34019
|
onDragEnd: (cfId, finalIndex) => this.onDragEnd(cfId, finalIndex),
|
|
34006
34020
|
});
|
|
34007
34021
|
}
|
|
@@ -36013,6 +36027,7 @@ class PivotLayoutConfigurator extends owl.Component {
|
|
|
36013
36027
|
unusedMeasureFields: Array,
|
|
36014
36028
|
unusedDateTimeGranularities: Object,
|
|
36015
36029
|
allGranularities: Array,
|
|
36030
|
+
getScrollableContainerEl: { type: Function, optional: true },
|
|
36016
36031
|
};
|
|
36017
36032
|
dimensionsRef = owl.useRef("pivot-dimensions");
|
|
36018
36033
|
dragAndDrop = useDragAndDropListItems();
|
|
@@ -36041,7 +36056,7 @@ class PivotLayoutConfigurator extends owl.Component {
|
|
|
36041
36056
|
draggedItemId: dimension.nameWithGranularity,
|
|
36042
36057
|
initialMousePosition: event.clientY,
|
|
36043
36058
|
items: draggableItems,
|
|
36044
|
-
|
|
36059
|
+
scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
|
|
36045
36060
|
onDragEnd: (dimensionName, finalIndex) => {
|
|
36046
36061
|
const originalIndex = draggableIds.findIndex((id) => id === dimensionName);
|
|
36047
36062
|
if (originalIndex === finalIndex) {
|
|
@@ -36081,7 +36096,7 @@ class PivotLayoutConfigurator extends owl.Component {
|
|
|
36081
36096
|
draggedItemId: measure.name,
|
|
36082
36097
|
initialMousePosition: event.clientY,
|
|
36083
36098
|
items: draggableItems,
|
|
36084
|
-
|
|
36099
|
+
scrollableContainerEl: this.props.getScrollableContainerEl?.() || this.dimensionsRef.el,
|
|
36085
36100
|
onDragEnd: (measureName, finalIndex) => {
|
|
36086
36101
|
const originalIndex = draggableIds.findIndex((id) => id === measureName);
|
|
36087
36102
|
if (originalIndex === finalIndex) {
|
|
@@ -37520,6 +37535,7 @@ class PivotSpreadsheetSidePanel extends owl.Component {
|
|
|
37520
37535
|
};
|
|
37521
37536
|
store;
|
|
37522
37537
|
state;
|
|
37538
|
+
pivotSidePanelRef = owl.useRef("pivotSidePanel");
|
|
37523
37539
|
setup() {
|
|
37524
37540
|
this.store = useLocalStore(PivotSidePanelStore, this.props.pivotId);
|
|
37525
37541
|
this.state = owl.useState({
|
|
@@ -37548,6 +37564,9 @@ class PivotSpreadsheetSidePanel extends owl.Component {
|
|
|
37548
37564
|
get definition() {
|
|
37549
37565
|
return this.store.definition;
|
|
37550
37566
|
}
|
|
37567
|
+
getScrollableContainerEl() {
|
|
37568
|
+
return this.pivotSidePanelRef.el;
|
|
37569
|
+
}
|
|
37551
37570
|
onSelectionChanged(ranges) {
|
|
37552
37571
|
this.state.rangeHasChanged = true;
|
|
37553
37572
|
this.state.range = ranges[0];
|
|
@@ -41220,11 +41239,10 @@ class GridRenderer {
|
|
|
41220
41239
|
switch (layer) {
|
|
41221
41240
|
case "Background":
|
|
41222
41241
|
this.drawGlobalBackground(renderingContext);
|
|
41223
|
-
for (const zone of this.getters.
|
|
41242
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
41224
41243
|
const { ctx } = renderingContext;
|
|
41225
41244
|
ctx.save();
|
|
41226
41245
|
ctx.beginPath();
|
|
41227
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
41228
41246
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
41229
41247
|
ctx.clip();
|
|
41230
41248
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -41494,10 +41512,8 @@ class GridRenderer {
|
|
|
41494
41512
|
const { ctx, thinLineWidth } = renderingContext;
|
|
41495
41513
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
41496
41514
|
const left = visibleCols[0];
|
|
41497
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
41498
41515
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
41499
41516
|
const top = visibleRows[0];
|
|
41500
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
41501
41517
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
41502
41518
|
const selection = this.getters.getSelectedZones();
|
|
41503
41519
|
const selectedCols = getZonesCols(selection);
|
|
@@ -41513,7 +41529,7 @@ class GridRenderer {
|
|
|
41513
41529
|
ctx.lineWidth = thinLineWidth;
|
|
41514
41530
|
ctx.strokeStyle = "#333";
|
|
41515
41531
|
// Columns headers background
|
|
41516
|
-
for (
|
|
41532
|
+
for (const col of visibleCols) {
|
|
41517
41533
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
41518
41534
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
41519
41535
|
const isColActive = activeCols.has(col);
|
|
@@ -41530,7 +41546,7 @@ class GridRenderer {
|
|
|
41530
41546
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
41531
41547
|
}
|
|
41532
41548
|
// Rows headers background
|
|
41533
|
-
for (
|
|
41549
|
+
for (const row of visibleRows) {
|
|
41534
41550
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
41535
41551
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
41536
41552
|
const isRowActive = activeRows.has(row);
|
|
@@ -41556,21 +41572,21 @@ class GridRenderer {
|
|
|
41556
41572
|
ctx.stroke();
|
|
41557
41573
|
ctx.beginPath();
|
|
41558
41574
|
// column text + separator
|
|
41559
|
-
for (const
|
|
41560
|
-
const colSize = this.getters.getColSize(sheetId,
|
|
41561
|
-
const colName = numberToLetters(
|
|
41562
|
-
ctx.fillStyle = activeCols.has(
|
|
41563
|
-
let colStart = this.getHeaderOffset("COL", left,
|
|
41575
|
+
for (const col of visibleCols) {
|
|
41576
|
+
const colSize = this.getters.getColSize(sheetId, col);
|
|
41577
|
+
const colName = numberToLetters(col);
|
|
41578
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
41579
|
+
let colStart = this.getHeaderOffset("COL", left, col);
|
|
41564
41580
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
41565
41581
|
ctx.moveTo(colStart + colSize, 0);
|
|
41566
41582
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
41567
41583
|
}
|
|
41568
41584
|
// row text + separator
|
|
41569
|
-
for (const
|
|
41570
|
-
const rowSize = this.getters.getRowSize(sheetId,
|
|
41571
|
-
ctx.fillStyle = activeRows.has(
|
|
41572
|
-
let rowStart = this.getHeaderOffset("ROW", top,
|
|
41573
|
-
ctx.fillText(String(
|
|
41585
|
+
for (const row of visibleRows) {
|
|
41586
|
+
const rowSize = this.getters.getRowSize(sheetId, row);
|
|
41587
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
41588
|
+
let rowStart = this.getHeaderOffset("ROW", top, row);
|
|
41589
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
41574
41590
|
ctx.moveTo(0, rowStart + rowSize);
|
|
41575
41591
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
41576
41592
|
}
|
|
@@ -41868,6 +41884,9 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
41868
41884
|
canvas.width = width * dpr;
|
|
41869
41885
|
canvas.height = height * dpr;
|
|
41870
41886
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
41887
|
+
if (width === 0 || height === 0) {
|
|
41888
|
+
return;
|
|
41889
|
+
}
|
|
41871
41890
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
41872
41891
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
41873
41892
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -47600,7 +47619,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
47600
47619
|
getCommonSides(border1, border2) {
|
|
47601
47620
|
const commonBorder = {};
|
|
47602
47621
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
47603
|
-
if (border1[side] && border1[side]
|
|
47622
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
47604
47623
|
commonBorder[side] = border1[side];
|
|
47605
47624
|
}
|
|
47606
47625
|
}
|
|
@@ -60943,8 +60962,17 @@ class InternalViewport {
|
|
|
60943
60962
|
this.getters = getters;
|
|
60944
60963
|
this.sheetId = sheetId;
|
|
60945
60964
|
this.boundaries = boundaries;
|
|
60946
|
-
|
|
60947
|
-
|
|
60965
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
60966
|
+
throw new Error("Viewport size cannot be negative");
|
|
60967
|
+
}
|
|
60968
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
60969
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
60970
|
+
this.top = boundaries.top;
|
|
60971
|
+
this.bottom = boundaries.bottom;
|
|
60972
|
+
this.left = boundaries.left;
|
|
60973
|
+
this.right = boundaries.right;
|
|
60974
|
+
this.offsetX = offsets.x;
|
|
60975
|
+
this.offsetY = offsets.y;
|
|
60948
60976
|
this.offsetScrollbarX = offsets.x;
|
|
60949
60977
|
this.offsetScrollbarY = offsets.y;
|
|
60950
60978
|
this.canScrollVertically = options.canScrollVertically;
|
|
@@ -60987,9 +61015,9 @@ class InternalViewport {
|
|
|
60987
61015
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
60988
61016
|
);
|
|
60989
61017
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
60990
|
-
|
|
60991
|
-
|
|
60992
|
-
|
|
61018
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
61019
|
+
height += FOOTER_HEIGHT;
|
|
61020
|
+
}
|
|
60993
61021
|
}
|
|
60994
61022
|
return { width, height };
|
|
60995
61023
|
}
|
|
@@ -61130,6 +61158,9 @@ class InternalViewport {
|
|
|
61130
61158
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
61131
61159
|
}
|
|
61132
61160
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
61161
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
61162
|
+
return -1;
|
|
61163
|
+
}
|
|
61133
61164
|
const sheetId = this.sheetId;
|
|
61134
61165
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
61135
61166
|
// using a binary search:
|
|
@@ -61166,7 +61197,7 @@ class InternalViewport {
|
|
|
61166
61197
|
this.adjustViewportZoneY();
|
|
61167
61198
|
}
|
|
61168
61199
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
61169
|
-
* To make sure that at least
|
|
61200
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
61170
61201
|
*/
|
|
61171
61202
|
adjustViewportOffsetX() {
|
|
61172
61203
|
if (this.canScrollHorizontally) {
|
|
@@ -61178,7 +61209,7 @@ class InternalViewport {
|
|
|
61178
61209
|
this.adjustViewportZoneX();
|
|
61179
61210
|
}
|
|
61180
61211
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
61181
|
-
* To make sure that at least
|
|
61212
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
61182
61213
|
*/
|
|
61183
61214
|
adjustViewportOffsetY() {
|
|
61184
61215
|
if (this.canScrollVertically) {
|
|
@@ -61195,11 +61226,14 @@ class InternalViewport {
|
|
|
61195
61226
|
const sheetId = this.sheetId;
|
|
61196
61227
|
this.left = this.searchHeaderIndex("COL", this.offsetScrollbarX, this.boundaries.left);
|
|
61197
61228
|
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL", this.viewportWidth, this.left));
|
|
61229
|
+
if (!this.viewportWidth) {
|
|
61230
|
+
return;
|
|
61231
|
+
}
|
|
61198
61232
|
if (this.left === -1) {
|
|
61199
61233
|
this.left = this.boundaries.left;
|
|
61200
61234
|
}
|
|
61201
61235
|
if (this.right === -1) {
|
|
61202
|
-
this.right = this.
|
|
61236
|
+
this.right = this.boundaries.right;
|
|
61203
61237
|
}
|
|
61204
61238
|
this.offsetX =
|
|
61205
61239
|
this.getters.getColDimensions(sheetId, this.left).start -
|
|
@@ -61211,11 +61245,14 @@ class InternalViewport {
|
|
|
61211
61245
|
const sheetId = this.sheetId;
|
|
61212
61246
|
this.top = this.searchHeaderIndex("ROW", this.offsetScrollbarY, this.boundaries.top);
|
|
61213
61247
|
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW", this.viewportHeight, this.top));
|
|
61248
|
+
if (!this.viewportHeight) {
|
|
61249
|
+
return;
|
|
61250
|
+
}
|
|
61214
61251
|
if (this.top === -1) {
|
|
61215
61252
|
this.top = this.boundaries.top;
|
|
61216
61253
|
}
|
|
61217
61254
|
if (this.bottom === -1) {
|
|
61218
|
-
this.bottom = this.
|
|
61255
|
+
this.bottom = this.boundaries.bottom;
|
|
61219
61256
|
}
|
|
61220
61257
|
this.offsetY =
|
|
61221
61258
|
this.getters.getRowDimensions(sheetId, this.top).start -
|
|
@@ -61289,7 +61326,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61289
61326
|
"isPositionVisible",
|
|
61290
61327
|
"getColDimensionsInViewport",
|
|
61291
61328
|
"getRowDimensionsInViewport",
|
|
61292
|
-
"
|
|
61329
|
+
"getAllActiveViewportsZonesAndRect",
|
|
61293
61330
|
"getRect",
|
|
61294
61331
|
];
|
|
61295
61332
|
viewports = {};
|
|
@@ -61522,12 +61559,12 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61522
61559
|
const sheetId = this.getters.getActiveSheetId();
|
|
61523
61560
|
const viewports = this.getSubViewports(sheetId);
|
|
61524
61561
|
//TODO ake another commit to eimprove this
|
|
61525
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
61562
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
61526
61563
|
}
|
|
61527
61564
|
getSheetViewVisibleRows() {
|
|
61528
61565
|
const sheetId = this.getters.getActiveSheetId();
|
|
61529
61566
|
const viewports = this.getSubViewports(sheetId);
|
|
61530
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
61567
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
61531
61568
|
}
|
|
61532
61569
|
/**
|
|
61533
61570
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -61570,19 +61607,19 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61570
61607
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
61571
61608
|
};
|
|
61572
61609
|
}
|
|
61573
|
-
getColRowOffsetInViewport(dimension,
|
|
61574
|
-
|
|
61575
|
-
|
|
61576
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
61577
|
-
if (index < referenceIndex) {
|
|
61578
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
61610
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
61611
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
61612
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
61579
61613
|
}
|
|
61614
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
61615
|
+
const visibleHeaders = dimension === "COL"
|
|
61616
|
+
? this.getters.getSheetViewVisibleCols()
|
|
61617
|
+
: this.getters.getSheetViewVisibleRows();
|
|
61618
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
61619
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
61620
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
61580
61621
|
let offset = 0;
|
|
61581
|
-
const
|
|
61582
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
61583
|
-
if (!visibleIndexes.includes(i)) {
|
|
61584
|
-
continue;
|
|
61585
|
-
}
|
|
61622
|
+
for (const i of relevantIndexes) {
|
|
61586
61623
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
61587
61624
|
}
|
|
61588
61625
|
return offset;
|
|
@@ -61629,7 +61666,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61629
61666
|
}
|
|
61630
61667
|
return { canEdgeScroll, direction, delay };
|
|
61631
61668
|
}
|
|
61632
|
-
getEdgeScrollRow(y, previousY,
|
|
61669
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
61633
61670
|
let canEdgeScroll = false;
|
|
61634
61671
|
let direction = 0;
|
|
61635
61672
|
let delay = 0;
|
|
@@ -61650,7 +61687,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61650
61687
|
delay = scrollDelay(y - height);
|
|
61651
61688
|
direction = 1;
|
|
61652
61689
|
}
|
|
61653
|
-
else if (y < offsetCorrectionY &&
|
|
61690
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
61654
61691
|
// 2
|
|
61655
61692
|
canEdgeScroll = true;
|
|
61656
61693
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -61676,13 +61713,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61676
61713
|
*/
|
|
61677
61714
|
getVisibleRectWithoutHeaders(zone) {
|
|
61678
61715
|
const sheetId = this.getters.getActiveSheetId();
|
|
61679
|
-
|
|
61680
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
61681
|
-
.filter(isDefined);
|
|
61682
|
-
if (viewportRects.length === 0) {
|
|
61683
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61684
|
-
}
|
|
61685
|
-
return this.recomposeRect(viewportRects);
|
|
61716
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
61686
61717
|
}
|
|
61687
61718
|
/**
|
|
61688
61719
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -61690,13 +61721,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61690
61721
|
*/
|
|
61691
61722
|
getRect(zone) {
|
|
61692
61723
|
const sheetId = this.getters.getActiveSheetId();
|
|
61693
|
-
const
|
|
61694
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
61695
|
-
.filter(isDefined);
|
|
61696
|
-
if (viewportRects.length === 0) {
|
|
61697
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61698
|
-
}
|
|
61699
|
-
const rect = this.recomposeRect(viewportRects);
|
|
61724
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
61700
61725
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
61701
61726
|
}
|
|
61702
61727
|
/**
|
|
@@ -61741,9 +61766,18 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61741
61766
|
end: start + (isRowHidden ? 0 : size),
|
|
61742
61767
|
};
|
|
61743
61768
|
}
|
|
61744
|
-
|
|
61769
|
+
getAllActiveViewportsZonesAndRect() {
|
|
61745
61770
|
const sheetId = this.getters.getActiveSheetId();
|
|
61746
|
-
return this.getSubViewports(sheetId)
|
|
61771
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
61772
|
+
return {
|
|
61773
|
+
zone: viewport,
|
|
61774
|
+
rect: {
|
|
61775
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
61776
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
61777
|
+
...viewport.getMaxSize(),
|
|
61778
|
+
},
|
|
61779
|
+
};
|
|
61780
|
+
});
|
|
61747
61781
|
}
|
|
61748
61782
|
// ---------------------------------------------------------------------------
|
|
61749
61783
|
// Private
|
|
@@ -61802,12 +61836,11 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61802
61836
|
}
|
|
61803
61837
|
/** gets rid of deprecated sheetIds */
|
|
61804
61838
|
cleanViewports() {
|
|
61805
|
-
const
|
|
61806
|
-
for (
|
|
61807
|
-
|
|
61808
|
-
delete this.viewports[sheetId];
|
|
61809
|
-
}
|
|
61839
|
+
const newViewport = {};
|
|
61840
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
61841
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
61810
61842
|
}
|
|
61843
|
+
this.viewports = newViewport;
|
|
61811
61844
|
}
|
|
61812
61845
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
61813
61846
|
this.sheetViewHeight = height;
|
|
@@ -61817,7 +61850,7 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61817
61850
|
this.recomputeViewports();
|
|
61818
61851
|
}
|
|
61819
61852
|
recomputeViewports() {
|
|
61820
|
-
for (
|
|
61853
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
61821
61854
|
this.resetViewports(sheetId);
|
|
61822
61855
|
}
|
|
61823
61856
|
}
|
|
@@ -61839,8 +61872,10 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61839
61872
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
61840
61873
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
61841
61874
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
61842
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
61843
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
61875
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
61876
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
61877
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
61878
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
61844
61879
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
61845
61880
|
const canScrollHorizontally = xRatio < 1.0;
|
|
61846
61881
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -61851,14 +61886,14 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61851
61886
|
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 })) ||
|
|
61852
61887
|
undefined,
|
|
61853
61888
|
topRight: (ySplit &&
|
|
61854
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
61889
|
+
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 })) ||
|
|
61855
61890
|
undefined,
|
|
61856
61891
|
bottomLeft: (xSplit &&
|
|
61857
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
61892
|
+
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 })) ||
|
|
61858
61893
|
undefined,
|
|
61859
61894
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
61860
|
-
width:
|
|
61861
|
-
height:
|
|
61895
|
+
width: unfrozenWidth,
|
|
61896
|
+
height: unfrozenHeight,
|
|
61862
61897
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
61863
61898
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
61864
61899
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -61935,12 +61970,26 @@ class SheetViewPlugin extends UIPlugin {
|
|
|
61935
61970
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
61936
61971
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
61937
61972
|
}
|
|
61938
|
-
|
|
61939
|
-
|
|
61940
|
-
|
|
61941
|
-
|
|
61942
|
-
|
|
61943
|
-
|
|
61973
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
61974
|
+
let x = Infinity;
|
|
61975
|
+
let y = Infinity;
|
|
61976
|
+
let width = 0;
|
|
61977
|
+
let height = 0;
|
|
61978
|
+
let hasViewports = false;
|
|
61979
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
61980
|
+
const rect = rectCallBack(viewport);
|
|
61981
|
+
if (rect) {
|
|
61982
|
+
hasViewports = true;
|
|
61983
|
+
x = Math.min(x, rect.x);
|
|
61984
|
+
y = Math.min(y, rect.y);
|
|
61985
|
+
width = Math.max(width, rect.x + rect.width);
|
|
61986
|
+
height = Math.max(height, rect.y + rect.height);
|
|
61987
|
+
}
|
|
61988
|
+
}
|
|
61989
|
+
if (!hasViewports) {
|
|
61990
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
61991
|
+
}
|
|
61992
|
+
return { x, y, width: width - x, height: height - y };
|
|
61944
61993
|
}
|
|
61945
61994
|
}
|
|
61946
61995
|
|
|
@@ -62911,7 +62960,7 @@ class BottomBar extends owl.Component {
|
|
|
62911
62960
|
draggedItemId: sheetId,
|
|
62912
62961
|
initialMousePosition: event.clientX,
|
|
62913
62962
|
items: sheets,
|
|
62914
|
-
|
|
62963
|
+
scrollableContainerEl: this.sheetListRef.el,
|
|
62915
62964
|
onDragEnd: (sheetId, finalIndex) => this.onDragEnd(sheetId, finalIndex),
|
|
62916
62965
|
});
|
|
62917
62966
|
}
|
|
@@ -68873,6 +68922,6 @@ exports.tokenColors = tokenColors;
|
|
|
68873
68922
|
exports.tokenize = tokenize;
|
|
68874
68923
|
|
|
68875
68924
|
|
|
68876
|
-
__info__.version = "17.4.
|
|
68877
|
-
__info__.date = "2025-
|
|
68878
|
-
__info__.hash = "
|
|
68925
|
+
__info__.version = "17.4.22";
|
|
68926
|
+
__info__.date = "2025-02-10T09:14:48.889Z";
|
|
68927
|
+
__info__.hash = "667f2b1";
|