@odoo/o-spreadsheet 18.2.0-alpha.4 → 18.2.0-alpha.6
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 +596 -491
- package/dist/o-spreadsheet.d.ts +31 -66
- package/dist/o-spreadsheet.esm.js +596 -491
- package/dist/o-spreadsheet.iife.js +596 -491
- package/dist/o-spreadsheet.iife.min.js +214 -218
- package/dist/o_spreadsheet.xml +5553 -5540
- package/package.json +8 -5
|
@@ -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 18.2.0-alpha.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.0-alpha.6
|
|
6
|
+
* @date 2025-02-05T06:50:47.008Z
|
|
7
|
+
* @hash dae9ab2
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -3360,11 +3360,11 @@
|
|
|
3360
3360
|
* number from the point of view of the isNumber function.
|
|
3361
3361
|
*/
|
|
3362
3362
|
function parseNumber(str, locale) {
|
|
3363
|
+
// remove invaluable characters
|
|
3364
|
+
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3363
3365
|
if (locale.decimalSeparator !== ".") {
|
|
3364
3366
|
str = str.replace(locale.decimalSeparator, ".");
|
|
3365
3367
|
}
|
|
3366
|
-
// remove invaluable characters
|
|
3367
|
-
str = str.replace(getInvaluableSymbolsRegexp(locale), "");
|
|
3368
3368
|
let n = Number(str);
|
|
3369
3369
|
if (isNaN(n) && str.includes("%")) {
|
|
3370
3370
|
n = Number(str.split("%")[0]);
|
|
@@ -18633,19 +18633,20 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18633
18633
|
description: _t("Horizontal lookup"),
|
|
18634
18634
|
args: [
|
|
18635
18635
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18636
|
-
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.")),
|
|
18636
|
+
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.")),
|
|
18637
18637
|
arg("index (number)", _t("The row index of the value to be returned, where the first row in range is numbered 1.")),
|
|
18638
18638
|
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.")),
|
|
18639
18639
|
],
|
|
18640
18640
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18641
18641
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18642
|
-
|
|
18642
|
+
const _range = toMatrix(range);
|
|
18643
|
+
assert(() => 1 <= _index && _index <= _range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18643
18644
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18644
18645
|
const _isSorted = toBoolean(isSorted.value);
|
|
18645
18646
|
const colIndex = _isSorted
|
|
18646
|
-
? dichotomicSearch(
|
|
18647
|
-
: linearSearch(
|
|
18648
|
-
const col =
|
|
18647
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18648
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18649
|
+
const col = _range[colIndex];
|
|
18649
18650
|
if (col === undefined) {
|
|
18650
18651
|
return valueNotAvailable(searchKey);
|
|
18651
18652
|
}
|
|
@@ -18737,35 +18738,37 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18737
18738
|
description: _t("Look up a value."),
|
|
18738
18739
|
args: [
|
|
18739
18740
|
arg("search_key (string, number, boolean)", _t("The value to search for. For example, 42, 'Cats', or I24.")),
|
|
18740
|
-
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.")),
|
|
18741
|
-
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.")),
|
|
18741
|
+
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.")),
|
|
18742
|
+
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.")),
|
|
18742
18743
|
],
|
|
18743
18744
|
compute: function (searchKey, searchArray, resultRange) {
|
|
18744
|
-
|
|
18745
|
-
|
|
18745
|
+
const _searchArray = toMatrix(searchArray);
|
|
18746
|
+
const _resultRange = toMatrix(resultRange);
|
|
18747
|
+
let nbCol = _searchArray.length;
|
|
18748
|
+
let nbRow = _searchArray[0].length;
|
|
18746
18749
|
const verticalSearch = nbRow >= nbCol;
|
|
18747
18750
|
const getElement = verticalSearch
|
|
18748
18751
|
? (range, index) => range[0][index].value
|
|
18749
18752
|
: (range, index) => range[index][0].value;
|
|
18750
18753
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18751
|
-
const index = dichotomicSearch(
|
|
18754
|
+
const index = dichotomicSearch(_searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18752
18755
|
if (index === -1 ||
|
|
18753
|
-
(verticalSearch &&
|
|
18754
|
-
(!verticalSearch &&
|
|
18756
|
+
(verticalSearch && _searchArray[0][index] === undefined) ||
|
|
18757
|
+
(!verticalSearch && _searchArray[index][nbRow - 1] === undefined)) {
|
|
18755
18758
|
return valueNotAvailable(searchKey);
|
|
18756
18759
|
}
|
|
18757
|
-
if (
|
|
18758
|
-
return verticalSearch ?
|
|
18760
|
+
if (_resultRange[0].length === 0) {
|
|
18761
|
+
return verticalSearch ? _searchArray[nbCol - 1][index] : _searchArray[index][nbRow - 1];
|
|
18759
18762
|
}
|
|
18760
|
-
nbCol =
|
|
18761
|
-
nbRow =
|
|
18763
|
+
nbCol = _resultRange.length;
|
|
18764
|
+
nbRow = _resultRange[0].length;
|
|
18762
18765
|
assert(() => nbCol === 1 || nbRow === 1, _t("The result_range must be a single row or a single column."));
|
|
18763
18766
|
if (nbCol > 1) {
|
|
18764
18767
|
assert(() => index <= nbCol - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range row value %s.", (index + 1).toString()));
|
|
18765
|
-
return
|
|
18768
|
+
return _resultRange[index][0];
|
|
18766
18769
|
}
|
|
18767
18770
|
assert(() => index <= nbRow - 1, _t("[[FUNCTION_NAME]] evaluates to an out of range column value %s.", (index + 1).toString()));
|
|
18768
|
-
return
|
|
18771
|
+
return _resultRange[0][index];
|
|
18769
18772
|
},
|
|
18770
18773
|
isExported: true,
|
|
18771
18774
|
};
|
|
@@ -18782,28 +18785,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18782
18785
|
],
|
|
18783
18786
|
compute: function (searchKey, range, searchType = { value: DEFAULT_SEARCH_TYPE }) {
|
|
18784
18787
|
let _searchType = toNumber(searchType, this.locale);
|
|
18785
|
-
const
|
|
18786
|
-
const
|
|
18788
|
+
const _range = toMatrix(range);
|
|
18789
|
+
const nbCol = _range.length;
|
|
18790
|
+
const nbRow = _range[0].length;
|
|
18787
18791
|
assert(() => nbCol === 1 || nbRow === 1, _t("The range must be a single row or a single column."));
|
|
18788
18792
|
let index = -1;
|
|
18789
18793
|
const getElement = nbCol === 1
|
|
18790
|
-
? (
|
|
18791
|
-
: (
|
|
18792
|
-
const rangeLen = nbCol === 1 ?
|
|
18794
|
+
? (_range, index) => _range[0][index].value
|
|
18795
|
+
: (_range, index) => _range[index][0].value;
|
|
18796
|
+
const rangeLen = nbCol === 1 ? _range[0].length : _range.length;
|
|
18793
18797
|
_searchType = Math.sign(_searchType);
|
|
18794
18798
|
switch (_searchType) {
|
|
18795
18799
|
case 1:
|
|
18796
|
-
index = dichotomicSearch(
|
|
18800
|
+
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18797
18801
|
break;
|
|
18798
18802
|
case 0:
|
|
18799
|
-
index = linearSearch(
|
|
18803
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18800
18804
|
break;
|
|
18801
18805
|
case -1:
|
|
18802
|
-
index = dichotomicSearch(
|
|
18806
|
+
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18803
18807
|
break;
|
|
18804
18808
|
}
|
|
18805
|
-
if ((nbCol === 1 &&
|
|
18806
|
-
(nbCol !== 1 &&
|
|
18809
|
+
if ((nbCol === 1 && _range[0][index] === undefined) ||
|
|
18810
|
+
(nbCol !== 1 && _range[index] === undefined)) {
|
|
18807
18811
|
return valueNotAvailable(searchKey);
|
|
18808
18812
|
}
|
|
18809
18813
|
return index + 1;
|
|
@@ -18858,13 +18862,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18858
18862
|
],
|
|
18859
18863
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18860
18864
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18861
|
-
|
|
18865
|
+
const _range = toMatrix(range);
|
|
18866
|
+
assert(() => 1 <= _index && _index <= _range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18862
18867
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18863
18868
|
const _isSorted = toBoolean(isSorted.value);
|
|
18864
18869
|
const rowIndex = _isSorted
|
|
18865
|
-
? dichotomicSearch(
|
|
18866
|
-
: linearSearch(
|
|
18867
|
-
const value =
|
|
18870
|
+
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18871
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18872
|
+
const value = _range[_index - 1][rowIndex];
|
|
18868
18873
|
if (value === undefined) {
|
|
18869
18874
|
return valueNotAvailable(searchKey);
|
|
18870
18875
|
}
|
|
@@ -18901,27 +18906,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
18901
18906
|
compute: function (searchKey, lookupRange, returnRange, defaultValue, matchMode = { value: DEFAULT_MATCH_MODE }, searchMode = { value: DEFAULT_SEARCH_MODE }) {
|
|
18902
18907
|
const _matchMode = Math.trunc(toNumber(matchMode.value, this.locale));
|
|
18903
18908
|
const _searchMode = Math.trunc(toNumber(searchMode.value, this.locale));
|
|
18904
|
-
|
|
18909
|
+
const _lookupRange = toMatrix(lookupRange);
|
|
18910
|
+
const _returnRange = toMatrix(returnRange);
|
|
18911
|
+
assert(() => _lookupRange.length === 1 || _lookupRange[0].length === 1, _t("lookup_range should be either a single row or single column."));
|
|
18905
18912
|
assert(() => [-1, 1, -2, 2].includes(_searchMode), _t("search_mode should be a value in [-1, 1, -2, 2]."));
|
|
18906
18913
|
assert(() => [-1, 0, 1, 2].includes(_matchMode), _t("match_mode should be a value in [-1, 0, 1, 2]."));
|
|
18907
|
-
const lookupDirection =
|
|
18914
|
+
const lookupDirection = _lookupRange.length === 1 ? "col" : "row";
|
|
18908
18915
|
assert(() => !(_matchMode === 2 && [-2, 2].includes(_searchMode)), _t("the search and match mode combination is not supported for XLOOKUP evaluation."));
|
|
18909
18916
|
assert(() => lookupDirection === "col"
|
|
18910
|
-
?
|
|
18911
|
-
:
|
|
18917
|
+
? _returnRange[0].length === _lookupRange[0].length
|
|
18918
|
+
: _returnRange.length === _lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18912
18919
|
const getElement = lookupDirection === "col"
|
|
18913
18920
|
? (range, index) => range[0][index].value
|
|
18914
18921
|
: (range, index) => range[index][0].value;
|
|
18915
|
-
const rangeLen = lookupDirection === "col" ?
|
|
18922
|
+
const rangeLen = lookupDirection === "col" ? _lookupRange[0].length : _lookupRange.length;
|
|
18916
18923
|
const mode = MATCH_MODE[_matchMode];
|
|
18917
18924
|
const reverseSearch = _searchMode === -1;
|
|
18918
18925
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18919
|
-
? dichotomicSearch(
|
|
18920
|
-
: linearSearch(
|
|
18926
|
+
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18927
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18921
18928
|
if (index !== -1) {
|
|
18922
18929
|
return lookupDirection === "col"
|
|
18923
|
-
?
|
|
18924
|
-
: [
|
|
18930
|
+
? _returnRange.map((col) => [col[index]])
|
|
18931
|
+
: [_returnRange[index]];
|
|
18925
18932
|
}
|
|
18926
18933
|
if (defaultValue === undefined) {
|
|
18927
18934
|
return valueNotAvailable(searchKey);
|
|
@@ -28457,11 +28464,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28457
28464
|
if (values.length < 2 || labels.length < 2 || newLabels.length === 0) {
|
|
28458
28465
|
return [];
|
|
28459
28466
|
}
|
|
28460
|
-
const
|
|
28461
|
-
const labelMax = Math.max(...labels);
|
|
28462
|
-
const labelRange = labelMax - labelMin;
|
|
28463
|
-
const normalizedLabels = labels.map((v) => (v - labelMin) / labelRange);
|
|
28464
|
-
const normalizedNewLabels = newLabels.map((v) => (v - labelMin) / labelRange);
|
|
28467
|
+
const { normalizedLabels, normalizedNewLabels } = normalizeLabels(labels, newLabels, config);
|
|
28465
28468
|
try {
|
|
28466
28469
|
switch (config.type) {
|
|
28467
28470
|
case "polynomial": {
|
|
@@ -28506,6 +28509,30 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
28506
28509
|
return newLabels.map((x) => ({ x, y: NaN }));
|
|
28507
28510
|
}
|
|
28508
28511
|
}
|
|
28512
|
+
function normalizeLabels(labels, newLabels, config) {
|
|
28513
|
+
let normalizedLabels = [];
|
|
28514
|
+
let normalizedNewLabels = [];
|
|
28515
|
+
if (config.type === "logarithmic") {
|
|
28516
|
+
// Logarithmic trends in charts are used to visualize proportional growth or
|
|
28517
|
+
// relative changes. Therefore, we change the normalization technique for
|
|
28518
|
+
// logarithmic trend lines for a better fit. The method used here is Max Absolute
|
|
28519
|
+
// Scaling. This Technique is ideal for data spanning several orders of magnitude,
|
|
28520
|
+
// as it balances differences between small and large values by compressing larger
|
|
28521
|
+
// values while preserving proportionality and ensuring all values are scaled relative
|
|
28522
|
+
// to the largest magnitude.
|
|
28523
|
+
const labelMax = Math.max(...labels.map(Math.abs));
|
|
28524
|
+
normalizedLabels = labels.map((l) => l / labelMax);
|
|
28525
|
+
normalizedNewLabels = newLabels.map((l) => l / labelMax);
|
|
28526
|
+
}
|
|
28527
|
+
else {
|
|
28528
|
+
const labelMax = Math.max(...labels);
|
|
28529
|
+
const labelMin = Math.min(...labels);
|
|
28530
|
+
const labelRange = labelMax - labelMin;
|
|
28531
|
+
normalizedLabels = labels.map((l) => (l - labelMax) / labelRange);
|
|
28532
|
+
normalizedNewLabels = newLabels.map((l) => (l - labelMax) / labelRange);
|
|
28533
|
+
}
|
|
28534
|
+
return { normalizedLabels, normalizedNewLabels };
|
|
28535
|
+
}
|
|
28509
28536
|
function getChartAxisType(chart, labelRange, getters) {
|
|
28510
28537
|
if (isDateChart(chart, labelRange, getters) && isLuxonTimeAdapterInstalled()) {
|
|
28511
28538
|
return "time";
|
|
@@ -32537,36 +32564,58 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32537
32564
|
static maxSize = { maxHeight: ERROR_TOOLTIP_MAX_HEIGHT };
|
|
32538
32565
|
static template = "o-spreadsheet-ErrorToolTip";
|
|
32539
32566
|
static props = {
|
|
32540
|
-
|
|
32567
|
+
cellPosition: Object,
|
|
32541
32568
|
onClosed: { type: Function, optional: true },
|
|
32542
32569
|
};
|
|
32570
|
+
get dataValidationErrorMessage() {
|
|
32571
|
+
return this.env.model.getters.getInvalidDataValidationMessage(this.props.cellPosition);
|
|
32572
|
+
}
|
|
32573
|
+
get evaluationError() {
|
|
32574
|
+
const cell = this.env.model.getters.getEvaluatedCell(this.props.cellPosition);
|
|
32575
|
+
if (cell.message) {
|
|
32576
|
+
return cell;
|
|
32577
|
+
}
|
|
32578
|
+
return undefined;
|
|
32579
|
+
}
|
|
32580
|
+
get errorOriginPositionString() {
|
|
32581
|
+
const evaluationError = this.evaluationError;
|
|
32582
|
+
const position = evaluationError?.errorOriginPosition;
|
|
32583
|
+
if (!position || deepEquals(position, this.props.cellPosition)) {
|
|
32584
|
+
return "";
|
|
32585
|
+
}
|
|
32586
|
+
const sheetId = position.sheetId;
|
|
32587
|
+
return this.env.model.getters.getRangeString(this.env.model.getters.getRangeFromZone(sheetId, positionToZone(position)), this.env.model.getters.getActiveSheetId());
|
|
32588
|
+
}
|
|
32589
|
+
selectCell() {
|
|
32590
|
+
const position = this.evaluationError?.errorOriginPosition;
|
|
32591
|
+
if (!position) {
|
|
32592
|
+
return;
|
|
32593
|
+
}
|
|
32594
|
+
const activeSheetId = this.env.model.getters.getActiveSheetId();
|
|
32595
|
+
if (position.sheetId !== activeSheetId) {
|
|
32596
|
+
this.env.model.dispatch("ACTIVATE_SHEET", {
|
|
32597
|
+
sheetIdFrom: activeSheetId,
|
|
32598
|
+
sheetIdTo: position.sheetId,
|
|
32599
|
+
});
|
|
32600
|
+
}
|
|
32601
|
+
this.env.model.selection.selectCell(position.col, position.row);
|
|
32602
|
+
}
|
|
32543
32603
|
}
|
|
32544
32604
|
const ErrorToolTipPopoverBuilder = {
|
|
32545
32605
|
onHover: (position, getters) => {
|
|
32546
32606
|
const cell = getters.getEvaluatedCell(position);
|
|
32547
|
-
|
|
32548
|
-
|
|
32549
|
-
|
|
32550
|
-
|
|
32551
|
-
|
|
32552
|
-
|
|
32553
|
-
|
|
32554
|
-
|
|
32555
|
-
|
|
32556
|
-
|
|
32557
|
-
title: _t("Invalid"),
|
|
32558
|
-
message: validationErrorMessage,
|
|
32559
|
-
});
|
|
32560
|
-
}
|
|
32561
|
-
if (!errors.length) {
|
|
32562
|
-
return { isOpen: false };
|
|
32607
|
+
if ((cell.type === CellValueType.error && !!cell.message) ||
|
|
32608
|
+
getters.getInvalidDataValidationMessage(position)) {
|
|
32609
|
+
return {
|
|
32610
|
+
isOpen: true,
|
|
32611
|
+
props: {
|
|
32612
|
+
cellPosition: position,
|
|
32613
|
+
},
|
|
32614
|
+
Component: ErrorToolTip,
|
|
32615
|
+
cellCorner: "TopRight",
|
|
32616
|
+
};
|
|
32563
32617
|
}
|
|
32564
|
-
return {
|
|
32565
|
-
isOpen: true,
|
|
32566
|
-
props: { errors: errors },
|
|
32567
|
-
Component: ErrorToolTip,
|
|
32568
|
-
cellCorner: "TopRight",
|
|
32569
|
-
};
|
|
32618
|
+
return { isOpen: false };
|
|
32570
32619
|
},
|
|
32571
32620
|
};
|
|
32572
32621
|
|
|
@@ -33130,6 +33179,100 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
33130
33179
|
function getOpenedMenus() {
|
|
33131
33180
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
33132
33181
|
}
|
|
33182
|
+
function getCurrentSelection(el) {
|
|
33183
|
+
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
33184
|
+
let startSizeBefore = findSelectionIndex(el, startElement, startSelectionOffset);
|
|
33185
|
+
let endSizeBefore = findSelectionIndex(el, endElement, endSelectionOffset);
|
|
33186
|
+
return {
|
|
33187
|
+
start: startSizeBefore,
|
|
33188
|
+
end: endSizeBefore,
|
|
33189
|
+
};
|
|
33190
|
+
}
|
|
33191
|
+
function getStartAndEndSelection(el) {
|
|
33192
|
+
const selection = document.getSelection();
|
|
33193
|
+
return {
|
|
33194
|
+
startElement: selection.anchorNode || el,
|
|
33195
|
+
startSelectionOffset: selection.anchorOffset,
|
|
33196
|
+
endElement: selection.focusNode || el,
|
|
33197
|
+
endSelectionOffset: selection.focusOffset,
|
|
33198
|
+
};
|
|
33199
|
+
}
|
|
33200
|
+
/**
|
|
33201
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
33202
|
+
* The selected node is either a Text node or an Element node.
|
|
33203
|
+
*
|
|
33204
|
+
* case 1 -Text node:
|
|
33205
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
33206
|
+
* content length of all previous nodes.
|
|
33207
|
+
*
|
|
33208
|
+
* case 2 - Element node:
|
|
33209
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
33210
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
33211
|
+
*
|
|
33212
|
+
* See the MDN documentation for more details.
|
|
33213
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
33214
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
33215
|
+
*
|
|
33216
|
+
*/
|
|
33217
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
33218
|
+
let usedCharacters = 0;
|
|
33219
|
+
let it = iterateChildren(el);
|
|
33220
|
+
let current = it.next();
|
|
33221
|
+
let isFirstParagraph = true;
|
|
33222
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
33223
|
+
if (!current.value.hasChildNodes()) {
|
|
33224
|
+
if (current.value.textContent) {
|
|
33225
|
+
usedCharacters += current.value.textContent.length;
|
|
33226
|
+
}
|
|
33227
|
+
}
|
|
33228
|
+
// One new paragraph = one new line character, except for the first paragraph
|
|
33229
|
+
if (current.value.nodeName === "P" ||
|
|
33230
|
+
(current.value.nodeName === "DIV" && current.value !== el) // On paste, the HTML may contain <div> instead of <p>
|
|
33231
|
+
) {
|
|
33232
|
+
if (isFirstParagraph) {
|
|
33233
|
+
isFirstParagraph = false;
|
|
33234
|
+
}
|
|
33235
|
+
else {
|
|
33236
|
+
usedCharacters++;
|
|
33237
|
+
}
|
|
33238
|
+
}
|
|
33239
|
+
current = it.next();
|
|
33240
|
+
}
|
|
33241
|
+
if (current.value !== nodeToFind) {
|
|
33242
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
33243
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
33244
|
+
*
|
|
33245
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
33246
|
+
*/
|
|
33247
|
+
return 0;
|
|
33248
|
+
}
|
|
33249
|
+
else {
|
|
33250
|
+
if (!current.value.hasChildNodes()) {
|
|
33251
|
+
usedCharacters += nodeOffset;
|
|
33252
|
+
}
|
|
33253
|
+
else {
|
|
33254
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
33255
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
33256
|
+
if (child.textContent !== null) {
|
|
33257
|
+
// need to account for paragraph nodes that implicitly add a new line
|
|
33258
|
+
// except for the last paragraph
|
|
33259
|
+
let chars = child.textContent.length;
|
|
33260
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
33261
|
+
chars++;
|
|
33262
|
+
}
|
|
33263
|
+
return acc + chars;
|
|
33264
|
+
}
|
|
33265
|
+
else {
|
|
33266
|
+
return acc;
|
|
33267
|
+
}
|
|
33268
|
+
}, 0);
|
|
33269
|
+
}
|
|
33270
|
+
}
|
|
33271
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
33272
|
+
usedCharacters++;
|
|
33273
|
+
}
|
|
33274
|
+
return usedCharacters;
|
|
33275
|
+
}
|
|
33133
33276
|
const letterRegex = /^[a-zA-Z]$/;
|
|
33134
33277
|
/**
|
|
33135
33278
|
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
@@ -37057,7 +37200,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37057
37200
|
}
|
|
37058
37201
|
const { x: offsetCorrectionX, y: offsetCorrectionY } = getters.getMainViewportCoordinates();
|
|
37059
37202
|
let { top, left, bottom, right } = getters.getActiveMainViewport();
|
|
37060
|
-
let { scrollX, scrollY } = getters.
|
|
37203
|
+
let { scrollX, scrollY } = getters.getActiveSheetScrollInfo();
|
|
37061
37204
|
const { xSplit, ySplit } = getters.getPaneDivisions(sheetId);
|
|
37062
37205
|
let canEdgeScroll = false;
|
|
37063
37206
|
let timeoutDelay = MAX_DELAY;
|
|
@@ -40337,6 +40480,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40337
40480
|
if (currentStart === start && currentEnd === end) {
|
|
40338
40481
|
return;
|
|
40339
40482
|
}
|
|
40483
|
+
if (selection.rangeCount === 0) {
|
|
40484
|
+
const range = document.createRange();
|
|
40485
|
+
selection.addRange(range);
|
|
40486
|
+
}
|
|
40340
40487
|
const currentRange = selection.getRangeAt(0);
|
|
40341
40488
|
let range;
|
|
40342
40489
|
if (this.el.contains(currentRange.startContainer)) {
|
|
@@ -40499,7 +40646,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40499
40646
|
if (!focusedNode || !this.el.contains(focusedNode))
|
|
40500
40647
|
return;
|
|
40501
40648
|
const element = focusedNode instanceof HTMLElement ? focusedNode : focusedNode.parentElement;
|
|
40502
|
-
element?.scrollIntoView({ block: "nearest" });
|
|
40649
|
+
element?.scrollIntoView?.({ block: "nearest" });
|
|
40503
40650
|
}
|
|
40504
40651
|
/**
|
|
40505
40652
|
* remove the current selection of the user
|
|
@@ -40519,100 +40666,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40519
40666
|
* finds the indexes of the current selection.
|
|
40520
40667
|
* */
|
|
40521
40668
|
getCurrentSelection() {
|
|
40522
|
-
|
|
40523
|
-
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
40524
|
-
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
40525
|
-
return {
|
|
40526
|
-
start: startSizeBefore,
|
|
40527
|
-
end: endSizeBefore,
|
|
40528
|
-
};
|
|
40529
|
-
}
|
|
40530
|
-
/**
|
|
40531
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
40532
|
-
* The selected node is either a Text node or an Element node.
|
|
40533
|
-
*
|
|
40534
|
-
* case 1 -Text node:
|
|
40535
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
40536
|
-
* content length of all previous nodes.
|
|
40537
|
-
*
|
|
40538
|
-
* case 2 - Element node:
|
|
40539
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
40540
|
-
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
40541
|
-
*
|
|
40542
|
-
* See the MDN documentation for more details.
|
|
40543
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
40544
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
40545
|
-
*
|
|
40546
|
-
*/
|
|
40547
|
-
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
40548
|
-
let usedCharacters = 0;
|
|
40549
|
-
let it = iterateChildren(this.el);
|
|
40550
|
-
let current = it.next();
|
|
40551
|
-
let isFirstParagraph = true;
|
|
40552
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
40553
|
-
if (!current.value.hasChildNodes()) {
|
|
40554
|
-
if (current.value.textContent) {
|
|
40555
|
-
usedCharacters += current.value.textContent.length;
|
|
40556
|
-
}
|
|
40557
|
-
}
|
|
40558
|
-
// One new paragraph = one new line character, except for the first paragraph
|
|
40559
|
-
if (current.value.nodeName === "P" ||
|
|
40560
|
-
(current.value.nodeName === "DIV" && current.value !== this.el) // On paste, the HTML may contain <div> instead of <p>
|
|
40561
|
-
) {
|
|
40562
|
-
if (isFirstParagraph) {
|
|
40563
|
-
isFirstParagraph = false;
|
|
40564
|
-
}
|
|
40565
|
-
else {
|
|
40566
|
-
usedCharacters++;
|
|
40567
|
-
}
|
|
40568
|
-
}
|
|
40569
|
-
current = it.next();
|
|
40570
|
-
}
|
|
40571
|
-
if (current.value !== nodeToFind) {
|
|
40572
|
-
/** This situation can happen if the code is called while the selection is not currently on the ContentEditableHelper.
|
|
40573
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
40574
|
-
*
|
|
40575
|
-
* A known occurence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
40576
|
-
*
|
|
40577
|
-
* FIXME: find a way to test eventhough the selection API is not available in jsDOM.
|
|
40578
|
-
*/
|
|
40579
|
-
return 0;
|
|
40580
|
-
}
|
|
40581
|
-
else {
|
|
40582
|
-
if (!current.value.hasChildNodes()) {
|
|
40583
|
-
usedCharacters += nodeOffset;
|
|
40584
|
-
}
|
|
40585
|
-
else {
|
|
40586
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
40587
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
40588
|
-
if (child.textContent !== null) {
|
|
40589
|
-
// need to account for paragraph nodes that implicitely add a new line
|
|
40590
|
-
// except for the last paragraph
|
|
40591
|
-
let chars = child.textContent.length;
|
|
40592
|
-
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
40593
|
-
chars++;
|
|
40594
|
-
}
|
|
40595
|
-
return acc + chars;
|
|
40596
|
-
}
|
|
40597
|
-
else {
|
|
40598
|
-
return acc;
|
|
40599
|
-
}
|
|
40600
|
-
}, 0);
|
|
40601
|
-
}
|
|
40602
|
-
}
|
|
40603
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
40604
|
-
usedCharacters++;
|
|
40605
|
-
}
|
|
40606
|
-
return usedCharacters;
|
|
40607
|
-
}
|
|
40608
|
-
getStartAndEndSelection() {
|
|
40609
|
-
const selection = document.getSelection();
|
|
40610
|
-
return {
|
|
40611
|
-
startElement: selection.anchorNode || this.el,
|
|
40612
|
-
startSelectionOffset: selection.anchorOffset,
|
|
40613
|
-
endElement: selection.focusNode || this.el,
|
|
40614
|
-
endSelectionOffset: selection.focusOffset,
|
|
40615
|
-
};
|
|
40669
|
+
return getCurrentSelection(this.el);
|
|
40616
40670
|
}
|
|
40617
40671
|
getText() {
|
|
40618
40672
|
let text = "";
|
|
@@ -40876,6 +40930,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40876
40930
|
}
|
|
40877
40931
|
this.contentHelper.updateEl(el);
|
|
40878
40932
|
});
|
|
40933
|
+
this.env.model.selection.observe(this, {
|
|
40934
|
+
handleEvent: () => this.autoCompleteState.hide(),
|
|
40935
|
+
});
|
|
40936
|
+
owl.onWillUnmount(() => {
|
|
40937
|
+
this.env.model.selection.detachObserver(this);
|
|
40938
|
+
});
|
|
40879
40939
|
owl.useEffect(() => {
|
|
40880
40940
|
this.processContent();
|
|
40881
40941
|
if (document.activeElement === this.contentHelper.el &&
|
|
@@ -41313,6 +41373,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41313
41373
|
}
|
|
41314
41374
|
return providersDefinitions;
|
|
41315
41375
|
}
|
|
41376
|
+
/**
|
|
41377
|
+
* Replace the current reference selected by the new one.
|
|
41378
|
+
* */
|
|
41379
|
+
getZoneReference(zone) {
|
|
41380
|
+
const res = super.getZoneReference(zone);
|
|
41381
|
+
if (this.args().defaultStatic) {
|
|
41382
|
+
return setXcToFixedReferenceType(res, "colrow");
|
|
41383
|
+
}
|
|
41384
|
+
return res;
|
|
41385
|
+
}
|
|
41316
41386
|
getComposerContent() {
|
|
41317
41387
|
if (this.editionMode === "inactive") {
|
|
41318
41388
|
// References in the content might not be linked to the current active sheet
|
|
@@ -41378,6 +41448,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41378
41448
|
static props = {
|
|
41379
41449
|
composerContent: { type: String, optional: true },
|
|
41380
41450
|
defaultRangeSheetId: { type: String, optional: true },
|
|
41451
|
+
defaultStatic: { type: Boolean, optional: true },
|
|
41381
41452
|
onConfirm: Function,
|
|
41382
41453
|
contextualAutocomplete: { type: Object, optional: true },
|
|
41383
41454
|
placeholder: { type: String, optional: true },
|
|
@@ -41388,6 +41459,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41388
41459
|
static components = { Composer };
|
|
41389
41460
|
static defaultProps = {
|
|
41390
41461
|
composerContent: "",
|
|
41462
|
+
defaultStatic: false,
|
|
41391
41463
|
};
|
|
41392
41464
|
composerFocusStore;
|
|
41393
41465
|
standaloneComposerStore;
|
|
@@ -41398,6 +41470,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41398
41470
|
const standaloneComposerStore = useLocalStore(StandaloneComposerStore, () => ({
|
|
41399
41471
|
onConfirm: this.props.onConfirm,
|
|
41400
41472
|
content: this.props.composerContent,
|
|
41473
|
+
defaultStatic: this.props.defaultStatic ?? false,
|
|
41401
41474
|
contextualAutocomplete: this.props.contextualAutocomplete,
|
|
41402
41475
|
defaultRangeSheetId: this.props.defaultRangeSheetId,
|
|
41403
41476
|
getContextualColoredSymbolToken: this.props.getContextualColoredSymbolToken,
|
|
@@ -42133,6 +42206,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42133
42206
|
},
|
|
42134
42207
|
composerContent: this.state.rules.cellIs.values[valueIndex],
|
|
42135
42208
|
placeholder: _t("Value or formula"),
|
|
42209
|
+
defaultStatic: true,
|
|
42136
42210
|
invalid: isInvalid,
|
|
42137
42211
|
class: "o-sidePanel-composer",
|
|
42138
42212
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -42151,6 +42225,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42151
42225
|
},
|
|
42152
42226
|
composerContent: threshold.value || "",
|
|
42153
42227
|
placeholder: _t("Formula"),
|
|
42228
|
+
defaultStatic: true,
|
|
42154
42229
|
invalid: isInvalid,
|
|
42155
42230
|
class: "o-sidePanel-composer",
|
|
42156
42231
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -42166,6 +42241,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
42166
42241
|
},
|
|
42167
42242
|
composerContent: inflection.value || "",
|
|
42168
42243
|
placeholder: _t("Formula"),
|
|
42244
|
+
defaultStatic: true,
|
|
42169
42245
|
invalid: isInvalid,
|
|
42170
42246
|
class: "o-sidePanel-composer",
|
|
42171
42247
|
defaultRangeSheetId: this.env.model.getters.getActiveSheetId(),
|
|
@@ -49215,7 +49291,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49215
49291
|
axisStartEndPositions.push({ x: axis.position, y: figure.y + figure.height });
|
|
49216
49292
|
break;
|
|
49217
49293
|
}
|
|
49218
|
-
return axisStartEndPositions.some(getters.
|
|
49294
|
+
return axisStartEndPositions.some(getters.isPixelPositionVisible);
|
|
49219
49295
|
}
|
|
49220
49296
|
/**
|
|
49221
49297
|
* Get a snap line for the given figure, if the figure can snap to any other figure
|
|
@@ -49774,7 +49850,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49774
49850
|
});
|
|
49775
49851
|
this.props.focusGrid();
|
|
49776
49852
|
// After adding new rows, scroll down to the new last row
|
|
49777
|
-
const { scrollX } = this.env.model.getters.
|
|
49853
|
+
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
49778
49854
|
const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
|
|
49779
49855
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
49780
49856
|
offsetX: scrollX,
|
|
@@ -50032,7 +50108,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50032
50108
|
resizeObserver.disconnect();
|
|
50033
50109
|
});
|
|
50034
50110
|
useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
|
|
50035
|
-
const { scrollY } = this.env.model.getters.
|
|
50111
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
50036
50112
|
return scrollY > 0;
|
|
50037
50113
|
});
|
|
50038
50114
|
this.cellPopovers = useStore(CellPopoverStore);
|
|
@@ -50686,17 +50762,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50686
50762
|
get renderingLayers() {
|
|
50687
50763
|
return ["Background", "Headers"];
|
|
50688
50764
|
}
|
|
50689
|
-
/**
|
|
50690
|
-
* Get the offset of a header (see getColRowOffsetInViewport), adjusted with the header
|
|
50691
|
-
* size (HEADER_HEIGHT and HEADER_WIDTH)
|
|
50692
|
-
*/
|
|
50693
|
-
getHeaderOffset(dimension, start, index) {
|
|
50694
|
-
let size = this.getters.getColRowOffsetInViewport(dimension, start, index);
|
|
50695
|
-
if (!this.getters.isDashboard()) {
|
|
50696
|
-
size += dimension === "ROW" ? HEADER_HEIGHT : HEADER_WIDTH;
|
|
50697
|
-
}
|
|
50698
|
-
return size;
|
|
50699
|
-
}
|
|
50700
50765
|
// ---------------------------------------------------------------------------
|
|
50701
50766
|
// Grid rendering
|
|
50702
50767
|
// ---------------------------------------------------------------------------
|
|
@@ -50704,11 +50769,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50704
50769
|
switch (layer) {
|
|
50705
50770
|
case "Background":
|
|
50706
50771
|
this.drawGlobalBackground(renderingContext);
|
|
50707
|
-
for (const zone of this.getters.
|
|
50772
|
+
for (const { zone, rect } of this.getters.getAllActiveViewportsZonesAndRect()) {
|
|
50708
50773
|
const { ctx } = renderingContext;
|
|
50709
50774
|
ctx.save();
|
|
50710
50775
|
ctx.beginPath();
|
|
50711
|
-
const rect = this.getters.getVisibleRect(zone);
|
|
50712
50776
|
ctx.rect(rect.x, rect.y, rect.width, rect.height);
|
|
50713
50777
|
ctx.clip();
|
|
50714
50778
|
const boxes = this.getGridBoxes(zone);
|
|
@@ -50984,10 +51048,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
50984
51048
|
const { ctx, thinLineWidth } = renderingContext;
|
|
50985
51049
|
const visibleCols = this.getters.getSheetViewVisibleCols();
|
|
50986
51050
|
const left = visibleCols[0];
|
|
50987
|
-
const right = visibleCols[visibleCols.length - 1];
|
|
50988
51051
|
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
50989
51052
|
const top = visibleRows[0];
|
|
50990
|
-
const bottom = visibleRows[visibleRows.length - 1];
|
|
50991
51053
|
const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
|
|
50992
51054
|
const selection = this.getters.getSelectedZones();
|
|
50993
51055
|
const selectedCols = getZonesCols(selection);
|
|
@@ -51003,7 +51065,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51003
51065
|
ctx.lineWidth = thinLineWidth;
|
|
51004
51066
|
ctx.strokeStyle = "#333";
|
|
51005
51067
|
// Columns headers background
|
|
51006
|
-
for (
|
|
51068
|
+
for (const col of visibleCols) {
|
|
51007
51069
|
const colZone = { left: col, right: col, top: 0, bottom: numberOfRows - 1 };
|
|
51008
51070
|
const { x, width } = this.getters.getVisibleRect(colZone);
|
|
51009
51071
|
const isColActive = activeCols.has(col);
|
|
@@ -51020,7 +51082,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51020
51082
|
ctx.fillRect(x, 0, width, HEADER_HEIGHT);
|
|
51021
51083
|
}
|
|
51022
51084
|
// Rows headers background
|
|
51023
|
-
for (
|
|
51085
|
+
for (const row of visibleRows) {
|
|
51024
51086
|
const rowZone = { top: row, bottom: row, left: 0, right: numberOfCols - 1 };
|
|
51025
51087
|
const { y, height } = this.getters.getVisibleRect(rowZone);
|
|
51026
51088
|
const isRowActive = activeRows.has(row);
|
|
@@ -51044,27 +51106,41 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51044
51106
|
ctx.lineTo(width, HEADER_HEIGHT);
|
|
51045
51107
|
ctx.strokeStyle = HEADER_BORDER_COLOR;
|
|
51046
51108
|
ctx.stroke();
|
|
51047
|
-
ctx.beginPath();
|
|
51048
51109
|
// column text + separator
|
|
51049
|
-
for (const
|
|
51050
|
-
const
|
|
51051
|
-
|
|
51052
|
-
|
|
51053
|
-
|
|
51110
|
+
for (const col of visibleCols) {
|
|
51111
|
+
const colName = numberToLetters(col);
|
|
51112
|
+
ctx.fillStyle = activeCols.has(col) ? "#fff" : TEXT_HEADER_COLOR;
|
|
51113
|
+
const zone = { left: col, right: col, top: top, bottom: top };
|
|
51114
|
+
const { x: colStart, width: colSize } = this.getters.getRect(zone);
|
|
51115
|
+
const { x, width } = this.getters.getVisibleRect(zone);
|
|
51116
|
+
ctx.save();
|
|
51117
|
+
ctx.beginPath();
|
|
51118
|
+
ctx.rect(x, 0, width, HEADER_HEIGHT);
|
|
51119
|
+
ctx.clip();
|
|
51054
51120
|
ctx.fillText(colName, colStart + colSize / 2, HEADER_HEIGHT / 2);
|
|
51121
|
+
ctx.restore();
|
|
51122
|
+
ctx.beginPath();
|
|
51055
51123
|
ctx.moveTo(colStart + colSize, 0);
|
|
51056
51124
|
ctx.lineTo(colStart + colSize, HEADER_HEIGHT);
|
|
51125
|
+
ctx.stroke();
|
|
51057
51126
|
}
|
|
51058
51127
|
// row text + separator
|
|
51059
|
-
for (const
|
|
51060
|
-
|
|
51061
|
-
|
|
51062
|
-
|
|
51063
|
-
|
|
51128
|
+
for (const row of visibleRows) {
|
|
51129
|
+
ctx.fillStyle = activeRows.has(row) ? "#fff" : TEXT_HEADER_COLOR;
|
|
51130
|
+
const zone = { top: row, bottom: row, left: left, right: left };
|
|
51131
|
+
const { y: rowStart, height: rowSize } = this.getters.getRect(zone);
|
|
51132
|
+
const { y, height } = this.getters.getVisibleRect(zone);
|
|
51133
|
+
ctx.save();
|
|
51134
|
+
ctx.beginPath();
|
|
51135
|
+
ctx.rect(0, y, HEADER_WIDTH, height);
|
|
51136
|
+
ctx.clip();
|
|
51137
|
+
ctx.fillText(String(row + 1), HEADER_WIDTH / 2, rowStart + rowSize / 2);
|
|
51138
|
+
ctx.restore();
|
|
51139
|
+
ctx.beginPath();
|
|
51064
51140
|
ctx.moveTo(0, rowStart + rowSize);
|
|
51065
51141
|
ctx.lineTo(HEADER_WIDTH, rowStart + rowSize);
|
|
51142
|
+
ctx.stroke();
|
|
51066
51143
|
}
|
|
51067
|
-
ctx.stroke();
|
|
51068
51144
|
}
|
|
51069
51145
|
drawFrozenPanesHeaders(renderingContext) {
|
|
51070
51146
|
const { ctx, thinLineWidth } = renderingContext;
|
|
@@ -51242,8 +51318,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51242
51318
|
previousColIndex = col;
|
|
51243
51319
|
}
|
|
51244
51320
|
else {
|
|
51245
|
-
nextColIndex = this.findNextEmptyCol(col, right, row);
|
|
51246
|
-
previousColIndex = this.findPreviousEmptyCol(col, left, row);
|
|
51321
|
+
nextColIndex = box.border?.right ? zone.right : this.findNextEmptyCol(col, right, row);
|
|
51322
|
+
previousColIndex = box.border?.left ? zone.left : this.findPreviousEmptyCol(col, left, row);
|
|
51247
51323
|
box.isOverflow = true;
|
|
51248
51324
|
}
|
|
51249
51325
|
switch (align) {
|
|
@@ -51367,6 +51443,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51367
51443
|
canvas.width = width * dpr;
|
|
51368
51444
|
canvas.height = height * dpr;
|
|
51369
51445
|
canvas.setAttribute("style", `width:${width}px;height:${height}px;`);
|
|
51446
|
+
if (width === 0 || height === 0) {
|
|
51447
|
+
return;
|
|
51448
|
+
}
|
|
51370
51449
|
// Imagine each pixel as a large square. The whole-number coordinates (0, 1, 2…)
|
|
51371
51450
|
// are the edges of the squares. If you draw a one-unit-wide line between whole-number
|
|
51372
51451
|
// coordinates, it will overlap opposite sides of the pixel square, and the resulting
|
|
@@ -51710,7 +51789,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51710
51789
|
leftOffset: 0,
|
|
51711
51790
|
};
|
|
51712
51791
|
get offset() {
|
|
51713
|
-
return this.env.model.getters.
|
|
51792
|
+
return this.env.model.getters.getActiveSheetScrollInfo().scrollX;
|
|
51714
51793
|
}
|
|
51715
51794
|
get width() {
|
|
51716
51795
|
return this.env.model.getters.getMainViewportRect().width;
|
|
@@ -51729,7 +51808,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51729
51808
|
};
|
|
51730
51809
|
}
|
|
51731
51810
|
onScroll(offset) {
|
|
51732
|
-
const { scrollY } = this.env.model.getters.
|
|
51811
|
+
const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
51733
51812
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
51734
51813
|
offsetX: offset,
|
|
51735
51814
|
offsetY: scrollY, // offsetY is the same
|
|
@@ -51755,7 +51834,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51755
51834
|
topOffset: 0,
|
|
51756
51835
|
};
|
|
51757
51836
|
get offset() {
|
|
51758
|
-
return this.env.model.getters.
|
|
51837
|
+
return this.env.model.getters.getActiveSheetScrollInfo().scrollY;
|
|
51759
51838
|
}
|
|
51760
51839
|
get height() {
|
|
51761
51840
|
return this.env.model.getters.getMainViewportRect().height;
|
|
@@ -51774,7 +51853,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
51774
51853
|
};
|
|
51775
51854
|
}
|
|
51776
51855
|
onScroll(offset) {
|
|
51777
|
-
const { scrollX } = this.env.model.getters.
|
|
51856
|
+
const { scrollX } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
51778
51857
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
51779
51858
|
offsetX: scrollX, // offsetX is the same
|
|
51780
51859
|
offsetY: offset,
|
|
@@ -52245,7 +52324,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52245
52324
|
});
|
|
52246
52325
|
}
|
|
52247
52326
|
moveCanvas(deltaX, deltaY) {
|
|
52248
|
-
const { scrollX, scrollY } = this.env.model.getters.
|
|
52327
|
+
const { scrollX, scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
52249
52328
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
52250
52329
|
offsetX: scrollX + deltaX,
|
|
52251
52330
|
offsetY: scrollY + deltaY,
|
|
@@ -52716,7 +52795,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52716
52795
|
// map and slice preserve empty values and do not set `undefined` instead
|
|
52717
52796
|
const bordersCopy = borders
|
|
52718
52797
|
.slice()
|
|
52719
|
-
.map((col) => col?.slice().map((border) => (
|
|
52798
|
+
.map((col) => col?.slice().map((border) => deepCopy(border)));
|
|
52720
52799
|
this.history.update("borders", cmd.sheetIdTo, bordersCopy);
|
|
52721
52800
|
}
|
|
52722
52801
|
break;
|
|
@@ -52746,32 +52825,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52746
52825
|
const elements = [...cmd.elements].sort((a, b) => b - a);
|
|
52747
52826
|
for (const group of groupConsecutive(elements)) {
|
|
52748
52827
|
if (cmd.dimension === "COL") {
|
|
52749
|
-
|
|
52750
|
-
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52751
|
-
this.history.update("borders", cmd.sheetId, group[0] + 1, row, "vertical", undefined);
|
|
52752
|
-
}
|
|
52753
|
-
}
|
|
52754
|
-
if (group[group.length - 1] === 0) {
|
|
52755
|
-
for (let row = 0; row < this.getters.getNumberRows(cmd.sheetId); row++) {
|
|
52756
|
-
this.history.update("borders", cmd.sheetId, 0, row, "vertical", undefined);
|
|
52757
|
-
}
|
|
52758
|
-
}
|
|
52759
|
-
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52828
|
+
const zone = this.getters.getColsZone(cmd.sheetId, group[group.length - 1], group[0]);
|
|
52760
52829
|
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52761
52830
|
this.shiftBordersHorizontally(cmd.sheetId, group[0] + 1, -group.length);
|
|
52762
52831
|
}
|
|
52763
52832
|
else {
|
|
52764
|
-
|
|
52765
|
-
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52766
|
-
this.history.update("borders", cmd.sheetId, col, group[0] + 1, "horizontal", undefined);
|
|
52767
|
-
}
|
|
52768
|
-
}
|
|
52769
|
-
if (group[group.length - 1] === 0) {
|
|
52770
|
-
for (let col = 0; col < this.getters.getNumberCols(cmd.sheetId); col++) {
|
|
52771
|
-
this.history.update("borders", cmd.sheetId, col, 0, "horizontal", undefined);
|
|
52772
|
-
}
|
|
52773
|
-
}
|
|
52774
|
-
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1] + 1, group[0]);
|
|
52833
|
+
const zone = this.getters.getRowsZone(cmd.sheetId, group[group.length - 1], group[0]);
|
|
52775
52834
|
this.clearInsideBorders(cmd.sheetId, [zone]);
|
|
52776
52835
|
this.shiftBordersVertically(cmd.sheetId, group[0] + 1, -group.length);
|
|
52777
52836
|
}
|
|
@@ -52796,16 +52855,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52796
52855
|
let colLeftOfInsertion;
|
|
52797
52856
|
let colRightOfInsertion;
|
|
52798
52857
|
if (cmd.position === "before") {
|
|
52799
|
-
this.shiftBordersHorizontally(cmd.sheetId, cmd.base, cmd.quantity
|
|
52800
|
-
moveFirstLeftBorder: true,
|
|
52801
|
-
});
|
|
52858
|
+
this.shiftBordersHorizontally(cmd.sheetId, cmd.base, cmd.quantity);
|
|
52802
52859
|
colLeftOfInsertion = cmd.base - 1;
|
|
52803
52860
|
colRightOfInsertion = cmd.base + cmd.quantity;
|
|
52804
52861
|
}
|
|
52805
52862
|
else {
|
|
52806
|
-
this.shiftBordersHorizontally(cmd.sheetId, cmd.base + 1, cmd.quantity
|
|
52807
|
-
moveFirstLeftBorder: false,
|
|
52808
|
-
});
|
|
52863
|
+
this.shiftBordersHorizontally(cmd.sheetId, cmd.base + 1, cmd.quantity);
|
|
52809
52864
|
colLeftOfInsertion = cmd.base;
|
|
52810
52865
|
colRightOfInsertion = cmd.base + cmd.quantity + 1;
|
|
52811
52866
|
}
|
|
@@ -52820,16 +52875,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52820
52875
|
let rowAboveInsertion;
|
|
52821
52876
|
let rowBelowInsertion;
|
|
52822
52877
|
if (cmd.position === "before") {
|
|
52823
|
-
this.shiftBordersVertically(cmd.sheetId, cmd.base, cmd.quantity
|
|
52824
|
-
moveFirstTopBorder: true,
|
|
52825
|
-
});
|
|
52878
|
+
this.shiftBordersVertically(cmd.sheetId, cmd.base, cmd.quantity);
|
|
52826
52879
|
rowAboveInsertion = cmd.base - 1;
|
|
52827
52880
|
rowBelowInsertion = cmd.base + cmd.quantity;
|
|
52828
52881
|
}
|
|
52829
52882
|
else {
|
|
52830
|
-
this.shiftBordersVertically(cmd.sheetId, cmd.base + 1, cmd.quantity
|
|
52831
|
-
moveFirstTopBorder: false,
|
|
52832
|
-
});
|
|
52883
|
+
this.shiftBordersVertically(cmd.sheetId, cmd.base + 1, cmd.quantity);
|
|
52833
52884
|
rowAboveInsertion = cmd.base;
|
|
52834
52885
|
rowBelowInsertion = cmd.base + cmd.quantity + 1;
|
|
52835
52886
|
}
|
|
@@ -52839,16 +52890,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52839
52890
|
// Getters
|
|
52840
52891
|
// ---------------------------------------------------------------------------
|
|
52841
52892
|
getCellBorder({ sheetId, col, row }) {
|
|
52842
|
-
const border =
|
|
52843
|
-
|
|
52844
|
-
bottom: this.borders[sheetId]?.[col]?.[row + 1]?.horizontal,
|
|
52845
|
-
left: this.borders[sheetId]?.[col]?.[row]?.vertical,
|
|
52846
|
-
right: this.borders[sheetId]?.[col + 1]?.[row]?.vertical,
|
|
52847
|
-
};
|
|
52848
|
-
if (!border.bottom && !border.left && !border.right && !border.top) {
|
|
52849
|
-
return null;
|
|
52850
|
-
}
|
|
52851
|
-
return border;
|
|
52893
|
+
const border = this.borders[sheetId]?.[col]?.[row];
|
|
52894
|
+
return border?.top || border?.bottom || border?.left || border?.right ? deepCopy(border) : null;
|
|
52852
52895
|
}
|
|
52853
52896
|
getBordersColors(sheetId) {
|
|
52854
52897
|
const colors = [];
|
|
@@ -52856,11 +52899,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52856
52899
|
if (sheetBorders) {
|
|
52857
52900
|
for (const borders of sheetBorders.filter(isDefined)) {
|
|
52858
52901
|
for (const cellBorder of borders) {
|
|
52859
|
-
if (cellBorder
|
|
52860
|
-
|
|
52861
|
-
|
|
52862
|
-
|
|
52863
|
-
|
|
52902
|
+
if (cellBorder) {
|
|
52903
|
+
for (const direction of ["top", "bottom", "left", "right"]) {
|
|
52904
|
+
const color = cellBorder[direction]?.color;
|
|
52905
|
+
if (color) {
|
|
52906
|
+
colors.push(color);
|
|
52907
|
+
}
|
|
52908
|
+
}
|
|
52864
52909
|
}
|
|
52865
52910
|
}
|
|
52866
52911
|
}
|
|
@@ -52913,7 +52958,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52913
52958
|
getCommonSides(border1, border2) {
|
|
52914
52959
|
const commonBorder = {};
|
|
52915
52960
|
for (let side of ["top", "bottom", "left", "right"]) {
|
|
52916
|
-
if (border1[side] && border1[side]
|
|
52961
|
+
if (border1[side] && deepEquals(border1[side], border2[side])) {
|
|
52917
52962
|
commonBorder[side] = border1[side];
|
|
52918
52963
|
}
|
|
52919
52964
|
}
|
|
@@ -52958,23 +53003,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52958
53003
|
* @param start starting column (included)
|
|
52959
53004
|
* @param delta how much borders will be moved (negative if moved to the left)
|
|
52960
53005
|
*/
|
|
52961
|
-
shiftBordersHorizontally(sheetId, start, delta
|
|
53006
|
+
shiftBordersHorizontally(sheetId, start, delta) {
|
|
52962
53007
|
const borders = this.borders[sheetId];
|
|
52963
53008
|
if (!borders)
|
|
52964
53009
|
return;
|
|
52965
|
-
if (delta < 0) {
|
|
52966
|
-
this.moveBordersOfColumn(sheetId, start, delta, "vertical", {
|
|
52967
|
-
destructive: false,
|
|
52968
|
-
});
|
|
52969
|
-
}
|
|
52970
53010
|
this.getColumnsWithBorders(sheetId)
|
|
52971
53011
|
.filter((col) => col >= start)
|
|
52972
53012
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
52973
53013
|
.forEach((col) => {
|
|
52974
|
-
|
|
52975
|
-
this.moveBordersOfColumn(sheetId, col, delta, "vertical");
|
|
52976
|
-
}
|
|
52977
|
-
this.moveBordersOfColumn(sheetId, col, delta, "horizontal");
|
|
53014
|
+
this.moveBordersOfColumn(sheetId, col, delta);
|
|
52978
53015
|
});
|
|
52979
53016
|
}
|
|
52980
53017
|
/**
|
|
@@ -52983,12 +53020,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52983
53020
|
* @param start starting row (included)
|
|
52984
53021
|
* @param delta how much borders will be moved (negative if moved to the above)
|
|
52985
53022
|
*/
|
|
52986
|
-
shiftBordersVertically(sheetId, start, delta
|
|
53023
|
+
shiftBordersVertically(sheetId, start, delta) {
|
|
52987
53024
|
const borders = this.borders[sheetId];
|
|
52988
53025
|
if (!borders)
|
|
52989
53026
|
return;
|
|
52990
53027
|
if (delta < 0) {
|
|
52991
|
-
this.moveBordersOfRow(sheetId, start, delta,
|
|
53028
|
+
this.moveBordersOfRow(sheetId, start, delta, {
|
|
52992
53029
|
destructive: false,
|
|
52993
53030
|
});
|
|
52994
53031
|
}
|
|
@@ -52996,10 +53033,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
52996
53033
|
.filter((row) => row >= start)
|
|
52997
53034
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
52998
53035
|
.forEach((row) => {
|
|
52999
|
-
|
|
53000
|
-
this.moveBordersOfRow(sheetId, row, delta, "horizontal");
|
|
53001
|
-
}
|
|
53002
|
-
this.moveBordersOfRow(sheetId, row, delta, "vertical");
|
|
53036
|
+
this.moveBordersOfRow(sheetId, row, delta);
|
|
53003
53037
|
});
|
|
53004
53038
|
}
|
|
53005
53039
|
/**
|
|
@@ -53013,15 +53047,15 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53013
53047
|
* argument `destructive` is given false, the target border is preserved if
|
|
53014
53048
|
* the moved border is empty
|
|
53015
53049
|
*/
|
|
53016
|
-
moveBordersOfRow(sheetId, row, delta,
|
|
53050
|
+
moveBordersOfRow(sheetId, row, delta, { destructive } = { destructive: true }) {
|
|
53017
53051
|
const borders = this.borders[sheetId];
|
|
53018
53052
|
if (!borders)
|
|
53019
53053
|
return;
|
|
53020
53054
|
this.getColumnsWithBorders(sheetId).forEach((col) => {
|
|
53021
|
-
const targetBorder = borders[col]?.[row + delta]
|
|
53022
|
-
const movedBorder = borders[col]?.[row]
|
|
53023
|
-
this.history.update("borders", sheetId, col, row + delta,
|
|
53024
|
-
this.history.update("borders", sheetId, col, row,
|
|
53055
|
+
const targetBorder = borders[col]?.[row + delta];
|
|
53056
|
+
const movedBorder = borders[col]?.[row];
|
|
53057
|
+
this.history.update("borders", sheetId, col, row + delta, destructive ? movedBorder : movedBorder || targetBorder);
|
|
53058
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
53025
53059
|
});
|
|
53026
53060
|
}
|
|
53027
53061
|
/**
|
|
@@ -53035,15 +53069,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53035
53069
|
* argument `destructive` is given false, the target border is preserved if
|
|
53036
53070
|
* the moved border is empty
|
|
53037
53071
|
*/
|
|
53038
|
-
moveBordersOfColumn(sheetId, col, delta,
|
|
53072
|
+
moveBordersOfColumn(sheetId, col, delta, { destructive } = { destructive: true }) {
|
|
53039
53073
|
const borders = this.borders[sheetId];
|
|
53040
53074
|
if (!borders)
|
|
53041
53075
|
return;
|
|
53042
53076
|
this.getRowsRange(sheetId).forEach((row) => {
|
|
53043
|
-
const targetBorder = borders[col + delta]?.[row]
|
|
53044
|
-
const movedBorder = borders[col]?.[row]
|
|
53045
|
-
this.history.update("borders", sheetId, col + delta, row,
|
|
53046
|
-
|
|
53077
|
+
const targetBorder = borders[col + delta]?.[row];
|
|
53078
|
+
const movedBorder = borders[col]?.[row];
|
|
53079
|
+
this.history.update("borders", sheetId, col + delta, row, destructive ? movedBorder : movedBorder || targetBorder);
|
|
53080
|
+
if (destructive) {
|
|
53081
|
+
this.history.update("borders", sheetId, col, row, undefined);
|
|
53082
|
+
}
|
|
53047
53083
|
});
|
|
53048
53084
|
}
|
|
53049
53085
|
/**
|
|
@@ -53051,33 +53087,69 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53051
53087
|
* It overrides the current border if override === true.
|
|
53052
53088
|
*/
|
|
53053
53089
|
setBorder(sheetId, col, row, border, override = true) {
|
|
53054
|
-
|
|
53055
|
-
|
|
53090
|
+
const maxCol = this.getters.getNumberCols(sheetId) - 1;
|
|
53091
|
+
const maxRow = this.getters.getNumberRows(sheetId) - 1;
|
|
53092
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.left) {
|
|
53093
|
+
this.history.update("borders", sheetId, col, row, "left", border?.left);
|
|
53094
|
+
if (border?.left &&
|
|
53095
|
+
col > 0 &&
|
|
53096
|
+
!deepEquals(this.getCellBorder({ sheetId, col: col - 1, row })?.right, border?.left)) {
|
|
53097
|
+
this.history.update("borders", sheetId, col - 1, row, "right", undefined);
|
|
53098
|
+
}
|
|
53056
53099
|
}
|
|
53057
|
-
if (override || !this.borders
|
|
53058
|
-
this.history.update("borders", sheetId, col, row, "
|
|
53100
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.top) {
|
|
53101
|
+
this.history.update("borders", sheetId, col, row, "top", border?.top);
|
|
53102
|
+
if (border?.top &&
|
|
53103
|
+
row > 0 &&
|
|
53104
|
+
!deepEquals(this.getCellBorder({ sheetId, col, row: row - 1 })?.bottom, border?.top)) {
|
|
53105
|
+
this.history.update("borders", sheetId, col, row - 1, "bottom", undefined);
|
|
53106
|
+
}
|
|
53059
53107
|
}
|
|
53060
|
-
if (override || !this.borders
|
|
53061
|
-
this.history.update("borders", sheetId, col
|
|
53108
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.right) {
|
|
53109
|
+
this.history.update("borders", sheetId, col, row, "right", border?.right);
|
|
53110
|
+
if (border?.right &&
|
|
53111
|
+
col < maxCol &&
|
|
53112
|
+
!deepEquals(this.getCellBorder({ sheetId, col: col + 1, row })?.left, border?.right)) {
|
|
53113
|
+
this.history.update("borders", sheetId, col + 1, row, "left", undefined);
|
|
53114
|
+
}
|
|
53062
53115
|
}
|
|
53063
|
-
if (override || !this.borders
|
|
53064
|
-
this.history.update("borders", sheetId, col, row
|
|
53116
|
+
if (override || !this.borders[sheetId]?.[col]?.[row]?.bottom) {
|
|
53117
|
+
this.history.update("borders", sheetId, col, row, "bottom", border?.bottom);
|
|
53118
|
+
if (border?.bottom &&
|
|
53119
|
+
row < maxRow &&
|
|
53120
|
+
!deepEquals(this.getCellBorder({ sheetId, col, row: row + 1 })?.top, border?.bottom)) {
|
|
53121
|
+
this.history.update("borders", sheetId, col, row + 1, "top", undefined);
|
|
53122
|
+
}
|
|
53065
53123
|
}
|
|
53066
53124
|
}
|
|
53067
53125
|
/**
|
|
53068
53126
|
* Remove the borders of a zone
|
|
53069
53127
|
*/
|
|
53070
|
-
clearBorders(sheetId, zones) {
|
|
53128
|
+
clearBorders(sheetId, zones, eraseBoundaries = false) {
|
|
53129
|
+
const maxCol = this.getters.getNumberCols(sheetId) - 1;
|
|
53130
|
+
const maxRow = this.getters.getNumberRows(sheetId) - 1;
|
|
53071
53131
|
for (let zone of recomputeZones(zones)) {
|
|
53072
53132
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53073
|
-
|
|
53133
|
+
if (eraseBoundaries) {
|
|
53134
|
+
if (zone.left > 0) {
|
|
53135
|
+
this.history.update("borders", sheetId, zone.left - 1, row, "right", undefined);
|
|
53136
|
+
}
|
|
53137
|
+
if (zone.right < maxCol) {
|
|
53138
|
+
this.history.update("borders", sheetId, zone.right + 1, row, "left", undefined);
|
|
53139
|
+
}
|
|
53140
|
+
}
|
|
53074
53141
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53075
53142
|
this.history.update("borders", sheetId, col, row, undefined);
|
|
53143
|
+
if (eraseBoundaries) {
|
|
53144
|
+
if (zone.top > 0) {
|
|
53145
|
+
this.history.update("borders", sheetId, col, zone.top - 1, "bottom", undefined);
|
|
53146
|
+
}
|
|
53147
|
+
if (zone.bottom < maxRow) {
|
|
53148
|
+
this.history.update("borders", sheetId, col, zone.bottom + 1, "top", undefined);
|
|
53149
|
+
}
|
|
53150
|
+
}
|
|
53076
53151
|
}
|
|
53077
53152
|
}
|
|
53078
|
-
for (let col = zone.left; col <= zone.right; col++) {
|
|
53079
|
-
this.history.update("borders", sheetId, col, zone.bottom + 1, "horizontal", undefined);
|
|
53080
|
-
}
|
|
53081
53153
|
}
|
|
53082
53154
|
}
|
|
53083
53155
|
/**
|
|
@@ -53107,41 +53179,63 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
53107
53179
|
*/
|
|
53108
53180
|
setBorders(sheetId, zones, position, border) {
|
|
53109
53181
|
if (position === "clear") {
|
|
53110
|
-
return this.clearBorders(sheetId, zones);
|
|
53182
|
+
return this.clearBorders(sheetId, zones, true);
|
|
53111
53183
|
}
|
|
53112
53184
|
for (let zone of recomputeZones(zones)) {
|
|
53113
|
-
if (position === "
|
|
53114
|
-
for (let row = zone.top
|
|
53185
|
+
if (position === "all") {
|
|
53186
|
+
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53115
53187
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53116
|
-
this.addBorder(sheetId, col, row, {
|
|
53188
|
+
this.addBorder(sheetId, col, row, {
|
|
53189
|
+
top: border,
|
|
53190
|
+
right: border,
|
|
53191
|
+
bottom: border,
|
|
53192
|
+
left: border,
|
|
53193
|
+
});
|
|
53117
53194
|
}
|
|
53118
53195
|
}
|
|
53119
53196
|
}
|
|
53120
|
-
if (position === "
|
|
53197
|
+
if (position === "h" || position === "hv") {
|
|
53198
|
+
if (zone.top === zone.bottom) {
|
|
53199
|
+
continue;
|
|
53200
|
+
}
|
|
53201
|
+
for (let col = zone.left; col <= zone.right; col++) {
|
|
53202
|
+
this.addBorder(sheetId, col, zone.top, { bottom: border });
|
|
53203
|
+
for (let row = zone.top + 1; row < zone.bottom; row++) {
|
|
53204
|
+
this.addBorder(sheetId, col, row, { top: border, bottom: border });
|
|
53205
|
+
}
|
|
53206
|
+
this.addBorder(sheetId, col, zone.bottom, { top: border });
|
|
53207
|
+
}
|
|
53208
|
+
}
|
|
53209
|
+
if (position === "v" || position === "hv") {
|
|
53210
|
+
if (zone.left === zone.right) {
|
|
53211
|
+
continue;
|
|
53212
|
+
}
|
|
53121
53213
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53122
|
-
|
|
53123
|
-
|
|
53214
|
+
this.addBorder(sheetId, zone.left, row, { right: border });
|
|
53215
|
+
for (let col = zone.left + 1; col < zone.right; col++) {
|
|
53216
|
+
this.addBorder(sheetId, col, row, { left: border, right: border });
|
|
53124
53217
|
}
|
|
53218
|
+
this.addBorder(sheetId, zone.right, row, { left: border });
|
|
53125
53219
|
}
|
|
53126
53220
|
}
|
|
53127
|
-
if (position === "left" || position === "
|
|
53221
|
+
if (position === "left" || position === "external") {
|
|
53128
53222
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53129
53223
|
this.addBorder(sheetId, zone.left, row, { left: border });
|
|
53130
53224
|
}
|
|
53131
53225
|
}
|
|
53132
|
-
if (position === "right" || position === "
|
|
53226
|
+
if (position === "right" || position === "external") {
|
|
53133
53227
|
for (let row = zone.top; row <= zone.bottom; row++) {
|
|
53134
|
-
this.addBorder(sheetId, zone.right
|
|
53228
|
+
this.addBorder(sheetId, zone.right, row, { right: border });
|
|
53135
53229
|
}
|
|
53136
53230
|
}
|
|
53137
|
-
if (position === "top" || position === "
|
|
53231
|
+
if (position === "top" || position === "external") {
|
|
53138
53232
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53139
53233
|
this.addBorder(sheetId, col, zone.top, { top: border });
|
|
53140
53234
|
}
|
|
53141
53235
|
}
|
|
53142
|
-
if (position === "bottom" || position === "
|
|
53236
|
+
if (position === "bottom" || position === "external") {
|
|
53143
53237
|
for (let col = zone.left; col <= zone.right; col++) {
|
|
53144
|
-
this.addBorder(sheetId, col, zone.bottom
|
|
53238
|
+
this.addBorder(sheetId, col, zone.bottom, { bottom: border });
|
|
53145
53239
|
}
|
|
53146
53240
|
}
|
|
53147
53241
|
}
|
|
@@ -59886,7 +59980,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59886
59980
|
computeFormulaCell(formulaPosition, cellData) {
|
|
59887
59981
|
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, formulaPosition.sheetId, this.buildSafeGetSymbolValue(), formulaPosition);
|
|
59888
59982
|
if (!isMatrix(formulaReturn)) {
|
|
59889
|
-
|
|
59983
|
+
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(formulaReturn), this.getters.getLocale(), cellData);
|
|
59984
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
59985
|
+
evaluatedCell.errorOriginPosition = formulaReturn.errorOriginPosition ?? formulaPosition;
|
|
59986
|
+
}
|
|
59987
|
+
return evaluatedCell;
|
|
59890
59988
|
}
|
|
59891
59989
|
this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
|
|
59892
59990
|
const nbColumns = formulaReturn.length;
|
|
@@ -59959,6 +60057,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
59959
60057
|
const position = { sheetId, col: i + col, row: j + row };
|
|
59960
60058
|
const cell = this.getters.getCell(position);
|
|
59961
60059
|
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
60060
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
60061
|
+
evaluatedCell.errorOriginPosition = matrixResult[i][j].errorOriginPosition ?? position;
|
|
60062
|
+
}
|
|
59962
60063
|
this.evaluatedCells.set(position, evaluatedCell);
|
|
59963
60064
|
};
|
|
59964
60065
|
return spreadValues;
|
|
@@ -61517,7 +61618,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
61517
61618
|
const symbolIndex = rowDomain.findIndex((row) => row.field === symbolName);
|
|
61518
61619
|
return this.getPivotHeaderValueAndFormat(rowDomain.slice(0, symbolIndex + 1));
|
|
61519
61620
|
}
|
|
61520
|
-
return this.
|
|
61621
|
+
return this.getPivotCellValueAndFormat(symbolName, domain);
|
|
61521
61622
|
};
|
|
61522
61623
|
const result = this.getters.evaluateCompiledFormula(measure.computedBy.sheetId, formula, getSymbolValue);
|
|
61523
61624
|
if (isMatrix(result)) {
|
|
@@ -64703,14 +64804,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
64703
64804
|
}
|
|
64704
64805
|
break;
|
|
64705
64806
|
case "AUTORESIZE_ROWS":
|
|
64706
|
-
|
|
64707
|
-
|
|
64708
|
-
|
|
64709
|
-
|
|
64710
|
-
|
|
64711
|
-
|
|
64712
|
-
});
|
|
64713
|
-
}
|
|
64807
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
64808
|
+
elements: cmd.rows,
|
|
64809
|
+
dimension: "ROW",
|
|
64810
|
+
size: null,
|
|
64811
|
+
sheetId: cmd.sheetId,
|
|
64812
|
+
});
|
|
64714
64813
|
break;
|
|
64715
64814
|
}
|
|
64716
64815
|
}
|
|
@@ -67106,8 +67205,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67106
67205
|
right;
|
|
67107
67206
|
offsetX;
|
|
67108
67207
|
offsetY;
|
|
67109
|
-
offsetScrollbarX;
|
|
67110
|
-
offsetScrollbarY;
|
|
67111
67208
|
canScrollVertically;
|
|
67112
67209
|
canScrollHorizontally;
|
|
67113
67210
|
viewportWidth;
|
|
@@ -67118,10 +67215,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67118
67215
|
this.getters = getters;
|
|
67119
67216
|
this.sheetId = sheetId;
|
|
67120
67217
|
this.boundaries = boundaries;
|
|
67121
|
-
|
|
67122
|
-
|
|
67123
|
-
|
|
67124
|
-
this.
|
|
67218
|
+
if (sizeInGrid.width < 0 || sizeInGrid.height < 0) {
|
|
67219
|
+
throw new Error("Viewport size cannot be negative");
|
|
67220
|
+
}
|
|
67221
|
+
this.viewportWidth = sizeInGrid.height && sizeInGrid.width;
|
|
67222
|
+
this.viewportHeight = sizeInGrid.width && sizeInGrid.height;
|
|
67223
|
+
this.top = boundaries.top;
|
|
67224
|
+
this.bottom = boundaries.bottom;
|
|
67225
|
+
this.left = boundaries.left;
|
|
67226
|
+
this.right = boundaries.right;
|
|
67227
|
+
this.offsetX = offsets.x;
|
|
67228
|
+
this.offsetY = offsets.y;
|
|
67125
67229
|
this.canScrollVertically = options.canScrollVertically;
|
|
67126
67230
|
this.canScrollHorizontally = options.canScrollHorizontally;
|
|
67127
67231
|
this.offsetCorrectionX = this.getters.getColDimensions(this.sheetId, this.boundaries.left).start;
|
|
@@ -67162,9 +67266,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67162
67266
|
Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
|
|
67163
67267
|
);
|
|
67164
67268
|
height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
|
|
67165
|
-
|
|
67166
|
-
|
|
67167
|
-
|
|
67269
|
+
if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
|
|
67270
|
+
height += FOOTER_HEIGHT;
|
|
67271
|
+
}
|
|
67168
67272
|
}
|
|
67169
67273
|
return { width, height };
|
|
67170
67274
|
}
|
|
@@ -67177,7 +67281,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67177
67281
|
if (x < this.offsetCorrectionX || x > this.offsetCorrectionX + this.viewportWidth) {
|
|
67178
67282
|
return -1;
|
|
67179
67283
|
}
|
|
67180
|
-
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX, this.left);
|
|
67284
|
+
return this.searchHeaderIndex("COL", x - this.offsetCorrectionX + this.snapCorrection.x, this.left);
|
|
67181
67285
|
}
|
|
67182
67286
|
/**
|
|
67183
67287
|
* Return the index of a row given an offset y, based on the pane top
|
|
@@ -67188,7 +67292,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67188
67292
|
if (y < this.offsetCorrectionY || y > this.offsetCorrectionY + this.viewportHeight) {
|
|
67189
67293
|
return -1;
|
|
67190
67294
|
}
|
|
67191
|
-
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY, this.top);
|
|
67295
|
+
return this.searchHeaderIndex("ROW", y - this.offsetCorrectionY + this.snapCorrection.y, this.top);
|
|
67192
67296
|
}
|
|
67193
67297
|
/**
|
|
67194
67298
|
* This function will make sure that the provided cell position (or current selected position) is part of
|
|
@@ -67208,55 +67312,29 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67208
67312
|
}
|
|
67209
67313
|
adjustPositionX(targetCol) {
|
|
67210
67314
|
const sheetId = this.sheetId;
|
|
67211
|
-
const { end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
67212
|
-
if (this.offsetX + this.
|
|
67213
|
-
|
|
67214
|
-
|
|
67215
|
-
|
|
67216
|
-
|
|
67217
|
-
}
|
|
67218
|
-
const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
|
|
67219
|
-
const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left);
|
|
67220
|
-
this.offsetScrollbarX =
|
|
67221
|
-
this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
|
|
67222
|
-
}
|
|
67223
|
-
else if (this.left > targetCol) {
|
|
67224
|
-
let finalTarget = targetCol;
|
|
67225
|
-
while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
67226
|
-
finalTarget--;
|
|
67227
|
-
}
|
|
67228
|
-
this.offsetScrollbarX =
|
|
67229
|
-
this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
|
|
67315
|
+
const { start, end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
67316
|
+
if (this.offsetX + this.viewportWidth + this.offsetCorrectionX < end) {
|
|
67317
|
+
this.offsetX = end - this.viewportWidth;
|
|
67318
|
+
}
|
|
67319
|
+
else if (this.offsetX + this.offsetCorrectionX > start) {
|
|
67320
|
+
this.offsetX = start - this.offsetCorrectionX;
|
|
67230
67321
|
}
|
|
67231
67322
|
this.adjustViewportZoneX();
|
|
67232
67323
|
}
|
|
67233
67324
|
adjustPositionY(targetRow) {
|
|
67234
67325
|
const sheetId = this.sheetId;
|
|
67235
|
-
const { end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
67326
|
+
const { start, end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
67236
67327
|
if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
|
|
67237
|
-
|
|
67238
|
-
let finalTarget = targetRow;
|
|
67239
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget < maxRow) {
|
|
67240
|
-
finalTarget++;
|
|
67241
|
-
}
|
|
67242
|
-
const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
|
|
67243
|
-
const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top);
|
|
67244
|
-
this.offsetScrollbarY =
|
|
67245
|
-
this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
|
|
67328
|
+
this.offsetY = end - this.viewportHeight;
|
|
67246
67329
|
}
|
|
67247
|
-
else if (this.
|
|
67248
|
-
|
|
67249
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
67250
|
-
finalTarget--;
|
|
67251
|
-
}
|
|
67252
|
-
this.offsetScrollbarY =
|
|
67253
|
-
this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
|
|
67330
|
+
else if (this.offsetY + this.offsetCorrectionY > start) {
|
|
67331
|
+
this.offsetY = start - this.offsetCorrectionY;
|
|
67254
67332
|
}
|
|
67255
67333
|
this.adjustViewportZoneY();
|
|
67256
67334
|
}
|
|
67257
67335
|
willNewOffsetScrollViewport(offsetX, offsetY) {
|
|
67258
|
-
return ((this.canScrollHorizontally && this.
|
|
67259
|
-
(this.canScrollVertically && this.
|
|
67336
|
+
return ((this.canScrollHorizontally && this.offsetX !== offsetX) ||
|
|
67337
|
+
(this.canScrollVertically && this.offsetY !== offsetY));
|
|
67260
67338
|
}
|
|
67261
67339
|
setViewportOffset(offsetX, offsetY) {
|
|
67262
67340
|
this.setViewportOffsetX(offsetX);
|
|
@@ -67273,11 +67351,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67273
67351
|
*/
|
|
67274
67352
|
getVisibleRect(zone) {
|
|
67275
67353
|
const targetZone = intersection(zone, this);
|
|
67354
|
+
const scrollDeltaX = this.snapCorrection.x;
|
|
67355
|
+
const scrollDeltaY = this.snapCorrection.y;
|
|
67276
67356
|
if (targetZone) {
|
|
67277
|
-
const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) +
|
|
67278
|
-
|
|
67279
|
-
|
|
67280
|
-
const
|
|
67357
|
+
const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) +
|
|
67358
|
+
this.offsetCorrectionX -
|
|
67359
|
+
(this.left !== targetZone.left ? scrollDeltaX : 0);
|
|
67360
|
+
const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) +
|
|
67361
|
+
this.offsetCorrectionY -
|
|
67362
|
+
(this.top !== targetZone.top ? scrollDeltaY : 0);
|
|
67363
|
+
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1) -
|
|
67364
|
+
(this.left === targetZone.left ? scrollDeltaX : 0), this.viewportWidth);
|
|
67365
|
+
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1) -
|
|
67366
|
+
(this.top === targetZone.top ? scrollDeltaY : 0), this.viewportHeight);
|
|
67281
67367
|
return { x, y, width, height };
|
|
67282
67368
|
}
|
|
67283
67369
|
return undefined;
|
|
@@ -67289,12 +67375,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67289
67375
|
*/
|
|
67290
67376
|
getFullRect(zone) {
|
|
67291
67377
|
const targetZone = intersection(zone, this);
|
|
67378
|
+
const scrollDeltaX = this.snapCorrection.x;
|
|
67379
|
+
const scrollDeltaY = this.snapCorrection.y;
|
|
67292
67380
|
if (targetZone) {
|
|
67293
67381
|
const x = this.getters.getColRowOffset("COL", this.left, zone.left) + this.offsetCorrectionX;
|
|
67294
67382
|
const y = this.getters.getColRowOffset("ROW", this.top, zone.top) + this.offsetCorrectionY;
|
|
67295
67383
|
const width = this.getters.getColRowOffset("COL", zone.left, zone.right + 1);
|
|
67296
67384
|
const height = this.getters.getColRowOffset("ROW", zone.top, zone.bottom + 1);
|
|
67297
|
-
return { x, y, width, height };
|
|
67385
|
+
return { x: x - scrollDeltaX, y: y - scrollDeltaY, width, height };
|
|
67298
67386
|
}
|
|
67299
67387
|
return undefined;
|
|
67300
67388
|
}
|
|
@@ -67305,6 +67393,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67305
67393
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
67306
67394
|
}
|
|
67307
67395
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
67396
|
+
if (this.viewportWidth <= 0 || this.viewportHeight <= 0) {
|
|
67397
|
+
return -1;
|
|
67398
|
+
}
|
|
67308
67399
|
const sheetId = this.sheetId;
|
|
67309
67400
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
67310
67401
|
// using a binary search:
|
|
@@ -67330,36 +67421,36 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67330
67421
|
if (!this.canScrollHorizontally) {
|
|
67331
67422
|
return;
|
|
67332
67423
|
}
|
|
67333
|
-
this.
|
|
67424
|
+
this.offsetX = offsetX;
|
|
67334
67425
|
this.adjustViewportZoneX();
|
|
67335
67426
|
}
|
|
67336
67427
|
setViewportOffsetY(offsetY) {
|
|
67337
67428
|
if (!this.canScrollVertically) {
|
|
67338
67429
|
return;
|
|
67339
67430
|
}
|
|
67340
|
-
this.
|
|
67431
|
+
this.offsetY = offsetY;
|
|
67341
67432
|
this.adjustViewportZoneY();
|
|
67342
67433
|
}
|
|
67343
67434
|
/** Corrects the viewport's horizontal offset based on the current structure
|
|
67344
|
-
* To make sure that at least
|
|
67435
|
+
* To make sure that at least one column is visible inside the viewport.
|
|
67345
67436
|
*/
|
|
67346
67437
|
adjustViewportOffsetX() {
|
|
67347
67438
|
if (this.canScrollHorizontally) {
|
|
67348
67439
|
const { width: viewportWidth } = this.getMaxSize();
|
|
67349
|
-
if (this.viewportWidth + this.
|
|
67350
|
-
this.
|
|
67440
|
+
if (this.viewportWidth + this.offsetX > viewportWidth) {
|
|
67441
|
+
this.offsetX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
67351
67442
|
}
|
|
67352
67443
|
}
|
|
67353
67444
|
this.adjustViewportZoneX();
|
|
67354
67445
|
}
|
|
67355
67446
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
67356
|
-
* To make sure that at least
|
|
67447
|
+
* To make sure that at least one row is visible inside the viewport.
|
|
67357
67448
|
*/
|
|
67358
67449
|
adjustViewportOffsetY() {
|
|
67359
67450
|
if (this.canScrollVertically) {
|
|
67360
67451
|
const { height: paneHeight } = this.getMaxSize();
|
|
67361
|
-
if (this.viewportHeight + this.
|
|
67362
|
-
this.
|
|
67452
|
+
if (this.viewportHeight + this.offsetY > paneHeight) {
|
|
67453
|
+
this.offsetY = Math.max(0, paneHeight - this.viewportHeight);
|
|
67363
67454
|
}
|
|
67364
67455
|
}
|
|
67365
67456
|
this.adjustViewportZoneY();
|
|
@@ -67367,34 +67458,47 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67367
67458
|
/** Updates the pane zone and snapped offset based on its horizontal
|
|
67368
67459
|
* offset (will find Left) and its width (will find Right) */
|
|
67369
67460
|
adjustViewportZoneX() {
|
|
67370
|
-
|
|
67371
|
-
this.
|
|
67372
|
-
|
|
67461
|
+
this.left = this.searchHeaderIndex("COL", this.offsetX, this.boundaries.left);
|
|
67462
|
+
this.right = Math.min(this.boundaries.right, this.searchHeaderIndex("COL",
|
|
67463
|
+
// if we hit the border of two cells, we want to match the previous
|
|
67464
|
+
Math.max(this.viewportWidth + this.snapCorrection.x - 0.1), this.left));
|
|
67465
|
+
if (!this.viewportWidth) {
|
|
67466
|
+
return;
|
|
67467
|
+
}
|
|
67373
67468
|
if (this.left === -1) {
|
|
67374
67469
|
this.left = this.boundaries.left;
|
|
67375
67470
|
}
|
|
67376
67471
|
if (this.right === -1) {
|
|
67377
|
-
this.right = this.
|
|
67472
|
+
this.right = this.boundaries.right;
|
|
67378
67473
|
}
|
|
67379
|
-
this.offsetX =
|
|
67380
|
-
this.getters.getColDimensions(sheetId, this.left).start -
|
|
67381
|
-
this.getters.getColDimensions(sheetId, this.boundaries.left).start;
|
|
67382
67474
|
}
|
|
67383
67475
|
/** Updates the pane zone and snapped offset based on its vertical
|
|
67384
67476
|
* offset (will find Top) and its width (will find Bottom) */
|
|
67385
67477
|
adjustViewportZoneY() {
|
|
67386
|
-
|
|
67387
|
-
this.
|
|
67388
|
-
|
|
67478
|
+
this.top = this.searchHeaderIndex("ROW", this.offsetY, this.boundaries.top);
|
|
67479
|
+
this.bottom = Math.min(this.boundaries.bottom, this.searchHeaderIndex("ROW",
|
|
67480
|
+
// if we hit the border of two cells, we want to match the previous
|
|
67481
|
+
Math.max(this.viewportHeight + this.snapCorrection.y - 0.1, 0), this.top));
|
|
67482
|
+
if (!this.viewportHeight) {
|
|
67483
|
+
return;
|
|
67484
|
+
}
|
|
67389
67485
|
if (this.top === -1) {
|
|
67390
67486
|
this.top = this.boundaries.top;
|
|
67391
67487
|
}
|
|
67392
67488
|
if (this.bottom === -1) {
|
|
67393
|
-
this.bottom = this.
|
|
67489
|
+
this.bottom = this.boundaries.bottom;
|
|
67394
67490
|
}
|
|
67395
|
-
|
|
67396
|
-
|
|
67397
|
-
|
|
67491
|
+
}
|
|
67492
|
+
/** represents the part of the header on the topLeft that could be partially
|
|
67493
|
+
* hidden due to the scroll
|
|
67494
|
+
* */
|
|
67495
|
+
get snapCorrection() {
|
|
67496
|
+
return {
|
|
67497
|
+
x: Math.abs(this.offsetX -
|
|
67498
|
+
this.getters.getColRowOffset("COL", this.boundaries.left, Math.max(0, this.left))),
|
|
67499
|
+
y: Math.abs(this.offsetY -
|
|
67500
|
+
this.getters.getColRowOffset("ROW", this.boundaries.top, Math.max(0, this.top))),
|
|
67501
|
+
};
|
|
67398
67502
|
}
|
|
67399
67503
|
}
|
|
67400
67504
|
|
|
@@ -67457,14 +67561,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67457
67561
|
"getColRowOffsetInViewport",
|
|
67458
67562
|
"getMainViewportCoordinates",
|
|
67459
67563
|
"getActiveSheetScrollInfo",
|
|
67460
|
-
"getActiveSheetDOMScrollInfo",
|
|
67461
67564
|
"getSheetViewVisibleCols",
|
|
67462
67565
|
"getSheetViewVisibleRows",
|
|
67463
67566
|
"getFrozenSheetViewRatio",
|
|
67464
|
-
"
|
|
67567
|
+
"isPixelPositionVisible",
|
|
67465
67568
|
"getColDimensionsInViewport",
|
|
67466
67569
|
"getRowDimensionsInViewport",
|
|
67467
|
-
"
|
|
67570
|
+
"getAllActiveViewportsZonesAndRect",
|
|
67468
67571
|
"getRect",
|
|
67469
67572
|
];
|
|
67470
67573
|
viewports = {};
|
|
@@ -67667,8 +67770,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67667
67770
|
return this.getMainViewport(sheetId);
|
|
67668
67771
|
}
|
|
67669
67772
|
/**
|
|
67670
|
-
* Return the scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67671
|
-
* the grid left/top side, snapped to the
|
|
67773
|
+
* Return the DOM scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67774
|
+
* the grid left/top side, corresponding to the scroll of the scrollbars and not snapped to the grid.
|
|
67672
67775
|
*/
|
|
67673
67776
|
getActiveSheetScrollInfo() {
|
|
67674
67777
|
const sheetId = this.getters.getActiveSheetId();
|
|
@@ -67678,28 +67781,16 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67678
67781
|
scrollY: viewport.offsetY,
|
|
67679
67782
|
};
|
|
67680
67783
|
}
|
|
67681
|
-
/**
|
|
67682
|
-
* Return the DOM scroll info of the active sheet, ie. the offset between the viewport left/top side and
|
|
67683
|
-
* the grid left/top side, corresponding to the scroll of the scrollbars and not snapped to the grid.
|
|
67684
|
-
*/
|
|
67685
|
-
getActiveSheetDOMScrollInfo() {
|
|
67686
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
67687
|
-
const viewport = this.getMainInternalViewport(sheetId);
|
|
67688
|
-
return {
|
|
67689
|
-
scrollX: viewport.offsetScrollbarX,
|
|
67690
|
-
scrollY: viewport.offsetScrollbarY,
|
|
67691
|
-
};
|
|
67692
|
-
}
|
|
67693
67784
|
getSheetViewVisibleCols() {
|
|
67694
67785
|
const sheetId = this.getters.getActiveSheetId();
|
|
67695
67786
|
const viewports = this.getSubViewports(sheetId);
|
|
67696
67787
|
//TODO ake another commit to eimprove this
|
|
67697
|
-
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67788
|
+
return [...new Set(viewports.map((v) => range(v.left, v.right + 1)).flat())].filter((col) => col >= 0 && !this.getters.isHeaderHidden(sheetId, "COL", col));
|
|
67698
67789
|
}
|
|
67699
67790
|
getSheetViewVisibleRows() {
|
|
67700
67791
|
const sheetId = this.getters.getActiveSheetId();
|
|
67701
67792
|
const viewports = this.getSubViewports(sheetId);
|
|
67702
|
-
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67793
|
+
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => row >= 0 && !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
67703
67794
|
}
|
|
67704
67795
|
/**
|
|
67705
67796
|
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
@@ -67742,19 +67833,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67742
67833
|
maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
|
|
67743
67834
|
};
|
|
67744
67835
|
}
|
|
67745
|
-
getColRowOffsetInViewport(dimension,
|
|
67746
|
-
|
|
67747
|
-
|
|
67748
|
-
const visibleRows = this.getters.getSheetViewVisibleRows();
|
|
67749
|
-
if (index < referenceIndex) {
|
|
67750
|
-
return -this.getColRowOffsetInViewport(dimension, index, referenceIndex);
|
|
67836
|
+
getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
|
|
67837
|
+
if (targetHeaderIndex < referenceHeaderIndex) {
|
|
67838
|
+
return -this.getColRowOffsetInViewport(dimension, targetHeaderIndex, referenceHeaderIndex);
|
|
67751
67839
|
}
|
|
67840
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
67841
|
+
const visibleHeaders = dimension === "COL"
|
|
67842
|
+
? this.getters.getSheetViewVisibleCols()
|
|
67843
|
+
: this.getters.getSheetViewVisibleRows();
|
|
67844
|
+
const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
|
|
67845
|
+
const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
|
|
67846
|
+
const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
|
|
67752
67847
|
let offset = 0;
|
|
67753
|
-
const
|
|
67754
|
-
for (let i = referenceIndex; i < index; i++) {
|
|
67755
|
-
if (!visibleIndexes.includes(i)) {
|
|
67756
|
-
continue;
|
|
67757
|
-
}
|
|
67848
|
+
for (const i of relevantIndexes) {
|
|
67758
67849
|
offset += this.getters.getHeaderSize(sheetId, dimension, i);
|
|
67759
67850
|
}
|
|
67760
67851
|
return offset;
|
|
@@ -67801,7 +67892,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67801
67892
|
}
|
|
67802
67893
|
return { canEdgeScroll, direction, delay };
|
|
67803
67894
|
}
|
|
67804
|
-
getEdgeScrollRow(y, previousY,
|
|
67895
|
+
getEdgeScrollRow(y, previousY, startingY) {
|
|
67805
67896
|
let canEdgeScroll = false;
|
|
67806
67897
|
let direction = 0;
|
|
67807
67898
|
let delay = 0;
|
|
@@ -67822,7 +67913,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67822
67913
|
delay = scrollDelay(y - height);
|
|
67823
67914
|
direction = 1;
|
|
67824
67915
|
}
|
|
67825
|
-
else if (y < offsetCorrectionY &&
|
|
67916
|
+
else if (y < offsetCorrectionY && startingY >= offsetCorrectionY && currentOffsetY > 0) {
|
|
67826
67917
|
// 2
|
|
67827
67918
|
canEdgeScroll = true;
|
|
67828
67919
|
delay = scrollDelay(offsetCorrectionY - y);
|
|
@@ -67848,13 +67939,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67848
67939
|
*/
|
|
67849
67940
|
getVisibleRectWithoutHeaders(zone) {
|
|
67850
67941
|
const sheetId = this.getters.getActiveSheetId();
|
|
67851
|
-
|
|
67852
|
-
.map((viewport) => viewport.getVisibleRect(zone))
|
|
67853
|
-
.filter(isDefined);
|
|
67854
|
-
if (viewportRects.length === 0) {
|
|
67855
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67856
|
-
}
|
|
67857
|
-
return this.recomposeRect(viewportRects);
|
|
67942
|
+
return this.mapViewportsToRect(sheetId, (viewport) => viewport.getVisibleRect(zone));
|
|
67858
67943
|
}
|
|
67859
67944
|
/**
|
|
67860
67945
|
* Computes the actual size and position (:Rect) of the zone on the canvas
|
|
@@ -67862,13 +67947,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67862
67947
|
*/
|
|
67863
67948
|
getRect(zone) {
|
|
67864
67949
|
const sheetId = this.getters.getActiveSheetId();
|
|
67865
|
-
const
|
|
67866
|
-
.map((viewport) => viewport.getFullRect(zone))
|
|
67867
|
-
.filter(isDefined);
|
|
67868
|
-
if (viewportRects.length === 0) {
|
|
67869
|
-
return { x: 0, y: 0, width: 0, height: 0 };
|
|
67870
|
-
}
|
|
67871
|
-
const rect = this.recomposeRect(viewportRects);
|
|
67950
|
+
const rect = this.mapViewportsToRect(sheetId, (viewport) => viewport.getFullRect(zone));
|
|
67872
67951
|
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
67873
67952
|
}
|
|
67874
67953
|
/**
|
|
@@ -67888,34 +67967,43 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67888
67967
|
* column of the current viewport
|
|
67889
67968
|
*/
|
|
67890
67969
|
getColDimensionsInViewport(sheetId, col) {
|
|
67891
|
-
const
|
|
67892
|
-
|
|
67893
|
-
|
|
67894
|
-
|
|
67895
|
-
|
|
67896
|
-
start,
|
|
67897
|
-
size: size,
|
|
67898
|
-
end: start + (isColHidden ? 0 : size),
|
|
67970
|
+
const zone = {
|
|
67971
|
+
left: col,
|
|
67972
|
+
right: col,
|
|
67973
|
+
top: 0,
|
|
67974
|
+
bottom: this.getters.getNumberRows(sheetId) - 1,
|
|
67899
67975
|
};
|
|
67976
|
+
const { x, width } = this.getVisibleRect(zone);
|
|
67977
|
+
const start = x - this.gridOffsetX;
|
|
67978
|
+
return { start, size: width, end: start + width };
|
|
67900
67979
|
}
|
|
67901
67980
|
/**
|
|
67902
67981
|
* Returns the size, start and end coordinates of a row relative to the top row
|
|
67903
67982
|
* of the current viewport
|
|
67904
67983
|
*/
|
|
67905
67984
|
getRowDimensionsInViewport(sheetId, row) {
|
|
67906
|
-
const
|
|
67907
|
-
|
|
67908
|
-
|
|
67909
|
-
|
|
67910
|
-
|
|
67911
|
-
start,
|
|
67912
|
-
size: size,
|
|
67913
|
-
end: start + (isRowHidden ? 0 : size),
|
|
67985
|
+
const zone = {
|
|
67986
|
+
left: 0,
|
|
67987
|
+
right: this.getters.getNumberCols(sheetId) - 1,
|
|
67988
|
+
top: row,
|
|
67989
|
+
bottom: row,
|
|
67914
67990
|
};
|
|
67991
|
+
const { y, height } = this.getVisibleRect(zone);
|
|
67992
|
+
const start = y - this.gridOffsetY;
|
|
67993
|
+
return { start, size: height, end: start + height };
|
|
67915
67994
|
}
|
|
67916
|
-
|
|
67995
|
+
getAllActiveViewportsZonesAndRect() {
|
|
67917
67996
|
const sheetId = this.getters.getActiveSheetId();
|
|
67918
|
-
return this.getSubViewports(sheetId)
|
|
67997
|
+
return this.getSubViewports(sheetId).map((viewport) => {
|
|
67998
|
+
return {
|
|
67999
|
+
zone: viewport,
|
|
68000
|
+
rect: {
|
|
68001
|
+
x: viewport.offsetCorrectionX + this.gridOffsetX,
|
|
68002
|
+
y: viewport.offsetCorrectionY + this.gridOffsetY,
|
|
68003
|
+
...viewport.getMaxSize(),
|
|
68004
|
+
},
|
|
68005
|
+
};
|
|
68006
|
+
});
|
|
67919
68007
|
}
|
|
67920
68008
|
// ---------------------------------------------------------------------------
|
|
67921
68009
|
// Private
|
|
@@ -67974,12 +68062,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67974
68062
|
}
|
|
67975
68063
|
/** gets rid of deprecated sheetIds */
|
|
67976
68064
|
cleanViewports() {
|
|
67977
|
-
const
|
|
67978
|
-
for (
|
|
67979
|
-
|
|
67980
|
-
delete this.viewports[sheetId];
|
|
67981
|
-
}
|
|
68065
|
+
const newViewport = {};
|
|
68066
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68067
|
+
newViewport[sheetId] = this.viewports[sheetId];
|
|
67982
68068
|
}
|
|
68069
|
+
this.viewports = newViewport;
|
|
67983
68070
|
}
|
|
67984
68071
|
resizeSheetView(height, width, gridOffsetX = 0, gridOffsetY = 0) {
|
|
67985
68072
|
this.sheetViewHeight = height;
|
|
@@ -67989,7 +68076,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67989
68076
|
this.recomputeViewports();
|
|
67990
68077
|
}
|
|
67991
68078
|
recomputeViewports() {
|
|
67992
|
-
for (
|
|
68079
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
67993
68080
|
this.resetViewports(sheetId);
|
|
67994
68081
|
}
|
|
67995
68082
|
}
|
|
@@ -68000,8 +68087,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68000
68087
|
}
|
|
68001
68088
|
getViewportOffset(sheetId) {
|
|
68002
68089
|
return {
|
|
68003
|
-
x: this.viewports[sheetId]?.bottomRight.
|
|
68004
|
-
y: this.viewports[sheetId]?.bottomRight.
|
|
68090
|
+
x: this.viewports[sheetId]?.bottomRight.offsetX || 0,
|
|
68091
|
+
y: this.viewports[sheetId]?.bottomRight.offsetY || 0,
|
|
68005
68092
|
};
|
|
68006
68093
|
}
|
|
68007
68094
|
resetViewports(sheetId) {
|
|
@@ -68011,8 +68098,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68011
68098
|
const { xSplit, ySplit } = this.getters.getPaneDivisions(sheetId);
|
|
68012
68099
|
const nCols = this.getters.getNumberCols(sheetId);
|
|
68013
68100
|
const nRows = this.getters.getNumberRows(sheetId);
|
|
68014
|
-
const colOffset = this.getters.getColRowOffset("COL", 0, xSplit, sheetId);
|
|
68015
|
-
const rowOffset = this.getters.getColRowOffset("ROW", 0, ySplit, sheetId);
|
|
68101
|
+
const colOffset = Math.min(this.getters.getColRowOffset("COL", 0, xSplit, sheetId), this.sheetViewWidth);
|
|
68102
|
+
const rowOffset = Math.min(this.getters.getColRowOffset("ROW", 0, ySplit, sheetId), this.sheetViewHeight);
|
|
68103
|
+
const unfrozenWidth = Math.max(this.sheetViewWidth - colOffset, 0);
|
|
68104
|
+
const unfrozenHeight = Math.max(this.sheetViewHeight - rowOffset, 0);
|
|
68016
68105
|
const { xRatio, yRatio } = this.getFrozenSheetViewRatio(sheetId);
|
|
68017
68106
|
const canScrollHorizontally = xRatio < 1.0;
|
|
68018
68107
|
const canScrollVertically = yRatio < 1.0;
|
|
@@ -68023,14 +68112,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68023
68112
|
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 })) ||
|
|
68024
68113
|
undefined,
|
|
68025
68114
|
topRight: (ySplit &&
|
|
68026
|
-
new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: 0, bottom: ySplit - 1 }, { width:
|
|
68115
|
+
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 })) ||
|
|
68027
68116
|
undefined,
|
|
68028
68117
|
bottomLeft: (xSplit &&
|
|
68029
|
-
new InternalViewport(this.getters, sheetId, { left: 0, right: xSplit - 1, top: ySplit, bottom: nRows - 1 }, { width: colOffset, height:
|
|
68118
|
+
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 })) ||
|
|
68030
68119
|
undefined,
|
|
68031
68120
|
bottomRight: new InternalViewport(this.getters, sheetId, { left: xSplit, right: nCols - 1, top: ySplit, bottom: nRows - 1 }, {
|
|
68032
|
-
width:
|
|
68033
|
-
height:
|
|
68121
|
+
width: unfrozenWidth,
|
|
68122
|
+
height: unfrozenHeight,
|
|
68034
68123
|
}, { canScrollHorizontally, canScrollVertically }, {
|
|
68035
68124
|
x: canScrollHorizontally ? previousOffset.x : 0,
|
|
68036
68125
|
y: canScrollVertically ? previousOffset.y : 0,
|
|
@@ -68085,7 +68174,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68085
68174
|
}
|
|
68086
68175
|
return result;
|
|
68087
68176
|
}
|
|
68088
|
-
|
|
68177
|
+
isPixelPositionVisible(position) {
|
|
68089
68178
|
const { scrollX, scrollY } = this.getters.getActiveSheetScrollInfo();
|
|
68090
68179
|
const { x: mainViewportX, y: mainViewportY } = this.getters.getMainViewportCoordinates();
|
|
68091
68180
|
const { width, height } = this.getters.getSheetViewDimension();
|
|
@@ -68107,12 +68196,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68107
68196
|
const height = this.sheetViewHeight + this.gridOffsetY;
|
|
68108
68197
|
return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
|
|
68109
68198
|
}
|
|
68110
|
-
|
|
68111
|
-
|
|
68112
|
-
|
|
68113
|
-
|
|
68114
|
-
|
|
68115
|
-
|
|
68199
|
+
mapViewportsToRect(sheetId, rectCallBack) {
|
|
68200
|
+
let x = Infinity;
|
|
68201
|
+
let y = Infinity;
|
|
68202
|
+
let width = 0;
|
|
68203
|
+
let height = 0;
|
|
68204
|
+
let hasViewports = false;
|
|
68205
|
+
for (const viewport of this.getSubViewports(sheetId)) {
|
|
68206
|
+
const rect = rectCallBack(viewport);
|
|
68207
|
+
if (rect) {
|
|
68208
|
+
hasViewports = true;
|
|
68209
|
+
x = Math.min(x, rect.x);
|
|
68210
|
+
y = Math.min(y, rect.y);
|
|
68211
|
+
width = Math.max(width, rect.x + rect.width);
|
|
68212
|
+
height = Math.max(height, rect.y + rect.height);
|
|
68213
|
+
}
|
|
68214
|
+
}
|
|
68215
|
+
if (!hasViewports) {
|
|
68216
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
68217
|
+
}
|
|
68218
|
+
return { x, y, width: width - x, height: height - y };
|
|
68116
68219
|
}
|
|
68117
68220
|
}
|
|
68118
68221
|
|
|
@@ -69287,7 +69390,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69287
69390
|
});
|
|
69288
69391
|
}
|
|
69289
69392
|
moveCanvas(deltaX, deltaY) {
|
|
69290
|
-
const { scrollX, scrollY } = this.env.model.getters.
|
|
69393
|
+
const { scrollX, scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
|
|
69291
69394
|
this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
|
|
69292
69395
|
offsetX: scrollX + deltaX,
|
|
69293
69396
|
offsetY: scrollY + deltaY,
|
|
@@ -70480,12 +70583,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70480
70583
|
.o-spreadsheet {
|
|
70481
70584
|
position: relative;
|
|
70482
70585
|
display: grid;
|
|
70483
|
-
color: ${TEXT_BODY};
|
|
70484
70586
|
font-size: 14px;
|
|
70485
70587
|
|
|
70486
|
-
input {
|
|
70487
|
-
background-color: white;
|
|
70488
|
-
}
|
|
70489
70588
|
.text-muted {
|
|
70490
70589
|
color: ${TEXT_BODY_MUTED} !important;
|
|
70491
70590
|
}
|
|
@@ -71732,6 +71831,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71732
71831
|
observe(owner, callbacks) {
|
|
71733
71832
|
this.observers.set(owner, { owner, callbacks });
|
|
71734
71833
|
}
|
|
71834
|
+
detachObserver(owner) {
|
|
71835
|
+
this.observers.delete(owner);
|
|
71836
|
+
}
|
|
71735
71837
|
/**
|
|
71736
71838
|
* Capture the stream for yourself
|
|
71737
71839
|
*/
|
|
@@ -71824,6 +71926,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
71824
71926
|
observe(owner, callbacks) {
|
|
71825
71927
|
this.stream.observe(owner, callbacks);
|
|
71826
71928
|
}
|
|
71929
|
+
detachObserver(owner) {
|
|
71930
|
+
this.stream.detachObserver(owner);
|
|
71931
|
+
}
|
|
71827
71932
|
release(owner) {
|
|
71828
71933
|
if (this.stream.isListening(owner)) {
|
|
71829
71934
|
this.stream.release(owner);
|
|
@@ -75273,9 +75378,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
75273
75378
|
exports.tokenize = tokenize;
|
|
75274
75379
|
|
|
75275
75380
|
|
|
75276
|
-
__info__.version = "18.2.0-alpha.
|
|
75277
|
-
__info__.date = "2025-
|
|
75278
|
-
__info__.hash = "
|
|
75381
|
+
__info__.version = "18.2.0-alpha.6";
|
|
75382
|
+
__info__.date = "2025-02-05T06:50:47.008Z";
|
|
75383
|
+
__info__.hash = "dae9ab2";
|
|
75279
75384
|
|
|
75280
75385
|
|
|
75281
75386
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|