@odoo/o-spreadsheet 18.2.27 → 18.2.29
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 +107 -58
- package/dist/o-spreadsheet.d.ts +14 -13
- package/dist/o-spreadsheet.esm.js +107 -58
- package/dist/o-spreadsheet.iife.js +107 -58
- package/dist/o-spreadsheet.iife.min.js +388 -388
- package/dist/o_spreadsheet.xml +4 -7
- 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 18.2.
|
|
6
|
-
* @date 2025-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.2.29
|
|
6
|
+
* @date 2025-09-11T08:44:31.801Z
|
|
7
|
+
* @hash 665bc43
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -3477,6 +3477,7 @@
|
|
|
3477
3477
|
"AUTOFILL_CELL",
|
|
3478
3478
|
"SET_BORDER",
|
|
3479
3479
|
"SET_ZONE_BORDERS",
|
|
3480
|
+
"SET_BORDERS_ON_TARGET",
|
|
3480
3481
|
]);
|
|
3481
3482
|
const readonlyAllowedCommands = new Set([
|
|
3482
3483
|
"START",
|
|
@@ -6903,7 +6904,7 @@
|
|
|
6903
6904
|
this.getters = getters;
|
|
6904
6905
|
this.dispatch = dispatch;
|
|
6905
6906
|
}
|
|
6906
|
-
copy(data) {
|
|
6907
|
+
copy(data, mode = "copyPaste") {
|
|
6907
6908
|
return;
|
|
6908
6909
|
}
|
|
6909
6910
|
paste(target, clippedContent, options) { }
|
|
@@ -6922,7 +6923,7 @@
|
|
|
6922
6923
|
}
|
|
6923
6924
|
|
|
6924
6925
|
class AbstractCellClipboardHandler extends ClipboardHandler {
|
|
6925
|
-
copy(data) {
|
|
6926
|
+
copy(data, mode = "copyPaste") {
|
|
6926
6927
|
return;
|
|
6927
6928
|
}
|
|
6928
6929
|
pasteFromCopy(sheetId, target, content, options) {
|
|
@@ -7527,8 +7528,11 @@
|
|
|
7527
7528
|
// (a) Swap 2 rows. This multiply the determinant by -1.
|
|
7528
7529
|
// (b) Multiply a row by a scalar. This multiply the determinant by that scalar.
|
|
7529
7530
|
// (c) Add to a row a multiple of another row. This does not change the determinant.
|
|
7531
|
+
if (M.length < 1 || M[0].length < 1) {
|
|
7532
|
+
throw new Error("invertMatrix: an empty matrix cannot be inverted.");
|
|
7533
|
+
}
|
|
7530
7534
|
if (M.length !== M[0].length) {
|
|
7531
|
-
throw new
|
|
7535
|
+
throw new Error("invertMatrix: only square matrices are invertible");
|
|
7532
7536
|
}
|
|
7533
7537
|
let determinant = 1;
|
|
7534
7538
|
const dim = M.length;
|
|
@@ -7597,8 +7601,11 @@
|
|
|
7597
7601
|
* Note: we use indexing [col][row] instead of the standard mathematical notation [row][col]
|
|
7598
7602
|
*/
|
|
7599
7603
|
function multiplyMatrices(matrix1, matrix2) {
|
|
7604
|
+
if (matrix1.length < 1 || matrix2.length < 1) {
|
|
7605
|
+
throw new Error("multiplyMatrices: empty matrices cannot be multiplied.");
|
|
7606
|
+
}
|
|
7600
7607
|
if (matrix1.length !== matrix2[0].length) {
|
|
7601
|
-
throw new
|
|
7608
|
+
throw new Error("multiplyMatrices: incompatible matrices size.");
|
|
7602
7609
|
}
|
|
7603
7610
|
const rowsM1 = matrix1[0].length;
|
|
7604
7611
|
const colsM2 = matrix2.length;
|
|
@@ -7624,7 +7631,7 @@
|
|
|
7624
7631
|
return arg;
|
|
7625
7632
|
}
|
|
7626
7633
|
if (!isSingleElementMatrix(arg)) {
|
|
7627
|
-
throw new
|
|
7634
|
+
throw new Error("The value should be a scalar or a 1x1 matrix");
|
|
7628
7635
|
}
|
|
7629
7636
|
return arg[0][0];
|
|
7630
7637
|
}
|
|
@@ -7861,6 +7868,16 @@
|
|
|
7861
7868
|
}
|
|
7862
7869
|
return values;
|
|
7863
7870
|
}
|
|
7871
|
+
function assertNonEmptyMatrix(matrix, argName) {
|
|
7872
|
+
assert(() => matrix.length > 0 && matrix[0].length > 0, _t("[[FUNCTION_NAME]] expects the provided values of %(argName)s to be a non-empty matrix.", {
|
|
7873
|
+
argName,
|
|
7874
|
+
}));
|
|
7875
|
+
}
|
|
7876
|
+
function assertNonEmpty(...data) {
|
|
7877
|
+
if (data.length === 0 || data.some((arg) => arg.length === 0)) {
|
|
7878
|
+
throw new NotAvailableError(_t("[[FUNCTION_NAME]] has no valid input data."));
|
|
7879
|
+
}
|
|
7880
|
+
}
|
|
7864
7881
|
|
|
7865
7882
|
const PREVIOUS_VALUE = "(previous)";
|
|
7866
7883
|
const NEXT_VALUE = "(next)";
|
|
@@ -8623,7 +8640,7 @@
|
|
|
8623
8640
|
}
|
|
8624
8641
|
return "Success" /* CommandResult.Success */;
|
|
8625
8642
|
}
|
|
8626
|
-
copy(data) {
|
|
8643
|
+
copy(data, mode = "copyPaste") {
|
|
8627
8644
|
const sheetId = data.sheetId;
|
|
8628
8645
|
const { clippedZones, rowsIndexes, columnsIndexes } = data;
|
|
8629
8646
|
const clippedCells = [];
|
|
@@ -8636,7 +8653,7 @@
|
|
|
8636
8653
|
const evaluatedCell = this.getters.getEvaluatedCell(position);
|
|
8637
8654
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
8638
8655
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
8639
|
-
if (pivotId && spreader) {
|
|
8656
|
+
if (mode !== "shiftCells" && pivotId && spreader) {
|
|
8640
8657
|
const pivotZone = this.getters.getSpreadZone(spreader);
|
|
8641
8658
|
if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
|
|
8642
8659
|
pivotZone &&
|
|
@@ -8654,7 +8671,7 @@
|
|
|
8654
8671
|
};
|
|
8655
8672
|
}
|
|
8656
8673
|
}
|
|
8657
|
-
else {
|
|
8674
|
+
else if (mode !== "shiftCells") {
|
|
8658
8675
|
if (spreader && !deepEquals(spreader, position)) {
|
|
8659
8676
|
const isSpreaderCopied = rowsIndexes.includes(spreader.row) && columnsIndexes.includes(spreader.col);
|
|
8660
8677
|
const content = isSpreaderCopied
|
|
@@ -9347,7 +9364,7 @@
|
|
|
9347
9364
|
}
|
|
9348
9365
|
|
|
9349
9366
|
class TableClipboardHandler extends AbstractCellClipboardHandler {
|
|
9350
|
-
copy(data) {
|
|
9367
|
+
copy(data, mode = "copyPaste") {
|
|
9351
9368
|
const sheetId = data.sheetId;
|
|
9352
9369
|
const { rowsIndexes, columnsIndexes, zones } = data;
|
|
9353
9370
|
const copiedTablesIds = new Set();
|
|
@@ -9377,11 +9394,13 @@
|
|
|
9377
9394
|
type: coreTable.type,
|
|
9378
9395
|
};
|
|
9379
9396
|
}
|
|
9380
|
-
|
|
9381
|
-
|
|
9382
|
-
|
|
9383
|
-
|
|
9384
|
-
|
|
9397
|
+
if (mode !== "shiftCells") {
|
|
9398
|
+
tableCellsInRow.push({
|
|
9399
|
+
table: copiedTable,
|
|
9400
|
+
style: this.getTableStyleToCopy(position),
|
|
9401
|
+
isWholeTableCopied: copiedTablesIds.has(table.id),
|
|
9402
|
+
});
|
|
9403
|
+
}
|
|
9385
9404
|
}
|
|
9386
9405
|
}
|
|
9387
9406
|
return {
|
|
@@ -11798,6 +11817,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
11798
11817
|
compute: function (matrix1, matrix2) {
|
|
11799
11818
|
const _matrix1 = toNumberMatrix(matrix1, "matrix1");
|
|
11800
11819
|
const _matrix2 = toNumberMatrix(matrix2, "matrix2");
|
|
11820
|
+
assert(() => _matrix1.length > 0 && _matrix2.length > 0, _t("The first and second arguments of [[FUNCTION_NAME]] must be non-empty matrices."));
|
|
11801
11821
|
assert(() => _matrix1.length === _matrix2[0].length, _t("In [[FUNCTION_NAME]], the number of columns of the first matrix (%s) must be equal to the \
|
|
11802
11822
|
number of rows of the second matrix (%s).", _matrix1.length.toString(), _matrix2[0].length.toString()));
|
|
11803
11823
|
return multiplyMatrices(_matrix1, _matrix2);
|
|
@@ -13593,6 +13613,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13593
13613
|
],
|
|
13594
13614
|
compute: function (x, dataY, dataX) {
|
|
13595
13615
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13616
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13596
13617
|
return predictLinearValues([flatDataY], [flatDataX], matrixMap(toMatrix(x), (value) => toNumber(value, this.locale)), true);
|
|
13597
13618
|
},
|
|
13598
13619
|
isExported: true,
|
|
@@ -13609,6 +13630,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13609
13630
|
arg("b (boolean, default=TRUE)", _t("Given a general exponential form of y = b*m^x for a curve fit, calculates b if TRUE or forces b to be 1 and only calculates the m values if FALSE.")),
|
|
13610
13631
|
],
|
|
13611
13632
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
13633
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
13612
13634
|
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "the first argument (known_data_y)")), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b)));
|
|
13613
13635
|
},
|
|
13614
13636
|
};
|
|
@@ -13623,6 +13645,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13623
13645
|
],
|
|
13624
13646
|
compute: function (dataY, dataX) {
|
|
13625
13647
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13648
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13626
13649
|
const [[], [intercept]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
13627
13650
|
return intercept;
|
|
13628
13651
|
},
|
|
@@ -13672,6 +13695,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13672
13695
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13673
13696
|
],
|
|
13674
13697
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13698
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
13675
13699
|
return fullLinearRegression(toNumberMatrix(dataX, "the first argument (data_y)"), toNumberMatrix(dataY, "the second argument (data_x)"), toBoolean(calculateB), toBoolean(verbose));
|
|
13676
13700
|
},
|
|
13677
13701
|
isExported: true,
|
|
@@ -13688,6 +13712,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13688
13712
|
arg("verbose (boolean, default=FALSE)", _t("A flag specifying whether to return additional regression statistics or only the linear coefficients and the y-intercept")),
|
|
13689
13713
|
],
|
|
13690
13714
|
compute: function (dataY, dataX = [[]], calculateB = { value: true }, verbose = { value: false }) {
|
|
13715
|
+
assertNonEmptyMatrix(dataY, "data_y");
|
|
13691
13716
|
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "the second argument (data_x)"), logM(toNumberMatrix(dataY, "the first argument (data_y)")), toBoolean(calculateB), toBoolean(verbose));
|
|
13692
13717
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13693
13718
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
@@ -13709,9 +13734,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13709
13734
|
const flatX = dataX.flat();
|
|
13710
13735
|
const flatY = dataY.flat();
|
|
13711
13736
|
assertSameNumberOfElements(flatX, flatY);
|
|
13712
|
-
|
|
13713
|
-
return new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
13714
|
-
}
|
|
13737
|
+
assertNonEmpty(flatX, flatY);
|
|
13715
13738
|
const n = flatX.length;
|
|
13716
13739
|
let trueN = 0, trueP = 0, falseP = 0, falseN = 0;
|
|
13717
13740
|
for (let i = 0; i < n; ++i) {
|
|
@@ -13875,12 +13898,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13875
13898
|
// -----------------------------------------------------------------------------
|
|
13876
13899
|
function pearson(dataY, dataX) {
|
|
13877
13900
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13878
|
-
|
|
13879
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] expects non-empty ranges for both parameters."));
|
|
13880
|
-
}
|
|
13881
|
-
if (flatDataX.length < 2) {
|
|
13882
|
-
throw new EvaluationError(_t("[[FUNCTION_NAME]] needs at least two values for both parameters."));
|
|
13883
|
-
}
|
|
13901
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13884
13902
|
const n = flatDataX.length;
|
|
13885
13903
|
let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0, sumYY = 0;
|
|
13886
13904
|
for (let i = 0; i < n; i++) {
|
|
@@ -13969,6 +13987,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13969
13987
|
],
|
|
13970
13988
|
compute: function (dataY, dataX, order, intercept = { value: true }) {
|
|
13971
13989
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
13990
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13972
13991
|
return polynomialRegression(flatDataY, flatDataX, toNumber(order, this.locale), toBoolean(intercept));
|
|
13973
13992
|
},
|
|
13974
13993
|
isExported: false,
|
|
@@ -13988,6 +14007,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13988
14007
|
compute: function (x, dataY, dataX, order, intercept = { value: true }) {
|
|
13989
14008
|
const _order = toNumber(order, this.locale);
|
|
13990
14009
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14010
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
13991
14011
|
const coeffs = polynomialRegression(flatDataY, flatDataX, _order, toBoolean(intercept)).flat();
|
|
13992
14012
|
return matrixMap(toMatrix(x), (xij) => evaluatePolynomial(coeffs, toNumber(xij, this.locale), _order));
|
|
13993
14013
|
},
|
|
@@ -14104,6 +14124,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14104
14124
|
],
|
|
14105
14125
|
compute: function (dataY, dataX) {
|
|
14106
14126
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14127
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14107
14128
|
const [[slope]] = fullLinearRegression([flatDataX], [flatDataY]);
|
|
14108
14129
|
return slope;
|
|
14109
14130
|
},
|
|
@@ -14152,6 +14173,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14152
14173
|
],
|
|
14153
14174
|
compute: function (dataX, dataY) {
|
|
14154
14175
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14176
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14155
14177
|
const n = flatDataX.length;
|
|
14156
14178
|
const order = flatDataX.map((e, i) => [e, flatDataY[i]]);
|
|
14157
14179
|
order.sort((a, b) => a[0] - b[0]);
|
|
@@ -14262,6 +14284,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14262
14284
|
],
|
|
14263
14285
|
compute: function (dataY, dataX) {
|
|
14264
14286
|
const { flatDataX, flatDataY } = filterAndFlatData(dataY, dataX);
|
|
14287
|
+
assertNonEmpty(flatDataX, flatDataY);
|
|
14265
14288
|
const data = fullLinearRegression([flatDataX], [flatDataY], true, true);
|
|
14266
14289
|
return data[1][2];
|
|
14267
14290
|
},
|
|
@@ -14279,6 +14302,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14279
14302
|
arg("b (boolean, optional, default=TRUE)", _t("Given a general linear form of y = m*x+b for a curve fit, calculates b if TRUE or forces b to be 0 and only calculates the m values if FALSE, i.e. forces the curve fit to pass through the origin.")),
|
|
14280
14303
|
],
|
|
14281
14304
|
compute: function (knownDataY, knownDataX = [[]], newDataX = [[]], b = { value: true }) {
|
|
14305
|
+
assertNonEmptyMatrix(knownDataY, "known_data_y");
|
|
14282
14306
|
return predictLinearValues(toNumberMatrix(knownDataY, "the first argument (known_data_y)"), toNumberMatrix(knownDataX, "the second argument (known_data_x)"), toNumberMatrix(newDataX, "the third argument (new_data_y)"), toBoolean(b));
|
|
14283
14307
|
},
|
|
14284
14308
|
};
|
|
@@ -23772,7 +23796,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23772
23796
|
];
|
|
23773
23797
|
const SUPPORTED_VERTICAL_ALIGNMENTS = ["top", "center", "bottom"];
|
|
23774
23798
|
const SUPPORTED_FONTS = ["Arial"];
|
|
23775
|
-
const SUPPORTED_FILL_PATTERNS = ["solid"];
|
|
23799
|
+
const SUPPORTED_FILL_PATTERNS = ["solid", "none"];
|
|
23776
23800
|
const SUPPORTED_CF_TYPES = [
|
|
23777
23801
|
"expression",
|
|
23778
23802
|
"cellIs",
|
|
@@ -23957,7 +23981,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23957
23981
|
};
|
|
23958
23982
|
/** Mapping between Excel format indexes (see XLSX_FORMAT_MAP) and some supported formats */
|
|
23959
23983
|
const XLSX_FORMATS_CONVERSION_MAP = {
|
|
23960
|
-
0: "",
|
|
23984
|
+
0: "General",
|
|
23961
23985
|
1: "0",
|
|
23962
23986
|
2: "0.00",
|
|
23963
23987
|
3: "#,#00",
|
|
@@ -24283,11 +24307,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24283
24307
|
* Excel format are defined in openXML §18.8.31
|
|
24284
24308
|
*/
|
|
24285
24309
|
function convertXlsxFormat(numFmtId, formats, warningManager) {
|
|
24286
|
-
if (numFmtId === 0) {
|
|
24287
|
-
return undefined;
|
|
24288
|
-
}
|
|
24289
24310
|
// Format is either defined in the imported data, or the formatId is defined in openXML §18.8.30
|
|
24290
24311
|
let format = XLSX_FORMATS_CONVERSION_MAP[numFmtId] || formats.find((f) => f.id === numFmtId)?.format;
|
|
24312
|
+
if (format === "General") {
|
|
24313
|
+
return undefined;
|
|
24314
|
+
}
|
|
24291
24315
|
if (format) {
|
|
24292
24316
|
try {
|
|
24293
24317
|
let convertedFormat = format.replace(/\[(.*)-[A-Z0-9]{3}\]/g, "[$1]"); // remove currency and locale/date system/number system info (ECMA §18.8.31)
|
|
@@ -24485,9 +24509,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24485
24509
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
24486
24510
|
continue;
|
|
24487
24511
|
operator = convertCFCellIsOperator(rule.operator);
|
|
24488
|
-
values.push(rule.formula[0]);
|
|
24512
|
+
values.push(prefixFormula(rule.formula[0]));
|
|
24489
24513
|
if (rule.formula.length === 2) {
|
|
24490
|
-
values.push(rule.formula[1]);
|
|
24514
|
+
values.push(prefixFormula(rule.formula[1]));
|
|
24491
24515
|
}
|
|
24492
24516
|
break;
|
|
24493
24517
|
}
|
|
@@ -24645,6 +24669,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24645
24669
|
? ICON_SETS[iconSet].neutral
|
|
24646
24670
|
: ICON_SETS[iconSet].good;
|
|
24647
24671
|
}
|
|
24672
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
24673
|
+
function prefixFormula(formula) {
|
|
24674
|
+
const tokens = tokenize(formula);
|
|
24675
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
24676
|
+
}
|
|
24648
24677
|
// ---------------------------------------------------------------------------
|
|
24649
24678
|
// Warnings
|
|
24650
24679
|
// ---------------------------------------------------------------------------
|
|
@@ -27243,10 +27272,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27243
27272
|
});
|
|
27244
27273
|
}
|
|
27245
27274
|
extractRows(worksheet) {
|
|
27275
|
+
const spilledCells = new Set();
|
|
27246
27276
|
return this.mapOnElements({ parent: worksheet, query: "sheetData row" }, (rowElement) => {
|
|
27247
27277
|
return {
|
|
27248
27278
|
index: this.extractAttr(rowElement, "r", { required: true })?.asNum(),
|
|
27249
|
-
cells: this.extractCells(rowElement),
|
|
27279
|
+
cells: this.extractCells(rowElement, spilledCells),
|
|
27250
27280
|
height: this.extractAttr(rowElement, "ht")?.asNum(),
|
|
27251
27281
|
customHeight: this.extractAttr(rowElement, "customHeight")?.asBool(),
|
|
27252
27282
|
hidden: this.extractAttr(rowElement, "hidden")?.asBool(),
|
|
@@ -27256,14 +27286,26 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27256
27286
|
};
|
|
27257
27287
|
});
|
|
27258
27288
|
}
|
|
27259
|
-
extractCells(row) {
|
|
27289
|
+
extractCells(row, spilledCells) {
|
|
27260
27290
|
return this.mapOnElements({ parent: row, query: "c" }, (cellElement) => {
|
|
27291
|
+
const xc = this.extractAttr(cellElement, "r", { required: true })?.asString();
|
|
27292
|
+
const formula = this.extractCellFormula(cellElement);
|
|
27293
|
+
if (formula?.ref && formula.sharedIndex === undefined) {
|
|
27294
|
+
const zone = toZone(formula.ref);
|
|
27295
|
+
for (const { col, row } of positions(zone)) {
|
|
27296
|
+
const followerXc = toXC(col, row);
|
|
27297
|
+
if (followerXc !== xc) {
|
|
27298
|
+
spilledCells.add(followerXc);
|
|
27299
|
+
}
|
|
27300
|
+
}
|
|
27301
|
+
}
|
|
27302
|
+
const isSpilled = spilledCells.has(xc);
|
|
27261
27303
|
return {
|
|
27262
|
-
xc
|
|
27304
|
+
xc,
|
|
27263
27305
|
styleIndex: this.extractAttr(cellElement, "s")?.asNum(),
|
|
27264
27306
|
type: CELL_TYPE_CONVERSION_MAP[this.extractAttr(cellElement, "t", { default: "n" })?.asString()],
|
|
27265
|
-
value: this.extractChildTextContent(cellElement, "v"),
|
|
27266
|
-
formula:
|
|
27307
|
+
value: isSpilled ? undefined : this.extractChildTextContent(cellElement, "v") ?? undefined,
|
|
27308
|
+
formula: isSpilled ? undefined : formula,
|
|
27267
27309
|
};
|
|
27268
27310
|
});
|
|
27269
27311
|
}
|
|
@@ -27271,11 +27313,14 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
27271
27313
|
const formulaElement = this.querySelector(cellElement, "f");
|
|
27272
27314
|
if (!formulaElement)
|
|
27273
27315
|
return undefined;
|
|
27274
|
-
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27316
|
+
const content = this.extractTextContent(formulaElement);
|
|
27317
|
+
const sharedIndex = this.extractAttr(formulaElement, "si")?.asNum();
|
|
27318
|
+
const ref = this.extractAttr(formulaElement, "ref")?.asString();
|
|
27319
|
+
// This is the case of spilled cells of array formulas where <f> is empty
|
|
27320
|
+
if ((content === undefined || content.trim() === "") && sharedIndex === undefined) {
|
|
27321
|
+
return undefined;
|
|
27322
|
+
}
|
|
27323
|
+
return { content, sharedIndex, ref };
|
|
27279
27324
|
}
|
|
27280
27325
|
extractHyperLinks(worksheet) {
|
|
27281
27326
|
return this.mapOnElements({ parent: worksheet, query: "hyperlink" }, (linkElement) => {
|
|
@@ -36169,7 +36214,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36169
36214
|
const reinsertDynamicPivotMenu = {
|
|
36170
36215
|
id: "reinsert_dynamic_pivot",
|
|
36171
36216
|
name: _t("Re-insert dynamic pivot"),
|
|
36172
|
-
sequence:
|
|
36217
|
+
sequence: 60,
|
|
36173
36218
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
36174
36219
|
children: [REINSERT_DYNAMIC_PIVOT_CHILDREN],
|
|
36175
36220
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -36177,7 +36222,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
36177
36222
|
const reinsertStaticPivotMenu = {
|
|
36178
36223
|
id: "reinsert_static_pivot",
|
|
36179
36224
|
name: _t("Re-insert static pivot"),
|
|
36180
|
-
sequence:
|
|
36225
|
+
sequence: 70,
|
|
36181
36226
|
icon: "o-spreadsheet-Icon.INSERT_PIVOT",
|
|
36182
36227
|
children: [REINSERT_STATIC_PIVOT_CHILDREN],
|
|
36183
36228
|
isVisible: (env) => env.model.getters.getPivotIds().some((id) => env.model.getters.getPivot(id).isValid()),
|
|
@@ -37915,8 +37960,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37915
37960
|
sequence: 40,
|
|
37916
37961
|
separator: true,
|
|
37917
37962
|
})
|
|
37918
|
-
.addChild("
|
|
37963
|
+
.addChild("pivot_data_sources", ["data"], (env) => {
|
|
37919
37964
|
const sequence = 50;
|
|
37965
|
+
const numberOfPivots = env.model.getters.getPivotIds().length;
|
|
37920
37966
|
return env.model.getters.getPivotIds().map((pivotId, index) => {
|
|
37921
37967
|
const highlightProvider = {
|
|
37922
37968
|
get highlights() {
|
|
@@ -37926,7 +37972,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
37926
37972
|
return {
|
|
37927
37973
|
id: `item_pivot_${env.model.getters.getPivotFormulaId(pivotId)}`,
|
|
37928
37974
|
name: env.model.getters.getPivotDisplayName(pivotId),
|
|
37929
|
-
sequence: sequence + index,
|
|
37975
|
+
sequence: sequence + index / numberOfPivots,
|
|
37930
37976
|
isReadonlyAllowed: true,
|
|
37931
37977
|
execute: (env) => env.openSidePanel("PivotSidePanel", { pivotId }),
|
|
37932
37978
|
onStartHover: (env) => env.getStore(HighlightStore).register(highlightProvider),
|
|
@@ -63898,7 +63944,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63898
63944
|
if (!result) {
|
|
63899
63945
|
return EMPTY_PIVOT_CELL;
|
|
63900
63946
|
}
|
|
63901
|
-
|
|
63947
|
+
let { functionName, args } = result;
|
|
63902
63948
|
const formulaId = args[0];
|
|
63903
63949
|
if (!formulaId) {
|
|
63904
63950
|
return EMPTY_PIVOT_CELL;
|
|
@@ -63928,6 +63974,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
63928
63974
|
return pivotCells[pivotCol][pivotRow];
|
|
63929
63975
|
}
|
|
63930
63976
|
try {
|
|
63977
|
+
const offsetRow = position.row - mainPosition.row;
|
|
63978
|
+
const offsetCol = position.col - mainPosition.col;
|
|
63979
|
+
args = args.map((arg) => (isMatrix(arg) ? arg[offsetCol][offsetRow] : arg));
|
|
63931
63980
|
if (functionName === "PIVOT.HEADER" && args.at(-2) === "measure") {
|
|
63932
63981
|
const domain = pivot.parseArgsToPivotDomain(args.slice(1, -2).map((value) => ({ value })));
|
|
63933
63982
|
return {
|
|
@@ -67776,12 +67825,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67776
67825
|
}
|
|
67777
67826
|
case "INSERT_CELL": {
|
|
67778
67827
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67779
|
-
const copiedData = this.copy(cut);
|
|
67828
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67780
67829
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
67781
67830
|
}
|
|
67782
67831
|
case "DELETE_CELL": {
|
|
67783
67832
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67784
|
-
const copiedData = this.copy(cut);
|
|
67833
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67785
67834
|
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
67786
67835
|
}
|
|
67787
67836
|
}
|
|
@@ -67871,13 +67920,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67871
67920
|
});
|
|
67872
67921
|
break;
|
|
67873
67922
|
}
|
|
67874
|
-
const copiedData = this.copy(cut);
|
|
67923
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67875
67924
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
67876
67925
|
break;
|
|
67877
67926
|
}
|
|
67878
67927
|
case "INSERT_CELL": {
|
|
67879
67928
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
67880
|
-
const copiedData = this.copy(cut);
|
|
67929
|
+
const copiedData = this.copy(cut, "shiftCells");
|
|
67881
67930
|
this.paste(paste, copiedData, { isCutOperation: true });
|
|
67882
67931
|
break;
|
|
67883
67932
|
}
|
|
@@ -67992,11 +68041,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
67992
68041
|
}
|
|
67993
68042
|
return false;
|
|
67994
68043
|
}
|
|
67995
|
-
copy(zones) {
|
|
68044
|
+
copy(zones, mode = "copyPaste") {
|
|
67996
68045
|
let copiedData = {};
|
|
67997
68046
|
const clipboardData = this.getClipboardData(zones);
|
|
67998
68047
|
for (const { handlerName, handler } of this.selectClipboardHandlers(clipboardData)) {
|
|
67999
|
-
const data = handler.copy(clipboardData);
|
|
68048
|
+
const data = handler.copy(clipboardData, mode);
|
|
68000
68049
|
copiedData[handlerName] = data;
|
|
68001
68050
|
const minimalKeys = ["sheetId", "cells", "zones", "figureId"];
|
|
68002
68051
|
for (const key of minimalKeys) {
|
|
@@ -68860,7 +68909,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68860
68909
|
];
|
|
68861
68910
|
for (const Handler of clipboardHandlersRegistries.cellHandlers.getAll()) {
|
|
68862
68911
|
const handler = new Handler(this.getters, this.dispatch);
|
|
68863
|
-
const data = handler.copy(getClipboardDataPositions(sheetId, target));
|
|
68912
|
+
const data = handler.copy(getClipboardDataPositions(sheetId, target), "shiftCells");
|
|
68864
68913
|
if (!data) {
|
|
68865
68914
|
continue;
|
|
68866
68915
|
}
|
|
@@ -77284,9 +77333,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
77284
77333
|
exports.tokenize = tokenize;
|
|
77285
77334
|
|
|
77286
77335
|
|
|
77287
|
-
__info__.version = "18.2.
|
|
77288
|
-
__info__.date = "2025-
|
|
77289
|
-
__info__.hash = "
|
|
77336
|
+
__info__.version = "18.2.29";
|
|
77337
|
+
__info__.date = "2025-09-11T08:44:31.801Z";
|
|
77338
|
+
__info__.hash = "665bc43";
|
|
77290
77339
|
|
|
77291
77340
|
|
|
77292
77341
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|