@odoo/o-spreadsheet 17.2.14 → 17.2.16
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 +233 -191
- package/dist/o-spreadsheet.d.ts +6 -3
- package/dist/o-spreadsheet.esm.js +233 -191
- package/dist/o-spreadsheet.iife.js +233 -191
- package/dist/o-spreadsheet.iife.min.js +6 -6
- package/dist/o_spreadsheet.xml +4 -4
- package/package.json +1 -1
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.
|
|
7
|
-
* @date 2024-07-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.16
|
|
7
|
+
* @date 2024-07-11T06:38:53.101Z
|
|
8
|
+
* @hash 9f20685
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -575,7 +575,7 @@ function getAddHeaderStartIndex(position, base) {
|
|
|
575
575
|
/**
|
|
576
576
|
* Compares two objects.
|
|
577
577
|
*/
|
|
578
|
-
function deepEquals(o1, o2
|
|
578
|
+
function deepEquals(o1, o2) {
|
|
579
579
|
if (o1 === o2)
|
|
580
580
|
return true;
|
|
581
581
|
if ((o1 && !o2) || (o2 && !o1))
|
|
@@ -591,17 +591,13 @@ function deepEquals(o1, o2, ignoreFunctions) {
|
|
|
591
591
|
}
|
|
592
592
|
}
|
|
593
593
|
for (const key in o1) {
|
|
594
|
-
|
|
595
|
-
if (typeOfO1Key !== typeof o2[key])
|
|
594
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
596
595
|
return false;
|
|
597
|
-
if (
|
|
598
|
-
if (!deepEquals(o1[key], o2[key]
|
|
596
|
+
if (typeof o1[key] === "object") {
|
|
597
|
+
if (!deepEquals(o1[key], o2[key]))
|
|
599
598
|
return false;
|
|
600
599
|
}
|
|
601
600
|
else {
|
|
602
|
-
if (ignoreFunctions && typeOfO1Key === "function") {
|
|
603
|
-
continue;
|
|
604
|
-
}
|
|
605
601
|
if (o1[key] !== o2[key])
|
|
606
602
|
return false;
|
|
607
603
|
}
|
|
@@ -1750,7 +1746,7 @@ const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSepa
|
|
|
1750
1746
|
});
|
|
1751
1747
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
1752
1748
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
1753
|
-
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
|
|
1749
|
+
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
|
|
1754
1750
|
const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
|
|
1755
1751
|
const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
|
|
1756
1752
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -1777,7 +1773,7 @@ function isNumber(value, locale) {
|
|
|
1777
1773
|
return getNumberRegex(locale).test(value.trim());
|
|
1778
1774
|
}
|
|
1779
1775
|
const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
|
|
1780
|
-
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
|
|
1776
|
+
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
|
|
1781
1777
|
});
|
|
1782
1778
|
/**
|
|
1783
1779
|
* Convert a string into a number. It assumes that the string actually represents
|
|
@@ -2646,6 +2642,9 @@ function getPredicate(descr, locale) {
|
|
|
2646
2642
|
* If the character is a special regular expression character, it is escaped with "\\".
|
|
2647
2643
|
*/
|
|
2648
2644
|
const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
|
|
2645
|
+
if (operand === "*") {
|
|
2646
|
+
return /.+/;
|
|
2647
|
+
}
|
|
2649
2648
|
let exp = "";
|
|
2650
2649
|
let predecessor = "";
|
|
2651
2650
|
for (let char of operand) {
|
|
@@ -2669,9 +2668,9 @@ const wildcardToRegExp = memoize(function wildcardToRegExp(operand) {
|
|
|
2669
2668
|
}
|
|
2670
2669
|
return new RegExp("^" + exp + "$", "i");
|
|
2671
2670
|
});
|
|
2672
|
-
function evaluatePredicate(value, criterion) {
|
|
2671
|
+
function evaluatePredicate(value = "", criterion) {
|
|
2673
2672
|
const { operator, operand } = criterion;
|
|
2674
|
-
if (
|
|
2673
|
+
if (operand === undefined || value === null || operand === null) {
|
|
2675
2674
|
return false;
|
|
2676
2675
|
}
|
|
2677
2676
|
if (typeof operand === "number" && operator === "=") {
|
|
@@ -5357,19 +5356,22 @@ class TokenizingChars {
|
|
|
5357
5356
|
}
|
|
5358
5357
|
|
|
5359
5358
|
function isValidLocale(locale) {
|
|
5360
|
-
if (!
|
|
5361
|
-
typeof locale
|
|
5362
|
-
typeof locale.
|
|
5363
|
-
typeof locale.code === "string" &&
|
|
5364
|
-
typeof locale.thousandsSeparator === "string" &&
|
|
5365
|
-
typeof locale.decimalSeparator === "string" &&
|
|
5366
|
-
typeof locale.dateFormat === "string" &&
|
|
5367
|
-
typeof locale.timeFormat === "string" &&
|
|
5368
|
-
typeof locale.formulaArgSeparator === "string")) {
|
|
5359
|
+
if (!locale ||
|
|
5360
|
+
typeof locale !== "object" ||
|
|
5361
|
+
!(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
|
|
5369
5362
|
return false;
|
|
5370
5363
|
}
|
|
5371
|
-
|
|
5372
|
-
|
|
5364
|
+
for (const property of [
|
|
5365
|
+
"code",
|
|
5366
|
+
"name",
|
|
5367
|
+
"decimalSeparator",
|
|
5368
|
+
"dateFormat",
|
|
5369
|
+
"timeFormat",
|
|
5370
|
+
"formulaArgSeparator",
|
|
5371
|
+
]) {
|
|
5372
|
+
if (!locale[property] || typeof locale[property] !== "string") {
|
|
5373
|
+
return false;
|
|
5374
|
+
}
|
|
5373
5375
|
}
|
|
5374
5376
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
5375
5377
|
return false;
|
|
@@ -5467,7 +5469,10 @@ function canonicalizeNumberLiteral(content, locale) {
|
|
|
5467
5469
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
5468
5470
|
return content;
|
|
5469
5471
|
}
|
|
5470
|
-
|
|
5472
|
+
if (locale.thousandsSeparator) {
|
|
5473
|
+
content = content.replaceAll(locale.thousandsSeparator, "");
|
|
5474
|
+
}
|
|
5475
|
+
return content.replace(locale.decimalSeparator, ".");
|
|
5471
5476
|
}
|
|
5472
5477
|
/**
|
|
5473
5478
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -6451,6 +6456,146 @@ function transformRangeData(range, executed) {
|
|
|
6451
6456
|
return undefined;
|
|
6452
6457
|
}
|
|
6453
6458
|
|
|
6459
|
+
var State;
|
|
6460
|
+
(function (State) {
|
|
6461
|
+
/**
|
|
6462
|
+
* Initial state.
|
|
6463
|
+
* Expecting any reference for the left part of a range
|
|
6464
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6465
|
+
*/
|
|
6466
|
+
State[State["LeftRef"] = 0] = "LeftRef";
|
|
6467
|
+
/**
|
|
6468
|
+
* Expecting any reference for the right part of a range
|
|
6469
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6470
|
+
*/
|
|
6471
|
+
State[State["RightRef"] = 1] = "RightRef";
|
|
6472
|
+
/**
|
|
6473
|
+
* Expecting the separator without any constraint on the right part
|
|
6474
|
+
*/
|
|
6475
|
+
State[State["Separator"] = 2] = "Separator";
|
|
6476
|
+
/**
|
|
6477
|
+
* Expecting the separator for a full column range
|
|
6478
|
+
*/
|
|
6479
|
+
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
6480
|
+
/**
|
|
6481
|
+
* Expecting the separator for a full row range
|
|
6482
|
+
*/
|
|
6483
|
+
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
6484
|
+
/**
|
|
6485
|
+
* Expecting the right part of a full column range
|
|
6486
|
+
* e.g. "1", "A1"
|
|
6487
|
+
*/
|
|
6488
|
+
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
6489
|
+
/**
|
|
6490
|
+
* Expecting the right part of a full row range
|
|
6491
|
+
* e.g. "A", "A1"
|
|
6492
|
+
*/
|
|
6493
|
+
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
6494
|
+
/**
|
|
6495
|
+
* Final state. A range has been matched
|
|
6496
|
+
*/
|
|
6497
|
+
State[State["Found"] = 7] = "Found";
|
|
6498
|
+
})(State || (State = {}));
|
|
6499
|
+
const goTo = (state, guard = () => true) => [
|
|
6500
|
+
{
|
|
6501
|
+
goTo: state,
|
|
6502
|
+
guard,
|
|
6503
|
+
},
|
|
6504
|
+
];
|
|
6505
|
+
const goToMulti = (state, guard = () => true) => ({
|
|
6506
|
+
goTo: state,
|
|
6507
|
+
guard,
|
|
6508
|
+
});
|
|
6509
|
+
const machine = {
|
|
6510
|
+
[State.LeftRef]: {
|
|
6511
|
+
REFERENCE: goTo(State.Separator),
|
|
6512
|
+
NUMBER: goTo(State.FullRowSeparator),
|
|
6513
|
+
SYMBOL: [
|
|
6514
|
+
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
6515
|
+
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
6516
|
+
],
|
|
6517
|
+
},
|
|
6518
|
+
[State.FullColumnSeparator]: {
|
|
6519
|
+
SPACE: goTo(State.FullColumnSeparator),
|
|
6520
|
+
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
6521
|
+
},
|
|
6522
|
+
[State.FullRowSeparator]: {
|
|
6523
|
+
SPACE: goTo(State.FullRowSeparator),
|
|
6524
|
+
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
6525
|
+
},
|
|
6526
|
+
[State.Separator]: {
|
|
6527
|
+
SPACE: goTo(State.Separator),
|
|
6528
|
+
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
6529
|
+
},
|
|
6530
|
+
[State.RightRef]: {
|
|
6531
|
+
SPACE: goTo(State.RightRef),
|
|
6532
|
+
NUMBER: goTo(State.Found),
|
|
6533
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6534
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
6535
|
+
},
|
|
6536
|
+
[State.RightColumnRef]: {
|
|
6537
|
+
SPACE: goTo(State.RightColumnRef),
|
|
6538
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
6539
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6540
|
+
},
|
|
6541
|
+
[State.RightRowRef]: {
|
|
6542
|
+
SPACE: goTo(State.RightRowRef),
|
|
6543
|
+
NUMBER: goTo(State.Found),
|
|
6544
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6545
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
6546
|
+
},
|
|
6547
|
+
[State.Found]: {},
|
|
6548
|
+
};
|
|
6549
|
+
/**
|
|
6550
|
+
* Check if the list of tokens starts with a sequence of tokens representing
|
|
6551
|
+
* a range.
|
|
6552
|
+
* If a range is found, the sequence is removed from the list and is returned
|
|
6553
|
+
* as a single token.
|
|
6554
|
+
*/
|
|
6555
|
+
function matchReference(tokens) {
|
|
6556
|
+
let head = 0;
|
|
6557
|
+
let transitions = machine[State.LeftRef];
|
|
6558
|
+
let matchedTokens = "";
|
|
6559
|
+
while (transitions !== undefined) {
|
|
6560
|
+
const token = tokens[head++];
|
|
6561
|
+
if (!token) {
|
|
6562
|
+
return null;
|
|
6563
|
+
}
|
|
6564
|
+
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
6565
|
+
const nextState = transition ? transition.goTo : undefined;
|
|
6566
|
+
switch (nextState) {
|
|
6567
|
+
case undefined:
|
|
6568
|
+
return null;
|
|
6569
|
+
case State.Found:
|
|
6570
|
+
matchedTokens += token.value;
|
|
6571
|
+
tokens.splice(0, head);
|
|
6572
|
+
return {
|
|
6573
|
+
type: "REFERENCE",
|
|
6574
|
+
value: matchedTokens,
|
|
6575
|
+
};
|
|
6576
|
+
default:
|
|
6577
|
+
transitions = machine[nextState];
|
|
6578
|
+
matchedTokens += token.value;
|
|
6579
|
+
break;
|
|
6580
|
+
}
|
|
6581
|
+
}
|
|
6582
|
+
return null;
|
|
6583
|
+
}
|
|
6584
|
+
/**
|
|
6585
|
+
* Take the result of the tokenizer and transform it to be usable in the
|
|
6586
|
+
* manipulations of range
|
|
6587
|
+
*
|
|
6588
|
+
* @param formula
|
|
6589
|
+
*/
|
|
6590
|
+
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
6591
|
+
const tokens = tokenize(formula, locale);
|
|
6592
|
+
const result = [];
|
|
6593
|
+
while (tokens.length) {
|
|
6594
|
+
result.push(matchReference(tokens) || tokens.shift());
|
|
6595
|
+
}
|
|
6596
|
+
return result;
|
|
6597
|
+
}
|
|
6598
|
+
|
|
6454
6599
|
const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
|
|
6455
6600
|
const UNARY_OPERATORS_PREFIX = ["-", "+"];
|
|
6456
6601
|
const UNARY_OPERATORS_POSTFIX = ["%"];
|
|
@@ -6599,7 +6744,7 @@ function parseExpression(tokens, parent_priority = 0) {
|
|
|
6599
6744
|
* Parse an expression (as a string) into an AST.
|
|
6600
6745
|
*/
|
|
6601
6746
|
function parse(str) {
|
|
6602
|
-
return parseTokens(
|
|
6747
|
+
return parseTokens(rangeTokenize(str));
|
|
6603
6748
|
}
|
|
6604
6749
|
function parseTokens(tokens) {
|
|
6605
6750
|
tokens = tokens.filter((x) => x.type !== "SPACE");
|
|
@@ -6735,146 +6880,6 @@ function rightOperandToFormula(operationAST) {
|
|
|
6735
6880
|
return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
|
|
6736
6881
|
}
|
|
6737
6882
|
|
|
6738
|
-
var State;
|
|
6739
|
-
(function (State) {
|
|
6740
|
-
/**
|
|
6741
|
-
* Initial state.
|
|
6742
|
-
* Expecting any reference for the left part of a range
|
|
6743
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6744
|
-
*/
|
|
6745
|
-
State[State["LeftRef"] = 0] = "LeftRef";
|
|
6746
|
-
/**
|
|
6747
|
-
* Expecting any reference for the right part of a range
|
|
6748
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
6749
|
-
*/
|
|
6750
|
-
State[State["RightRef"] = 1] = "RightRef";
|
|
6751
|
-
/**
|
|
6752
|
-
* Expecting the separator without any constraint on the right part
|
|
6753
|
-
*/
|
|
6754
|
-
State[State["Separator"] = 2] = "Separator";
|
|
6755
|
-
/**
|
|
6756
|
-
* Expecting the separator for a full column range
|
|
6757
|
-
*/
|
|
6758
|
-
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
6759
|
-
/**
|
|
6760
|
-
* Expecting the separator for a full row range
|
|
6761
|
-
*/
|
|
6762
|
-
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
6763
|
-
/**
|
|
6764
|
-
* Expecting the right part of a full column range
|
|
6765
|
-
* e.g. "1", "A1"
|
|
6766
|
-
*/
|
|
6767
|
-
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
6768
|
-
/**
|
|
6769
|
-
* Expecting the right part of a full row range
|
|
6770
|
-
* e.g. "A", "A1"
|
|
6771
|
-
*/
|
|
6772
|
-
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
6773
|
-
/**
|
|
6774
|
-
* Final state. A range has been matched
|
|
6775
|
-
*/
|
|
6776
|
-
State[State["Found"] = 7] = "Found";
|
|
6777
|
-
})(State || (State = {}));
|
|
6778
|
-
const goTo = (state, guard = () => true) => [
|
|
6779
|
-
{
|
|
6780
|
-
goTo: state,
|
|
6781
|
-
guard,
|
|
6782
|
-
},
|
|
6783
|
-
];
|
|
6784
|
-
const goToMulti = (state, guard = () => true) => ({
|
|
6785
|
-
goTo: state,
|
|
6786
|
-
guard,
|
|
6787
|
-
});
|
|
6788
|
-
const machine = {
|
|
6789
|
-
[State.LeftRef]: {
|
|
6790
|
-
REFERENCE: goTo(State.Separator),
|
|
6791
|
-
NUMBER: goTo(State.FullRowSeparator),
|
|
6792
|
-
SYMBOL: [
|
|
6793
|
-
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
6794
|
-
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
6795
|
-
],
|
|
6796
|
-
},
|
|
6797
|
-
[State.FullColumnSeparator]: {
|
|
6798
|
-
SPACE: goTo(State.FullColumnSeparator),
|
|
6799
|
-
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
6800
|
-
},
|
|
6801
|
-
[State.FullRowSeparator]: {
|
|
6802
|
-
SPACE: goTo(State.FullRowSeparator),
|
|
6803
|
-
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
6804
|
-
},
|
|
6805
|
-
[State.Separator]: {
|
|
6806
|
-
SPACE: goTo(State.Separator),
|
|
6807
|
-
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
6808
|
-
},
|
|
6809
|
-
[State.RightRef]: {
|
|
6810
|
-
SPACE: goTo(State.RightRef),
|
|
6811
|
-
NUMBER: goTo(State.Found),
|
|
6812
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6813
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
6814
|
-
},
|
|
6815
|
-
[State.RightColumnRef]: {
|
|
6816
|
-
SPACE: goTo(State.RightColumnRef),
|
|
6817
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
6818
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6819
|
-
},
|
|
6820
|
-
[State.RightRowRef]: {
|
|
6821
|
-
SPACE: goTo(State.RightRowRef),
|
|
6822
|
-
NUMBER: goTo(State.Found),
|
|
6823
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
6824
|
-
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
6825
|
-
},
|
|
6826
|
-
[State.Found]: {},
|
|
6827
|
-
};
|
|
6828
|
-
/**
|
|
6829
|
-
* Check if the list of tokens starts with a sequence of tokens representing
|
|
6830
|
-
* a range.
|
|
6831
|
-
* If a range is found, the sequence is removed from the list and is returned
|
|
6832
|
-
* as a single token.
|
|
6833
|
-
*/
|
|
6834
|
-
function matchReference(tokens) {
|
|
6835
|
-
let head = 0;
|
|
6836
|
-
let transitions = machine[State.LeftRef];
|
|
6837
|
-
let matchedTokens = "";
|
|
6838
|
-
while (transitions !== undefined) {
|
|
6839
|
-
const token = tokens[head++];
|
|
6840
|
-
if (!token) {
|
|
6841
|
-
return null;
|
|
6842
|
-
}
|
|
6843
|
-
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
6844
|
-
const nextState = transition ? transition.goTo : undefined;
|
|
6845
|
-
switch (nextState) {
|
|
6846
|
-
case undefined:
|
|
6847
|
-
return null;
|
|
6848
|
-
case State.Found:
|
|
6849
|
-
matchedTokens += token.value;
|
|
6850
|
-
tokens.splice(0, head);
|
|
6851
|
-
return {
|
|
6852
|
-
type: "REFERENCE",
|
|
6853
|
-
value: matchedTokens,
|
|
6854
|
-
};
|
|
6855
|
-
default:
|
|
6856
|
-
transitions = machine[nextState];
|
|
6857
|
-
matchedTokens += token.value;
|
|
6858
|
-
break;
|
|
6859
|
-
}
|
|
6860
|
-
}
|
|
6861
|
-
return null;
|
|
6862
|
-
}
|
|
6863
|
-
/**
|
|
6864
|
-
* Take the result of the tokenizer and transform it to be usable in the
|
|
6865
|
-
* manipulations of range
|
|
6866
|
-
*
|
|
6867
|
-
* @param formula
|
|
6868
|
-
*/
|
|
6869
|
-
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
6870
|
-
const tokens = tokenize(formula, locale);
|
|
6871
|
-
const result = [];
|
|
6872
|
-
while (tokens.length) {
|
|
6873
|
-
result.push(matchReference(tokens) || tokens.shift());
|
|
6874
|
-
}
|
|
6875
|
-
return result;
|
|
6876
|
-
}
|
|
6877
|
-
|
|
6878
6883
|
/**
|
|
6879
6884
|
* Add the following information on tokens:
|
|
6880
6885
|
* - length
|
|
@@ -9198,7 +9203,6 @@ class ChartJsComponent extends Component {
|
|
|
9198
9203
|
};
|
|
9199
9204
|
canvas = useRef("graphContainer");
|
|
9200
9205
|
chart;
|
|
9201
|
-
currentRuntime;
|
|
9202
9206
|
get background() {
|
|
9203
9207
|
return this.chartRuntime.background;
|
|
9204
9208
|
}
|
|
@@ -9215,18 +9219,11 @@ class ChartJsComponent extends Component {
|
|
|
9215
9219
|
setup() {
|
|
9216
9220
|
onMounted(() => {
|
|
9217
9221
|
const runtime = this.chartRuntime;
|
|
9218
|
-
this.currentRuntime = runtime;
|
|
9219
9222
|
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
9220
9223
|
this.createChart(deepCopy(runtime.chartJsConfig));
|
|
9221
9224
|
});
|
|
9222
9225
|
onWillUnmount(() => this.chart?.destroy());
|
|
9223
|
-
useEffect(() =>
|
|
9224
|
-
const runtime = this.chartRuntime;
|
|
9225
|
-
if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
|
|
9226
|
-
this.currentRuntime = runtime;
|
|
9227
|
-
this.updateChartJs(deepCopy(runtime));
|
|
9228
|
-
}
|
|
9229
|
-
});
|
|
9226
|
+
useEffect(() => this.updateChartJs(deepCopy(this.chartRuntime)), () => [this.chartRuntime]);
|
|
9230
9227
|
}
|
|
9231
9228
|
createChart(chartData) {
|
|
9232
9229
|
const canvas = this.canvas.el;
|
|
@@ -19628,7 +19625,7 @@ function truncateLabel(label) {
|
|
|
19628
19625
|
/**
|
|
19629
19626
|
* Get a default chart js configuration
|
|
19630
19627
|
*/
|
|
19631
|
-
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
|
|
19628
|
+
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true }) {
|
|
19632
19629
|
const options = {
|
|
19633
19630
|
// https://www.chartjs.org/docs/latest/general/responsive.html
|
|
19634
19631
|
responsive: true,
|
|
@@ -20546,10 +20543,6 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
20546
20543
|
const cumulative = "cumulative" in chart ? chart.cumulative : false;
|
|
20547
20544
|
const colors = new ChartColors();
|
|
20548
20545
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
20549
|
-
if (["linear", "time"].includes(axisType)) {
|
|
20550
|
-
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
20551
|
-
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
20552
|
-
}
|
|
20553
20546
|
const color = colors.next();
|
|
20554
20547
|
let backgroundRGBA = colorToRGBA(color);
|
|
20555
20548
|
if (stacked) {
|
|
@@ -20565,6 +20558,10 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
20565
20558
|
return value;
|
|
20566
20559
|
});
|
|
20567
20560
|
}
|
|
20561
|
+
if (["linear", "time"].includes(axisType)) {
|
|
20562
|
+
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
20563
|
+
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
20564
|
+
}
|
|
20568
20565
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
20569
20566
|
const dataset = {
|
|
20570
20567
|
label,
|
|
@@ -30422,7 +30419,13 @@ class SettingsPanel extends Component {
|
|
|
30422
30419
|
}
|
|
30423
30420
|
async loadLocales() {
|
|
30424
30421
|
this.loadedLocales = (await this.env.loadLocales())
|
|
30425
|
-
.filter(
|
|
30422
|
+
.filter((locale) => {
|
|
30423
|
+
const isValid = isValidLocale(locale);
|
|
30424
|
+
if (!isValid) {
|
|
30425
|
+
console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
|
|
30426
|
+
}
|
|
30427
|
+
return isValid;
|
|
30428
|
+
})
|
|
30426
30429
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
30427
30430
|
}
|
|
30428
30431
|
get numberFormatPreview() {
|
|
@@ -36230,6 +36233,7 @@ class Grid extends Component {
|
|
|
36230
36233
|
return;
|
|
36231
36234
|
}
|
|
36232
36235
|
if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
|
|
36236
|
+
ev.preventDefault();
|
|
36233
36237
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
36234
36238
|
const target = this.env.model.getters.getSelectedZones();
|
|
36235
36239
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
@@ -40806,6 +40810,21 @@ class BordersPlugin extends CorePlugin {
|
|
|
40806
40810
|
return [];
|
|
40807
40811
|
return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
|
|
40808
40812
|
}
|
|
40813
|
+
/**
|
|
40814
|
+
* Get all the rows which contains at least a border
|
|
40815
|
+
*/
|
|
40816
|
+
getRowsWithBorders(sheetId) {
|
|
40817
|
+
const sheetBorders = this.borders[sheetId]?.filter(isDefined$1);
|
|
40818
|
+
if (!sheetBorders)
|
|
40819
|
+
return [];
|
|
40820
|
+
const rowsWithBorders = new Set();
|
|
40821
|
+
for (const rowBorders of sheetBorders) {
|
|
40822
|
+
for (const rowBorder in rowBorders) {
|
|
40823
|
+
rowsWithBorders.add(parseInt(rowBorder, 10));
|
|
40824
|
+
}
|
|
40825
|
+
}
|
|
40826
|
+
return Array.from(rowsWithBorders);
|
|
40827
|
+
}
|
|
40809
40828
|
/**
|
|
40810
40829
|
* Get the range of all the rows in the sheet
|
|
40811
40830
|
*/
|
|
@@ -40855,7 +40874,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
40855
40874
|
destructive: false,
|
|
40856
40875
|
});
|
|
40857
40876
|
}
|
|
40858
|
-
this.
|
|
40877
|
+
this.getRowsWithBorders(sheetId)
|
|
40859
40878
|
.filter((row) => row >= start)
|
|
40860
40879
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
40861
40880
|
.forEach((row) => {
|
|
@@ -47478,7 +47497,7 @@ class PositionSet {
|
|
|
47478
47497
|
return this.sheets[position.sheetId].getValue(position) === 1;
|
|
47479
47498
|
}
|
|
47480
47499
|
clear() {
|
|
47481
|
-
const insertions = this
|
|
47500
|
+
const insertions = [...this];
|
|
47482
47501
|
this.insertions = [];
|
|
47483
47502
|
for (const sheetId in this.sheets) {
|
|
47484
47503
|
this.sheets[sheetId].clear();
|
|
@@ -47796,6 +47815,7 @@ class Evaluator {
|
|
|
47796
47815
|
}
|
|
47797
47816
|
finally {
|
|
47798
47817
|
this.cellsBeingComputed.delete(cellId);
|
|
47818
|
+
this.nextPositionsToUpdate.delete(position);
|
|
47799
47819
|
}
|
|
47800
47820
|
}
|
|
47801
47821
|
computeAndSave(position) {
|
|
@@ -47820,8 +47840,33 @@ class Evaluator {
|
|
|
47820
47840
|
forEachSpreadPositionInMatrix(nbColumns, nbRows,
|
|
47821
47841
|
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
|
|
47822
47842
|
this.spreadValues(formulaPosition, formulaReturn));
|
|
47843
|
+
this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
|
|
47823
47844
|
return createEvaluatedCell(nullValueToZeroValue(formulaReturn[0][0]), this.getters.getLocale(), cellData);
|
|
47824
47845
|
}
|
|
47846
|
+
invalidatePositionsDependingOnSpread(arrayFormulaPosition, nbColumns, nbRows) {
|
|
47847
|
+
// the result matrix is split in 2 zones to exclude the array formula position
|
|
47848
|
+
const top = arrayFormulaPosition.row;
|
|
47849
|
+
const left = arrayFormulaPosition.col;
|
|
47850
|
+
const bottom = top + nbRows - 1;
|
|
47851
|
+
const leftColumnZone = {
|
|
47852
|
+
top: top + 1,
|
|
47853
|
+
bottom,
|
|
47854
|
+
left,
|
|
47855
|
+
right: left,
|
|
47856
|
+
};
|
|
47857
|
+
const rightPartZone = {
|
|
47858
|
+
top,
|
|
47859
|
+
bottom,
|
|
47860
|
+
left: left + 1,
|
|
47861
|
+
right: left + nbColumns - 1,
|
|
47862
|
+
};
|
|
47863
|
+
const sheetId = arrayFormulaPosition.sheetId;
|
|
47864
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
|
|
47865
|
+
{ sheetId, zone: rightPartZone },
|
|
47866
|
+
{ sheetId, zone: leftColumnZone },
|
|
47867
|
+
]);
|
|
47868
|
+
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
47869
|
+
}
|
|
47825
47870
|
assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
|
|
47826
47871
|
const numberOfCols = this.getters.getNumberCols(sheetId);
|
|
47827
47872
|
const numberOfRows = this.getters.getNumberRows(sheetId);
|
|
@@ -47864,9 +47909,6 @@ class Evaluator {
|
|
|
47864
47909
|
const cell = this.getters.getCell(position);
|
|
47865
47910
|
const evaluatedCell = createEvaluatedCell(nullValueToZeroValue(matrixResult[i][j]), this.getters.getLocale(), cell);
|
|
47866
47911
|
this.evaluatedCells.set(position, evaluatedCell);
|
|
47867
|
-
// check if formula dependencies present in the spread zone
|
|
47868
|
-
// if so, they need to be recomputed
|
|
47869
|
-
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([position]));
|
|
47870
47912
|
};
|
|
47871
47913
|
}
|
|
47872
47914
|
invalidateSpreading(position) {
|
|
@@ -60798,6 +60840,6 @@ const constants = {
|
|
|
60798
60840
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
60799
60841
|
|
|
60800
60842
|
|
|
60801
|
-
__info__.version = "17.2.
|
|
60802
|
-
__info__.date = "2024-07-
|
|
60803
|
-
__info__.hash = "
|
|
60843
|
+
__info__.version = "17.2.16";
|
|
60844
|
+
__info__.date = "2024-07-11T06:38:53.101Z";
|
|
60845
|
+
__info__.hash = "9f20685";
|