@odoo/o-spreadsheet 18.0.20 → 18.0.21
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 +91 -82
- package/dist/o-spreadsheet.esm.js +91 -82
- package/dist/o-spreadsheet.iife.js +91 -82
- package/dist/o-spreadsheet.iife.min.js +58 -56
- package/dist/o_spreadsheet.xml +6 -3
- 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.0.
|
|
6
|
-
* @date 2025-03-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.0.21
|
|
6
|
+
* @date 2025-03-26T12:49:46.872Z
|
|
7
|
+
* @hash c687e1c
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -1111,7 +1111,10 @@ function rgbaStringToHex(color) {
|
|
|
1111
1111
|
}
|
|
1112
1112
|
else if (stringVals.length === 4) {
|
|
1113
1113
|
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1114
|
-
|
|
1114
|
+
if (isNaN(alpha)) {
|
|
1115
|
+
throw new Error("invalid alpha value");
|
|
1116
|
+
}
|
|
1117
|
+
alphaHex = Math.round(alpha * 255);
|
|
1115
1118
|
}
|
|
1116
1119
|
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1117
1120
|
if (alphaHex !== 255) {
|
|
@@ -6835,7 +6838,7 @@ function isValidLocale(locale) {
|
|
|
6835
6838
|
*/
|
|
6836
6839
|
function canonicalizeNumberContent(content, locale) {
|
|
6837
6840
|
return content.startsWith("=")
|
|
6838
|
-
? canonicalizeFormula
|
|
6841
|
+
? canonicalizeFormula(content, locale)
|
|
6839
6842
|
: canonicalizeNumberLiteral(content, locale);
|
|
6840
6843
|
}
|
|
6841
6844
|
/**
|
|
@@ -6850,7 +6853,7 @@ function canonicalizeNumberContent(content, locale) {
|
|
|
6850
6853
|
*/
|
|
6851
6854
|
function canonicalizeContent(content, locale) {
|
|
6852
6855
|
return content.startsWith("=")
|
|
6853
|
-
? canonicalizeFormula
|
|
6856
|
+
? canonicalizeFormula(content, locale)
|
|
6854
6857
|
: canonicalizeLiteral(content, locale);
|
|
6855
6858
|
}
|
|
6856
6859
|
/**
|
|
@@ -6866,15 +6869,21 @@ function localizeContent(content, locale) {
|
|
|
6866
6869
|
? localizeFormula(content, locale)
|
|
6867
6870
|
: localizeLiteral(content, locale);
|
|
6868
6871
|
}
|
|
6872
|
+
/** Change a number string to its canonical form (en_US locale) */
|
|
6873
|
+
function canonicalizeNumberValue(content, locale) {
|
|
6874
|
+
return content.startsWith("=")
|
|
6875
|
+
? canonicalizeFormula(content, locale)
|
|
6876
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
6877
|
+
}
|
|
6869
6878
|
/** Change a formula to its canonical form (en_US locale) */
|
|
6870
|
-
function canonicalizeFormula
|
|
6871
|
-
return _localizeFormula
|
|
6879
|
+
function canonicalizeFormula(formula, locale) {
|
|
6880
|
+
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
6872
6881
|
}
|
|
6873
6882
|
/** Change a formula from the canonical form to the given locale */
|
|
6874
6883
|
function localizeFormula(formula, locale) {
|
|
6875
|
-
return _localizeFormula
|
|
6884
|
+
return _localizeFormula(formula, DEFAULT_LOCALE, locale);
|
|
6876
6885
|
}
|
|
6877
|
-
function _localizeFormula
|
|
6886
|
+
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
6878
6887
|
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
6879
6888
|
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
6880
6889
|
return formula;
|
|
@@ -7030,37 +7039,6 @@ function getDateTimeFormat(locale) {
|
|
|
7030
7039
|
return locale.dateFormat + " " + locale.timeFormat;
|
|
7031
7040
|
}
|
|
7032
7041
|
|
|
7033
|
-
/** Change a number string to its canonical form (en_US locale) */
|
|
7034
|
-
function canonicalizeNumberValue(content, locale) {
|
|
7035
|
-
return content.startsWith("=")
|
|
7036
|
-
? canonicalizeFormula(content, locale)
|
|
7037
|
-
: canonicalizeNumberLiteral(content, locale);
|
|
7038
|
-
}
|
|
7039
|
-
/** Change a formula to its canonical form (en_US locale) */
|
|
7040
|
-
function canonicalizeFormula(formula, locale) {
|
|
7041
|
-
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
7042
|
-
}
|
|
7043
|
-
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
7044
|
-
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
7045
|
-
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
7046
|
-
return formula;
|
|
7047
|
-
}
|
|
7048
|
-
const tokens = tokenize(formula, fromLocale);
|
|
7049
|
-
let localizedFormula = "";
|
|
7050
|
-
for (const token of tokens) {
|
|
7051
|
-
if (token.type === "NUMBER") {
|
|
7052
|
-
localizedFormula += token.value.replace(fromLocale.decimalSeparator, toLocale.decimalSeparator);
|
|
7053
|
-
}
|
|
7054
|
-
else if (token.type === "ARG_SEPARATOR") {
|
|
7055
|
-
localizedFormula += toLocale.formulaArgSeparator;
|
|
7056
|
-
}
|
|
7057
|
-
else {
|
|
7058
|
-
localizedFormula += token.value;
|
|
7059
|
-
}
|
|
7060
|
-
}
|
|
7061
|
-
return localizedFormula;
|
|
7062
|
-
}
|
|
7063
|
-
|
|
7064
7042
|
function boolAnd(args) {
|
|
7065
7043
|
let foundBoolean = false;
|
|
7066
7044
|
let acc = true;
|
|
@@ -10071,9 +10049,9 @@ const XLSX_CHART_TYPES = [
|
|
|
10071
10049
|
/** In XLSX color format (no #) */
|
|
10072
10050
|
const AUTO_COLOR = "000000";
|
|
10073
10051
|
const XLSX_ICONSET_MAP = {
|
|
10074
|
-
|
|
10052
|
+
arrows: "3Arrows",
|
|
10075
10053
|
smiley: "3Symbols",
|
|
10076
|
-
|
|
10054
|
+
dots: "3TrafficLights1",
|
|
10077
10055
|
};
|
|
10078
10056
|
const NAMESPACE = {
|
|
10079
10057
|
styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
@@ -10745,6 +10723,7 @@ const ICON_SET_CONVERSION_MAP = {
|
|
|
10745
10723
|
};
|
|
10746
10724
|
/** Map between legend position in XLSX file and human readable position */
|
|
10747
10725
|
const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
|
|
10726
|
+
none: "none",
|
|
10748
10727
|
b: "bottom",
|
|
10749
10728
|
t: "top",
|
|
10750
10729
|
l: "left",
|
|
@@ -13501,7 +13480,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
13501
13480
|
default: "ffffff",
|
|
13502
13481
|
}).asString(),
|
|
13503
13482
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
|
|
13504
|
-
default: "
|
|
13483
|
+
default: "none",
|
|
13505
13484
|
}).asString()],
|
|
13506
13485
|
stacked: barChartGrouping === "stacked",
|
|
13507
13486
|
fontColor: "000000",
|
|
@@ -13535,7 +13514,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
13535
13514
|
default: "ffffff",
|
|
13536
13515
|
}).asString(),
|
|
13537
13516
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(chartElement, "c:legendPos", "val", {
|
|
13538
|
-
default: "
|
|
13517
|
+
default: "none",
|
|
13539
13518
|
}).asString()],
|
|
13540
13519
|
stacked: barChartGrouping === "stacked",
|
|
13541
13520
|
fontColor: "000000",
|
|
@@ -16727,7 +16706,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
|
|
|
16727
16706
|
}
|
|
16728
16707
|
}
|
|
16729
16708
|
else if (dataSets.length === 1) {
|
|
16730
|
-
|
|
16709
|
+
const dataLength = getData(getters, dataSets[0]).length;
|
|
16710
|
+
for (let i = 0; i < dataLength; i++) {
|
|
16731
16711
|
labels.formattedValues.push("");
|
|
16732
16712
|
labels.values.push("");
|
|
16733
16713
|
}
|
|
@@ -25973,11 +25953,26 @@ const SEARCH = {
|
|
|
25973
25953
|
const _searchFor = toString(searchFor).toLowerCase();
|
|
25974
25954
|
const _textToSearch = toString(textToSearch).toLowerCase();
|
|
25975
25955
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
25976
|
-
|
|
25977
|
-
|
|
25956
|
+
if (_textToSearch === "") {
|
|
25957
|
+
return {
|
|
25958
|
+
value: CellErrorType.GenericError,
|
|
25959
|
+
message: _t("The text_to_search must be non-empty."),
|
|
25960
|
+
};
|
|
25961
|
+
}
|
|
25962
|
+
if (_startingAt < 1) {
|
|
25963
|
+
return {
|
|
25964
|
+
value: CellErrorType.GenericError,
|
|
25965
|
+
message: _t("The starting_at (%s) must be greater than or equal to 1.", _startingAt),
|
|
25966
|
+
};
|
|
25967
|
+
}
|
|
25978
25968
|
const result = _textToSearch.indexOf(_searchFor, _startingAt - 1);
|
|
25979
|
-
|
|
25980
|
-
|
|
25969
|
+
if (result === -1) {
|
|
25970
|
+
return {
|
|
25971
|
+
value: CellErrorType.GenericError,
|
|
25972
|
+
message: _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor, _textToSearch),
|
|
25973
|
+
};
|
|
25974
|
+
}
|
|
25975
|
+
return { value: result + 1 };
|
|
25981
25976
|
},
|
|
25982
25977
|
isExported: true,
|
|
25983
25978
|
};
|
|
@@ -27827,11 +27822,14 @@ function compileTokens(tokens) {
|
|
|
27827
27822
|
}
|
|
27828
27823
|
}
|
|
27829
27824
|
function compileTokensOrThrow(tokens) {
|
|
27830
|
-
const { dependencies,
|
|
27831
|
-
const cacheKey = compilationCacheKey(tokens
|
|
27825
|
+
const { dependencies, literalValues, symbols } = formulaArguments(tokens);
|
|
27826
|
+
const cacheKey = compilationCacheKey(tokens);
|
|
27832
27827
|
if (!functionCache[cacheKey]) {
|
|
27833
27828
|
const ast = parseTokens([...tokens]);
|
|
27834
27829
|
const scope = new Scope();
|
|
27830
|
+
let stringCount = 0;
|
|
27831
|
+
let numberCount = 0;
|
|
27832
|
+
let dependencyCount = 0;
|
|
27835
27833
|
if (ast.type === "BIN_OPERATION" && ast.value === ":") {
|
|
27836
27834
|
throw new BadExpressionError(_t("Invalid formula"));
|
|
27837
27835
|
}
|
|
@@ -27904,16 +27902,15 @@ function compileTokensOrThrow(tokens) {
|
|
|
27904
27902
|
case "BOOLEAN":
|
|
27905
27903
|
return code.return(`{ value: ${ast.value} }`);
|
|
27906
27904
|
case "NUMBER":
|
|
27907
|
-
return code.return(`
|
|
27905
|
+
return code.return(`this.literalValues.numbers[${numberCount++}]`);
|
|
27908
27906
|
case "STRING":
|
|
27909
|
-
return code.return(`
|
|
27907
|
+
return code.return(`this.literalValues.strings[${stringCount++}]`);
|
|
27910
27908
|
case "REFERENCE":
|
|
27911
|
-
const referenceIndex = dependencies.indexOf(ast.value);
|
|
27912
27909
|
if ((!isMeta && ast.value.includes(":")) || hasRange) {
|
|
27913
|
-
return code.return(`range(deps[${
|
|
27910
|
+
return code.return(`range(deps[${dependencyCount++}])`);
|
|
27914
27911
|
}
|
|
27915
27912
|
else {
|
|
27916
|
-
return code.return(`ref(deps[${
|
|
27913
|
+
return code.return(`ref(deps[${dependencyCount++}], ${isMeta ? "true" : "false"})`);
|
|
27917
27914
|
}
|
|
27918
27915
|
case "FUNCALL":
|
|
27919
27916
|
const args = compileFunctionArgs(ast).map((arg) => arg.assignResultToVariable());
|
|
@@ -27945,7 +27942,7 @@ function compileTokensOrThrow(tokens) {
|
|
|
27945
27942
|
const compiledFormula = {
|
|
27946
27943
|
execute: functionCache[cacheKey],
|
|
27947
27944
|
dependencies,
|
|
27948
|
-
|
|
27945
|
+
literalValues,
|
|
27949
27946
|
symbols,
|
|
27950
27947
|
tokens,
|
|
27951
27948
|
isBadExpression: false,
|
|
@@ -27957,33 +27954,31 @@ function compileTokensOrThrow(tokens) {
|
|
|
27957
27954
|
* References, numbers and strings are replaced with placeholders because
|
|
27958
27955
|
* the compiled formula does not depend on their actual value.
|
|
27959
27956
|
* Both `=A1+1+"2"` and `=A2+2+"3"` are compiled to the exact same function.
|
|
27960
|
-
*
|
|
27961
27957
|
* Spaces are also ignored to compute the cache key.
|
|
27962
27958
|
*
|
|
27963
|
-
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|
|
|
27959
|
+
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|C|+|C|+SUM(|N|,|N|,|S|)`
|
|
27964
27960
|
*/
|
|
27965
|
-
function compilationCacheKey(tokens
|
|
27961
|
+
function compilationCacheKey(tokens) {
|
|
27966
27962
|
let cacheKey = "";
|
|
27967
27963
|
for (const token of tokens) {
|
|
27968
27964
|
switch (token.type) {
|
|
27969
27965
|
case "STRING":
|
|
27970
|
-
|
|
27971
|
-
cacheKey += `|S${constantValues.strings.indexOf(value)}|`;
|
|
27966
|
+
cacheKey += "|S|";
|
|
27972
27967
|
break;
|
|
27973
27968
|
case "NUMBER":
|
|
27974
|
-
cacheKey +=
|
|
27969
|
+
cacheKey += "|N|";
|
|
27975
27970
|
break;
|
|
27976
27971
|
case "REFERENCE":
|
|
27977
27972
|
case "INVALID_REFERENCE":
|
|
27978
27973
|
if (token.value.includes(":")) {
|
|
27979
|
-
cacheKey +=
|
|
27974
|
+
cacheKey += "|R|";
|
|
27980
27975
|
}
|
|
27981
27976
|
else {
|
|
27982
|
-
cacheKey +=
|
|
27977
|
+
cacheKey += "|C|";
|
|
27983
27978
|
}
|
|
27984
27979
|
break;
|
|
27985
27980
|
case "SPACE":
|
|
27986
|
-
|
|
27981
|
+
// ignore spaces
|
|
27987
27982
|
break;
|
|
27988
27983
|
default:
|
|
27989
27984
|
cacheKey += token.value;
|
|
@@ -27996,7 +27991,7 @@ function compilationCacheKey(tokens, dependencies, constantValues, symbols) {
|
|
|
27996
27991
|
* Return formula arguments which are references, strings and numbers.
|
|
27997
27992
|
*/
|
|
27998
27993
|
function formulaArguments(tokens) {
|
|
27999
|
-
const
|
|
27994
|
+
const literalValues = {
|
|
28000
27995
|
numbers: [],
|
|
28001
27996
|
strings: [],
|
|
28002
27997
|
};
|
|
@@ -28010,15 +28005,11 @@ function formulaArguments(tokens) {
|
|
|
28010
28005
|
break;
|
|
28011
28006
|
case "STRING":
|
|
28012
28007
|
const value = removeStringQuotes(token.value);
|
|
28013
|
-
|
|
28014
|
-
constantValues.strings.push(value);
|
|
28015
|
-
}
|
|
28008
|
+
literalValues.strings.push({ value });
|
|
28016
28009
|
break;
|
|
28017
28010
|
case "NUMBER": {
|
|
28018
28011
|
const value = parseNumber(token.value, DEFAULT_LOCALE);
|
|
28019
|
-
|
|
28020
|
-
constantValues.numbers.push(value);
|
|
28021
|
-
}
|
|
28012
|
+
literalValues.numbers.push({ value });
|
|
28022
28013
|
break;
|
|
28023
28014
|
}
|
|
28024
28015
|
case "SYMBOL": {
|
|
@@ -28029,7 +28020,7 @@ function formulaArguments(tokens) {
|
|
|
28029
28020
|
}
|
|
28030
28021
|
return {
|
|
28031
28022
|
dependencies,
|
|
28032
|
-
|
|
28023
|
+
literalValues,
|
|
28033
28024
|
symbols,
|
|
28034
28025
|
};
|
|
28035
28026
|
}
|
|
@@ -68297,7 +68288,9 @@ css /* scss */ `
|
|
|
68297
68288
|
border: 1px solid;
|
|
68298
68289
|
font-family: ${DEFAULT_FONT};
|
|
68299
68290
|
|
|
68300
|
-
|
|
68291
|
+
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
68292
|
+
.o-composer:empty:not(:focus):not(.active)::before,
|
|
68293
|
+
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
68301
68294
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
68302
68295
|
position: relative;
|
|
68303
68296
|
top: 20%;
|
|
@@ -71658,10 +71651,14 @@ function addIconSetRule(cf, rule) {
|
|
|
71658
71651
|
continue;
|
|
71659
71652
|
}
|
|
71660
71653
|
const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
|
|
71654
|
+
const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
|
|
71655
|
+
if (isIconSetReversed(rule.icons)) {
|
|
71656
|
+
iconSetAttrs.push(["reverse", "1"]);
|
|
71657
|
+
}
|
|
71661
71658
|
conditionalFormats.push(escapeXml /*xml*/ `
|
|
71662
71659
|
<conditionalFormatting sqref="${range}">
|
|
71663
71660
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
71664
|
-
<iconSet
|
|
71661
|
+
<iconSet ${formatAttributes(iconSetAttrs)}>
|
|
71665
71662
|
${joinXmlNodes(cfValueObjectNodes)}
|
|
71666
71663
|
</iconSet>
|
|
71667
71664
|
</cfRule>
|
|
@@ -71679,9 +71676,21 @@ function commonCfAttributes(cf) {
|
|
|
71679
71676
|
["stopIfTrue", cf.stopIfTrue ? 1 : 0],
|
|
71680
71677
|
];
|
|
71681
71678
|
}
|
|
71679
|
+
function isIconSetReversed(iconSet) {
|
|
71680
|
+
const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
|
|
71681
|
+
return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
|
|
71682
|
+
}
|
|
71682
71683
|
function getIconSet(iconSet) {
|
|
71683
|
-
return XLSX_ICONSET_MAP[
|
|
71684
|
-
|
|
71684
|
+
return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
|
|
71685
|
+
}
|
|
71686
|
+
/**
|
|
71687
|
+
* Partial detection based on "upper" point only.
|
|
71688
|
+
* We support any arbitrary icon in the set, while excel doesn't allow
|
|
71689
|
+
* mixing icons from different types.
|
|
71690
|
+
*/
|
|
71691
|
+
function detectIconsType(iconSet) {
|
|
71692
|
+
const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
|
|
71693
|
+
return type;
|
|
71685
71694
|
}
|
|
71686
71695
|
function thresholdAttributes(threshold, position) {
|
|
71687
71696
|
const type = getExcelThresholdType(threshold.type, position);
|
|
@@ -73562,6 +73571,6 @@ const constants = {
|
|
|
73562
73571
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, 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 };
|
|
73563
73572
|
|
|
73564
73573
|
|
|
73565
|
-
__info__.version = "18.0.
|
|
73566
|
-
__info__.date = "2025-03-
|
|
73567
|
-
__info__.hash = "
|
|
73574
|
+
__info__.version = "18.0.21";
|
|
73575
|
+
__info__.date = "2025-03-26T12:49:46.872Z";
|
|
73576
|
+
__info__.hash = "c687e1c";
|