@odoo/o-spreadsheet 18.0.19 → 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 +172 -107
- package/dist/o-spreadsheet.d.ts +1 -0
- package/dist/o-spreadsheet.esm.js +172 -107
- package/dist/o-spreadsheet.iife.js +172 -107
- package/dist/o-spreadsheet.iife.min.js +380 -378
- package/dist/o_spreadsheet.xml +7 -4
- 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
|
'use strict';
|
|
@@ -1113,7 +1113,10 @@ function rgbaStringToHex(color) {
|
|
|
1113
1113
|
}
|
|
1114
1114
|
else if (stringVals.length === 4) {
|
|
1115
1115
|
const alpha = parseFloat(stringVals.pop() || "1");
|
|
1116
|
-
|
|
1116
|
+
if (isNaN(alpha)) {
|
|
1117
|
+
throw new Error("invalid alpha value");
|
|
1118
|
+
}
|
|
1119
|
+
alphaHex = Math.round(alpha * 255);
|
|
1117
1120
|
}
|
|
1118
1121
|
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
1119
1122
|
if (alphaHex !== 255) {
|
|
@@ -6109,11 +6112,13 @@ function getDefaultCellHeight(ctx, cell, colSize) {
|
|
|
6109
6112
|
if (!cell || (!cell.isFormula && !cell.content)) {
|
|
6110
6113
|
return DEFAULT_CELL_HEIGHT;
|
|
6111
6114
|
}
|
|
6112
|
-
const
|
|
6113
|
-
|
|
6114
|
-
|
|
6115
|
-
|
|
6116
|
-
const
|
|
6115
|
+
const content = cell.isFormula ? "" : cell.content;
|
|
6116
|
+
return getCellContentHeight(ctx, content, cell.style, colSize);
|
|
6117
|
+
}
|
|
6118
|
+
function getCellContentHeight(ctx, content, style, colSize) {
|
|
6119
|
+
const maxWidth = style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
6120
|
+
const numberOfLines = splitTextToWidth(ctx, content, style, maxWidth).length;
|
|
6121
|
+
const fontSize = computeTextFontSizeInPixels(style);
|
|
6117
6122
|
return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
|
|
6118
6123
|
}
|
|
6119
6124
|
function getDefaultContextFont(fontSize, bold = false, italic = false) {
|
|
@@ -6835,7 +6840,7 @@ function isValidLocale(locale) {
|
|
|
6835
6840
|
*/
|
|
6836
6841
|
function canonicalizeNumberContent(content, locale) {
|
|
6837
6842
|
return content.startsWith("=")
|
|
6838
|
-
? canonicalizeFormula
|
|
6843
|
+
? canonicalizeFormula(content, locale)
|
|
6839
6844
|
: canonicalizeNumberLiteral(content, locale);
|
|
6840
6845
|
}
|
|
6841
6846
|
/**
|
|
@@ -6850,7 +6855,7 @@ function canonicalizeNumberContent(content, locale) {
|
|
|
6850
6855
|
*/
|
|
6851
6856
|
function canonicalizeContent(content, locale) {
|
|
6852
6857
|
return content.startsWith("=")
|
|
6853
|
-
? canonicalizeFormula
|
|
6858
|
+
? canonicalizeFormula(content, locale)
|
|
6854
6859
|
: canonicalizeLiteral(content, locale);
|
|
6855
6860
|
}
|
|
6856
6861
|
/**
|
|
@@ -6866,15 +6871,21 @@ function localizeContent(content, locale) {
|
|
|
6866
6871
|
? localizeFormula(content, locale)
|
|
6867
6872
|
: localizeLiteral(content, locale);
|
|
6868
6873
|
}
|
|
6874
|
+
/** Change a number string to its canonical form (en_US locale) */
|
|
6875
|
+
function canonicalizeNumberValue(content, locale) {
|
|
6876
|
+
return content.startsWith("=")
|
|
6877
|
+
? canonicalizeFormula(content, locale)
|
|
6878
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
6879
|
+
}
|
|
6869
6880
|
/** Change a formula to its canonical form (en_US locale) */
|
|
6870
|
-
function canonicalizeFormula
|
|
6871
|
-
return _localizeFormula
|
|
6881
|
+
function canonicalizeFormula(formula, locale) {
|
|
6882
|
+
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
6872
6883
|
}
|
|
6873
6884
|
/** Change a formula from the canonical form to the given locale */
|
|
6874
6885
|
function localizeFormula(formula, locale) {
|
|
6875
|
-
return _localizeFormula
|
|
6886
|
+
return _localizeFormula(formula, DEFAULT_LOCALE, locale);
|
|
6876
6887
|
}
|
|
6877
|
-
function _localizeFormula
|
|
6888
|
+
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
6878
6889
|
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
6879
6890
|
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
6880
6891
|
return formula;
|
|
@@ -7030,37 +7041,6 @@ function getDateTimeFormat(locale) {
|
|
|
7030
7041
|
return locale.dateFormat + " " + locale.timeFormat;
|
|
7031
7042
|
}
|
|
7032
7043
|
|
|
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
7044
|
function boolAnd(args) {
|
|
7065
7045
|
let foundBoolean = false;
|
|
7066
7046
|
let acc = true;
|
|
@@ -8276,13 +8256,6 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8276
8256
|
this.clearClippedZones(content);
|
|
8277
8257
|
const selection = target[0];
|
|
8278
8258
|
this.pasteZone(sheetId, selection.left, selection.top, content.cells, options);
|
|
8279
|
-
this.dispatch("MOVE_RANGES", {
|
|
8280
|
-
target: content.zones,
|
|
8281
|
-
sheetId: content.sheetId,
|
|
8282
|
-
targetSheetId: sheetId,
|
|
8283
|
-
col: selection.left,
|
|
8284
|
-
row: selection.top,
|
|
8285
|
-
});
|
|
8286
8259
|
}
|
|
8287
8260
|
/**
|
|
8288
8261
|
* Clear the clipped zones: remove the cells and clear the formatting
|
|
@@ -8791,14 +8764,15 @@ class MergeClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8791
8764
|
}
|
|
8792
8765
|
merges.push(mergesInRow);
|
|
8793
8766
|
}
|
|
8794
|
-
return { merges };
|
|
8767
|
+
return { merges, sheetId };
|
|
8795
8768
|
}
|
|
8796
8769
|
/**
|
|
8797
8770
|
* Paste the clipboard content in the given target
|
|
8798
8771
|
*/
|
|
8799
8772
|
paste(target, content, options) {
|
|
8800
8773
|
if (options.isCutOperation) {
|
|
8801
|
-
|
|
8774
|
+
const copiedMerges = content.merges.flat().filter(isDefined);
|
|
8775
|
+
this.dispatch("REMOVE_MERGE", { sheetId: content.sheetId, target: copiedMerges });
|
|
8802
8776
|
}
|
|
8803
8777
|
this.pasteFromCopy(target.sheetId, target.zones, content.merges, options);
|
|
8804
8778
|
}
|
|
@@ -8833,6 +8807,27 @@ class MergeClipboardHandler extends AbstractCellClipboardHandler {
|
|
|
8833
8807
|
}
|
|
8834
8808
|
}
|
|
8835
8809
|
|
|
8810
|
+
class ReferenceClipboardHandler extends AbstractCellClipboardHandler {
|
|
8811
|
+
copy(data) {
|
|
8812
|
+
return {
|
|
8813
|
+
zones: data.clippedZones,
|
|
8814
|
+
sheetId: data.sheetId,
|
|
8815
|
+
};
|
|
8816
|
+
}
|
|
8817
|
+
paste(target, content, options) {
|
|
8818
|
+
if (options.isCutOperation) {
|
|
8819
|
+
const selection = target.zones[0];
|
|
8820
|
+
this.dispatch("MOVE_RANGES", {
|
|
8821
|
+
target: content.zones,
|
|
8822
|
+
sheetId: content.sheetId,
|
|
8823
|
+
targetSheetId: target.sheetId,
|
|
8824
|
+
col: selection.left,
|
|
8825
|
+
row: selection.top,
|
|
8826
|
+
});
|
|
8827
|
+
}
|
|
8828
|
+
}
|
|
8829
|
+
}
|
|
8830
|
+
|
|
8836
8831
|
class SheetClipboardHandler extends AbstractCellClipboardHandler {
|
|
8837
8832
|
isPasteAllowed(sheetId, target, content, options) {
|
|
8838
8833
|
if (!("cells" in content)) {
|
|
@@ -9000,7 +8995,8 @@ clipboardHandlersRegistries.cellHandlers
|
|
|
9000
8995
|
.add("merge", MergeClipboardHandler)
|
|
9001
8996
|
.add("border", BorderClipboardHandler)
|
|
9002
8997
|
.add("table", TableClipboardHandler)
|
|
9003
|
-
.add("conditionalFormat", ConditionalFormatClipboardHandler)
|
|
8998
|
+
.add("conditionalFormat", ConditionalFormatClipboardHandler)
|
|
8999
|
+
.add("references", ReferenceClipboardHandler);
|
|
9004
9000
|
|
|
9005
9001
|
function transformZone(zone, executed) {
|
|
9006
9002
|
if (executed.type === "REMOVE_COLUMNS_ROWS") {
|
|
@@ -10055,9 +10051,9 @@ const XLSX_CHART_TYPES = [
|
|
|
10055
10051
|
/** In XLSX color format (no #) */
|
|
10056
10052
|
const AUTO_COLOR = "000000";
|
|
10057
10053
|
const XLSX_ICONSET_MAP = {
|
|
10058
|
-
|
|
10054
|
+
arrows: "3Arrows",
|
|
10059
10055
|
smiley: "3Symbols",
|
|
10060
|
-
|
|
10056
|
+
dots: "3TrafficLights1",
|
|
10061
10057
|
};
|
|
10062
10058
|
const NAMESPACE = {
|
|
10063
10059
|
styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
@@ -10729,6 +10725,7 @@ const ICON_SET_CONVERSION_MAP = {
|
|
|
10729
10725
|
};
|
|
10730
10726
|
/** Map between legend position in XLSX file and human readable position */
|
|
10731
10727
|
const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
|
|
10728
|
+
none: "none",
|
|
10732
10729
|
b: "bottom",
|
|
10733
10730
|
t: "top",
|
|
10734
10731
|
l: "left",
|
|
@@ -13485,7 +13482,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
13485
13482
|
default: "ffffff",
|
|
13486
13483
|
}).asString(),
|
|
13487
13484
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
|
|
13488
|
-
default: "
|
|
13485
|
+
default: "none",
|
|
13489
13486
|
}).asString()],
|
|
13490
13487
|
stacked: barChartGrouping === "stacked",
|
|
13491
13488
|
fontColor: "000000",
|
|
@@ -13519,7 +13516,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
13519
13516
|
default: "ffffff",
|
|
13520
13517
|
}).asString(),
|
|
13521
13518
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(chartElement, "c:legendPos", "val", {
|
|
13522
|
-
default: "
|
|
13519
|
+
default: "none",
|
|
13523
13520
|
}).asString()],
|
|
13524
13521
|
stacked: barChartGrouping === "stacked",
|
|
13525
13522
|
fontColor: "000000",
|
|
@@ -16711,7 +16708,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
|
|
|
16711
16708
|
}
|
|
16712
16709
|
}
|
|
16713
16710
|
else if (dataSets.length === 1) {
|
|
16714
|
-
|
|
16711
|
+
const dataLength = getData(getters, dataSets[0]).length;
|
|
16712
|
+
for (let i = 0; i < dataLength; i++) {
|
|
16715
16713
|
labels.formattedValues.push("");
|
|
16716
16714
|
labels.values.push("");
|
|
16717
16715
|
}
|
|
@@ -25957,11 +25955,26 @@ const SEARCH = {
|
|
|
25957
25955
|
const _searchFor = toString(searchFor).toLowerCase();
|
|
25958
25956
|
const _textToSearch = toString(textToSearch).toLowerCase();
|
|
25959
25957
|
const _startingAt = toNumber(startingAt, this.locale);
|
|
25960
|
-
|
|
25961
|
-
|
|
25958
|
+
if (_textToSearch === "") {
|
|
25959
|
+
return {
|
|
25960
|
+
value: CellErrorType.GenericError,
|
|
25961
|
+
message: _t("The text_to_search must be non-empty."),
|
|
25962
|
+
};
|
|
25963
|
+
}
|
|
25964
|
+
if (_startingAt < 1) {
|
|
25965
|
+
return {
|
|
25966
|
+
value: CellErrorType.GenericError,
|
|
25967
|
+
message: _t("The starting_at (%s) must be greater than or equal to 1.", _startingAt),
|
|
25968
|
+
};
|
|
25969
|
+
}
|
|
25962
25970
|
const result = _textToSearch.indexOf(_searchFor, _startingAt - 1);
|
|
25963
|
-
|
|
25964
|
-
|
|
25971
|
+
if (result === -1) {
|
|
25972
|
+
return {
|
|
25973
|
+
value: CellErrorType.GenericError,
|
|
25974
|
+
message: _t("In [[FUNCTION_NAME]] evaluation, cannot find '%s' within '%s'.", _searchFor, _textToSearch),
|
|
25975
|
+
};
|
|
25976
|
+
}
|
|
25977
|
+
return { value: result + 1 };
|
|
25965
25978
|
},
|
|
25966
25979
|
isExported: true,
|
|
25967
25980
|
};
|
|
@@ -27811,11 +27824,14 @@ function compileTokens(tokens) {
|
|
|
27811
27824
|
}
|
|
27812
27825
|
}
|
|
27813
27826
|
function compileTokensOrThrow(tokens) {
|
|
27814
|
-
const { dependencies,
|
|
27815
|
-
const cacheKey = compilationCacheKey(tokens
|
|
27827
|
+
const { dependencies, literalValues, symbols } = formulaArguments(tokens);
|
|
27828
|
+
const cacheKey = compilationCacheKey(tokens);
|
|
27816
27829
|
if (!functionCache[cacheKey]) {
|
|
27817
27830
|
const ast = parseTokens([...tokens]);
|
|
27818
27831
|
const scope = new Scope();
|
|
27832
|
+
let stringCount = 0;
|
|
27833
|
+
let numberCount = 0;
|
|
27834
|
+
let dependencyCount = 0;
|
|
27819
27835
|
if (ast.type === "BIN_OPERATION" && ast.value === ":") {
|
|
27820
27836
|
throw new BadExpressionError(_t("Invalid formula"));
|
|
27821
27837
|
}
|
|
@@ -27888,16 +27904,15 @@ function compileTokensOrThrow(tokens) {
|
|
|
27888
27904
|
case "BOOLEAN":
|
|
27889
27905
|
return code.return(`{ value: ${ast.value} }`);
|
|
27890
27906
|
case "NUMBER":
|
|
27891
|
-
return code.return(`
|
|
27907
|
+
return code.return(`this.literalValues.numbers[${numberCount++}]`);
|
|
27892
27908
|
case "STRING":
|
|
27893
|
-
return code.return(`
|
|
27909
|
+
return code.return(`this.literalValues.strings[${stringCount++}]`);
|
|
27894
27910
|
case "REFERENCE":
|
|
27895
|
-
const referenceIndex = dependencies.indexOf(ast.value);
|
|
27896
27911
|
if ((!isMeta && ast.value.includes(":")) || hasRange) {
|
|
27897
|
-
return code.return(`range(deps[${
|
|
27912
|
+
return code.return(`range(deps[${dependencyCount++}])`);
|
|
27898
27913
|
}
|
|
27899
27914
|
else {
|
|
27900
|
-
return code.return(`ref(deps[${
|
|
27915
|
+
return code.return(`ref(deps[${dependencyCount++}], ${isMeta ? "true" : "false"})`);
|
|
27901
27916
|
}
|
|
27902
27917
|
case "FUNCALL":
|
|
27903
27918
|
const args = compileFunctionArgs(ast).map((arg) => arg.assignResultToVariable());
|
|
@@ -27929,7 +27944,7 @@ function compileTokensOrThrow(tokens) {
|
|
|
27929
27944
|
const compiledFormula = {
|
|
27930
27945
|
execute: functionCache[cacheKey],
|
|
27931
27946
|
dependencies,
|
|
27932
|
-
|
|
27947
|
+
literalValues,
|
|
27933
27948
|
symbols,
|
|
27934
27949
|
tokens,
|
|
27935
27950
|
isBadExpression: false,
|
|
@@ -27941,33 +27956,31 @@ function compileTokensOrThrow(tokens) {
|
|
|
27941
27956
|
* References, numbers and strings are replaced with placeholders because
|
|
27942
27957
|
* the compiled formula does not depend on their actual value.
|
|
27943
27958
|
* Both `=A1+1+"2"` and `=A2+2+"3"` are compiled to the exact same function.
|
|
27944
|
-
*
|
|
27945
27959
|
* Spaces are also ignored to compute the cache key.
|
|
27946
27960
|
*
|
|
27947
|
-
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|
|
|
27961
|
+
* A formula `=A1+A2+SUM(2, 2, "2")` have the cache key `=|C|+|C|+SUM(|N|,|N|,|S|)`
|
|
27948
27962
|
*/
|
|
27949
|
-
function compilationCacheKey(tokens
|
|
27963
|
+
function compilationCacheKey(tokens) {
|
|
27950
27964
|
let cacheKey = "";
|
|
27951
27965
|
for (const token of tokens) {
|
|
27952
27966
|
switch (token.type) {
|
|
27953
27967
|
case "STRING":
|
|
27954
|
-
|
|
27955
|
-
cacheKey += `|S${constantValues.strings.indexOf(value)}|`;
|
|
27968
|
+
cacheKey += "|S|";
|
|
27956
27969
|
break;
|
|
27957
27970
|
case "NUMBER":
|
|
27958
|
-
cacheKey +=
|
|
27971
|
+
cacheKey += "|N|";
|
|
27959
27972
|
break;
|
|
27960
27973
|
case "REFERENCE":
|
|
27961
27974
|
case "INVALID_REFERENCE":
|
|
27962
27975
|
if (token.value.includes(":")) {
|
|
27963
|
-
cacheKey +=
|
|
27976
|
+
cacheKey += "|R|";
|
|
27964
27977
|
}
|
|
27965
27978
|
else {
|
|
27966
|
-
cacheKey +=
|
|
27979
|
+
cacheKey += "|C|";
|
|
27967
27980
|
}
|
|
27968
27981
|
break;
|
|
27969
27982
|
case "SPACE":
|
|
27970
|
-
|
|
27983
|
+
// ignore spaces
|
|
27971
27984
|
break;
|
|
27972
27985
|
default:
|
|
27973
27986
|
cacheKey += token.value;
|
|
@@ -27980,7 +27993,7 @@ function compilationCacheKey(tokens, dependencies, constantValues, symbols) {
|
|
|
27980
27993
|
* Return formula arguments which are references, strings and numbers.
|
|
27981
27994
|
*/
|
|
27982
27995
|
function formulaArguments(tokens) {
|
|
27983
|
-
const
|
|
27996
|
+
const literalValues = {
|
|
27984
27997
|
numbers: [],
|
|
27985
27998
|
strings: [],
|
|
27986
27999
|
};
|
|
@@ -27994,15 +28007,11 @@ function formulaArguments(tokens) {
|
|
|
27994
28007
|
break;
|
|
27995
28008
|
case "STRING":
|
|
27996
28009
|
const value = removeStringQuotes(token.value);
|
|
27997
|
-
|
|
27998
|
-
constantValues.strings.push(value);
|
|
27999
|
-
}
|
|
28010
|
+
literalValues.strings.push({ value });
|
|
28000
28011
|
break;
|
|
28001
28012
|
case "NUMBER": {
|
|
28002
28013
|
const value = parseNumber(token.value, DEFAULT_LOCALE);
|
|
28003
|
-
|
|
28004
|
-
constantValues.numbers.push(value);
|
|
28005
|
-
}
|
|
28014
|
+
literalValues.numbers.push({ value });
|
|
28006
28015
|
break;
|
|
28007
28016
|
}
|
|
28008
28017
|
case "SYMBOL": {
|
|
@@ -28013,7 +28022,7 @@ function formulaArguments(tokens) {
|
|
|
28013
28022
|
}
|
|
28014
28023
|
return {
|
|
28015
28024
|
dependencies,
|
|
28016
|
-
|
|
28025
|
+
literalValues,
|
|
28017
28026
|
symbols,
|
|
28018
28027
|
};
|
|
28019
28028
|
}
|
|
@@ -28437,7 +28446,7 @@ autoCompleteProviders.add("pivot_group_values", {
|
|
|
28437
28446
|
text,
|
|
28438
28447
|
description: usedLabel,
|
|
28439
28448
|
htmlContent: [{ value: text, color }],
|
|
28440
|
-
fuzzySearchKey:
|
|
28449
|
+
fuzzySearchKey: text + usedLabel,
|
|
28441
28450
|
};
|
|
28442
28451
|
});
|
|
28443
28452
|
},
|
|
@@ -38840,8 +38849,8 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
38840
38849
|
this.updateRangeColor();
|
|
38841
38850
|
}
|
|
38842
38851
|
cancelEdition() {
|
|
38843
|
-
this.cancelEditionAndActivateSheet();
|
|
38844
38852
|
this.resetContent();
|
|
38853
|
+
this.cancelEditionAndActivateSheet();
|
|
38845
38854
|
}
|
|
38846
38855
|
setCurrentContent(content, selection) {
|
|
38847
38856
|
if (selection && !this.isSelectionValid(content.length, selection.start, selection.end)) {
|
|
@@ -38857,8 +38866,8 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
38857
38866
|
switch (cmd.type) {
|
|
38858
38867
|
case "SELECT_FIGURE":
|
|
38859
38868
|
if (cmd.id) {
|
|
38860
|
-
this.cancelEditionAndActivateSheet();
|
|
38861
38869
|
this.resetContent();
|
|
38870
|
+
this.cancelEditionAndActivateSheet();
|
|
38862
38871
|
}
|
|
38863
38872
|
break;
|
|
38864
38873
|
case "START_CHANGE_HIGHLIGHT":
|
|
@@ -44753,6 +44762,7 @@ class RemoveDuplicatesPanel extends owl.Component {
|
|
|
44753
44762
|
columns: {},
|
|
44754
44763
|
});
|
|
44755
44764
|
setup() {
|
|
44765
|
+
this.updateColumns();
|
|
44756
44766
|
owl.onWillUpdateProps(() => this.updateColumns());
|
|
44757
44767
|
}
|
|
44758
44768
|
toggleHasHeader() {
|
|
@@ -46541,8 +46551,8 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
46541
46551
|
const sheetIdExists = !!this.getters.tryGetSheet(this.sheetId);
|
|
46542
46552
|
if (!sheetIdExists && this.editionMode !== "inactive") {
|
|
46543
46553
|
this.sheetId = this.getters.getActiveSheetId();
|
|
46544
|
-
this.cancelEditionAndActivateSheet();
|
|
46545
46554
|
this.resetContent();
|
|
46555
|
+
this.cancelEditionAndActivateSheet();
|
|
46546
46556
|
this.notificationStore.raiseError(CELL_DELETED_MESSAGE);
|
|
46547
46557
|
}
|
|
46548
46558
|
break;
|
|
@@ -62898,12 +62908,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
62898
62908
|
}
|
|
62899
62909
|
break;
|
|
62900
62910
|
case "AUTORESIZE_ROWS":
|
|
62901
|
-
this.
|
|
62902
|
-
elements: cmd.rows,
|
|
62903
|
-
dimension: "ROW",
|
|
62904
|
-
size: null,
|
|
62905
|
-
sheetId: cmd.sheetId,
|
|
62906
|
-
});
|
|
62911
|
+
this.autoResizeRows(cmd.sheetId, cmd.rows);
|
|
62907
62912
|
break;
|
|
62908
62913
|
}
|
|
62909
62914
|
}
|
|
@@ -63068,6 +63073,48 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
63068
63073
|
}
|
|
63069
63074
|
return "Success" /* CommandResult.Success */;
|
|
63070
63075
|
}
|
|
63076
|
+
autoResizeRows(sheetId, rows) {
|
|
63077
|
+
const rowSizes = [];
|
|
63078
|
+
for (const row of rows) {
|
|
63079
|
+
let evaluatedRowSize = 0;
|
|
63080
|
+
for (const cellId of this.getters.getRowCells(sheetId, row)) {
|
|
63081
|
+
const cell = this.getters.getCellById(cellId);
|
|
63082
|
+
if (!cell) {
|
|
63083
|
+
continue;
|
|
63084
|
+
}
|
|
63085
|
+
const position = this.getters.getCellPosition(cell.id);
|
|
63086
|
+
const colSize = this.getters.getColSize(sheetId, position.col);
|
|
63087
|
+
if (cell.isFormula) {
|
|
63088
|
+
const content = this.getters.getEvaluatedCell(position).formattedValue;
|
|
63089
|
+
const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
63090
|
+
if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
|
|
63091
|
+
evaluatedRowSize = evaluatedSize;
|
|
63092
|
+
}
|
|
63093
|
+
}
|
|
63094
|
+
else {
|
|
63095
|
+
const content = cell.content;
|
|
63096
|
+
const dynamicRowSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
63097
|
+
// Only keep the size of evaluated cells if it's bigger than the dynamic row size
|
|
63098
|
+
if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > DEFAULT_CELL_HEIGHT) {
|
|
63099
|
+
evaluatedRowSize = 0;
|
|
63100
|
+
}
|
|
63101
|
+
}
|
|
63102
|
+
}
|
|
63103
|
+
rowSizes.push(evaluatedRowSize || null);
|
|
63104
|
+
}
|
|
63105
|
+
const groupedSizes = new Map(rowSizes.map((size) => [size, []]));
|
|
63106
|
+
for (let i = 0; i < rowSizes.length; i++) {
|
|
63107
|
+
groupedSizes.get(rowSizes[i])?.push(rows[i]);
|
|
63108
|
+
}
|
|
63109
|
+
for (const [size, rows] of groupedSizes) {
|
|
63110
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
63111
|
+
elements: rows,
|
|
63112
|
+
dimension: "ROW",
|
|
63113
|
+
size,
|
|
63114
|
+
sheetId,
|
|
63115
|
+
});
|
|
63116
|
+
}
|
|
63117
|
+
}
|
|
63071
63118
|
}
|
|
63072
63119
|
|
|
63073
63120
|
class TableComputedStylePlugin extends UIPlugin {
|
|
@@ -68243,7 +68290,9 @@ css /* scss */ `
|
|
|
68243
68290
|
border: 1px solid;
|
|
68244
68291
|
font-family: ${DEFAULT_FONT};
|
|
68245
68292
|
|
|
68246
|
-
|
|
68293
|
+
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
68294
|
+
.o-composer:empty:not(:focus):not(.active)::before,
|
|
68295
|
+
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
68247
68296
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
68248
68297
|
position: relative;
|
|
68249
68298
|
top: 20%;
|
|
@@ -71604,10 +71653,14 @@ function addIconSetRule(cf, rule) {
|
|
|
71604
71653
|
continue;
|
|
71605
71654
|
}
|
|
71606
71655
|
const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
|
|
71656
|
+
const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
|
|
71657
|
+
if (isIconSetReversed(rule.icons)) {
|
|
71658
|
+
iconSetAttrs.push(["reverse", "1"]);
|
|
71659
|
+
}
|
|
71607
71660
|
conditionalFormats.push(escapeXml /*xml*/ `
|
|
71608
71661
|
<conditionalFormatting sqref="${range}">
|
|
71609
71662
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
71610
|
-
<iconSet
|
|
71663
|
+
<iconSet ${formatAttributes(iconSetAttrs)}>
|
|
71611
71664
|
${joinXmlNodes(cfValueObjectNodes)}
|
|
71612
71665
|
</iconSet>
|
|
71613
71666
|
</cfRule>
|
|
@@ -71625,9 +71678,21 @@ function commonCfAttributes(cf) {
|
|
|
71625
71678
|
["stopIfTrue", cf.stopIfTrue ? 1 : 0],
|
|
71626
71679
|
];
|
|
71627
71680
|
}
|
|
71681
|
+
function isIconSetReversed(iconSet) {
|
|
71682
|
+
const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
|
|
71683
|
+
return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
|
|
71684
|
+
}
|
|
71628
71685
|
function getIconSet(iconSet) {
|
|
71629
|
-
return XLSX_ICONSET_MAP[
|
|
71630
|
-
|
|
71686
|
+
return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
|
|
71687
|
+
}
|
|
71688
|
+
/**
|
|
71689
|
+
* Partial detection based on "upper" point only.
|
|
71690
|
+
* We support any arbitrary icon in the set, while excel doesn't allow
|
|
71691
|
+
* mixing icons from different types.
|
|
71692
|
+
*/
|
|
71693
|
+
function detectIconsType(iconSet) {
|
|
71694
|
+
const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
|
|
71695
|
+
return type;
|
|
71631
71696
|
}
|
|
71632
71697
|
function thresholdAttributes(threshold, position) {
|
|
71633
71698
|
const type = getExcelThresholdType(threshold.type, position);
|
|
@@ -73551,6 +73616,6 @@ exports.tokenColors = tokenColors;
|
|
|
73551
73616
|
exports.tokenize = tokenize;
|
|
73552
73617
|
|
|
73553
73618
|
|
|
73554
|
-
__info__.version = "18.0.
|
|
73555
|
-
__info__.date = "2025-03-
|
|
73556
|
-
__info__.hash = "
|
|
73619
|
+
__info__.version = "18.0.21";
|
|
73620
|
+
__info__.date = "2025-03-26T12:49:46.872Z";
|
|
73621
|
+
__info__.hash = "c687e1c";
|
package/dist/o-spreadsheet.d.ts
CHANGED