@odoo/o-spreadsheet 17.4.0-alpha.11 → 17.4.0-alpha.12
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 +235 -173
- package/dist/o-spreadsheet.d.ts +13 -1
- package/dist/o-spreadsheet.esm.js +235 -173
- package/dist/o-spreadsheet.iife.js +235 -173
- package/dist/o-spreadsheet.iife.min.js +10 -10
- package/dist/o_spreadsheet.xml +6 -6
- package/package.json +2 -2
- package/readme.md +2 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.4.0-alpha.
|
|
6
|
-
* @date 2024-07-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.4.0-alpha.12
|
|
6
|
+
* @date 2024-07-08T05:43:07.933Z
|
|
7
|
+
* @hash 7cfe14a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -1805,7 +1805,7 @@ const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSepa
|
|
|
1805
1805
|
});
|
|
1806
1806
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
1807
1807
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
1808
|
-
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
|
|
1808
|
+
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
|
|
1809
1809
|
const pIntegerAndDecimals = `(?:\\d+(?:${thousandsSeparator}\\d{3,})*(?:${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
|
|
1810
1810
|
const pOnlyDecimals = `(?:${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
|
|
1811
1811
|
const pScientificFormat = "(?:e(?:\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -1838,7 +1838,7 @@ function isNumber(value, locale) {
|
|
|
1838
1838
|
return getNumberRegex(locale).test(value.trim());
|
|
1839
1839
|
}
|
|
1840
1840
|
const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
|
|
1841
|
-
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
|
|
1841
|
+
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
|
|
1842
1842
|
});
|
|
1843
1843
|
/**
|
|
1844
1844
|
* Convert a string into a number. It assumes that the string actually represents
|
|
@@ -5862,19 +5862,22 @@ class TokenizingChars {
|
|
|
5862
5862
|
}
|
|
5863
5863
|
|
|
5864
5864
|
function isValidLocale(locale) {
|
|
5865
|
-
if (!
|
|
5866
|
-
typeof locale
|
|
5867
|
-
typeof locale.
|
|
5868
|
-
typeof locale.code === "string" &&
|
|
5869
|
-
typeof locale.thousandsSeparator === "string" &&
|
|
5870
|
-
typeof locale.decimalSeparator === "string" &&
|
|
5871
|
-
typeof locale.dateFormat === "string" &&
|
|
5872
|
-
typeof locale.timeFormat === "string" &&
|
|
5873
|
-
typeof locale.formulaArgSeparator === "string")) {
|
|
5865
|
+
if (!locale ||
|
|
5866
|
+
typeof locale !== "object" ||
|
|
5867
|
+
!(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
|
|
5874
5868
|
return false;
|
|
5875
5869
|
}
|
|
5876
|
-
|
|
5877
|
-
|
|
5870
|
+
for (const property of [
|
|
5871
|
+
"code",
|
|
5872
|
+
"name",
|
|
5873
|
+
"decimalSeparator",
|
|
5874
|
+
"dateFormat",
|
|
5875
|
+
"timeFormat",
|
|
5876
|
+
"formulaArgSeparator",
|
|
5877
|
+
]) {
|
|
5878
|
+
if (!locale[property] || typeof locale[property] !== "string") {
|
|
5879
|
+
return false;
|
|
5880
|
+
}
|
|
5878
5881
|
}
|
|
5879
5882
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
5880
5883
|
return false;
|
|
@@ -5972,7 +5975,10 @@ function canonicalizeNumberLiteral(content, locale) {
|
|
|
5972
5975
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
5973
5976
|
return content;
|
|
5974
5977
|
}
|
|
5975
|
-
|
|
5978
|
+
if (locale.thousandsSeparator) {
|
|
5979
|
+
content = content.replaceAll(locale.thousandsSeparator, "");
|
|
5980
|
+
}
|
|
5981
|
+
return content.replace(locale.decimalSeparator, ".");
|
|
5976
5982
|
}
|
|
5977
5983
|
/**
|
|
5978
5984
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -6324,7 +6330,7 @@ const quarterNumberAdapter = {
|
|
|
6324
6330
|
},
|
|
6325
6331
|
toValueAndFormat(normalizedValue) {
|
|
6326
6332
|
return {
|
|
6327
|
-
value:
|
|
6333
|
+
value: _t("Q%(quarter_number)s", { quarter_number: normalizedValue }),
|
|
6328
6334
|
format: "0",
|
|
6329
6335
|
};
|
|
6330
6336
|
},
|
|
@@ -6454,9 +6460,9 @@ function getMaxObjectId(o) {
|
|
|
6454
6460
|
}
|
|
6455
6461
|
const ALL_PERIODS = {
|
|
6456
6462
|
year: _t("Year"),
|
|
6457
|
-
quarter: _t("Quarter"),
|
|
6458
|
-
month: _t("Month"),
|
|
6459
|
-
week: _t("Week"),
|
|
6463
|
+
quarter: _t("Quarter & Year"),
|
|
6464
|
+
month: _t("Month & Year"),
|
|
6465
|
+
week: _t("Week & Year"),
|
|
6460
6466
|
day: _t("Day"),
|
|
6461
6467
|
quarter_number: _t("Quarter"),
|
|
6462
6468
|
month_number: _t("Month"),
|
|
@@ -6608,7 +6614,7 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
6608
6614
|
const pivotId = this.getters.getPivotIdFromPosition(position);
|
|
6609
6615
|
const spreader = this.getters.getArrayFormulaSpreadingOn(position);
|
|
6610
6616
|
if (pivotId) {
|
|
6611
|
-
if (!deepEquals(spreader, position) || !isCopyingOneCell) {
|
|
6617
|
+
if (spreader && (!deepEquals(spreader, position) || !isCopyingOneCell)) {
|
|
6612
6618
|
const pivotCell = this.getters.getPivotCellFromPosition(position);
|
|
6613
6619
|
const formulaPivotId = this.getters.getPivotFormulaId(pivotId);
|
|
6614
6620
|
const pivotFormula = createPivotFormula(formulaPivotId, pivotCell);
|
|
@@ -7413,6 +7419,146 @@ function transformRangeData(range, executed) {
|
|
|
7413
7419
|
return undefined;
|
|
7414
7420
|
}
|
|
7415
7421
|
|
|
7422
|
+
var State;
|
|
7423
|
+
(function (State) {
|
|
7424
|
+
/**
|
|
7425
|
+
* Initial state.
|
|
7426
|
+
* Expecting any reference for the left part of a range
|
|
7427
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7428
|
+
*/
|
|
7429
|
+
State[State["LeftRef"] = 0] = "LeftRef";
|
|
7430
|
+
/**
|
|
7431
|
+
* Expecting any reference for the right part of a range
|
|
7432
|
+
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7433
|
+
*/
|
|
7434
|
+
State[State["RightRef"] = 1] = "RightRef";
|
|
7435
|
+
/**
|
|
7436
|
+
* Expecting the separator without any constraint on the right part
|
|
7437
|
+
*/
|
|
7438
|
+
State[State["Separator"] = 2] = "Separator";
|
|
7439
|
+
/**
|
|
7440
|
+
* Expecting the separator for a full column range
|
|
7441
|
+
*/
|
|
7442
|
+
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
7443
|
+
/**
|
|
7444
|
+
* Expecting the separator for a full row range
|
|
7445
|
+
*/
|
|
7446
|
+
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
7447
|
+
/**
|
|
7448
|
+
* Expecting the right part of a full column range
|
|
7449
|
+
* e.g. "1", "A1"
|
|
7450
|
+
*/
|
|
7451
|
+
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
7452
|
+
/**
|
|
7453
|
+
* Expecting the right part of a full row range
|
|
7454
|
+
* e.g. "A", "A1"
|
|
7455
|
+
*/
|
|
7456
|
+
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
7457
|
+
/**
|
|
7458
|
+
* Final state. A range has been matched
|
|
7459
|
+
*/
|
|
7460
|
+
State[State["Found"] = 7] = "Found";
|
|
7461
|
+
})(State || (State = {}));
|
|
7462
|
+
const goTo = (state, guard = () => true) => [
|
|
7463
|
+
{
|
|
7464
|
+
goTo: state,
|
|
7465
|
+
guard,
|
|
7466
|
+
},
|
|
7467
|
+
];
|
|
7468
|
+
const goToMulti = (state, guard = () => true) => ({
|
|
7469
|
+
goTo: state,
|
|
7470
|
+
guard,
|
|
7471
|
+
});
|
|
7472
|
+
const machine = {
|
|
7473
|
+
[State.LeftRef]: {
|
|
7474
|
+
REFERENCE: goTo(State.Separator),
|
|
7475
|
+
NUMBER: goTo(State.FullRowSeparator),
|
|
7476
|
+
SYMBOL: [
|
|
7477
|
+
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
7478
|
+
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
7479
|
+
],
|
|
7480
|
+
},
|
|
7481
|
+
[State.FullColumnSeparator]: {
|
|
7482
|
+
SPACE: goTo(State.FullColumnSeparator),
|
|
7483
|
+
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
7484
|
+
},
|
|
7485
|
+
[State.FullRowSeparator]: {
|
|
7486
|
+
SPACE: goTo(State.FullRowSeparator),
|
|
7487
|
+
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
7488
|
+
},
|
|
7489
|
+
[State.Separator]: {
|
|
7490
|
+
SPACE: goTo(State.Separator),
|
|
7491
|
+
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
7492
|
+
},
|
|
7493
|
+
[State.RightRef]: {
|
|
7494
|
+
SPACE: goTo(State.RightRef),
|
|
7495
|
+
NUMBER: goTo(State.Found),
|
|
7496
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7497
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
7498
|
+
},
|
|
7499
|
+
[State.RightColumnRef]: {
|
|
7500
|
+
SPACE: goTo(State.RightColumnRef),
|
|
7501
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
7502
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7503
|
+
},
|
|
7504
|
+
[State.RightRowRef]: {
|
|
7505
|
+
SPACE: goTo(State.RightRowRef),
|
|
7506
|
+
NUMBER: goTo(State.Found),
|
|
7507
|
+
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7508
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
7509
|
+
},
|
|
7510
|
+
[State.Found]: {},
|
|
7511
|
+
};
|
|
7512
|
+
/**
|
|
7513
|
+
* Check if the list of tokens starts with a sequence of tokens representing
|
|
7514
|
+
* a range.
|
|
7515
|
+
* If a range is found, the sequence is removed from the list and is returned
|
|
7516
|
+
* as a single token.
|
|
7517
|
+
*/
|
|
7518
|
+
function matchReference(tokens) {
|
|
7519
|
+
let head = 0;
|
|
7520
|
+
let transitions = machine[State.LeftRef];
|
|
7521
|
+
let matchedTokens = "";
|
|
7522
|
+
while (transitions !== undefined) {
|
|
7523
|
+
const token = tokens[head++];
|
|
7524
|
+
if (!token) {
|
|
7525
|
+
return null;
|
|
7526
|
+
}
|
|
7527
|
+
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
7528
|
+
const nextState = transition ? transition.goTo : undefined;
|
|
7529
|
+
switch (nextState) {
|
|
7530
|
+
case undefined:
|
|
7531
|
+
return null;
|
|
7532
|
+
case State.Found:
|
|
7533
|
+
matchedTokens += token.value;
|
|
7534
|
+
tokens.splice(0, head);
|
|
7535
|
+
return {
|
|
7536
|
+
type: "REFERENCE",
|
|
7537
|
+
value: matchedTokens,
|
|
7538
|
+
};
|
|
7539
|
+
default:
|
|
7540
|
+
transitions = machine[nextState];
|
|
7541
|
+
matchedTokens += token.value;
|
|
7542
|
+
break;
|
|
7543
|
+
}
|
|
7544
|
+
}
|
|
7545
|
+
return null;
|
|
7546
|
+
}
|
|
7547
|
+
/**
|
|
7548
|
+
* Take the result of the tokenizer and transform it to be usable in the
|
|
7549
|
+
* manipulations of range
|
|
7550
|
+
*
|
|
7551
|
+
* @param formula
|
|
7552
|
+
*/
|
|
7553
|
+
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
7554
|
+
const tokens = tokenize(formula, locale);
|
|
7555
|
+
const result = [];
|
|
7556
|
+
while (tokens.length) {
|
|
7557
|
+
result.push(matchReference(tokens) || tokens.shift());
|
|
7558
|
+
}
|
|
7559
|
+
return result;
|
|
7560
|
+
}
|
|
7561
|
+
|
|
7416
7562
|
const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
|
|
7417
7563
|
const UNARY_OPERATORS_PREFIX = ["-", "+"];
|
|
7418
7564
|
const UNARY_OPERATORS_POSTFIX = ["%"];
|
|
@@ -7561,7 +7707,7 @@ function parseExpression(tokens, parent_priority = 0) {
|
|
|
7561
7707
|
* Parse an expression (as a string) into an AST.
|
|
7562
7708
|
*/
|
|
7563
7709
|
function parse(str) {
|
|
7564
|
-
return parseTokens(
|
|
7710
|
+
return parseTokens(rangeTokenize(str));
|
|
7565
7711
|
}
|
|
7566
7712
|
function parseTokens(tokens) {
|
|
7567
7713
|
tokens = tokens.filter((x) => x.type !== "SPACE");
|
|
@@ -7697,146 +7843,6 @@ function rightOperandToFormula(operationAST) {
|
|
|
7697
7843
|
return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
|
|
7698
7844
|
}
|
|
7699
7845
|
|
|
7700
|
-
var State;
|
|
7701
|
-
(function (State) {
|
|
7702
|
-
/**
|
|
7703
|
-
* Initial state.
|
|
7704
|
-
* Expecting any reference for the left part of a range
|
|
7705
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7706
|
-
*/
|
|
7707
|
-
State[State["LeftRef"] = 0] = "LeftRef";
|
|
7708
|
-
/**
|
|
7709
|
-
* Expecting any reference for the right part of a range
|
|
7710
|
-
* e.g. "A1", "1", "A", "Sheet1!A1", "Sheet1!A"
|
|
7711
|
-
*/
|
|
7712
|
-
State[State["RightRef"] = 1] = "RightRef";
|
|
7713
|
-
/**
|
|
7714
|
-
* Expecting the separator without any constraint on the right part
|
|
7715
|
-
*/
|
|
7716
|
-
State[State["Separator"] = 2] = "Separator";
|
|
7717
|
-
/**
|
|
7718
|
-
* Expecting the separator for a full column range
|
|
7719
|
-
*/
|
|
7720
|
-
State[State["FullColumnSeparator"] = 3] = "FullColumnSeparator";
|
|
7721
|
-
/**
|
|
7722
|
-
* Expecting the separator for a full row range
|
|
7723
|
-
*/
|
|
7724
|
-
State[State["FullRowSeparator"] = 4] = "FullRowSeparator";
|
|
7725
|
-
/**
|
|
7726
|
-
* Expecting the right part of a full column range
|
|
7727
|
-
* e.g. "1", "A1"
|
|
7728
|
-
*/
|
|
7729
|
-
State[State["RightColumnRef"] = 5] = "RightColumnRef";
|
|
7730
|
-
/**
|
|
7731
|
-
* Expecting the right part of a full row range
|
|
7732
|
-
* e.g. "A", "A1"
|
|
7733
|
-
*/
|
|
7734
|
-
State[State["RightRowRef"] = 6] = "RightRowRef";
|
|
7735
|
-
/**
|
|
7736
|
-
* Final state. A range has been matched
|
|
7737
|
-
*/
|
|
7738
|
-
State[State["Found"] = 7] = "Found";
|
|
7739
|
-
})(State || (State = {}));
|
|
7740
|
-
const goTo = (state, guard = () => true) => [
|
|
7741
|
-
{
|
|
7742
|
-
goTo: state,
|
|
7743
|
-
guard,
|
|
7744
|
-
},
|
|
7745
|
-
];
|
|
7746
|
-
const goToMulti = (state, guard = () => true) => ({
|
|
7747
|
-
goTo: state,
|
|
7748
|
-
guard,
|
|
7749
|
-
});
|
|
7750
|
-
const machine = {
|
|
7751
|
-
[State.LeftRef]: {
|
|
7752
|
-
REFERENCE: goTo(State.Separator),
|
|
7753
|
-
NUMBER: goTo(State.FullRowSeparator),
|
|
7754
|
-
SYMBOL: [
|
|
7755
|
-
goToMulti(State.FullColumnSeparator, (token) => isColReference(token.value)),
|
|
7756
|
-
goToMulti(State.FullRowSeparator, (token) => isRowReference(token.value)),
|
|
7757
|
-
],
|
|
7758
|
-
},
|
|
7759
|
-
[State.FullColumnSeparator]: {
|
|
7760
|
-
SPACE: goTo(State.FullColumnSeparator),
|
|
7761
|
-
OPERATOR: goTo(State.RightColumnRef, (token) => token.value === ":"),
|
|
7762
|
-
},
|
|
7763
|
-
[State.FullRowSeparator]: {
|
|
7764
|
-
SPACE: goTo(State.FullRowSeparator),
|
|
7765
|
-
OPERATOR: goTo(State.RightRowRef, (token) => token.value === ":"),
|
|
7766
|
-
},
|
|
7767
|
-
[State.Separator]: {
|
|
7768
|
-
SPACE: goTo(State.Separator),
|
|
7769
|
-
OPERATOR: goTo(State.RightRef, (token) => token.value === ":"),
|
|
7770
|
-
},
|
|
7771
|
-
[State.RightRef]: {
|
|
7772
|
-
SPACE: goTo(State.RightRef),
|
|
7773
|
-
NUMBER: goTo(State.Found),
|
|
7774
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7775
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
7776
|
-
},
|
|
7777
|
-
[State.RightColumnRef]: {
|
|
7778
|
-
SPACE: goTo(State.RightColumnRef),
|
|
7779
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
7780
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7781
|
-
},
|
|
7782
|
-
[State.RightRowRef]: {
|
|
7783
|
-
SPACE: goTo(State.RightRowRef),
|
|
7784
|
-
NUMBER: goTo(State.Found),
|
|
7785
|
-
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
7786
|
-
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
7787
|
-
},
|
|
7788
|
-
[State.Found]: {},
|
|
7789
|
-
};
|
|
7790
|
-
/**
|
|
7791
|
-
* Check if the list of tokens starts with a sequence of tokens representing
|
|
7792
|
-
* a range.
|
|
7793
|
-
* If a range is found, the sequence is removed from the list and is returned
|
|
7794
|
-
* as a single token.
|
|
7795
|
-
*/
|
|
7796
|
-
function matchReference(tokens) {
|
|
7797
|
-
let head = 0;
|
|
7798
|
-
let transitions = machine[State.LeftRef];
|
|
7799
|
-
let matchedTokens = "";
|
|
7800
|
-
while (transitions !== undefined) {
|
|
7801
|
-
const token = tokens[head++];
|
|
7802
|
-
if (!token) {
|
|
7803
|
-
return null;
|
|
7804
|
-
}
|
|
7805
|
-
const transition = transitions[token.type]?.find((transition) => transition.guard(token));
|
|
7806
|
-
const nextState = transition ? transition.goTo : undefined;
|
|
7807
|
-
switch (nextState) {
|
|
7808
|
-
case undefined:
|
|
7809
|
-
return null;
|
|
7810
|
-
case State.Found:
|
|
7811
|
-
matchedTokens += token.value;
|
|
7812
|
-
tokens.splice(0, head);
|
|
7813
|
-
return {
|
|
7814
|
-
type: "REFERENCE",
|
|
7815
|
-
value: matchedTokens,
|
|
7816
|
-
};
|
|
7817
|
-
default:
|
|
7818
|
-
transitions = machine[nextState];
|
|
7819
|
-
matchedTokens += token.value;
|
|
7820
|
-
break;
|
|
7821
|
-
}
|
|
7822
|
-
}
|
|
7823
|
-
return null;
|
|
7824
|
-
}
|
|
7825
|
-
/**
|
|
7826
|
-
* Take the result of the tokenizer and transform it to be usable in the
|
|
7827
|
-
* manipulations of range
|
|
7828
|
-
*
|
|
7829
|
-
* @param formula
|
|
7830
|
-
*/
|
|
7831
|
-
function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
7832
|
-
const tokens = tokenize(formula, locale);
|
|
7833
|
-
const result = [];
|
|
7834
|
-
while (tokens.length) {
|
|
7835
|
-
result.push(matchReference(tokens) || tokens.shift());
|
|
7836
|
-
}
|
|
7837
|
-
return result;
|
|
7838
|
-
}
|
|
7839
|
-
|
|
7840
7846
|
/**
|
|
7841
7847
|
* Add the following information on tokens:
|
|
7842
7848
|
* - length
|
|
@@ -24027,10 +24033,6 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
24027
24033
|
const colors = new ColorGenerator();
|
|
24028
24034
|
const definition = chart.getDefinition();
|
|
24029
24035
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
24030
|
-
if (["linear", "time"].includes(axisType)) {
|
|
24031
|
-
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
24032
|
-
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
24033
|
-
}
|
|
24034
24036
|
const color = colors.next();
|
|
24035
24037
|
let backgroundRGBA = colorToRGBA(color);
|
|
24036
24038
|
if (areaChart) {
|
|
@@ -24046,6 +24048,10 @@ function createLineOrScatterChartRuntime(chart, getters) {
|
|
|
24046
24048
|
return value;
|
|
24047
24049
|
});
|
|
24048
24050
|
}
|
|
24051
|
+
if (["linear", "time"].includes(axisType)) {
|
|
24052
|
+
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
24053
|
+
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
24054
|
+
}
|
|
24049
24055
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
24050
24056
|
const dataset = {
|
|
24051
24057
|
label,
|
|
@@ -34638,6 +34644,8 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
34638
34644
|
isSearchDirty = false;
|
|
34639
34645
|
initialShowFormulaState;
|
|
34640
34646
|
preserveSelectedMatchIndex = false;
|
|
34647
|
+
irreplaceableMatchCount = 0;
|
|
34648
|
+
notificationStore = this.get(NotificationStore);
|
|
34641
34649
|
// fixme: why do we make selectedMatchIndex on top of a selected
|
|
34642
34650
|
// property in the matches?
|
|
34643
34651
|
selectedMatchIndex = null;
|
|
@@ -34714,6 +34722,11 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
34714
34722
|
for (const match of cmd.matches) {
|
|
34715
34723
|
this.replaceMatch(match, cmd.searchString, cmd.replaceWith, cmd.searchOptions);
|
|
34716
34724
|
}
|
|
34725
|
+
if (this.irreplaceableMatchCount > 0) {
|
|
34726
|
+
this.showReplaceWarningMessage(cmd.matches.length, this.irreplaceableMatchCount);
|
|
34727
|
+
}
|
|
34728
|
+
this.irreplaceableMatchCount = 0;
|
|
34729
|
+
break;
|
|
34717
34730
|
}
|
|
34718
34731
|
}
|
|
34719
34732
|
finalize() {
|
|
@@ -34895,12 +34908,36 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
34895
34908
|
searchOptions: this.searchOptions,
|
|
34896
34909
|
});
|
|
34897
34910
|
}
|
|
34911
|
+
/**
|
|
34912
|
+
* Show a warning message based on the number of matches replaced and irreplaceable.
|
|
34913
|
+
*/
|
|
34914
|
+
showReplaceWarningMessage(totalMatches, irreplaceableMatches) {
|
|
34915
|
+
const replaceableMatches = totalMatches - irreplaceableMatches;
|
|
34916
|
+
if (replaceableMatches === 0) {
|
|
34917
|
+
this.notificationStore.notifyUser({
|
|
34918
|
+
type: "warning",
|
|
34919
|
+
sticky: false,
|
|
34920
|
+
text: _t("Match(es) cannot be replaced as they are part of a formula."),
|
|
34921
|
+
});
|
|
34922
|
+
}
|
|
34923
|
+
else {
|
|
34924
|
+
this.notificationStore.notifyUser({
|
|
34925
|
+
type: "warning",
|
|
34926
|
+
sticky: false,
|
|
34927
|
+
text: _t("%(replaceable_count)s match(es) replaced. %(irreplaceable_count)s match(es) cannot be replaced as they are part of a formula.", {
|
|
34928
|
+
replaceable_count: replaceableMatches,
|
|
34929
|
+
irreplaceable_count: irreplaceableMatches,
|
|
34930
|
+
}),
|
|
34931
|
+
});
|
|
34932
|
+
}
|
|
34933
|
+
}
|
|
34898
34934
|
replaceMatch(selectedMatch, searchString, replaceWith, searchOptions) {
|
|
34899
34935
|
const cell = this.getters.getCell(selectedMatch);
|
|
34900
34936
|
if (!cell?.content) {
|
|
34901
34937
|
return;
|
|
34902
34938
|
}
|
|
34903
34939
|
if (cell?.isFormula && !searchOptions.searchFormulas) {
|
|
34940
|
+
this.irreplaceableMatchCount++;
|
|
34904
34941
|
return;
|
|
34905
34942
|
}
|
|
34906
34943
|
const searchRegex = getSearchRegex(searchString, searchOptions);
|
|
@@ -36966,7 +37003,13 @@ class SettingsPanel extends owl.Component {
|
|
|
36966
37003
|
}
|
|
36967
37004
|
async loadLocales() {
|
|
36968
37005
|
this.loadedLocales = (await this.env.loadLocales())
|
|
36969
|
-
.filter(
|
|
37006
|
+
.filter((locale) => {
|
|
37007
|
+
const isValid = isValidLocale(locale);
|
|
37008
|
+
if (!isValid) {
|
|
37009
|
+
console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
|
|
37010
|
+
}
|
|
37011
|
+
return isValid;
|
|
37012
|
+
})
|
|
36970
37013
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
36971
37014
|
}
|
|
36972
37015
|
get numberFormatPreview() {
|
|
@@ -38025,6 +38068,9 @@ class TopBarComponentRegistry extends Registry {
|
|
|
38025
38068
|
const component = { ...value, id: this.uuidGenerator.uuidv4() };
|
|
38026
38069
|
return super.add(name, component);
|
|
38027
38070
|
}
|
|
38071
|
+
getAllOrdered() {
|
|
38072
|
+
return this.getAll().sort((a, b) => a.sequence - b.sequence);
|
|
38073
|
+
}
|
|
38028
38074
|
}
|
|
38029
38075
|
const topbarComponentRegistry = new TopBarComponentRegistry();
|
|
38030
38076
|
|
|
@@ -42135,6 +42181,7 @@ class Grid extends owl.Component {
|
|
|
42135
42181
|
return;
|
|
42136
42182
|
}
|
|
42137
42183
|
if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
|
|
42184
|
+
ev.preventDefault();
|
|
42138
42185
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
42139
42186
|
const target = this.env.model.getters.getSelectedZones();
|
|
42140
42187
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
@@ -46798,6 +46845,21 @@ class BordersPlugin extends CorePlugin {
|
|
|
46798
46845
|
return [];
|
|
46799
46846
|
return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
|
|
46800
46847
|
}
|
|
46848
|
+
/**
|
|
46849
|
+
* Get all the rows which contains at least a border
|
|
46850
|
+
*/
|
|
46851
|
+
getRowsWithBorders(sheetId) {
|
|
46852
|
+
const sheetBorders = this.borders[sheetId]?.filter(isDefined);
|
|
46853
|
+
if (!sheetBorders)
|
|
46854
|
+
return [];
|
|
46855
|
+
const rowsWithBorders = new Set();
|
|
46856
|
+
for (const rowBorders of sheetBorders) {
|
|
46857
|
+
for (const rowBorder in rowBorders) {
|
|
46858
|
+
rowsWithBorders.add(parseInt(rowBorder, 10));
|
|
46859
|
+
}
|
|
46860
|
+
}
|
|
46861
|
+
return Array.from(rowsWithBorders);
|
|
46862
|
+
}
|
|
46801
46863
|
/**
|
|
46802
46864
|
* Get the range of all the rows in the sheet
|
|
46803
46865
|
*/
|
|
@@ -46847,7 +46909,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
46847
46909
|
destructive: false,
|
|
46848
46910
|
});
|
|
46849
46911
|
}
|
|
46850
|
-
this.
|
|
46912
|
+
this.getRowsWithBorders(sheetId)
|
|
46851
46913
|
.filter((row) => row >= start)
|
|
46852
46914
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
46853
46915
|
.forEach((row) => {
|
|
@@ -63140,7 +63202,7 @@ class TopBar extends owl.Component {
|
|
|
63140
63202
|
}
|
|
63141
63203
|
get topbarComponents() {
|
|
63142
63204
|
return topbarComponentRegistry
|
|
63143
|
-
.
|
|
63205
|
+
.getAllOrdered()
|
|
63144
63206
|
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
63145
63207
|
}
|
|
63146
63208
|
onExternalClick(ev) {
|
|
@@ -67771,6 +67833,6 @@ exports.tokenColors = tokenColors;
|
|
|
67771
67833
|
exports.tokenize = tokenize;
|
|
67772
67834
|
|
|
67773
67835
|
|
|
67774
|
-
__info__.version = "17.4.0-alpha.
|
|
67775
|
-
__info__.date = "2024-07-
|
|
67776
|
-
__info__.hash = "
|
|
67836
|
+
__info__.version = "17.4.0-alpha.12";
|
|
67837
|
+
__info__.date = "2024-07-08T05:43:07.933Z";
|
|
67838
|
+
__info__.hash = "7cfe14a";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -1855,7 +1855,7 @@ type LocaleCode = string & Alias;
|
|
|
1855
1855
|
interface Locale {
|
|
1856
1856
|
name: string;
|
|
1857
1857
|
code: LocaleCode;
|
|
1858
|
-
thousandsSeparator
|
|
1858
|
+
thousandsSeparator?: string;
|
|
1859
1859
|
decimalSeparator: string;
|
|
1860
1860
|
dateFormat: string;
|
|
1861
1861
|
timeFormat: string;
|
|
@@ -2606,6 +2606,10 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
|
|
|
2606
2606
|
* Get all the columns which contains at least a border
|
|
2607
2607
|
*/
|
|
2608
2608
|
private getColumnsWithBorders;
|
|
2609
|
+
/**
|
|
2610
|
+
* Get all the rows which contains at least a border
|
|
2611
|
+
*/
|
|
2612
|
+
private getRowsWithBorders;
|
|
2609
2613
|
/**
|
|
2610
2614
|
* Get the range of all the rows in the sheet
|
|
2611
2615
|
*/
|
|
@@ -6255,6 +6259,7 @@ interface TopbarComponent {
|
|
|
6255
6259
|
id: UID;
|
|
6256
6260
|
component: any;
|
|
6257
6261
|
isVisible?: (env: SpreadsheetChildEnv) => boolean;
|
|
6262
|
+
sequence: number;
|
|
6258
6263
|
}
|
|
6259
6264
|
|
|
6260
6265
|
/**
|
|
@@ -9055,6 +9060,8 @@ declare class FindAndReplaceStore extends SpreadsheetStore implements HighlightP
|
|
|
9055
9060
|
private isSearchDirty;
|
|
9056
9061
|
private initialShowFormulaState;
|
|
9057
9062
|
private preserveSelectedMatchIndex;
|
|
9063
|
+
private irreplaceableMatchCount;
|
|
9064
|
+
private notificationStore;
|
|
9058
9065
|
selectedMatchIndex: number | null;
|
|
9059
9066
|
toSearch: string;
|
|
9060
9067
|
toReplace: string;
|
|
@@ -9105,6 +9112,10 @@ declare class FindAndReplaceStore extends SpreadsheetStore implements HighlightP
|
|
|
9105
9112
|
* Apply the replace function to all the matches one time.
|
|
9106
9113
|
*/
|
|
9107
9114
|
replaceAll(): void;
|
|
9115
|
+
/**
|
|
9116
|
+
* Show a warning message based on the number of matches replaced and irreplaceable.
|
|
9117
|
+
*/
|
|
9118
|
+
private showReplaceWarningMessage;
|
|
9108
9119
|
private replaceMatch;
|
|
9109
9120
|
private getSearchableString;
|
|
9110
9121
|
get highlights(): Highlight$1[];
|
|
@@ -10477,6 +10488,7 @@ declare const registries: {
|
|
|
10477
10488
|
};
|
|
10478
10489
|
uuidGenerator: UuidGenerator;
|
|
10479
10490
|
add(name: string, value: Omit<TopbarComponent, "id">): Registry<TopbarComponent>;
|
|
10491
|
+
getAllOrdered(): TopbarComponent[];
|
|
10480
10492
|
content: {
|
|
10481
10493
|
[key: string]: TopbarComponent;
|
|
10482
10494
|
};
|