@odoo/o-spreadsheet 18.5.0-alpha.10 → 18.5.0-alpha.11
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 +322 -122
- package/dist/o-spreadsheet.d.ts +9 -9
- package/dist/o-spreadsheet.esm.js +322 -122
- package/dist/o-spreadsheet.iife.js +322 -122
- package/dist/o-spreadsheet.iife.min.js +404 -402
- package/dist/o_spreadsheet.xml +20 -16
- 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.5.0-alpha.
|
|
6
|
-
* @date 2025-08-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.5.0-alpha.11
|
|
6
|
+
* @date 2025-08-26T10:14:05.357Z
|
|
7
|
+
* @hash b913e49
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, App, blockDom, useState, onPatched, useExternalListener, onWillUpdateProps, onWillStart, onWillPatch, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -723,7 +723,7 @@ function batched(callback) {
|
|
|
723
723
|
/*
|
|
724
724
|
* Concatenate an array of strings.
|
|
725
725
|
*/
|
|
726
|
-
function concat(chars) {
|
|
726
|
+
function concat$1(chars) {
|
|
727
727
|
// ~40% faster than chars.join("")
|
|
728
728
|
let output = "";
|
|
729
729
|
for (let i = 0, len = chars.length; i < len; i++) {
|
|
@@ -1195,7 +1195,7 @@ function rgbaStringToHex(color) {
|
|
|
1195
1195
|
if (alphaHex !== 255) {
|
|
1196
1196
|
vals.push(alphaHex);
|
|
1197
1197
|
}
|
|
1198
|
-
return "#" + concat(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
|
|
1198
|
+
return "#" + concat$1(vals.map((value) => value.toString(16).padStart(2, "0"))).toUpperCase();
|
|
1199
1199
|
}
|
|
1200
1200
|
/**
|
|
1201
1201
|
* RGBA to HEX representation (#RRGGBBAA).
|
|
@@ -5109,6 +5109,9 @@ function parseLiteral(content, locale) {
|
|
|
5109
5109
|
if (content === "") {
|
|
5110
5110
|
return null;
|
|
5111
5111
|
}
|
|
5112
|
+
if (content.includes("\n")) {
|
|
5113
|
+
return content;
|
|
5114
|
+
}
|
|
5112
5115
|
if (isNumber(content, DEFAULT_LOCALE)) {
|
|
5113
5116
|
return parseNumber(content, DEFAULT_LOCALE);
|
|
5114
5117
|
}
|
|
@@ -7317,14 +7320,11 @@ function getPasteZones(target, content) {
|
|
|
7317
7320
|
const width = content[0].length, height = content.length;
|
|
7318
7321
|
return target.map((t) => splitZoneForPaste(t, width, height)).flat();
|
|
7319
7322
|
}
|
|
7320
|
-
function parseOSClipboardContent(content
|
|
7323
|
+
function parseOSClipboardContent(content) {
|
|
7321
7324
|
let spreadsheetContent = undefined;
|
|
7322
7325
|
if (content[ClipboardMIMEType.Html]) {
|
|
7323
7326
|
const htmlDocument = new DOMParser().parseFromString(content[ClipboardMIMEType.Html], "text/html");
|
|
7324
|
-
|
|
7325
|
-
.querySelector("div")
|
|
7326
|
-
?.getAttribute("data-osheet-clipboard");
|
|
7327
|
-
spreadsheetContent = oSheetClipboardData && JSON.parse(oSheetClipboardData);
|
|
7327
|
+
spreadsheetContent = getOSheetDataFromHTML(htmlDocument);
|
|
7328
7328
|
}
|
|
7329
7329
|
const textContent = content[ClipboardMIMEType.PlainText] || "";
|
|
7330
7330
|
let imageBlob = undefined;
|
|
@@ -7343,6 +7343,17 @@ function parseOSClipboardContent(content, clipboardId) {
|
|
|
7343
7343
|
};
|
|
7344
7344
|
return osClipboardContent;
|
|
7345
7345
|
}
|
|
7346
|
+
function getOSheetDataFromHTML(htmlDocument) {
|
|
7347
|
+
const attributes = [...htmlDocument.documentElement.attributes];
|
|
7348
|
+
// Check if it's a Microsoft Office clipboard data (it will have some namespaces defined in the root element)
|
|
7349
|
+
if (attributes.some((attr) => attr.value.includes("microsoft"))) {
|
|
7350
|
+
return undefined;
|
|
7351
|
+
}
|
|
7352
|
+
const oSheetClipboardData = htmlDocument
|
|
7353
|
+
.querySelector("div")
|
|
7354
|
+
?.getAttribute("data-osheet-clipboard");
|
|
7355
|
+
return oSheetClipboardData && JSON.parse(oSheetClipboardData);
|
|
7356
|
+
}
|
|
7346
7357
|
/**
|
|
7347
7358
|
* Applies each clipboard handler to paste its corresponding data into the target.
|
|
7348
7359
|
*/
|
|
@@ -18336,7 +18347,6 @@ function rangeTokenize(formula, locale = DEFAULT_LOCALE) {
|
|
|
18336
18347
|
const functionRegex = /[a-zA-Z0-9\_]+(\.[a-zA-Z0-9\_]+)*/;
|
|
18337
18348
|
const UNARY_OPERATORS_PREFIX = ["-", "+"];
|
|
18338
18349
|
const UNARY_OPERATORS_POSTFIX = ["%"];
|
|
18339
|
-
const ASSOCIATIVE_OPERATORS = ["*", "+", "&"];
|
|
18340
18350
|
class TokenList {
|
|
18341
18351
|
tokens;
|
|
18342
18352
|
currentIndex = 0;
|
|
@@ -18357,8 +18367,8 @@ class TokenList {
|
|
|
18357
18367
|
}
|
|
18358
18368
|
}
|
|
18359
18369
|
const OP_PRIORITY = {
|
|
18370
|
+
"%": 40,
|
|
18360
18371
|
"^": 30,
|
|
18361
|
-
"%": 30,
|
|
18362
18372
|
"*": 20,
|
|
18363
18373
|
"/": 20,
|
|
18364
18374
|
"+": 15,
|
|
@@ -18639,64 +18649,6 @@ function mapAst(ast, fn) {
|
|
|
18639
18649
|
return ast;
|
|
18640
18650
|
}
|
|
18641
18651
|
}
|
|
18642
|
-
/**
|
|
18643
|
-
* Converts an ast formula to the corresponding string
|
|
18644
|
-
*/
|
|
18645
|
-
function astToFormula(ast) {
|
|
18646
|
-
switch (ast.type) {
|
|
18647
|
-
case "FUNCALL":
|
|
18648
|
-
const args = ast.args.map((arg) => astToFormula(arg));
|
|
18649
|
-
return `${ast.value}(${args.join(",")})`;
|
|
18650
|
-
case "NUMBER":
|
|
18651
|
-
return ast.value.toString();
|
|
18652
|
-
case "REFERENCE":
|
|
18653
|
-
return ast.value;
|
|
18654
|
-
case "STRING":
|
|
18655
|
-
return `"${ast.value}"`;
|
|
18656
|
-
case "BOOLEAN":
|
|
18657
|
-
return ast.value ? "TRUE" : "FALSE";
|
|
18658
|
-
case "UNARY_OPERATION":
|
|
18659
|
-
return ast.postfix
|
|
18660
|
-
? leftOperandToFormula(ast) + ast.value
|
|
18661
|
-
: ast.value + rightOperandToFormula(ast);
|
|
18662
|
-
case "BIN_OPERATION":
|
|
18663
|
-
return leftOperandToFormula(ast) + ast.value + rightOperandToFormula(ast);
|
|
18664
|
-
default:
|
|
18665
|
-
return ast.value;
|
|
18666
|
-
}
|
|
18667
|
-
}
|
|
18668
|
-
/**
|
|
18669
|
-
* Convert the left operand of a binary operation to the corresponding string
|
|
18670
|
-
* and enclose the result inside parenthesis if necessary.
|
|
18671
|
-
*/
|
|
18672
|
-
function leftOperandToFormula(operationAST) {
|
|
18673
|
-
const mainOperator = operationAST.value;
|
|
18674
|
-
const leftOperation = "left" in operationAST ? operationAST.left : operationAST.operand;
|
|
18675
|
-
const leftOperator = leftOperation.value;
|
|
18676
|
-
const needParenthesis = leftOperation.type === "BIN_OPERATION" && OP_PRIORITY[leftOperator] < OP_PRIORITY[mainOperator];
|
|
18677
|
-
return needParenthesis ? `(${astToFormula(leftOperation)})` : astToFormula(leftOperation);
|
|
18678
|
-
}
|
|
18679
|
-
/**
|
|
18680
|
-
* Convert the right operand of a binary or unary operation to the corresponding string
|
|
18681
|
-
* and enclose the result inside parenthesis if necessary.
|
|
18682
|
-
*/
|
|
18683
|
-
function rightOperandToFormula(operationAST) {
|
|
18684
|
-
const mainOperator = operationAST.value;
|
|
18685
|
-
const rightOperation = "right" in operationAST ? operationAST.right : operationAST.operand;
|
|
18686
|
-
const rightPriority = OP_PRIORITY[rightOperation.value];
|
|
18687
|
-
const mainPriority = OP_PRIORITY[mainOperator];
|
|
18688
|
-
let needParenthesis = false;
|
|
18689
|
-
if (rightOperation.type !== "BIN_OPERATION") {
|
|
18690
|
-
needParenthesis = false;
|
|
18691
|
-
}
|
|
18692
|
-
else if (rightPriority < mainPriority) {
|
|
18693
|
-
needParenthesis = true;
|
|
18694
|
-
}
|
|
18695
|
-
else if (rightPriority === mainPriority && !ASSOCIATIVE_OPERATORS.includes(mainOperator)) {
|
|
18696
|
-
needParenthesis = true;
|
|
18697
|
-
}
|
|
18698
|
-
return needParenthesis ? `(${astToFormula(rightOperation)})` : astToFormula(rightOperation);
|
|
18699
|
-
}
|
|
18700
18652
|
|
|
18701
18653
|
/**
|
|
18702
18654
|
* Add the following information on tokens:
|
|
@@ -22195,7 +22147,7 @@ function adaptFormulaStringRanges(defaultSheetId, formula, applyChange) {
|
|
|
22195
22147
|
};
|
|
22196
22148
|
}
|
|
22197
22149
|
}
|
|
22198
|
-
return concat(tokens.map((token) => token.value));
|
|
22150
|
+
return concat$1(tokens.map((token) => token.value));
|
|
22199
22151
|
}
|
|
22200
22152
|
function adaptStringRange(defaultSheetId, sheetXC, applyChange) {
|
|
22201
22153
|
const sheetName = splitReference(sheetXC).sheetName;
|
|
@@ -28280,10 +28232,6 @@ class ComboChart extends AbstractChart {
|
|
|
28280
28232
|
};
|
|
28281
28233
|
}
|
|
28282
28234
|
getDefinitionForExcel() {
|
|
28283
|
-
// Excel does not support aggregating labels
|
|
28284
|
-
if (this.aggregated) {
|
|
28285
|
-
return undefined;
|
|
28286
|
-
}
|
|
28287
28235
|
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
28288
28236
|
const definition = this.getDefinition();
|
|
28289
28237
|
return {
|
|
@@ -29485,9 +29433,6 @@ class RadarChart extends AbstractChart {
|
|
|
29485
29433
|
};
|
|
29486
29434
|
}
|
|
29487
29435
|
getDefinitionForExcel() {
|
|
29488
|
-
if (this.aggregated) {
|
|
29489
|
-
return undefined;
|
|
29490
|
-
}
|
|
29491
29436
|
const { dataSets, labelRange } = this.getCommonDataSetAttributesForExcel(this.labelRange, this.dataSets, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
29492
29437
|
const definition = this.getDefinition();
|
|
29493
29438
|
return {
|
|
@@ -29635,10 +29580,6 @@ class ScatterChart extends AbstractChart {
|
|
|
29635
29580
|
return new ScatterChart(definition, this.sheetId, this.getters);
|
|
29636
29581
|
}
|
|
29637
29582
|
getDefinitionForExcel() {
|
|
29638
|
-
// Excel does not support aggregating labels
|
|
29639
|
-
if (this.aggregated) {
|
|
29640
|
-
return undefined;
|
|
29641
|
-
}
|
|
29642
29583
|
const dataSets = this.dataSets
|
|
29643
29584
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
29644
29585
|
.filter((ds) => ds.range !== "");
|
|
@@ -30957,7 +30898,7 @@ function escapeXml(strings, ...expressions) {
|
|
|
30957
30898
|
const value = expressions[i] instanceof XMLString ? expressions[i] : xmlEscape(expressions[i]);
|
|
30958
30899
|
str.push(value + strings[i + 1]);
|
|
30959
30900
|
}
|
|
30960
|
-
return new XMLString(concat(str));
|
|
30901
|
+
return new XMLString(concat$1(str));
|
|
30961
30902
|
}
|
|
30962
30903
|
/**
|
|
30963
30904
|
* Removes the escaped namespace of all the xml tags in the string.
|
|
@@ -32043,10 +31984,10 @@ class ChartDashboardMenuStore extends SpreadsheetStore {
|
|
|
32043
31984
|
const item = chartSubtypeRegistry.get(type);
|
|
32044
31985
|
return {
|
|
32045
31986
|
id: item.chartType,
|
|
32046
|
-
label: item.displayName,
|
|
31987
|
+
label: _t("Show as %(chart_type)s chart", { chart_type: item.displayName.toLowerCase() }),
|
|
32047
31988
|
onClick: () => this.updateType(item.chartType),
|
|
32048
|
-
|
|
32049
|
-
|
|
31989
|
+
class: item.chartType === definition.type ? "active" : "",
|
|
31990
|
+
preview: item.preview,
|
|
32050
31991
|
};
|
|
32051
31992
|
});
|
|
32052
31993
|
}
|
|
@@ -32082,18 +32023,6 @@ class ChartDashboardMenuStore extends SpreadsheetStore {
|
|
|
32082
32023
|
sheetId: this.getters.getActiveSheetId(),
|
|
32083
32024
|
});
|
|
32084
32025
|
}
|
|
32085
|
-
getIconClasses(type) {
|
|
32086
|
-
if (type.includes("bar")) {
|
|
32087
|
-
return "fa fa-bar-chart";
|
|
32088
|
-
}
|
|
32089
|
-
if (type.includes("line")) {
|
|
32090
|
-
return "fa fa-line-chart";
|
|
32091
|
-
}
|
|
32092
|
-
if (type.includes("pie")) {
|
|
32093
|
-
return "fa fa-pie-chart";
|
|
32094
|
-
}
|
|
32095
|
-
return "";
|
|
32096
|
-
}
|
|
32097
32026
|
}
|
|
32098
32027
|
|
|
32099
32028
|
class ChartDashboardMenu extends Component {
|
|
@@ -32132,20 +32061,11 @@ class ChartDashboardMenu extends Component {
|
|
|
32132
32061
|
if (definition.type === "scorecard") {
|
|
32133
32062
|
return undefined;
|
|
32134
32063
|
}
|
|
32135
|
-
|
|
32136
|
-
return {
|
|
32137
|
-
id: "fullScreenChart",
|
|
32138
|
-
label: _t("Exit Full Screen"),
|
|
32139
|
-
iconClass: "fa fa-compress",
|
|
32140
|
-
onClick: () => {
|
|
32141
|
-
this.fullScreenFigureStore.toggleFullScreenChart(figureId);
|
|
32142
|
-
},
|
|
32143
|
-
};
|
|
32144
|
-
}
|
|
32064
|
+
const isFullScreen = this.props.chartId === this.fullScreenFigureStore.fullScreenFigure?.id;
|
|
32145
32065
|
return {
|
|
32146
32066
|
id: "fullScreenChart",
|
|
32147
|
-
label: _t("Full Screen"),
|
|
32148
|
-
|
|
32067
|
+
label: isFullScreen ? _t("Exit Full Screen") : _t("Full Screen"),
|
|
32068
|
+
class: `text-muted fa ${isFullScreen ? "fa-compress" : "fa-expand"}`,
|
|
32149
32069
|
onClick: () => {
|
|
32150
32070
|
this.fullScreenFigureStore.toggleFullScreenChart(figureId);
|
|
32151
32071
|
},
|
|
@@ -34327,7 +34247,7 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
34327
34247
|
if (isFormula(content)) {
|
|
34328
34248
|
const missing = this.getNumberOfMissingParenthesis(this.currentTokens);
|
|
34329
34249
|
if (missing > 0) {
|
|
34330
|
-
content += concat(new Array(missing).fill(")"));
|
|
34250
|
+
content += concat$1(new Array(missing).fill(")"));
|
|
34331
34251
|
}
|
|
34332
34252
|
}
|
|
34333
34253
|
}
|
|
@@ -34379,9 +34299,10 @@ class AbstractComposerStore extends SpreadsheetStore {
|
|
|
34379
34299
|
if (isNewCurrentContent || this.editionMode !== "inactive") {
|
|
34380
34300
|
const locale = this.getters.getLocale();
|
|
34381
34301
|
this.currentTokens = isFormula(text) ? composerTokenize(text, locale) : [];
|
|
34382
|
-
|
|
34302
|
+
const nonSpaceTokensCount = this.currentTokens.filter((token) => token.type !== "SPACE").length;
|
|
34303
|
+
if (nonSpaceTokensCount > 1000) {
|
|
34383
34304
|
if (raise) {
|
|
34384
|
-
this.notificationStore.raiseError(_t("This formula has over
|
|
34305
|
+
this.notificationStore.raiseError(_t("This formula has over 1000 parts. It can't be processed properly, consider splitting it into multiple cells"));
|
|
34385
34306
|
}
|
|
34386
34307
|
}
|
|
34387
34308
|
}
|
|
@@ -34802,6 +34723,8 @@ css /* scss */ `
|
|
|
34802
34723
|
padding-right: 3px;
|
|
34803
34724
|
outline: none;
|
|
34804
34725
|
|
|
34726
|
+
tab-size: 4;
|
|
34727
|
+
|
|
34805
34728
|
p {
|
|
34806
34729
|
margin-bottom: 0px;
|
|
34807
34730
|
|
|
@@ -48652,6 +48575,280 @@ class ClientTag extends Component {
|
|
|
48652
48575
|
}
|
|
48653
48576
|
}
|
|
48654
48577
|
|
|
48578
|
+
const ASSOCIATIVE_OPERATORS = ["*", "+", "&"];
|
|
48579
|
+
/**
|
|
48580
|
+
* Pretty-prints formula ASTs into readable formulas.
|
|
48581
|
+
*
|
|
48582
|
+
* Implements a Wadler-inspired pretty printer:
|
|
48583
|
+
* it converts an AST into a `Doc` structure,
|
|
48584
|
+
* and then chooses between compact (flat) or expanded (with
|
|
48585
|
+
* line breaks and indentation) layouts depending on space.
|
|
48586
|
+
*
|
|
48587
|
+
* References:
|
|
48588
|
+
* - https://lik.ai/blog/how-a-pretty-printer-works/
|
|
48589
|
+
* - Wadler, "A prettier printer": https://homepages.inf.ed.ac.uk/wadler/papers/prettier/prettier.pdf
|
|
48590
|
+
*/
|
|
48591
|
+
function prettify(ast, width = 60) {
|
|
48592
|
+
return "=" + print(astToDoc(ast), width - 1); // width-1 because of the leading '='
|
|
48593
|
+
}
|
|
48594
|
+
/**
|
|
48595
|
+
* A possible line break.
|
|
48596
|
+
* Printed as either space or newline.
|
|
48597
|
+
*/
|
|
48598
|
+
function line() {
|
|
48599
|
+
return { type: "insertLine" };
|
|
48600
|
+
}
|
|
48601
|
+
/**
|
|
48602
|
+
* Increase indentation for a nested block.
|
|
48603
|
+
*/
|
|
48604
|
+
function nest(indentLevel, doc) {
|
|
48605
|
+
return { type: "nest", indentLevel, doc };
|
|
48606
|
+
}
|
|
48607
|
+
/**
|
|
48608
|
+
* Combines multiple docs into a single doc, concatenating them side by side
|
|
48609
|
+
* without any line breaks or indentation.
|
|
48610
|
+
*/
|
|
48611
|
+
function concat(docs) {
|
|
48612
|
+
return { type: "concat", docs };
|
|
48613
|
+
}
|
|
48614
|
+
/**
|
|
48615
|
+
* Marks a document as a unit to be printed "flat" (all on one line)
|
|
48616
|
+
* if it fits within the width, otherwise with line breaks.
|
|
48617
|
+
*/
|
|
48618
|
+
function group(doc) {
|
|
48619
|
+
return chooseBetween(flatten(doc), doc);
|
|
48620
|
+
}
|
|
48621
|
+
/**
|
|
48622
|
+
* Creates a choice between two alternative layouts.
|
|
48623
|
+
* The formatter tries `doc1`; if it does not fit within
|
|
48624
|
+
* the line width, it falls back to `doc2`.
|
|
48625
|
+
*/
|
|
48626
|
+
function chooseBetween(doc1, doc2) {
|
|
48627
|
+
return { type: "chooseBetween", doc1, doc2 };
|
|
48628
|
+
}
|
|
48629
|
+
/**
|
|
48630
|
+
* Flattens a doc into its single-line form.
|
|
48631
|
+
*/
|
|
48632
|
+
function flatten(doc) {
|
|
48633
|
+
if (typeof doc === "string") {
|
|
48634
|
+
return doc;
|
|
48635
|
+
}
|
|
48636
|
+
if (doc.type === "chooseBetween") {
|
|
48637
|
+
// Normally should be "chooseBetween(flatten(doc.doc1), flatten(doc.doc2))",
|
|
48638
|
+
// but this is simplified for performance reasons.
|
|
48639
|
+
return flatten(doc.doc1);
|
|
48640
|
+
}
|
|
48641
|
+
if (doc.type === "concat") {
|
|
48642
|
+
return concat(doc.docs.map(flatten));
|
|
48643
|
+
}
|
|
48644
|
+
if (doc.type === "nest") {
|
|
48645
|
+
return {
|
|
48646
|
+
type: "nest",
|
|
48647
|
+
indentLevel: doc.indentLevel,
|
|
48648
|
+
doc: flatten(doc.doc),
|
|
48649
|
+
};
|
|
48650
|
+
}
|
|
48651
|
+
if (doc.type === "insertLine") {
|
|
48652
|
+
return "";
|
|
48653
|
+
}
|
|
48654
|
+
return doc;
|
|
48655
|
+
}
|
|
48656
|
+
const getIndentationString = memoize(function getIndentationString(indentLevel) {
|
|
48657
|
+
return "\n" + "\t".repeat(indentLevel);
|
|
48658
|
+
});
|
|
48659
|
+
/**
|
|
48660
|
+
* Converts a `Doc` into a string representation that fits within
|
|
48661
|
+
* the specified width.
|
|
48662
|
+
*/
|
|
48663
|
+
function print(doc, width) {
|
|
48664
|
+
return stringify(selectBestLayout(width, doc));
|
|
48665
|
+
}
|
|
48666
|
+
/**
|
|
48667
|
+
* Join all segments of a LinkedString into the final string.
|
|
48668
|
+
*/
|
|
48669
|
+
function stringify(linkedString) {
|
|
48670
|
+
let result = "";
|
|
48671
|
+
while (linkedString) {
|
|
48672
|
+
result += linkedString.subString;
|
|
48673
|
+
linkedString = linkedString.next;
|
|
48674
|
+
}
|
|
48675
|
+
return result;
|
|
48676
|
+
}
|
|
48677
|
+
/**
|
|
48678
|
+
* Layout selection for a `Doc` that fits within the given width.
|
|
48679
|
+
*/
|
|
48680
|
+
function selectBestLayout(width, doc) {
|
|
48681
|
+
const head = {
|
|
48682
|
+
indentLevel: 0,
|
|
48683
|
+
doc,
|
|
48684
|
+
next: null,
|
|
48685
|
+
};
|
|
48686
|
+
return _selectBestLayout(width, 0, head);
|
|
48687
|
+
}
|
|
48688
|
+
function _selectBestLayout(width, currentIndentLevel, head) {
|
|
48689
|
+
if (head === null) {
|
|
48690
|
+
return null;
|
|
48691
|
+
}
|
|
48692
|
+
const { indentLevel, doc, next } = head;
|
|
48693
|
+
if (typeof doc === "string") {
|
|
48694
|
+
return {
|
|
48695
|
+
subString: doc,
|
|
48696
|
+
next: _selectBestLayout(width, currentIndentLevel + doc.length, next),
|
|
48697
|
+
};
|
|
48698
|
+
}
|
|
48699
|
+
if (doc.type === "concat") {
|
|
48700
|
+
let newHead = next;
|
|
48701
|
+
for (let i = doc.docs.length - 1; i >= 0; i--) {
|
|
48702
|
+
newHead = { indentLevel, doc: doc.docs[i], next: newHead };
|
|
48703
|
+
}
|
|
48704
|
+
return _selectBestLayout(width, currentIndentLevel, newHead);
|
|
48705
|
+
}
|
|
48706
|
+
if (doc.type === "nest") {
|
|
48707
|
+
return _selectBestLayout(width, currentIndentLevel, {
|
|
48708
|
+
indentLevel: indentLevel + doc.indentLevel,
|
|
48709
|
+
doc: doc.doc,
|
|
48710
|
+
next,
|
|
48711
|
+
});
|
|
48712
|
+
}
|
|
48713
|
+
if (doc.type === "insertLine") {
|
|
48714
|
+
return {
|
|
48715
|
+
subString: getIndentationString(indentLevel),
|
|
48716
|
+
next: _selectBestLayout(width, indentLevel, next),
|
|
48717
|
+
};
|
|
48718
|
+
}
|
|
48719
|
+
if (doc.type === "chooseBetween") {
|
|
48720
|
+
const head1 = { indentLevel, doc: doc.doc1, next };
|
|
48721
|
+
const possibleLinkedString = _selectBestLayout(width, currentIndentLevel, head1);
|
|
48722
|
+
if (fits(width - currentIndentLevel, possibleLinkedString)) {
|
|
48723
|
+
return possibleLinkedString;
|
|
48724
|
+
}
|
|
48725
|
+
const head2 = { indentLevel, doc: doc.doc2, next };
|
|
48726
|
+
return _selectBestLayout(width, currentIndentLevel, head2);
|
|
48727
|
+
}
|
|
48728
|
+
return null;
|
|
48729
|
+
}
|
|
48730
|
+
/**
|
|
48731
|
+
* Check if a layout fits on a single line within width.
|
|
48732
|
+
*/
|
|
48733
|
+
function fits(width, linkedString) {
|
|
48734
|
+
while (linkedString) {
|
|
48735
|
+
if (linkedString.subString[0] === "\n") {
|
|
48736
|
+
return true;
|
|
48737
|
+
}
|
|
48738
|
+
width -= linkedString.subString.length;
|
|
48739
|
+
if (width < 0)
|
|
48740
|
+
return false;
|
|
48741
|
+
linkedString = linkedString.next;
|
|
48742
|
+
}
|
|
48743
|
+
return true;
|
|
48744
|
+
}
|
|
48745
|
+
function astToDoc(ast) {
|
|
48746
|
+
switch (ast.type) {
|
|
48747
|
+
case "NUMBER":
|
|
48748
|
+
return String(ast.value);
|
|
48749
|
+
case "STRING":
|
|
48750
|
+
return `"${ast.value}"`;
|
|
48751
|
+
case "BOOLEAN":
|
|
48752
|
+
return ast.value ? "TRUE" : "FALSE";
|
|
48753
|
+
case "REFERENCE":
|
|
48754
|
+
return ast.value;
|
|
48755
|
+
case "FUNCALL":
|
|
48756
|
+
const docs = ast.args.map(astToDoc);
|
|
48757
|
+
return wrapInParentheses(concat(docs.map((doc, i) => (i < 1 ? doc : concat([", ", line(), doc])))), ast.value);
|
|
48758
|
+
case "UNARY_OPERATION":
|
|
48759
|
+
const operandDoc = astToDoc(ast.operand);
|
|
48760
|
+
const needParenthesis = ast.postfix
|
|
48761
|
+
? leftOperandNeedsParenthesis(ast)
|
|
48762
|
+
: rightOperandNeedsParenthesis(ast);
|
|
48763
|
+
const finalOperandDoc = needParenthesis ? wrapInParentheses(operandDoc) : operandDoc;
|
|
48764
|
+
return ast.postfix
|
|
48765
|
+
? concat([finalOperandDoc, ast.value])
|
|
48766
|
+
: concat([ast.value, finalOperandDoc]);
|
|
48767
|
+
case "BIN_OPERATION": {
|
|
48768
|
+
const leftDoc = astToDoc(ast.left);
|
|
48769
|
+
const needParenthesisLeftDoc = leftOperandNeedsParenthesis(ast);
|
|
48770
|
+
const finalLeftDoc = needParenthesisLeftDoc ? wrapInParentheses(leftDoc) : leftDoc;
|
|
48771
|
+
const rightDoc = astToDoc(ast.right);
|
|
48772
|
+
const needParenthesisRightDoc = rightOperandNeedsParenthesis(ast);
|
|
48773
|
+
const finalRightDoc = needParenthesisRightDoc ? wrapInParentheses(rightDoc) : rightDoc;
|
|
48774
|
+
const operator = `${ast.value}`;
|
|
48775
|
+
return group(concat([finalLeftDoc, operator, nest(1, concat([line(), finalRightDoc]))]));
|
|
48776
|
+
}
|
|
48777
|
+
case "SYMBOL":
|
|
48778
|
+
return ast.value;
|
|
48779
|
+
case "EMPTY":
|
|
48780
|
+
return "";
|
|
48781
|
+
}
|
|
48782
|
+
}
|
|
48783
|
+
/**
|
|
48784
|
+
* Wraps a `Doc` in parentheses (with optional function name).
|
|
48785
|
+
*/
|
|
48786
|
+
function wrapInParentheses(doc, functionName = undefined) {
|
|
48787
|
+
const docToConcat = ["(", nest(1, concat([line(), doc])), line(), ")"];
|
|
48788
|
+
if (functionName) {
|
|
48789
|
+
docToConcat.unshift(functionName);
|
|
48790
|
+
}
|
|
48791
|
+
return group(concat(docToConcat));
|
|
48792
|
+
}
|
|
48793
|
+
/**
|
|
48794
|
+
* Converts an ast formula to the corresponding string
|
|
48795
|
+
*/
|
|
48796
|
+
function astToFormula(ast) {
|
|
48797
|
+
switch (ast.type) {
|
|
48798
|
+
case "FUNCALL":
|
|
48799
|
+
const args = ast.args.map((arg) => astToFormula(arg));
|
|
48800
|
+
return `${ast.value}(${args.join(",")})`;
|
|
48801
|
+
case "NUMBER":
|
|
48802
|
+
return ast.value.toString();
|
|
48803
|
+
case "REFERENCE":
|
|
48804
|
+
return ast.value;
|
|
48805
|
+
case "STRING":
|
|
48806
|
+
return `"${ast.value}"`;
|
|
48807
|
+
case "BOOLEAN":
|
|
48808
|
+
return ast.value ? "TRUE" : "FALSE";
|
|
48809
|
+
case "UNARY_OPERATION":
|
|
48810
|
+
if (ast.postfix) {
|
|
48811
|
+
const leftOperand = leftOperandNeedsParenthesis(ast)
|
|
48812
|
+
? `(${astToFormula(ast.operand)})`
|
|
48813
|
+
: astToFormula(ast.operand);
|
|
48814
|
+
return leftOperand + ast.value;
|
|
48815
|
+
}
|
|
48816
|
+
const rightOperand = rightOperandNeedsParenthesis(ast)
|
|
48817
|
+
? `(${astToFormula(ast.operand)})`
|
|
48818
|
+
: astToFormula(ast.operand);
|
|
48819
|
+
return ast.value + rightOperand;
|
|
48820
|
+
case "BIN_OPERATION":
|
|
48821
|
+
const leftOperation = leftOperandNeedsParenthesis(ast)
|
|
48822
|
+
? `(${astToFormula(ast.left)})`
|
|
48823
|
+
: astToFormula(ast.left);
|
|
48824
|
+
const rightOperation = rightOperandNeedsParenthesis(ast)
|
|
48825
|
+
? `(${astToFormula(ast.right)})`
|
|
48826
|
+
: astToFormula(ast.right);
|
|
48827
|
+
return leftOperation + ast.value + rightOperation;
|
|
48828
|
+
default:
|
|
48829
|
+
return ast.value;
|
|
48830
|
+
}
|
|
48831
|
+
}
|
|
48832
|
+
function leftOperandNeedsParenthesis(operationAST) {
|
|
48833
|
+
const mainOperator = operationAST.value;
|
|
48834
|
+
const leftOperation = "left" in operationAST ? operationAST.left : operationAST.operand;
|
|
48835
|
+
const leftOperator = leftOperation.value;
|
|
48836
|
+
return (leftOperation.type === "BIN_OPERATION" && OP_PRIORITY[leftOperator] < OP_PRIORITY[mainOperator]);
|
|
48837
|
+
}
|
|
48838
|
+
function rightOperandNeedsParenthesis(operationAST) {
|
|
48839
|
+
const mainOperator = operationAST.value;
|
|
48840
|
+
const rightOperation = "right" in operationAST ? operationAST.right : operationAST.operand;
|
|
48841
|
+
const rightPriority = OP_PRIORITY[rightOperation.value];
|
|
48842
|
+
const mainPriority = OP_PRIORITY[mainOperator];
|
|
48843
|
+
if (rightOperation.type !== "BIN_OPERATION") {
|
|
48844
|
+
return false;
|
|
48845
|
+
}
|
|
48846
|
+
if (rightPriority < mainPriority) {
|
|
48847
|
+
return true;
|
|
48848
|
+
}
|
|
48849
|
+
return rightPriority === mainPriority && !ASSOCIATIVE_OPERATORS.includes(mainOperator);
|
|
48850
|
+
}
|
|
48851
|
+
|
|
48655
48852
|
const CELL_DELETED_MESSAGE = _t("The cell you are trying to edit has been deleted.");
|
|
48656
48853
|
class CellComposerStore extends AbstractComposerStore {
|
|
48657
48854
|
canStopEdition() {
|
|
@@ -48795,7 +48992,10 @@ class CellComposerStore extends AbstractComposerStore {
|
|
|
48795
48992
|
const locale = this.getters.getLocale();
|
|
48796
48993
|
const cell = this.getters.getCell(position);
|
|
48797
48994
|
if (cell?.isFormula) {
|
|
48798
|
-
|
|
48995
|
+
const prettifiedContent = cell.compiledFormula.isBadExpression
|
|
48996
|
+
? cell.content
|
|
48997
|
+
: prettify(parseTokens(cell.compiledFormula.tokens), 80);
|
|
48998
|
+
return localizeFormula(prettifiedContent, locale);
|
|
48799
48999
|
}
|
|
48800
49000
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
48801
49001
|
if (spreader) {
|
|
@@ -61793,10 +61993,10 @@ class CellPlugin extends CorePlugin {
|
|
|
61793
61993
|
*/
|
|
61794
61994
|
getFormulaString(sheetId, tokens, dependencies, useBoundedReference = false) {
|
|
61795
61995
|
if (!dependencies.length) {
|
|
61796
|
-
return concat(tokens.map((token) => token.value));
|
|
61996
|
+
return concat$1(tokens.map((token) => token.value));
|
|
61797
61997
|
}
|
|
61798
61998
|
let rangeIndex = 0;
|
|
61799
|
-
return concat(tokens.map((token) => {
|
|
61999
|
+
return concat$1(tokens.map((token) => {
|
|
61800
62000
|
if (token.type === "REFERENCE") {
|
|
61801
62001
|
const range = dependencies[rangeIndex++];
|
|
61802
62002
|
return this.getters.getRangeString(range, sheetId, { useBoundedReference });
|
|
@@ -62071,11 +62271,11 @@ class FormulaCellWithDependencies {
|
|
|
62071
62271
|
};
|
|
62072
62272
|
}
|
|
62073
62273
|
get content() {
|
|
62074
|
-
return concat(this.compiledFormula.tokens.map((token) => token.value));
|
|
62274
|
+
return concat$1(this.compiledFormula.tokens.map((token) => token.value));
|
|
62075
62275
|
}
|
|
62076
62276
|
get contentWithFixedReferences() {
|
|
62077
62277
|
let rangeIndex = 0;
|
|
62078
|
-
return concat(this.compiledFormula.tokens.map((token) => {
|
|
62278
|
+
return concat$1(this.compiledFormula.tokens.map((token) => {
|
|
62079
62279
|
if (token.type === "REFERENCE") {
|
|
62080
62280
|
const index = rangeIndex++;
|
|
62081
62281
|
return this.getRangeString(this.compiledFormula.dependencies[index], this.sheetId, {
|
|
@@ -81235,7 +81435,7 @@ class SmallBottomBar extends Component {
|
|
|
81235
81435
|
}
|
|
81236
81436
|
}
|
|
81237
81437
|
|
|
81238
|
-
const COMPOSER_MAX_HEIGHT =
|
|
81438
|
+
const COMPOSER_MAX_HEIGHT = 300;
|
|
81239
81439
|
/* svg free of use from https://uxwing.com/formula-fx-icon/ */
|
|
81240
81440
|
const FX_SVG = /*xml*/ `
|
|
81241
81441
|
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 121.8 122.9' width='16' height='16' focusable='false'>
|
|
@@ -87430,6 +87630,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
87430
87630
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CorePlugin, CoreViewPlugin, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
87431
87631
|
|
|
87432
87632
|
|
|
87433
|
-
__info__.version = "18.5.0-alpha.
|
|
87434
|
-
__info__.date = "2025-08-
|
|
87435
|
-
__info__.hash = "
|
|
87633
|
+
__info__.version = "18.5.0-alpha.11";
|
|
87634
|
+
__info__.date = "2025-08-26T10:14:05.357Z";
|
|
87635
|
+
__info__.hash = "b913e49";
|