@odoo/o-spreadsheet 17.1.4 → 17.1.7
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 +274 -183
- package/dist/o-spreadsheet.d.ts +28 -14
- package/dist/o-spreadsheet.esm.js +274 -183
- package/dist/o-spreadsheet.iife.js +274 -183
- package/dist/o-spreadsheet.iife.min.js +294 -291
- package/dist/o_spreadsheet.xml +7 -6
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.1.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.7
|
|
6
|
+
* @date 2024-03-12T07:56:10.783Z
|
|
7
|
+
* @hash 3a9f334
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -452,8 +452,8 @@
|
|
|
452
452
|
* If the given item does not exist in the dictionary, it creates one with a new id.
|
|
453
453
|
*/
|
|
454
454
|
function getItemId(item, itemsDic) {
|
|
455
|
-
for (
|
|
456
|
-
if (deepEquals(
|
|
455
|
+
for (const key in itemsDic) {
|
|
456
|
+
if (deepEquals(itemsDic[key], item)) {
|
|
457
457
|
return parseInt(key, 10);
|
|
458
458
|
}
|
|
459
459
|
}
|
|
@@ -552,11 +552,13 @@
|
|
|
552
552
|
if (typeof o1 !== "object")
|
|
553
553
|
return o1 === o2;
|
|
554
554
|
// Objects can have different keys if the values are undefined
|
|
555
|
-
const
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
555
|
+
for (const key in o2) {
|
|
556
|
+
if (!(key in o1) && o2[key] !== undefined) {
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
for (const key in o1) {
|
|
561
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
560
562
|
return false;
|
|
561
563
|
if (typeof o1[key] === "object") {
|
|
562
564
|
if (!deepEquals(o1[key], o2[key]))
|
|
@@ -626,18 +628,18 @@
|
|
|
626
628
|
return true;
|
|
627
629
|
}
|
|
628
630
|
class JetSet extends Set {
|
|
629
|
-
|
|
631
|
+
addMany(iterable) {
|
|
630
632
|
for (const element of iterable) {
|
|
631
633
|
super.add(element);
|
|
632
634
|
}
|
|
633
635
|
return this;
|
|
634
636
|
}
|
|
635
|
-
|
|
636
|
-
let
|
|
637
|
+
deleteMany(iterable) {
|
|
638
|
+
let wasDeleted = false;
|
|
637
639
|
for (const element of iterable) {
|
|
638
|
-
|
|
640
|
+
wasDeleted ||= super.delete(element);
|
|
639
641
|
}
|
|
640
|
-
return
|
|
642
|
+
return wasDeleted;
|
|
641
643
|
}
|
|
642
644
|
}
|
|
643
645
|
/**
|
|
@@ -1935,7 +1937,7 @@
|
|
|
1935
1937
|
* Static helper which returns a successful DispatchResult
|
|
1936
1938
|
*/
|
|
1937
1939
|
static get Success() {
|
|
1938
|
-
return
|
|
1940
|
+
return SUCCESS;
|
|
1939
1941
|
}
|
|
1940
1942
|
get isSuccessful() {
|
|
1941
1943
|
return this.reasons.length === 0;
|
|
@@ -1948,6 +1950,7 @@
|
|
|
1948
1950
|
return this.reasons.includes(reason);
|
|
1949
1951
|
}
|
|
1950
1952
|
}
|
|
1953
|
+
const SUCCESS = new DispatchResult();
|
|
1951
1954
|
exports.CommandResult = void 0;
|
|
1952
1955
|
(function (CommandResult) {
|
|
1953
1956
|
CommandResult["Success"] = "Success";
|
|
@@ -6096,8 +6099,10 @@
|
|
|
6096
6099
|
if (x === cell) {
|
|
6097
6100
|
found = true;
|
|
6098
6101
|
}
|
|
6099
|
-
const cellValue =
|
|
6100
|
-
|
|
6102
|
+
const cellValue = x?.isFormula
|
|
6103
|
+
? undefined
|
|
6104
|
+
: evaluateLiteral(x?.content, { locale: DEFAULT_LOCALE });
|
|
6105
|
+
if (cellValue && filter(cellValue)) {
|
|
6101
6106
|
group.push(cellValue);
|
|
6102
6107
|
}
|
|
6103
6108
|
else {
|
|
@@ -6321,11 +6326,14 @@
|
|
|
6321
6326
|
* Transform CSS properties into a CSS string.
|
|
6322
6327
|
*/
|
|
6323
6328
|
function cssPropertiesToCss(attributes) {
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
|
|
6327
|
-
|
|
6328
|
-
|
|
6329
|
+
let styleStr = "";
|
|
6330
|
+
for (const attName in attributes) {
|
|
6331
|
+
if (!attributes[attName]) {
|
|
6332
|
+
continue;
|
|
6333
|
+
}
|
|
6334
|
+
styleStr += `${attName}:${attributes[attName]}; `;
|
|
6335
|
+
}
|
|
6336
|
+
return styleStr;
|
|
6329
6337
|
}
|
|
6330
6338
|
function getElementMargins(el) {
|
|
6331
6339
|
const style = window.getComputedStyle(el);
|
|
@@ -7654,6 +7662,9 @@
|
|
|
7654
7662
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
7655
7663
|
return false;
|
|
7656
7664
|
}
|
|
7665
|
+
if (locale.thousandsSeparator === locale.decimalSeparator) {
|
|
7666
|
+
return false;
|
|
7667
|
+
}
|
|
7657
7668
|
try {
|
|
7658
7669
|
formatValue(1, { locale, format: "#,##0.00" });
|
|
7659
7670
|
formatValue(1, { locale, format: locale.dateFormat });
|
|
@@ -7744,7 +7755,7 @@
|
|
|
7744
7755
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
7745
7756
|
return content;
|
|
7746
7757
|
}
|
|
7747
|
-
return content.replace(locale.decimalSeparator, ".");
|
|
7758
|
+
return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
|
|
7748
7759
|
}
|
|
7749
7760
|
/**
|
|
7750
7761
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -10839,6 +10850,12 @@
|
|
|
10839
10850
|
let { col, row } = env.model.getters.getActivePosition();
|
|
10840
10851
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
10841
10852
|
};
|
|
10853
|
+
const INSERT_LINK_NAME = (env) => {
|
|
10854
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
10855
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
10856
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
10857
|
+
return cell && cell.link ? _t("Edit link") : _t("Insert link");
|
|
10858
|
+
};
|
|
10842
10859
|
//------------------------------------------------------------------------------
|
|
10843
10860
|
// Filters action
|
|
10844
10861
|
//------------------------------------------------------------------------------
|
|
@@ -13040,6 +13057,18 @@
|
|
|
13040
13057
|
},
|
|
13041
13058
|
isExported: true,
|
|
13042
13059
|
};
|
|
13060
|
+
// -----------------------------------------------------------------------------
|
|
13061
|
+
// INT
|
|
13062
|
+
// -----------------------------------------------------------------------------
|
|
13063
|
+
const INT = {
|
|
13064
|
+
description: _t("Rounds a number down to the nearest integer that is less than or equal to it."),
|
|
13065
|
+
args: [arg("value (number)", _t("The number to round down to the nearest integer."))],
|
|
13066
|
+
returns: ["NUMBER"],
|
|
13067
|
+
compute: function (value) {
|
|
13068
|
+
return Math.floor(toNumber(value, this.locale));
|
|
13069
|
+
},
|
|
13070
|
+
isExported: true,
|
|
13071
|
+
};
|
|
13043
13072
|
|
|
13044
13073
|
var math = /*#__PURE__*/Object.freeze({
|
|
13045
13074
|
__proto__: null,
|
|
@@ -13073,6 +13102,7 @@
|
|
|
13073
13102
|
FLOOR: FLOOR,
|
|
13074
13103
|
FLOOR_MATH: FLOOR_MATH,
|
|
13075
13104
|
FLOOR_PRECISE: FLOOR_PRECISE,
|
|
13105
|
+
INT: INT,
|
|
13076
13106
|
ISEVEN: ISEVEN,
|
|
13077
13107
|
ISODD: ISODD,
|
|
13078
13108
|
ISO_CEILING: ISO_CEILING,
|
|
@@ -18599,10 +18629,11 @@
|
|
|
18599
18629
|
const DEFAULT_MATCH_MODE = 0;
|
|
18600
18630
|
const DEFAULT_SEARCH_MODE = 1;
|
|
18601
18631
|
const DEFAULT_ABSOLUTE_RELATIVE_MODE = 1;
|
|
18602
|
-
function
|
|
18603
|
-
|
|
18604
|
-
|
|
18605
|
-
|
|
18632
|
+
function valueNotAvailable(searchKey) {
|
|
18633
|
+
return {
|
|
18634
|
+
value: CellErrorType.NotAvailable,
|
|
18635
|
+
message: _t("Did not find value '%s' in [[FUNCTION_NAME]] evaluation.", toString(searchKey)),
|
|
18636
|
+
};
|
|
18606
18637
|
}
|
|
18607
18638
|
// -----------------------------------------------------------------------------
|
|
18608
18639
|
// ADDRESS
|
|
@@ -18699,7 +18730,9 @@
|
|
|
18699
18730
|
? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range.length, getValueFromRange)
|
|
18700
18731
|
: linearSearch(range, searchKey, "strict", range.length, getValueFromRange);
|
|
18701
18732
|
const col = range[colIndex];
|
|
18702
|
-
|
|
18733
|
+
if (col === undefined) {
|
|
18734
|
+
return valueNotAvailable(searchKey);
|
|
18735
|
+
}
|
|
18703
18736
|
return col[_index - 1];
|
|
18704
18737
|
},
|
|
18705
18738
|
isExported: true,
|
|
@@ -18756,11 +18789,11 @@
|
|
|
18756
18789
|
: (range, index) => range[index][0].value;
|
|
18757
18790
|
const rangeLength = verticalSearch ? nbRow : nbCol;
|
|
18758
18791
|
const index = dichotomicSearch(searchArray, searchKey, "nextSmaller", "asc", rangeLength, getElement);
|
|
18759
|
-
if (index === -1
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
|
|
18763
|
-
|
|
18792
|
+
if (index === -1 ||
|
|
18793
|
+
(verticalSearch && searchArray[0][index] === undefined) ||
|
|
18794
|
+
(!verticalSearch && searchArray[index][nbRow - 1] === undefined)) {
|
|
18795
|
+
return valueNotAvailable(searchKey);
|
|
18796
|
+
}
|
|
18764
18797
|
if (resultRange === undefined) {
|
|
18765
18798
|
return verticalSearch ? searchArray[nbCol - 1][index] : searchArray[index][nbRow - 1];
|
|
18766
18799
|
}
|
|
@@ -18810,7 +18843,10 @@
|
|
|
18810
18843
|
index = dichotomicSearch(range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
18811
18844
|
break;
|
|
18812
18845
|
}
|
|
18813
|
-
|
|
18846
|
+
if ((nbCol === 1 && range[0][index] === undefined) ||
|
|
18847
|
+
(nbCol !== 1 && range[index] === undefined)) {
|
|
18848
|
+
return valueNotAvailable(searchKey);
|
|
18849
|
+
}
|
|
18814
18850
|
return index + 1;
|
|
18815
18851
|
},
|
|
18816
18852
|
isExported: true,
|
|
@@ -18869,7 +18905,9 @@
|
|
|
18869
18905
|
? dichotomicSearch(range, searchKey, "nextSmaller", "asc", range[0].length, getValueFromRange)
|
|
18870
18906
|
: linearSearch(range, searchKey, "strict", range[0].length, getValueFromRange);
|
|
18871
18907
|
const value = range[_index - 1][rowIndex];
|
|
18872
|
-
|
|
18908
|
+
if (value === undefined) {
|
|
18909
|
+
return valueNotAvailable(searchKey);
|
|
18910
|
+
}
|
|
18873
18911
|
return value;
|
|
18874
18912
|
},
|
|
18875
18913
|
isExported: true,
|
|
@@ -18919,7 +18957,9 @@
|
|
|
18919
18957
|
? returnRange.map((col) => [col[index]])
|
|
18920
18958
|
: [returnRange[index]];
|
|
18921
18959
|
}
|
|
18922
|
-
|
|
18960
|
+
if (defaultValue === undefined) {
|
|
18961
|
+
return valueNotAvailable(searchKey);
|
|
18962
|
+
}
|
|
18923
18963
|
return [[defaultValue]];
|
|
18924
18964
|
},
|
|
18925
18965
|
isExported: true,
|
|
@@ -19691,8 +19731,7 @@
|
|
|
19691
19731
|
function addErrorHandling(compute, functionName) {
|
|
19692
19732
|
return function (...args) {
|
|
19693
19733
|
try {
|
|
19694
|
-
|
|
19695
|
-
return computeFormula(...args);
|
|
19734
|
+
return compute.apply(this, args);
|
|
19696
19735
|
}
|
|
19697
19736
|
catch (e) {
|
|
19698
19737
|
return handleError(e, functionName);
|
|
@@ -19726,8 +19765,7 @@
|
|
|
19726
19765
|
}
|
|
19727
19766
|
function addResultHandling(compute) {
|
|
19728
19767
|
return function (...args) {
|
|
19729
|
-
const
|
|
19730
|
-
const result = computeResult(...args);
|
|
19768
|
+
const result = compute.apply(this, args);
|
|
19731
19769
|
if (!isMatrix(result)) {
|
|
19732
19770
|
if (typeof result === "object" && result !== null && "value" in result) {
|
|
19733
19771
|
return result;
|
|
@@ -20083,7 +20121,7 @@
|
|
|
20083
20121
|
})
|
|
20084
20122
|
.add("insert_link", {
|
|
20085
20123
|
...insertLink,
|
|
20086
|
-
name:
|
|
20124
|
+
name: INSERT_LINK_NAME,
|
|
20087
20125
|
sequence: 150,
|
|
20088
20126
|
separator: true,
|
|
20089
20127
|
});
|
|
@@ -21694,7 +21732,7 @@
|
|
|
21694
21732
|
? existingSelectionRanges
|
|
21695
21733
|
: this.props.ranges().map((xc, id) => ({
|
|
21696
21734
|
xc,
|
|
21697
|
-
id,
|
|
21735
|
+
id: id + 1,
|
|
21698
21736
|
isFocused: false,
|
|
21699
21737
|
}));
|
|
21700
21738
|
return ranges.map((range) => ({
|
|
@@ -26526,6 +26564,17 @@
|
|
|
26526
26564
|
onValueSelected: Function,
|
|
26527
26565
|
onValueHovered: Function,
|
|
26528
26566
|
};
|
|
26567
|
+
autoCompleteListRef = owl.useRef("autoCompleteList");
|
|
26568
|
+
setup() {
|
|
26569
|
+
owl.useEffect(() => {
|
|
26570
|
+
const selectedIndex = this.props.selectedIndex;
|
|
26571
|
+
if (selectedIndex === undefined) {
|
|
26572
|
+
return;
|
|
26573
|
+
}
|
|
26574
|
+
const selectedElement = this.autoCompleteListRef.el?.children[selectedIndex];
|
|
26575
|
+
selectedElement?.scrollIntoView?.({ block: "nearest" });
|
|
26576
|
+
}, () => [this.props.selectedIndex, this.autoCompleteListRef.el]);
|
|
26577
|
+
}
|
|
26529
26578
|
}
|
|
26530
26579
|
|
|
26531
26580
|
class ContentEditableHelper {
|
|
@@ -26970,6 +27019,7 @@
|
|
|
26970
27019
|
position: absolute;
|
|
26971
27020
|
margin: 1px 4px;
|
|
26972
27021
|
pointer-events: none;
|
|
27022
|
+
overflow: auto;
|
|
26973
27023
|
|
|
26974
27024
|
.o-semi-bold {
|
|
26975
27025
|
/** FIXME: to remove in favor of Bootstrap
|
|
@@ -27027,7 +27077,10 @@
|
|
|
27027
27077
|
if (this.props.delimitation && this.props.rect) {
|
|
27028
27078
|
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
27029
27079
|
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
27080
|
+
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
27030
27081
|
if (cellY > remainingHeight) {
|
|
27082
|
+
const availableSpaceAbove = cellY;
|
|
27083
|
+
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
27031
27084
|
// render top
|
|
27032
27085
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
27033
27086
|
assistantStyle.top = `-3px`;
|
|
@@ -27719,7 +27772,11 @@
|
|
|
27719
27772
|
}
|
|
27720
27773
|
}
|
|
27721
27774
|
updateCellReferenceVisibility() {
|
|
27722
|
-
if (this.
|
|
27775
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
27776
|
+
this.isCellReferenceVisible = false;
|
|
27777
|
+
return;
|
|
27778
|
+
}
|
|
27779
|
+
if (this.isCellReferenceVisible) {
|
|
27723
27780
|
return;
|
|
27724
27781
|
}
|
|
27725
27782
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
@@ -27748,19 +27805,21 @@
|
|
|
27748
27805
|
slots: Object,
|
|
27749
27806
|
};
|
|
27750
27807
|
get iconStyle() {
|
|
27751
|
-
const
|
|
27752
|
-
const
|
|
27808
|
+
const cellPosition = this.props.cellPosition;
|
|
27809
|
+
const merge = this.env.model.getters.getMerge(cellPosition);
|
|
27810
|
+
const zone = merge || positionToZone(cellPosition);
|
|
27811
|
+
const rect = this.env.model.getters.getVisibleRectWithoutHeaders(zone);
|
|
27812
|
+
const x = this.getIconHorizontalPosition(rect, cellPosition);
|
|
27813
|
+
const y = this.getIconVerticalPosition(rect, cellPosition);
|
|
27753
27814
|
return cssPropertiesToCss({
|
|
27754
27815
|
top: `${y + (this.props.offset?.y || 0)}px`,
|
|
27755
27816
|
left: `${x + (this.props.offset?.x || 0)}px`,
|
|
27756
27817
|
});
|
|
27757
27818
|
}
|
|
27758
|
-
getIconVerticalPosition() {
|
|
27759
|
-
const
|
|
27760
|
-
const
|
|
27761
|
-
const
|
|
27762
|
-
const end = this.env.model.getters.getRowDimensionsInViewport(sheetId, merge ? merge.bottom : row).end;
|
|
27763
|
-
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
27819
|
+
getIconVerticalPosition(rect, cellPosition) {
|
|
27820
|
+
const start = rect.y;
|
|
27821
|
+
const end = rect.y + rect.height;
|
|
27822
|
+
const cell = this.env.model.getters.getCell(cellPosition);
|
|
27764
27823
|
const align = this.props.verticalAlign || cell?.style?.verticalAlign || DEFAULT_VERTICAL_ALIGN;
|
|
27765
27824
|
switch (align) {
|
|
27766
27825
|
case "bottom":
|
|
@@ -27772,13 +27831,11 @@
|
|
|
27772
27831
|
return end - GRID_ICON_EDGE_LENGTH - centeringOffset;
|
|
27773
27832
|
}
|
|
27774
27833
|
}
|
|
27775
|
-
getIconHorizontalPosition() {
|
|
27776
|
-
const
|
|
27777
|
-
const
|
|
27778
|
-
const
|
|
27779
|
-
const
|
|
27780
|
-
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
27781
|
-
const evaluatedCell = this.env.model.getters.getEvaluatedCell(this.props.cellPosition);
|
|
27834
|
+
getIconHorizontalPosition(rect, cellPosition) {
|
|
27835
|
+
const start = rect.x;
|
|
27836
|
+
const end = rect.x + rect.width;
|
|
27837
|
+
const cell = this.env.model.getters.getCell(cellPosition);
|
|
27838
|
+
const evaluatedCell = this.env.model.getters.getEvaluatedCell(cellPosition);
|
|
27782
27839
|
const align = this.props.horizontalAlign || cell?.style?.align || evaluatedCell.defaultAlign;
|
|
27783
27840
|
switch (align) {
|
|
27784
27841
|
case "right":
|
|
@@ -27862,6 +27919,8 @@
|
|
|
27862
27919
|
height: ${CHECKBOX_WIDTH}px;
|
|
27863
27920
|
accent-color: #808080;
|
|
27864
27921
|
margin: ${MARGIN}px;
|
|
27922
|
+
/** required to prevent the checkbox position to be sensible to the font-size (affects Firefox) */
|
|
27923
|
+
position: absolute;
|
|
27865
27924
|
}
|
|
27866
27925
|
`;
|
|
27867
27926
|
class DataValidationCheckbox extends owl.Component {
|
|
@@ -27880,7 +27939,7 @@
|
|
|
27880
27939
|
}
|
|
27881
27940
|
get isDisabled() {
|
|
27882
27941
|
const cell = this.env.model.getters.getCell(this.props.cellPosition);
|
|
27883
|
-
return !!cell?.isFormula;
|
|
27942
|
+
return this.env.model.getters.isReadonly() || !!cell?.isFormula;
|
|
27884
27943
|
}
|
|
27885
27944
|
}
|
|
27886
27945
|
|
|
@@ -27920,12 +27979,17 @@
|
|
|
27920
27979
|
static props = {};
|
|
27921
27980
|
static components = { GridCellIcon, DataValidationCheckbox, DataValidationListIcon };
|
|
27922
27981
|
get checkBoxCellPositions() {
|
|
27923
|
-
return this.env.model.getters
|
|
27982
|
+
return this.env.model.getters
|
|
27983
|
+
.getVisibleCellPositions()
|
|
27984
|
+
.filter(this.env.model.getters.isCellValidCheckbox);
|
|
27924
27985
|
}
|
|
27925
27986
|
get listIconsCellPositions() {
|
|
27926
|
-
|
|
27927
|
-
|
|
27928
|
-
|
|
27987
|
+
if (this.env.model.getters.isReadonly()) {
|
|
27988
|
+
return [];
|
|
27989
|
+
}
|
|
27990
|
+
return this.env.model.getters
|
|
27991
|
+
.getVisibleCellPositions()
|
|
27992
|
+
.filter(this.env.model.getters.cellHasListDataValidationIcon);
|
|
27929
27993
|
}
|
|
27930
27994
|
}
|
|
27931
27995
|
|
|
@@ -34287,29 +34351,12 @@
|
|
|
34287
34351
|
from: 12,
|
|
34288
34352
|
to: 12.5,
|
|
34289
34353
|
applyMigration(data) {
|
|
34290
|
-
|
|
34291
|
-
let knownDataFilterZones = [];
|
|
34292
|
-
for (let filterTable of sheet.filterTables || []) {
|
|
34293
|
-
const zone = toZone(filterTable.range);
|
|
34294
|
-
// See commit message for the details
|
|
34295
|
-
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
34296
|
-
if (intersectZoneIndex !== -1) {
|
|
34297
|
-
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
34298
|
-
}
|
|
34299
|
-
else {
|
|
34300
|
-
knownDataFilterZones.push(zone);
|
|
34301
|
-
}
|
|
34302
|
-
}
|
|
34303
|
-
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
34304
|
-
range: zoneToXc(zone),
|
|
34305
|
-
}));
|
|
34306
|
-
}
|
|
34307
|
-
return data;
|
|
34354
|
+
return fixOverlappingFilters(data);
|
|
34308
34355
|
},
|
|
34309
34356
|
},
|
|
34310
34357
|
{
|
|
34311
34358
|
description: "Change Border description structure",
|
|
34312
|
-
from: 12,
|
|
34359
|
+
from: 12.5,
|
|
34313
34360
|
to: 13,
|
|
34314
34361
|
applyMigration(data) {
|
|
34315
34362
|
for (const borderId in data.borders) {
|
|
@@ -34340,6 +34387,14 @@
|
|
|
34340
34387
|
return data;
|
|
34341
34388
|
},
|
|
34342
34389
|
},
|
|
34390
|
+
{
|
|
34391
|
+
description: "Fix datafilter duplication (post saas-16.4)",
|
|
34392
|
+
from: 14,
|
|
34393
|
+
to: 14.5,
|
|
34394
|
+
applyMigration(data) {
|
|
34395
|
+
return fixOverlappingFilters(data);
|
|
34396
|
+
},
|
|
34397
|
+
},
|
|
34343
34398
|
];
|
|
34344
34399
|
/**
|
|
34345
34400
|
* This function is used to repair faulty data independently of the migration.
|
|
@@ -34497,6 +34552,26 @@
|
|
|
34497
34552
|
}
|
|
34498
34553
|
return messages;
|
|
34499
34554
|
}
|
|
34555
|
+
function fixOverlappingFilters(data) {
|
|
34556
|
+
for (let sheet of data.sheets || []) {
|
|
34557
|
+
let knownDataFilterZones = [];
|
|
34558
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
34559
|
+
const zone = toZone(filterTable.range);
|
|
34560
|
+
// See commit message of https://github.com/odoo/o-spreadsheet/pull/3632 of more details
|
|
34561
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
34562
|
+
if (intersectZoneIndex !== -1) {
|
|
34563
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
34564
|
+
}
|
|
34565
|
+
else {
|
|
34566
|
+
knownDataFilterZones.push(zone);
|
|
34567
|
+
}
|
|
34568
|
+
}
|
|
34569
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
34570
|
+
range: zoneToXc(zone),
|
|
34571
|
+
}));
|
|
34572
|
+
}
|
|
34573
|
+
return data;
|
|
34574
|
+
}
|
|
34500
34575
|
// -----------------------------------------------------------------------------
|
|
34501
34576
|
// Helpers
|
|
34502
34577
|
// -----------------------------------------------------------------------------
|
|
@@ -35146,22 +35221,7 @@
|
|
|
35146
35221
|
}
|
|
35147
35222
|
}
|
|
35148
35223
|
export(data) {
|
|
35149
|
-
// Borders
|
|
35150
|
-
let borderId = 0;
|
|
35151
35224
|
const borders = {};
|
|
35152
|
-
/**
|
|
35153
|
-
* Get the id of the given border. If the border does not exist, it creates
|
|
35154
|
-
* one.
|
|
35155
|
-
*/
|
|
35156
|
-
function getBorderId(border) {
|
|
35157
|
-
for (let [key, value] of Object.entries(borders)) {
|
|
35158
|
-
if (deepEquals(value, border)) {
|
|
35159
|
-
return parseInt(key, 10);
|
|
35160
|
-
}
|
|
35161
|
-
}
|
|
35162
|
-
borders[++borderId] = border;
|
|
35163
|
-
return borderId;
|
|
35164
|
-
}
|
|
35165
35225
|
for (let sheet of data.sheets) {
|
|
35166
35226
|
for (let col = 0; col < sheet.colNumber; col++) {
|
|
35167
35227
|
for (let row = 0; row < sheet.rowNumber; row++) {
|
|
@@ -35169,7 +35229,7 @@
|
|
|
35169
35229
|
if (border) {
|
|
35170
35230
|
const xc = toXC(col, row);
|
|
35171
35231
|
const cell = sheet.cells[xc];
|
|
35172
|
-
const borderId =
|
|
35232
|
+
const borderId = getItemId(border, borders);
|
|
35173
35233
|
if (cell) {
|
|
35174
35234
|
cell.border = borderId;
|
|
35175
35235
|
}
|
|
@@ -35958,9 +36018,9 @@
|
|
|
35958
36018
|
allowDispatch(cmd) {
|
|
35959
36019
|
switch (cmd.type) {
|
|
35960
36020
|
case "UPDATE_CELL":
|
|
35961
|
-
return this.
|
|
36021
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
35962
36022
|
case "CLEAR_CELL":
|
|
35963
|
-
return this.checkValidations(cmd, this.
|
|
36023
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
35964
36024
|
default:
|
|
35965
36025
|
return "Success" /* CommandResult.Success */;
|
|
35966
36026
|
}
|
|
@@ -36110,8 +36170,8 @@
|
|
|
36110
36170
|
}
|
|
36111
36171
|
removeDefaultStyleValues(style) {
|
|
36112
36172
|
const cleanedStyle = { ...style };
|
|
36113
|
-
for (const
|
|
36114
|
-
if (cleanedStyle[property] ===
|
|
36173
|
+
for (const property in DEFAULT_STYLE) {
|
|
36174
|
+
if (cleanedStyle[property] === DEFAULT_STYLE[property]) {
|
|
36115
36175
|
delete cleanedStyle[property];
|
|
36116
36176
|
}
|
|
36117
36177
|
}
|
|
@@ -36267,10 +36327,7 @@
|
|
|
36267
36327
|
else {
|
|
36268
36328
|
style = before ? before.style : undefined;
|
|
36269
36329
|
}
|
|
36270
|
-
const
|
|
36271
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
36272
|
-
detectDateFormat(afterContent, locale) ||
|
|
36273
|
-
detectNumberFormat(afterContent);
|
|
36330
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
36274
36331
|
/* Read the following IF as:
|
|
36275
36332
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
36276
36333
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -36311,6 +36368,7 @@
|
|
|
36311
36368
|
}
|
|
36312
36369
|
createLiteralCell(id, content, format, style) {
|
|
36313
36370
|
const locale = this.getters.getLocale();
|
|
36371
|
+
format = format || detectDateFormat(content, locale) || detectNumberFormat(content);
|
|
36314
36372
|
if (format !== PLAIN_TEXT_FORMAT && !isEvaluationError(content)) {
|
|
36315
36373
|
content = toString(parseLiteral(content, locale));
|
|
36316
36374
|
}
|
|
@@ -36383,6 +36441,18 @@
|
|
|
36383
36441
|
}
|
|
36384
36442
|
return "Success" /* CommandResult.Success */;
|
|
36385
36443
|
}
|
|
36444
|
+
checkUselessUpdateCell(cmd) {
|
|
36445
|
+
const cell = this.getters.getCell(cmd);
|
|
36446
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
36447
|
+
const hasStyle = "style" in cmd;
|
|
36448
|
+
const hasFormat = "format" in cmd;
|
|
36449
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
36450
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
36451
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
36452
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
36453
|
+
}
|
|
36454
|
+
return "Success" /* CommandResult.Success */;
|
|
36455
|
+
}
|
|
36386
36456
|
}
|
|
36387
36457
|
class FormulaCellWithDependencies {
|
|
36388
36458
|
id;
|
|
@@ -39023,7 +39093,6 @@
|
|
|
39023
39093
|
"getNumberHeaders",
|
|
39024
39094
|
"getGridLinesVisibility",
|
|
39025
39095
|
"getNextSheetName",
|
|
39026
|
-
"isEmpty",
|
|
39027
39096
|
"getSheetSize",
|
|
39028
39097
|
"getSheetZone",
|
|
39029
39098
|
"getPaneDivisions",
|
|
@@ -39398,14 +39467,6 @@
|
|
|
39398
39467
|
// ---------------------------------------------------------------------------
|
|
39399
39468
|
// Row/Col manipulation
|
|
39400
39469
|
// ---------------------------------------------------------------------------
|
|
39401
|
-
/**
|
|
39402
|
-
* Check if a zone only contains empty cells
|
|
39403
|
-
*/
|
|
39404
|
-
isEmpty(sheetId, zone) {
|
|
39405
|
-
return positions(zone)
|
|
39406
|
-
.map(({ col, row }) => this.getCell({ sheetId, col, row }))
|
|
39407
|
-
.every((cell) => !cell || cell.content === "");
|
|
39408
|
-
}
|
|
39409
39470
|
getCommandZones(cmd) {
|
|
39410
39471
|
const zones = [];
|
|
39411
39472
|
if ("zone" in cmd) {
|
|
@@ -41167,7 +41228,15 @@
|
|
|
41167
41228
|
if (!this.rTrees[sheetId]) {
|
|
41168
41229
|
return;
|
|
41169
41230
|
}
|
|
41170
|
-
this.rTrees[sheetId].remove(item,
|
|
41231
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
41232
|
+
}
|
|
41233
|
+
rtreeItemComparer(left, right) {
|
|
41234
|
+
return (left.data == right.data &&
|
|
41235
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
41236
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
41237
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
41238
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
41239
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
41171
41240
|
}
|
|
41172
41241
|
}
|
|
41173
41242
|
/**
|
|
@@ -41245,7 +41314,7 @@
|
|
|
41245
41314
|
const queue = Array.from(ranges).reverse();
|
|
41246
41315
|
while (queue.length > 0) {
|
|
41247
41316
|
const range = queue.pop();
|
|
41248
|
-
visited.
|
|
41317
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
41249
41318
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
41250
41319
|
for (const positionId of impactedPositionIds) {
|
|
41251
41320
|
if (!visited.has(positionId)) {
|
|
@@ -41253,7 +41322,7 @@
|
|
|
41253
41322
|
}
|
|
41254
41323
|
}
|
|
41255
41324
|
}
|
|
41256
|
-
visited.
|
|
41325
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
41257
41326
|
return visited;
|
|
41258
41327
|
}
|
|
41259
41328
|
}
|
|
@@ -41393,9 +41462,9 @@
|
|
|
41393
41462
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
41394
41463
|
const cellsToCompute = new JetSet(cells);
|
|
41395
41464
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
41396
|
-
cellsToCompute.
|
|
41397
|
-
cellsToCompute.
|
|
41398
|
-
cellsToCompute.
|
|
41465
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
41466
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
41467
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
41399
41468
|
this.evaluate(cellsToCompute);
|
|
41400
41469
|
}
|
|
41401
41470
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -41409,7 +41478,7 @@
|
|
|
41409
41478
|
}
|
|
41410
41479
|
if (!content) {
|
|
41411
41480
|
// The previous content could have blocked some array formulas
|
|
41412
|
-
impactedPositionIds.
|
|
41481
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
41413
41482
|
}
|
|
41414
41483
|
}
|
|
41415
41484
|
return impactedPositionIds;
|
|
@@ -41461,7 +41530,7 @@
|
|
|
41461
41530
|
}
|
|
41462
41531
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
41463
41532
|
const cells = new JetSet(arrayFormulas);
|
|
41464
|
-
cells.
|
|
41533
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
41465
41534
|
return cells;
|
|
41466
41535
|
}
|
|
41467
41536
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -41512,7 +41581,7 @@
|
|
|
41512
41581
|
: evaluateLiteral(cell.content, localeFormat);
|
|
41513
41582
|
}
|
|
41514
41583
|
catch (e) {
|
|
41515
|
-
return createEvaluatedCell(e.
|
|
41584
|
+
return createEvaluatedCell(e?.value || CellErrorType.GenericError, localeFormat, e?.message || implementationErrorMessage);
|
|
41516
41585
|
}
|
|
41517
41586
|
finally {
|
|
41518
41587
|
this.cellsBeingComputed.delete(cellId);
|
|
@@ -41599,7 +41668,7 @@
|
|
|
41599
41668
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
41600
41669
|
// check if formula dependencies present in the spread zone
|
|
41601
41670
|
// if so, they need to be recomputed
|
|
41602
|
-
this.nextPositionsToUpdate.
|
|
41671
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
41603
41672
|
};
|
|
41604
41673
|
}
|
|
41605
41674
|
invalidateSpreading(positionId) {
|
|
@@ -41614,8 +41683,8 @@
|
|
|
41614
41683
|
continue;
|
|
41615
41684
|
}
|
|
41616
41685
|
this.evaluatedCells.delete(child);
|
|
41617
|
-
this.nextPositionsToUpdate.
|
|
41618
|
-
this.nextPositionsToUpdate.
|
|
41686
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
41687
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
41619
41688
|
}
|
|
41620
41689
|
this.spreadingRelations.removeNode(positionId);
|
|
41621
41690
|
}
|
|
@@ -41846,6 +41915,7 @@
|
|
|
41846
41915
|
"getEvaluatedCellsInZone",
|
|
41847
41916
|
"getSpreadPositionsOf",
|
|
41848
41917
|
"getArrayFormulaSpreadingOn",
|
|
41918
|
+
"isEmpty",
|
|
41849
41919
|
];
|
|
41850
41920
|
shouldRebuildDependenciesGraph = true;
|
|
41851
41921
|
evaluator;
|
|
@@ -41951,6 +42021,14 @@
|
|
|
41951
42021
|
getArrayFormulaSpreadingOn(position) {
|
|
41952
42022
|
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
41953
42023
|
}
|
|
42024
|
+
/**
|
|
42025
|
+
* Check if a zone only contains empty cells
|
|
42026
|
+
*/
|
|
42027
|
+
isEmpty(sheetId, zone) {
|
|
42028
|
+
return positions(zone)
|
|
42029
|
+
.map(({ col, row }) => this.getEvaluatedCell({ sheetId, col, row }))
|
|
42030
|
+
.every((cell) => cell.type === CellValueType.empty);
|
|
42031
|
+
}
|
|
41954
42032
|
// ---------------------------------------------------------------------------
|
|
41955
42033
|
// Export
|
|
41956
42034
|
// ---------------------------------------------------------------------------
|
|
@@ -42598,8 +42676,6 @@
|
|
|
42598
42676
|
class EvaluationDataValidationPlugin extends UIPlugin {
|
|
42599
42677
|
static getters = [
|
|
42600
42678
|
"getDataValidationInvalidCriterionValueMessage",
|
|
42601
|
-
"getDataValidationCheckBoxCellPositions",
|
|
42602
|
-
"getDataValidationListCellsPositions",
|
|
42603
42679
|
"getInvalidDataValidationMessage",
|
|
42604
42680
|
"getValidationResultForCellValue",
|
|
42605
42681
|
"isCellValidCheckbox",
|
|
@@ -42663,19 +42739,6 @@
|
|
|
42663
42739
|
const error = this.getRuleErrorForCellValue(cellValue, cellPosition, rule);
|
|
42664
42740
|
return error ? { error, rule, isValid: false } : VALID_RESULT;
|
|
42665
42741
|
}
|
|
42666
|
-
getDataValidationCheckBoxCellPositions() {
|
|
42667
|
-
const rules = this.getters
|
|
42668
|
-
.getDataValidationRules(this.getters.getActiveSheetId())
|
|
42669
|
-
.filter((rule) => rule.criterion.type === "isBoolean");
|
|
42670
|
-
return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat()).filter((position) => this.isCellValidCheckbox(position));
|
|
42671
|
-
}
|
|
42672
|
-
getDataValidationListCellsPositions() {
|
|
42673
|
-
const rules = this.getters
|
|
42674
|
-
.getDataValidationRules(this.getters.getActiveSheetId())
|
|
42675
|
-
.filter((rule) => (rule.criterion.type === "isValueInList" || rule.criterion.type === "isValueInRange") &&
|
|
42676
|
-
rule.criterion.displayStyle === "arrow");
|
|
42677
|
-
return getCellPositionsInRanges(rules.map((rule) => rule.ranges).flat());
|
|
42678
|
-
}
|
|
42679
42742
|
getValidationResultForCell(cellPosition) {
|
|
42680
42743
|
const { col, row, sheetId } = cellPosition;
|
|
42681
42744
|
if (!this.validationResults[sheetId]) {
|
|
@@ -45484,7 +45547,7 @@
|
|
|
45484
45547
|
}
|
|
45485
45548
|
finalize() {
|
|
45486
45549
|
if (this.isSearchDirty) {
|
|
45487
|
-
this.refreshSearch();
|
|
45550
|
+
this.refreshSearch(false);
|
|
45488
45551
|
this.isSearchDirty = false;
|
|
45489
45552
|
}
|
|
45490
45553
|
}
|
|
@@ -45528,10 +45591,10 @@
|
|
|
45528
45591
|
/**
|
|
45529
45592
|
* refresh the matches according to the current search options
|
|
45530
45593
|
*/
|
|
45531
|
-
refreshSearch() {
|
|
45594
|
+
refreshSearch(jumpToMatchSheet = true) {
|
|
45532
45595
|
this.selectedMatchIndex = null;
|
|
45533
45596
|
this.findMatches();
|
|
45534
|
-
this.selectNextCell(Direction.current);
|
|
45597
|
+
this.selectNextCell(Direction.current, jumpToMatchSheet);
|
|
45535
45598
|
}
|
|
45536
45599
|
/**
|
|
45537
45600
|
* Updates the regex based on the current searchOptions and
|
|
@@ -45613,7 +45676,7 @@
|
|
|
45613
45676
|
* It is also used to keep coherence between the selected searchMatch
|
|
45614
45677
|
* and selectedMatchIndex.
|
|
45615
45678
|
*/
|
|
45616
|
-
selectNextCell(indexChange) {
|
|
45679
|
+
selectNextCell(indexChange, jumpToMatchSheet = true) {
|
|
45617
45680
|
const matches = this.searchMatches;
|
|
45618
45681
|
if (!matches.length) {
|
|
45619
45682
|
this.selectedMatchIndex = null;
|
|
@@ -45639,11 +45702,13 @@
|
|
|
45639
45702
|
this.selectedMatchIndex = nextIndex;
|
|
45640
45703
|
const selectedMatch = matches[nextIndex];
|
|
45641
45704
|
// Switch to the sheet where the match is located
|
|
45642
|
-
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
45705
|
+
if (jumpToMatchSheet && this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
45643
45706
|
this.dispatch("ACTIVATE_SHEET", {
|
|
45644
45707
|
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
45645
45708
|
sheetIdTo: selectedMatch.sheetId,
|
|
45646
45709
|
});
|
|
45710
|
+
// We do not want to reset the selection at finalize in this case
|
|
45711
|
+
this.isSearchDirty = false;
|
|
45647
45712
|
}
|
|
45648
45713
|
// we want grid selection to capture the selection stream
|
|
45649
45714
|
this.selection.getBackToDefault();
|
|
@@ -46945,19 +47010,17 @@
|
|
|
46945
47010
|
break;
|
|
46946
47011
|
case "FOCUS_RANGE":
|
|
46947
47012
|
case "CHANGE_RANGE":
|
|
46948
|
-
|
|
46949
|
-
|
|
46950
|
-
|
|
46951
|
-
|
|
46952
|
-
|
|
46953
|
-
|
|
46954
|
-
|
|
46955
|
-
|
|
46956
|
-
|
|
46957
|
-
});
|
|
46958
|
-
}
|
|
46959
|
-
this.focusedInputId = cmd.id;
|
|
47013
|
+
const input = this.inputs[cmd.id];
|
|
47014
|
+
const range = input.ranges.find((range) => range.id === cmd.rangeId);
|
|
47015
|
+
if (range) {
|
|
47016
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
47017
|
+
const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
|
|
47018
|
+
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, {
|
|
47019
|
+
handleEvent: input.handleEvent.bind(input),
|
|
47020
|
+
release: () => (this.focusedInputId = null),
|
|
47021
|
+
});
|
|
46960
47022
|
}
|
|
47023
|
+
this.focusedInputId = cmd.id;
|
|
46961
47024
|
break;
|
|
46962
47025
|
}
|
|
46963
47026
|
this.currentInput?.handle(cmd);
|
|
@@ -47211,7 +47274,7 @@
|
|
|
47211
47274
|
"getCellText",
|
|
47212
47275
|
"getCellMultiLineText",
|
|
47213
47276
|
"getContiguousZone",
|
|
47214
|
-
"
|
|
47277
|
+
"isEvaluatedCellEmpty",
|
|
47215
47278
|
];
|
|
47216
47279
|
ctx = document.createElement("canvas").getContext("2d");
|
|
47217
47280
|
// ---------------------------------------------------------------------------
|
|
@@ -47339,14 +47402,23 @@
|
|
|
47339
47402
|
return zone;
|
|
47340
47403
|
}
|
|
47341
47404
|
/**
|
|
47342
|
-
*
|
|
47343
|
-
* check
|
|
47405
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
47406
|
+
* the check applies to the main cell of the merge.
|
|
47344
47407
|
*/
|
|
47345
|
-
|
|
47408
|
+
isEvaluatedCellEmpty(position) {
|
|
47346
47409
|
const mainPosition = this.getters.getMainCellPosition(position);
|
|
47347
47410
|
const cell = this.getters.getEvaluatedCell(mainPosition);
|
|
47348
47411
|
return cell.type === CellValueType.empty;
|
|
47349
47412
|
}
|
|
47413
|
+
/**
|
|
47414
|
+
* Checks if a cell is empty (i.e. does not have a content or a formula does not spread over it).
|
|
47415
|
+
* If the cell is part of a merge, the check applies to the main cell of the merge.
|
|
47416
|
+
*/
|
|
47417
|
+
isCellEmpty(position) {
|
|
47418
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
47419
|
+
return !(this.getters.getCorrespondingFormulaCell(mainPosition) ||
|
|
47420
|
+
this.getters.getCell(mainPosition)?.content);
|
|
47421
|
+
}
|
|
47350
47422
|
getColMaxWidth(sheetId, index) {
|
|
47351
47423
|
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
|
|
47352
47424
|
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
|
|
@@ -50367,6 +50439,8 @@
|
|
|
50367
50439
|
"getEdgeScrollRow",
|
|
50368
50440
|
"getVisibleFigures",
|
|
50369
50441
|
"getVisibleRect",
|
|
50442
|
+
"getVisibleRectWithoutHeaders",
|
|
50443
|
+
"getVisibleCellPositions",
|
|
50370
50444
|
"getColRowOffsetInViewport",
|
|
50371
50445
|
"getMainViewportCoordinates",
|
|
50372
50446
|
"getActiveSheetScrollInfo",
|
|
@@ -50610,6 +50684,26 @@
|
|
|
50610
50684
|
const viewports = this.getSubViewports(sheetId);
|
|
50611
50685
|
return [...new Set(viewports.map((v) => range(v.top, v.bottom + 1)).flat())].filter((row) => !this.getters.isHeaderHidden(sheetId, "ROW", row));
|
|
50612
50686
|
}
|
|
50687
|
+
/**
|
|
50688
|
+
* Get the positions of all the cells that are visible in the viewport, taking merges into account.
|
|
50689
|
+
*/
|
|
50690
|
+
getVisibleCellPositions() {
|
|
50691
|
+
const visibleCols = this.getSheetViewVisibleCols();
|
|
50692
|
+
const visibleRows = this.getSheetViewVisibleRows();
|
|
50693
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
50694
|
+
const positions = [];
|
|
50695
|
+
for (const col of visibleCols) {
|
|
50696
|
+
for (const row of visibleRows) {
|
|
50697
|
+
const position = { sheetId, col, row };
|
|
50698
|
+
const mainPosition = this.getters.getMainCellPosition(position);
|
|
50699
|
+
if (mainPosition.row !== row || mainPosition.col !== col) {
|
|
50700
|
+
continue;
|
|
50701
|
+
}
|
|
50702
|
+
positions.push(position);
|
|
50703
|
+
}
|
|
50704
|
+
}
|
|
50705
|
+
return positions;
|
|
50706
|
+
}
|
|
50613
50707
|
/**
|
|
50614
50708
|
* Return the main viewport maximum size relative to the client size.
|
|
50615
50709
|
*/
|
|
@@ -50729,6 +50823,13 @@
|
|
|
50729
50823
|
* Computes the coordinates and size to draw the zone on the canvas
|
|
50730
50824
|
*/
|
|
50731
50825
|
getVisibleRect(zone) {
|
|
50826
|
+
const rect = this.getVisibleRectWithoutHeaders(zone);
|
|
50827
|
+
return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
|
|
50828
|
+
}
|
|
50829
|
+
/**
|
|
50830
|
+
* Computes the coordinates and size to draw the zone without taking the grid offset into account
|
|
50831
|
+
*/
|
|
50832
|
+
getVisibleRectWithoutHeaders(zone) {
|
|
50732
50833
|
const sheetId = this.getters.getActiveSheetId();
|
|
50733
50834
|
const viewportRects = this.getSubViewports(sheetId)
|
|
50734
50835
|
.map((viewport) => viewport.getRect(zone))
|
|
@@ -50740,12 +50841,7 @@
|
|
|
50740
50841
|
const y = Math.min(...viewportRects.map((rect) => rect.y));
|
|
50741
50842
|
const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
|
|
50742
50843
|
const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
|
|
50743
|
-
return {
|
|
50744
|
-
x: x + this.gridOffsetX,
|
|
50745
|
-
y: y + this.gridOffsetY,
|
|
50746
|
-
width,
|
|
50747
|
-
height,
|
|
50748
|
-
};
|
|
50844
|
+
return { x, y, width, height };
|
|
50749
50845
|
}
|
|
50750
50846
|
/**
|
|
50751
50847
|
* Returns the position of the MainViewport relatively to the start of the grid (without headers)
|
|
@@ -50969,13 +51065,8 @@
|
|
|
50969
51065
|
}
|
|
50970
51066
|
break;
|
|
50971
51067
|
case "UPDATE_CELL":
|
|
50972
|
-
|
|
50973
|
-
|
|
50974
|
-
this.isDirty = true;
|
|
50975
|
-
}
|
|
50976
|
-
else {
|
|
50977
|
-
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
50978
|
-
}
|
|
51068
|
+
this.headerPositions = {};
|
|
51069
|
+
this.isDirty = true;
|
|
50979
51070
|
break;
|
|
50980
51071
|
case "UPDATE_FILTER":
|
|
50981
51072
|
case "REMOVE_FILTER_TABLE":
|
|
@@ -54888,8 +54979,8 @@
|
|
|
54888
54979
|
let currentPosition = startPosition;
|
|
54889
54980
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
54890
54981
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
54891
|
-
let mode = !this.getters.
|
|
54892
|
-
!this.getters.
|
|
54982
|
+
let mode = !this.getters.isEvaluatedCellEmpty({ ...currentPosition, sheetId }) &&
|
|
54983
|
+
!this.getters.isEvaluatedCellEmpty({ ...nextCellPosition, sheetId })
|
|
54893
54984
|
? "endOfCluster"
|
|
54894
54985
|
: "nextCluster";
|
|
54895
54986
|
while (true) {
|
|
@@ -54899,7 +54990,7 @@
|
|
|
54899
54990
|
currentPosition.row === nextCellPosition.row) {
|
|
54900
54991
|
break;
|
|
54901
54992
|
}
|
|
54902
|
-
const isNextCellEmpty = this.getters.
|
|
54993
|
+
const isNextCellEmpty = this.getters.isEvaluatedCellEmpty({ ...nextCellPosition, sheetId });
|
|
54903
54994
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
54904
54995
|
break;
|
|
54905
54996
|
}
|
|
@@ -57184,9 +57275,9 @@
|
|
|
57184
57275
|
exports.tokenize = tokenize;
|
|
57185
57276
|
|
|
57186
57277
|
|
|
57187
|
-
__info__.version = "17.1.
|
|
57188
|
-
__info__.date = "2024-
|
|
57189
|
-
__info__.hash = "
|
|
57278
|
+
__info__.version = "17.1.7";
|
|
57279
|
+
__info__.date = "2024-03-12T07:56:10.783Z";
|
|
57280
|
+
__info__.hash = "3a9f334";
|
|
57190
57281
|
|
|
57191
57282
|
|
|
57192
57283
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|