@odoo/o-spreadsheet 17.0.53 → 17.0.55
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 +109 -73
- package/dist/o-spreadsheet.d.ts +1 -0
- package/dist/o-spreadsheet.esm.js +109 -73
- package/dist/o-spreadsheet.iife.js +109 -73
- package/dist/o-spreadsheet.iife.min.js +300 -298
- 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 17.0.
|
|
6
|
-
* @date 2025-03-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.55
|
|
6
|
+
* @date 2025-03-26T12:44:29.690Z
|
|
7
|
+
* @hash c3a4769
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -947,7 +947,10 @@ function rgbaStringToHex(color) {
|
|
|
947
947
|
}
|
|
948
948
|
else if (stringVals.length === 4) {
|
|
949
949
|
const alpha = parseFloat(stringVals.pop() || "1");
|
|
950
|
-
|
|
950
|
+
if (isNaN(alpha)) {
|
|
951
|
+
throw new Error("invalid alpha value");
|
|
952
|
+
}
|
|
953
|
+
alphaHex = Math.round(alpha * 255);
|
|
951
954
|
}
|
|
952
955
|
const vals = stringVals.map((val) => parseInt(val, 10));
|
|
953
956
|
if (alphaHex !== 255) {
|
|
@@ -4492,11 +4495,13 @@ function getDefaultCellHeight(ctx, cell, colSize) {
|
|
|
4492
4495
|
if (!cell || (!cell.isFormula && !cell.content)) {
|
|
4493
4496
|
return DEFAULT_CELL_HEIGHT;
|
|
4494
4497
|
}
|
|
4495
|
-
const
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
const
|
|
4498
|
+
const content = cell.isFormula ? "" : cell.content;
|
|
4499
|
+
return getCellContentHeight(ctx, content, cell.style, colSize);
|
|
4500
|
+
}
|
|
4501
|
+
function getCellContentHeight(ctx, content, style, colSize) {
|
|
4502
|
+
const maxWidth = style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4503
|
+
const numberOfLines = splitTextToWidth(ctx, content, style, maxWidth).length;
|
|
4504
|
+
const fontSize = computeTextFontSizeInPixels(style);
|
|
4500
4505
|
return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
|
|
4501
4506
|
}
|
|
4502
4507
|
const textWidthCache = {};
|
|
@@ -7767,7 +7772,7 @@ function isValidLocale(locale) {
|
|
|
7767
7772
|
*/
|
|
7768
7773
|
function canonicalizeNumberContent(content, locale) {
|
|
7769
7774
|
return content.startsWith("=")
|
|
7770
|
-
? canonicalizeFormula
|
|
7775
|
+
? canonicalizeFormula(content, locale)
|
|
7771
7776
|
: canonicalizeNumberLiteral(content, locale);
|
|
7772
7777
|
}
|
|
7773
7778
|
/**
|
|
@@ -7782,7 +7787,7 @@ function canonicalizeNumberContent(content, locale) {
|
|
|
7782
7787
|
*/
|
|
7783
7788
|
function canonicalizeContent(content, locale) {
|
|
7784
7789
|
return content.startsWith("=")
|
|
7785
|
-
? canonicalizeFormula
|
|
7790
|
+
? canonicalizeFormula(content, locale)
|
|
7786
7791
|
: canonicalizeLiteral(content, locale);
|
|
7787
7792
|
}
|
|
7788
7793
|
/**
|
|
@@ -7798,15 +7803,21 @@ function localizeContent(content, locale) {
|
|
|
7798
7803
|
? localizeFormula(content, locale)
|
|
7799
7804
|
: localizeLiteral(content, locale);
|
|
7800
7805
|
}
|
|
7806
|
+
/** Change a number string to its canonical form (en_US locale) */
|
|
7807
|
+
function canonicalizeNumberValue(content, locale) {
|
|
7808
|
+
return content.startsWith("=")
|
|
7809
|
+
? canonicalizeFormula(content, locale)
|
|
7810
|
+
: canonicalizeNumberLiteral(content, locale);
|
|
7811
|
+
}
|
|
7801
7812
|
/** Change a formula to its canonical form (en_US locale) */
|
|
7802
|
-
function canonicalizeFormula
|
|
7803
|
-
return _localizeFormula
|
|
7813
|
+
function canonicalizeFormula(formula, locale) {
|
|
7814
|
+
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
7804
7815
|
}
|
|
7805
7816
|
/** Change a formula from the canonical form to the given locale */
|
|
7806
7817
|
function localizeFormula(formula, locale) {
|
|
7807
|
-
return _localizeFormula
|
|
7818
|
+
return _localizeFormula(formula, DEFAULT_LOCALE, locale);
|
|
7808
7819
|
}
|
|
7809
|
-
function _localizeFormula
|
|
7820
|
+
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
7810
7821
|
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
7811
7822
|
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
7812
7823
|
return formula;
|
|
@@ -8560,7 +8571,8 @@ function getChartLabelValues(getters, dataSets, labelRange) {
|
|
|
8560
8571
|
}
|
|
8561
8572
|
}
|
|
8562
8573
|
else if (dataSets.length === 1) {
|
|
8563
|
-
|
|
8574
|
+
const dataLength = getData(getters, dataSets[0]).length;
|
|
8575
|
+
for (let i = 0; i < dataLength; i++) {
|
|
8564
8576
|
labels.formattedValues.push("");
|
|
8565
8577
|
labels.values.push("");
|
|
8566
8578
|
}
|
|
@@ -24290,6 +24302,7 @@ class RemoveDuplicatesPanel extends Component {
|
|
|
24290
24302
|
columns: {},
|
|
24291
24303
|
});
|
|
24292
24304
|
setup() {
|
|
24305
|
+
this.updateColumns();
|
|
24293
24306
|
onWillUpdateProps(() => this.updateColumns());
|
|
24294
24307
|
}
|
|
24295
24308
|
toggleHasHeader() {
|
|
@@ -30360,9 +30373,9 @@ const XLSX_CHART_TYPES = [
|
|
|
30360
30373
|
/** In XLSX color format (no #) */
|
|
30361
30374
|
const AUTO_COLOR = "000000";
|
|
30362
30375
|
const XLSX_ICONSET_MAP = {
|
|
30363
|
-
|
|
30376
|
+
arrows: "3Arrows",
|
|
30364
30377
|
smiley: "3Symbols",
|
|
30365
|
-
|
|
30378
|
+
dots: "3TrafficLights1",
|
|
30366
30379
|
};
|
|
30367
30380
|
const NAMESPACE = {
|
|
30368
30381
|
styleSheet: "http://schemas.openxmlformats.org/spreadsheetml/2006/main",
|
|
@@ -30778,6 +30791,7 @@ const ICON_SET_CONVERSION_MAP = {
|
|
|
30778
30791
|
};
|
|
30779
30792
|
/** Map between legend position in XLSX file and human readable position */
|
|
30780
30793
|
const DRAWING_LEGEND_POSITION_CONVERSION_MAP = {
|
|
30794
|
+
none: "none",
|
|
30781
30795
|
b: "bottom",
|
|
30782
30796
|
t: "top",
|
|
30783
30797
|
l: "left",
|
|
@@ -33010,7 +33024,7 @@ class XlsxChartExtractor extends XlsxBaseExtractor {
|
|
|
33010
33024
|
? "right"
|
|
33011
33025
|
: "left",
|
|
33012
33026
|
legendPosition: DRAWING_LEGEND_POSITION_CONVERSION_MAP[this.extractChildAttr(rootChartElement, "c:legendPos", "val", {
|
|
33013
|
-
default: "
|
|
33027
|
+
default: "none",
|
|
33014
33028
|
}).asString()],
|
|
33015
33029
|
stacked: barChartGrouping === "stacked",
|
|
33016
33030
|
fontColor: "000000",
|
|
@@ -45468,12 +45482,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
45468
45482
|
continue;
|
|
45469
45483
|
}
|
|
45470
45484
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
45471
|
-
|
|
45472
|
-
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
45473
|
-
// is not appropriate
|
|
45474
|
-
if (this.operation !== "CUT") {
|
|
45475
|
-
this.pasteMergeIfExist(origin.position, position);
|
|
45476
|
-
}
|
|
45485
|
+
this.pasteMergeIfExist(origin.position, position, this.operation);
|
|
45477
45486
|
this.pasteCell(origin, position, this.operation, clipboardOptions);
|
|
45478
45487
|
if (shouldPasteCF) {
|
|
45479
45488
|
this.pasteCf(origin.position, position);
|
|
@@ -45530,7 +45539,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
45530
45539
|
* If the origin position given is the top left of a merge, merge the target
|
|
45531
45540
|
* position.
|
|
45532
45541
|
*/
|
|
45533
|
-
pasteMergeIfExist(origin, target) {
|
|
45542
|
+
pasteMergeIfExist(origin, target, operation) {
|
|
45534
45543
|
let { sheetId, col, row } = origin;
|
|
45535
45544
|
const { col: mainCellColOrigin, row: mainCellRowOrigin } = this.getters.getMainCellPosition(origin);
|
|
45536
45545
|
if (mainCellColOrigin === col && mainCellRowOrigin === row) {
|
|
@@ -45538,6 +45547,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
45538
45547
|
if (!merge) {
|
|
45539
45548
|
return;
|
|
45540
45549
|
}
|
|
45550
|
+
if (operation === "CUT") {
|
|
45551
|
+
this.dispatch("REMOVE_MERGE", { sheetId, target: [merge] });
|
|
45552
|
+
}
|
|
45541
45553
|
({ sheetId, col, row } = target);
|
|
45542
45554
|
this.dispatch("ADD_MERGE", {
|
|
45543
45555
|
sheetId,
|
|
@@ -47829,12 +47841,7 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
47829
47841
|
}
|
|
47830
47842
|
break;
|
|
47831
47843
|
case "AUTORESIZE_ROWS":
|
|
47832
|
-
this.
|
|
47833
|
-
elements: cmd.rows,
|
|
47834
|
-
dimension: "ROW",
|
|
47835
|
-
size: null,
|
|
47836
|
-
sheetId: cmd.sheetId,
|
|
47837
|
-
});
|
|
47844
|
+
this.autoResizeRows(cmd.sheetId, cmd.rows);
|
|
47838
47845
|
break;
|
|
47839
47846
|
}
|
|
47840
47847
|
}
|
|
@@ -47932,6 +47939,48 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
47932
47939
|
}
|
|
47933
47940
|
return "Success" /* CommandResult.Success */;
|
|
47934
47941
|
}
|
|
47942
|
+
autoResizeRows(sheetId, rows) {
|
|
47943
|
+
const rowSizes = [];
|
|
47944
|
+
for (const row of rows) {
|
|
47945
|
+
let evaluatedRowSize = 0;
|
|
47946
|
+
for (const cellId of this.getters.getRowCells(sheetId, row)) {
|
|
47947
|
+
const cell = this.getters.getCellById(cellId);
|
|
47948
|
+
if (!cell) {
|
|
47949
|
+
continue;
|
|
47950
|
+
}
|
|
47951
|
+
const position = this.getters.getCellPosition(cell.id);
|
|
47952
|
+
const colSize = this.getters.getColSize(sheetId, position.col);
|
|
47953
|
+
if (cell.isFormula) {
|
|
47954
|
+
const content = this.getters.getEvaluatedCell(position).formattedValue;
|
|
47955
|
+
const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
47956
|
+
if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
|
|
47957
|
+
evaluatedRowSize = evaluatedSize;
|
|
47958
|
+
}
|
|
47959
|
+
}
|
|
47960
|
+
else {
|
|
47961
|
+
const content = cell.content;
|
|
47962
|
+
const dynamicRowSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
|
|
47963
|
+
// Only keep the size of evaluated cells if it's bigger than the dynamic row size
|
|
47964
|
+
if (dynamicRowSize >= evaluatedRowSize && dynamicRowSize > DEFAULT_CELL_HEIGHT) {
|
|
47965
|
+
evaluatedRowSize = 0;
|
|
47966
|
+
}
|
|
47967
|
+
}
|
|
47968
|
+
}
|
|
47969
|
+
rowSizes.push(evaluatedRowSize || null);
|
|
47970
|
+
}
|
|
47971
|
+
const groupedSizes = new Map(rowSizes.map((size) => [size, []]));
|
|
47972
|
+
for (let i = 0; i < rowSizes.length; i++) {
|
|
47973
|
+
groupedSizes.get(rowSizes[i])?.push(rows[i]);
|
|
47974
|
+
}
|
|
47975
|
+
for (const [size, rows] of groupedSizes) {
|
|
47976
|
+
this.dispatch("RESIZE_COLUMNS_ROWS", {
|
|
47977
|
+
elements: rows,
|
|
47978
|
+
dimension: "ROW",
|
|
47979
|
+
size,
|
|
47980
|
+
sheetId,
|
|
47981
|
+
});
|
|
47982
|
+
}
|
|
47983
|
+
}
|
|
47935
47984
|
}
|
|
47936
47985
|
|
|
47937
47986
|
const genericRepeatsTransforms = [
|
|
@@ -48581,37 +48630,6 @@ class ClipboardFigureImage {
|
|
|
48581
48630
|
}
|
|
48582
48631
|
}
|
|
48583
48632
|
|
|
48584
|
-
/** Change a number string to its canonical form (en_US locale) */
|
|
48585
|
-
function canonicalizeNumberValue(content, locale) {
|
|
48586
|
-
return content.startsWith("=")
|
|
48587
|
-
? canonicalizeFormula(content, locale)
|
|
48588
|
-
: canonicalizeNumberLiteral(content, locale);
|
|
48589
|
-
}
|
|
48590
|
-
/** Change a formula to its canonical form (en_US locale) */
|
|
48591
|
-
function canonicalizeFormula(formula, locale) {
|
|
48592
|
-
return _localizeFormula(formula, locale, DEFAULT_LOCALE);
|
|
48593
|
-
}
|
|
48594
|
-
function _localizeFormula(formula, fromLocale, toLocale) {
|
|
48595
|
-
if (fromLocale.formulaArgSeparator === toLocale.formulaArgSeparator &&
|
|
48596
|
-
fromLocale.decimalSeparator === toLocale.decimalSeparator) {
|
|
48597
|
-
return formula;
|
|
48598
|
-
}
|
|
48599
|
-
const tokens = tokenize(formula, fromLocale);
|
|
48600
|
-
let localizedFormula = "";
|
|
48601
|
-
for (const token of tokens) {
|
|
48602
|
-
if (token.type === "NUMBER") {
|
|
48603
|
-
localizedFormula += token.value.replace(fromLocale.decimalSeparator, toLocale.decimalSeparator);
|
|
48604
|
-
}
|
|
48605
|
-
else if (token.type === "ARG_SEPARATOR") {
|
|
48606
|
-
localizedFormula += toLocale.formulaArgSeparator;
|
|
48607
|
-
}
|
|
48608
|
-
else {
|
|
48609
|
-
localizedFormula += token.value;
|
|
48610
|
-
}
|
|
48611
|
-
}
|
|
48612
|
-
return localizedFormula;
|
|
48613
|
-
}
|
|
48614
|
-
|
|
48615
48633
|
/** State of the clipboard when copying/cutting from the OS clipboard*/
|
|
48616
48634
|
class ClipboardOsState extends ClipboardCellsAbstractState {
|
|
48617
48635
|
values;
|
|
@@ -49188,8 +49206,8 @@ class EditionPlugin extends UIPlugin {
|
|
|
49188
49206
|
this.colorIndexByRange = {};
|
|
49189
49207
|
break;
|
|
49190
49208
|
case "CANCEL_EDITION":
|
|
49191
|
-
this.cancelEditionAndActivateSheet();
|
|
49192
49209
|
this.resetContent();
|
|
49210
|
+
this.cancelEditionAndActivateSheet();
|
|
49193
49211
|
this.colorIndexByRange = {};
|
|
49194
49212
|
break;
|
|
49195
49213
|
case "SET_CURRENT_CONTENT":
|
|
@@ -49200,8 +49218,8 @@ class EditionPlugin extends UIPlugin {
|
|
|
49200
49218
|
this.replaceSelection(cmd.text);
|
|
49201
49219
|
break;
|
|
49202
49220
|
case "SELECT_FIGURE":
|
|
49203
|
-
this.cancelEditionAndActivateSheet();
|
|
49204
49221
|
this.resetContent();
|
|
49222
|
+
this.cancelEditionAndActivateSheet();
|
|
49205
49223
|
break;
|
|
49206
49224
|
case "ADD_COLUMNS_ROWS":
|
|
49207
49225
|
this.onAddElements(cmd);
|
|
@@ -49244,8 +49262,8 @@ class EditionPlugin extends UIPlugin {
|
|
|
49244
49262
|
const sheetIdExists = !!this.getters.tryGetSheet(this.sheetId);
|
|
49245
49263
|
if (!sheetIdExists && this.mode !== "inactive") {
|
|
49246
49264
|
this.sheetId = this.getters.getActiveSheetId();
|
|
49247
|
-
this.cancelEditionAndActivateSheet();
|
|
49248
49265
|
this.resetContent();
|
|
49266
|
+
this.cancelEditionAndActivateSheet();
|
|
49249
49267
|
this.ui.raiseBlockingErrorUI(CELL_DELETED_MESSAGE);
|
|
49250
49268
|
}
|
|
49251
49269
|
break;
|
|
@@ -53467,7 +53485,9 @@ css /* scss */ `
|
|
|
53467
53485
|
margin-top: -1px;
|
|
53468
53486
|
border: 1px solid;
|
|
53469
53487
|
|
|
53470
|
-
|
|
53488
|
+
/* In readonly we always show the fx icon if the composer is empty, not matter the focus */
|
|
53489
|
+
.o-composer:empty:not(:focus):not(.active)::before,
|
|
53490
|
+
&.o-topbar-composer-readonly .o-composer:empty::before {
|
|
53471
53491
|
content: url("data:image/svg+xml,${encodeURIComponent(FX_SVG)}");
|
|
53472
53492
|
position: relative;
|
|
53473
53493
|
top: 20%;
|
|
@@ -56468,10 +56488,14 @@ function addIconSetRule(cf, rule) {
|
|
|
56468
56488
|
continue;
|
|
56469
56489
|
}
|
|
56470
56490
|
const cfValueObjectNodes = cfValueObject.map((attrs) => escapeXml /*xml*/ `<cfvo ${formatAttributes(attrs)} />`);
|
|
56491
|
+
const iconSetAttrs = [["iconSet", getIconSet(rule.icons)]];
|
|
56492
|
+
if (isIconSetReversed(rule.icons)) {
|
|
56493
|
+
iconSetAttrs.push(["reverse", "1"]);
|
|
56494
|
+
}
|
|
56471
56495
|
conditionalFormats.push(escapeXml /*xml*/ `
|
|
56472
56496
|
<conditionalFormatting sqref="${range}">
|
|
56473
56497
|
<cfRule ${formatAttributes(ruleAttributes)}>
|
|
56474
|
-
<iconSet
|
|
56498
|
+
<iconSet ${formatAttributes(iconSetAttrs)}>
|
|
56475
56499
|
${joinXmlNodes(cfValueObjectNodes)}
|
|
56476
56500
|
</iconSet>
|
|
56477
56501
|
</cfRule>
|
|
@@ -56489,9 +56513,21 @@ function commonCfAttributes(cf) {
|
|
|
56489
56513
|
["stopIfTrue", cf.stopIfTrue ? 1 : 0],
|
|
56490
56514
|
];
|
|
56491
56515
|
}
|
|
56516
|
+
function isIconSetReversed(iconSet) {
|
|
56517
|
+
const defaultIconSet = ICON_SETS[detectIconsType(iconSet)];
|
|
56518
|
+
return iconSet.upper === defaultIconSet.bad && iconSet.lower === defaultIconSet.good;
|
|
56519
|
+
}
|
|
56492
56520
|
function getIconSet(iconSet) {
|
|
56493
|
-
return XLSX_ICONSET_MAP[
|
|
56494
|
-
|
|
56521
|
+
return XLSX_ICONSET_MAP[detectIconsType(iconSet)];
|
|
56522
|
+
}
|
|
56523
|
+
/**
|
|
56524
|
+
* Partial detection based on "upper" point only.
|
|
56525
|
+
* We support any arbitrary icon in the set, while excel doesn't allow
|
|
56526
|
+
* mixing icons from different types.
|
|
56527
|
+
*/
|
|
56528
|
+
function detectIconsType(iconSet) {
|
|
56529
|
+
const type = Object.keys(ICON_SETS).find((type) => Object.values(ICON_SETS[type]).includes(iconSet.upper)) || "dots";
|
|
56530
|
+
return type;
|
|
56495
56531
|
}
|
|
56496
56532
|
function thresholdAttributes(threshold, position) {
|
|
56497
56533
|
const type = getExcelThresholdType(threshold.type, position);
|
|
@@ -58032,6 +58068,6 @@ const constants = {
|
|
|
58032
58068
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
58033
58069
|
|
|
58034
58070
|
|
|
58035
|
-
__info__.version = "17.0.
|
|
58036
|
-
__info__.date = "2025-03-
|
|
58037
|
-
__info__.hash = "
|
|
58071
|
+
__info__.version = "17.0.55";
|
|
58072
|
+
__info__.date = "2025-03-26T12:44:29.690Z";
|
|
58073
|
+
__info__.hash = "c3a4769";
|