@odoo/o-spreadsheet 16.4.0-alpha.6 → 16.4.0-alpha.7
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 +249 -97
- package/dist/o-spreadsheet.d.ts +27 -27
- package/dist/o-spreadsheet.esm.js +249 -98
- package/dist/o-spreadsheet.iife.js +249 -97
- package/dist/o-spreadsheet.iife.min.js +248 -245
- package/package.json +1 -1
|
@@ -12592,6 +12592,18 @@ const AND = {
|
|
|
12592
12592
|
isExported: true,
|
|
12593
12593
|
};
|
|
12594
12594
|
// -----------------------------------------------------------------------------
|
|
12595
|
+
// FALSE
|
|
12596
|
+
// -----------------------------------------------------------------------------
|
|
12597
|
+
const FALSE = {
|
|
12598
|
+
description: _lt("Logical value `false`."),
|
|
12599
|
+
args: [],
|
|
12600
|
+
returns: ["BOOLEAN"],
|
|
12601
|
+
compute: function () {
|
|
12602
|
+
return false;
|
|
12603
|
+
},
|
|
12604
|
+
isExported: true,
|
|
12605
|
+
};
|
|
12606
|
+
// -----------------------------------------------------------------------------
|
|
12595
12607
|
// IF
|
|
12596
12608
|
// -----------------------------------------------------------------------------
|
|
12597
12609
|
const IF = {
|
|
@@ -12727,6 +12739,18 @@ const OR = {
|
|
|
12727
12739
|
isExported: true,
|
|
12728
12740
|
};
|
|
12729
12741
|
// -----------------------------------------------------------------------------
|
|
12742
|
+
// TRUE
|
|
12743
|
+
// -----------------------------------------------------------------------------
|
|
12744
|
+
const TRUE = {
|
|
12745
|
+
description: _lt("Logical value `true`."),
|
|
12746
|
+
args: [],
|
|
12747
|
+
returns: ["BOOLEAN"],
|
|
12748
|
+
compute: function () {
|
|
12749
|
+
return true;
|
|
12750
|
+
},
|
|
12751
|
+
isExported: true,
|
|
12752
|
+
};
|
|
12753
|
+
// -----------------------------------------------------------------------------
|
|
12730
12754
|
// XOR
|
|
12731
12755
|
// -----------------------------------------------------------------------------
|
|
12732
12756
|
const XOR = {
|
|
@@ -12753,12 +12777,14 @@ const XOR = {
|
|
|
12753
12777
|
var logical = /*#__PURE__*/Object.freeze({
|
|
12754
12778
|
__proto__: null,
|
|
12755
12779
|
AND: AND,
|
|
12780
|
+
FALSE: FALSE,
|
|
12756
12781
|
IF: IF,
|
|
12757
12782
|
IFERROR: IFERROR,
|
|
12758
12783
|
IFNA: IFNA,
|
|
12759
12784
|
IFS: IFS,
|
|
12760
12785
|
NOT: NOT,
|
|
12761
12786
|
OR: OR,
|
|
12787
|
+
TRUE: TRUE,
|
|
12762
12788
|
XOR: XOR
|
|
12763
12789
|
});
|
|
12764
12790
|
|
|
@@ -13945,7 +13971,6 @@ function indentCode(code) {
|
|
|
13945
13971
|
* is useful for the composer, which needs to be able to work with incomplete
|
|
13946
13972
|
* formulas.
|
|
13947
13973
|
*/
|
|
13948
|
-
const functions$3 = functionRegistry.content;
|
|
13949
13974
|
const POSTFIX_UNARY_OPERATORS = ["%"];
|
|
13950
13975
|
const OPERATORS = "+,-,*,/,:,=,<>,>=,>,<=,<,^,&".split(",").concat(POSTFIX_UNARY_OPERATORS);
|
|
13951
13976
|
function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
@@ -14076,17 +14101,11 @@ function tokenizeSymbol(chars) {
|
|
|
14076
14101
|
}
|
|
14077
14102
|
if (result.length) {
|
|
14078
14103
|
const value = result;
|
|
14079
|
-
const isFunction = value.toUpperCase() in functions$3;
|
|
14080
|
-
if (isFunction) {
|
|
14081
|
-
return { type: "FUNCTION", value };
|
|
14082
|
-
}
|
|
14083
14104
|
const isReference = rangeReference.test(value);
|
|
14084
14105
|
if (isReference) {
|
|
14085
14106
|
return { type: "REFERENCE", value };
|
|
14086
14107
|
}
|
|
14087
|
-
|
|
14088
|
-
return { type: "SYMBOL", value };
|
|
14089
|
-
}
|
|
14108
|
+
return { type: "SYMBOL", value };
|
|
14090
14109
|
}
|
|
14091
14110
|
return null;
|
|
14092
14111
|
}
|
|
@@ -14186,9 +14205,6 @@ function parseOperand(tokens) {
|
|
|
14186
14205
|
return { type: "NUMBER", value: parseNumber(current.value, DEFAULT_LOCALE) };
|
|
14187
14206
|
case "STRING":
|
|
14188
14207
|
return { type: "STRING", value: removeStringQuotes(current.value) };
|
|
14189
|
-
case "FUNCTION":
|
|
14190
|
-
const args = parseFunctionArgs(tokens);
|
|
14191
|
-
return { type: "FUNCALL", value: current.value, args };
|
|
14192
14208
|
case "INVALID_REFERENCE":
|
|
14193
14209
|
throw new InvalidReferenceError();
|
|
14194
14210
|
case "REFERENCE":
|
|
@@ -14205,13 +14221,15 @@ function parseOperand(tokens) {
|
|
|
14205
14221
|
value: current.value,
|
|
14206
14222
|
};
|
|
14207
14223
|
case "SYMBOL":
|
|
14208
|
-
|
|
14209
|
-
|
|
14224
|
+
const value = current.value;
|
|
14225
|
+
const nextToken = tokens[0];
|
|
14226
|
+
if (nextToken?.type === "LEFT_PAREN" && functionRegex.test(current.value)) {
|
|
14227
|
+
const args = parseFunctionArgs(tokens);
|
|
14228
|
+
return { type: "FUNCALL", value: value, args };
|
|
14210
14229
|
}
|
|
14211
|
-
|
|
14212
|
-
|
|
14213
|
-
|
|
14214
|
-
}
|
|
14230
|
+
const upperCaseValue = value.toUpperCase();
|
|
14231
|
+
if (upperCaseValue === "TRUE" || upperCaseValue === "FALSE") {
|
|
14232
|
+
return { type: "BOOLEAN", value: upperCaseValue === "TRUE" };
|
|
14215
14233
|
}
|
|
14216
14234
|
throw new BadExpressionError(_lt("Invalid formula"));
|
|
14217
14235
|
case "LEFT_PAREN":
|
|
@@ -14313,36 +14331,60 @@ function parseTokens(tokens) {
|
|
|
14313
14331
|
* to nodes of a specific type.
|
|
14314
14332
|
* Useful if you want to convert some part of a formula.
|
|
14315
14333
|
*
|
|
14316
|
-
*
|
|
14317
|
-
* ```ts
|
|
14334
|
+
* @example
|
|
14318
14335
|
* convertAstNodes(ast, "FUNCALL", convertFormulaToExcel)
|
|
14319
14336
|
*
|
|
14320
14337
|
* function convertFormulaToExcel(ast: ASTFuncall) {
|
|
14321
14338
|
* // ...
|
|
14322
14339
|
* return modifiedAst
|
|
14323
14340
|
* }
|
|
14324
|
-
* ```
|
|
14325
14341
|
*/
|
|
14326
14342
|
function convertAstNodes(ast, type, fn) {
|
|
14327
|
-
|
|
14328
|
-
ast
|
|
14343
|
+
return mapAst(ast, (ast) => {
|
|
14344
|
+
if (ast.type === type) {
|
|
14345
|
+
return fn(ast);
|
|
14346
|
+
}
|
|
14347
|
+
return ast;
|
|
14348
|
+
});
|
|
14349
|
+
}
|
|
14350
|
+
function iterateAstNodes(ast) {
|
|
14351
|
+
return Array.from(astIterator(ast));
|
|
14352
|
+
}
|
|
14353
|
+
function* astIterator(ast) {
|
|
14354
|
+
yield ast;
|
|
14355
|
+
switch (ast.type) {
|
|
14356
|
+
case "FUNCALL":
|
|
14357
|
+
for (const arg of ast.args) {
|
|
14358
|
+
yield* astIterator(arg);
|
|
14359
|
+
}
|
|
14360
|
+
break;
|
|
14361
|
+
case "UNARY_OPERATION":
|
|
14362
|
+
yield* astIterator(ast.operand);
|
|
14363
|
+
break;
|
|
14364
|
+
case "BIN_OPERATION":
|
|
14365
|
+
yield* astIterator(ast.left);
|
|
14366
|
+
yield* astIterator(ast.right);
|
|
14367
|
+
break;
|
|
14329
14368
|
}
|
|
14369
|
+
}
|
|
14370
|
+
function mapAst(ast, fn) {
|
|
14371
|
+
ast = fn(ast);
|
|
14330
14372
|
switch (ast.type) {
|
|
14331
14373
|
case "FUNCALL":
|
|
14332
14374
|
return {
|
|
14333
14375
|
...ast,
|
|
14334
|
-
args: ast.args.map((child) =>
|
|
14376
|
+
args: ast.args.map((child) => mapAst(child, fn)),
|
|
14335
14377
|
};
|
|
14336
14378
|
case "UNARY_OPERATION":
|
|
14337
14379
|
return {
|
|
14338
14380
|
...ast,
|
|
14339
|
-
operand:
|
|
14381
|
+
operand: mapAst(ast.operand, fn),
|
|
14340
14382
|
};
|
|
14341
14383
|
case "BIN_OPERATION":
|
|
14342
14384
|
return {
|
|
14343
14385
|
...ast,
|
|
14344
|
-
right:
|
|
14345
|
-
left:
|
|
14386
|
+
right: mapAst(ast.right, fn),
|
|
14387
|
+
left: mapAst(ast.left, fn),
|
|
14346
14388
|
};
|
|
14347
14389
|
default:
|
|
14348
14390
|
return ast;
|
|
@@ -14612,6 +14654,9 @@ function compile(formula) {
|
|
|
14612
14654
|
const { args } = ast;
|
|
14613
14655
|
const functionName = ast.value.toUpperCase();
|
|
14614
14656
|
const functionDefinition = functions$2[functionName];
|
|
14657
|
+
if (!functionDefinition) {
|
|
14658
|
+
throw new UnknownFunctionError(ast.value);
|
|
14659
|
+
}
|
|
14615
14660
|
assertEnoughArgs(ast);
|
|
14616
14661
|
const compiledArgs = [];
|
|
14617
14662
|
for (let i = 0; i < args.length; i++) {
|
|
@@ -14870,7 +14915,7 @@ function mapParentFunction(tokens) {
|
|
|
14870
14915
|
functionStarted = "";
|
|
14871
14916
|
}
|
|
14872
14917
|
switch (token.type) {
|
|
14873
|
-
case "
|
|
14918
|
+
case "SYMBOL":
|
|
14874
14919
|
functionStarted = token.value;
|
|
14875
14920
|
break;
|
|
14876
14921
|
case "LEFT_PAREN":
|
|
@@ -14907,6 +14952,17 @@ function composerTokenize(formula, locale) {
|
|
|
14907
14952
|
return mapParentFunction(mapParenthesis(enrichTokens(tokens)));
|
|
14908
14953
|
}
|
|
14909
14954
|
|
|
14955
|
+
const functions$1 = functionRegistry.content;
|
|
14956
|
+
function isExportableToExcel(tokens) {
|
|
14957
|
+
try {
|
|
14958
|
+
const nonExportableFunctions = iterateAstNodes(parseTokens(tokens)).filter((ast) => ast.type === "FUNCALL" && !functions$1[ast.value.toUpperCase()]?.isExported);
|
|
14959
|
+
return nonExportableFunctions.length === 0;
|
|
14960
|
+
}
|
|
14961
|
+
catch (error) {
|
|
14962
|
+
return false;
|
|
14963
|
+
}
|
|
14964
|
+
}
|
|
14965
|
+
|
|
14910
14966
|
function isValidLocale(locale) {
|
|
14911
14967
|
if (!(locale &&
|
|
14912
14968
|
typeof locale === "object" &&
|
|
@@ -17479,8 +17535,14 @@ function getImageMenuRegistry(figureId, onFigureDeleted, env) {
|
|
|
17479
17535
|
id: "reset_size",
|
|
17480
17536
|
name: _lt("Reset size"),
|
|
17481
17537
|
sequence: 4,
|
|
17482
|
-
execute: () => {
|
|
17483
|
-
const
|
|
17538
|
+
execute: async () => {
|
|
17539
|
+
const imagePath = env.model.getters.getImagePath(figureId);
|
|
17540
|
+
const size = env.model.getters.getImageSize(figureId) ??
|
|
17541
|
+
(await env.imageProvider?.getImageOriginalSize(imagePath));
|
|
17542
|
+
if (!env.model.getters.getImageSize(figureId)) {
|
|
17543
|
+
const image = env.model.getters.getImage(figureId);
|
|
17544
|
+
image.size = size;
|
|
17545
|
+
}
|
|
17484
17546
|
const { height, width } = getMaxFigureSize(env.model.getters, size);
|
|
17485
17547
|
env.model.dispatch("UPDATE_FIGURE", {
|
|
17486
17548
|
sheetId: env.model.getters.getActiveSheetId(),
|
|
@@ -23533,7 +23595,7 @@ FunctionDescriptionProvider.props = {
|
|
|
23533
23595
|
argToFocus: Number,
|
|
23534
23596
|
};
|
|
23535
23597
|
|
|
23536
|
-
const functions
|
|
23598
|
+
const functions = functionRegistry.content;
|
|
23537
23599
|
const ASSISTANT_WIDTH = 300;
|
|
23538
23600
|
const selectionIndicatorClass = "selector-flag";
|
|
23539
23601
|
const selectionIndicatorColor = "#a9a9a9";
|
|
@@ -23567,10 +23629,6 @@ css /* scss */ `
|
|
|
23567
23629
|
padding-right: 3px;
|
|
23568
23630
|
outline: none;
|
|
23569
23631
|
|
|
23570
|
-
&.unfocusable {
|
|
23571
|
-
pointer-events: none;
|
|
23572
|
-
}
|
|
23573
|
-
|
|
23574
23632
|
p {
|
|
23575
23633
|
margin-bottom: 0px;
|
|
23576
23634
|
|
|
@@ -23818,7 +23876,10 @@ class Composer extends Component {
|
|
|
23818
23876
|
}
|
|
23819
23877
|
}
|
|
23820
23878
|
showAutocomplete(searchTerm) {
|
|
23821
|
-
|
|
23879
|
+
const searchTermUpperCase = searchTerm.toUpperCase();
|
|
23880
|
+
if (!this.env.model.getters.getCurrentContent().startsWith("=") ||
|
|
23881
|
+
searchTermUpperCase === "TRUE" ||
|
|
23882
|
+
searchTermUpperCase === "FALSE") {
|
|
23822
23883
|
return;
|
|
23823
23884
|
}
|
|
23824
23885
|
this.autoCompleteState.showProvider = true;
|
|
@@ -23936,7 +23997,6 @@ class Composer extends Component {
|
|
|
23936
23997
|
switch (token.type) {
|
|
23937
23998
|
case "OPERATOR":
|
|
23938
23999
|
case "NUMBER":
|
|
23939
|
-
case "FUNCTION":
|
|
23940
24000
|
case "ARG_SEPARATOR":
|
|
23941
24001
|
case "STRING":
|
|
23942
24002
|
result.push({ value: token.value, color: tokenColors[token.type] || "#000" });
|
|
@@ -23946,10 +24006,14 @@ class Composer extends Component {
|
|
|
23946
24006
|
result.push({ value: token.value, color: this.rangeColor(xc, sheetName) || "#000" });
|
|
23947
24007
|
break;
|
|
23948
24008
|
case "SYMBOL":
|
|
23949
|
-
|
|
23950
|
-
|
|
24009
|
+
const value = token.value;
|
|
24010
|
+
const upperCaseValue = value.toUpperCase();
|
|
24011
|
+
if (upperCaseValue === "TRUE" || upperCaseValue === "FALSE") {
|
|
23951
24012
|
result.push({ value: token.value, color: tokenColors.NUMBER });
|
|
23952
24013
|
}
|
|
24014
|
+
else if (upperCaseValue in functionRegistry.content) {
|
|
24015
|
+
result.push({ value: token.value, color: tokenColors.FUNCTION });
|
|
24016
|
+
}
|
|
23953
24017
|
else {
|
|
23954
24018
|
result.push({ value: token.value, color: "#000" });
|
|
23955
24019
|
}
|
|
@@ -24045,25 +24109,28 @@ class Composer extends Component {
|
|
|
24045
24109
|
this.autoCompleteState.showProvider = false;
|
|
24046
24110
|
this.functionDescriptionState.showDescription = false;
|
|
24047
24111
|
if (content.startsWith("=")) {
|
|
24048
|
-
const
|
|
24049
|
-
if (
|
|
24050
|
-
|
|
24051
|
-
|
|
24052
|
-
|
|
24053
|
-
|
|
24054
|
-
|
|
24055
|
-
|
|
24056
|
-
|
|
24057
|
-
|
|
24058
|
-
|
|
24059
|
-
|
|
24060
|
-
|
|
24061
|
-
|
|
24062
|
-
|
|
24063
|
-
|
|
24064
|
-
|
|
24065
|
-
|
|
24066
|
-
|
|
24112
|
+
const token = this.env.model.getters.getTokenAtCursor();
|
|
24113
|
+
if (!token) {
|
|
24114
|
+
return;
|
|
24115
|
+
}
|
|
24116
|
+
if (token.type === "SYMBOL") {
|
|
24117
|
+
// initialize Autocomplete Dropdown
|
|
24118
|
+
this.showAutocomplete(token.value);
|
|
24119
|
+
return;
|
|
24120
|
+
}
|
|
24121
|
+
const tokenContext = token.functionContext;
|
|
24122
|
+
const parentFunction = tokenContext?.parent.toUpperCase();
|
|
24123
|
+
if (tokenContext &&
|
|
24124
|
+
parentFunction &&
|
|
24125
|
+
parentFunction in functions &&
|
|
24126
|
+
token.type !== "UNKNOWN") {
|
|
24127
|
+
// initialize Formula Assistant
|
|
24128
|
+
const description = functions[parentFunction];
|
|
24129
|
+
const argPosition = tokenContext.argPosition;
|
|
24130
|
+
this.functionDescriptionState.functionName = parentFunction;
|
|
24131
|
+
this.functionDescriptionState.functionDescription = description;
|
|
24132
|
+
this.functionDescriptionState.argToFocus = description.getArgToFocus(argPosition + 1) - 1;
|
|
24133
|
+
this.functionDescriptionState.showDescription = true;
|
|
24067
24134
|
}
|
|
24068
24135
|
}
|
|
24069
24136
|
}
|
|
@@ -26763,7 +26830,12 @@ const XLSX_RELATION_TYPE = {
|
|
|
26763
26830
|
};
|
|
26764
26831
|
const RELATIONSHIP_NSR = "http://schemas.openxmlformats.org/officeDocument/2006/relationships";
|
|
26765
26832
|
const HEIGHT_FACTOR = 0.75; // 100px => 75 u
|
|
26766
|
-
|
|
26833
|
+
/**
|
|
26834
|
+
* Excel says its default column width is 8.43 characters (64px)
|
|
26835
|
+
* which makes WIDTH_FACTOR = 0.1317, but it doesn't work well
|
|
26836
|
+
* 0.143 is a value from dev's experiments.
|
|
26837
|
+
*/
|
|
26838
|
+
const WIDTH_FACTOR = 0.143;
|
|
26767
26839
|
/** unit : maximum number of characters a column can hold at the standard font size. What. */
|
|
26768
26840
|
const EXCEL_DEFAULT_COL_WIDTH = 8.43;
|
|
26769
26841
|
/** unit : points */
|
|
@@ -27280,7 +27352,7 @@ const XLSX_INDEXED_COLORS = {
|
|
|
27280
27352
|
64: "000000",
|
|
27281
27353
|
65: "FFFFFF", // system background
|
|
27282
27354
|
};
|
|
27283
|
-
const
|
|
27355
|
+
const IMAGE_MIMETYPE_TO_EXTENSION_MAPPING = {
|
|
27284
27356
|
"image/avif": "avif",
|
|
27285
27357
|
"image/bmp": "bmp",
|
|
27286
27358
|
"image/gif": "gif",
|
|
@@ -27289,6 +27361,17 @@ const IMAGE_MIMETYPE_EXTENSION_MAPPING = {
|
|
|
27289
27361
|
"image/png": "png",
|
|
27290
27362
|
"image/tiff": "tiff",
|
|
27291
27363
|
"image/webp": "webp",
|
|
27364
|
+
};
|
|
27365
|
+
const IMAGE_EXTENSION_TO_MIMETYPE_MAPPING = {
|
|
27366
|
+
avif: "image/avif",
|
|
27367
|
+
bmp: "image/bmp",
|
|
27368
|
+
gif: "image/gif",
|
|
27369
|
+
ico: "image/vnd.microsoft.icon",
|
|
27370
|
+
jpeg: "image/jpeg",
|
|
27371
|
+
png: "image/png",
|
|
27372
|
+
tiff: "image/tiff",
|
|
27373
|
+
webp: "image/webp",
|
|
27374
|
+
jpg: "image/jpeg",
|
|
27292
27375
|
};
|
|
27293
27376
|
|
|
27294
27377
|
/**
|
|
@@ -28092,20 +28175,35 @@ function convertFigure(figure, id, sheetData) {
|
|
|
28092
28175
|
convertEMUToDotValue(figure.anchors[0].rowOffset);
|
|
28093
28176
|
const y2 = getRowPosition(figure.anchors[1].row, sheetData) +
|
|
28094
28177
|
convertEMUToDotValue(figure.anchors[1].rowOffset);
|
|
28095
|
-
const
|
|
28096
|
-
|
|
28097
|
-
|
|
28098
|
-
|
|
28099
|
-
|
|
28100
|
-
|
|
28101
|
-
|
|
28102
|
-
|
|
28103
|
-
|
|
28104
|
-
|
|
28105
|
-
|
|
28106
|
-
|
|
28107
|
-
|
|
28108
|
-
|
|
28178
|
+
const figureData = { id, x: x1, y: y1 };
|
|
28179
|
+
if (isChartData(figure.data)) {
|
|
28180
|
+
return {
|
|
28181
|
+
...figureData,
|
|
28182
|
+
width: x2 - x1,
|
|
28183
|
+
height: y2 - y1,
|
|
28184
|
+
tag: "chart",
|
|
28185
|
+
data: convertChartData(figure.data),
|
|
28186
|
+
};
|
|
28187
|
+
}
|
|
28188
|
+
else if (isImageData(figure.data)) {
|
|
28189
|
+
return {
|
|
28190
|
+
...figureData,
|
|
28191
|
+
width: convertEMUToDotValue(figure.data.size.cx),
|
|
28192
|
+
height: convertEMUToDotValue(figure.data.size.cy),
|
|
28193
|
+
tag: "image",
|
|
28194
|
+
data: {
|
|
28195
|
+
path: figure.data.imageSrc,
|
|
28196
|
+
mimetype: figure.data.mimetype,
|
|
28197
|
+
},
|
|
28198
|
+
};
|
|
28199
|
+
}
|
|
28200
|
+
return undefined;
|
|
28201
|
+
}
|
|
28202
|
+
function isChartData(data) {
|
|
28203
|
+
return "dataSets" in data;
|
|
28204
|
+
}
|
|
28205
|
+
function isImageData(data) {
|
|
28206
|
+
return "imageSrc" in data;
|
|
28109
28207
|
}
|
|
28110
28208
|
function convertChartData(chartData) {
|
|
28111
28209
|
const dataSetsHaveTitle = chartData.dataSets[0].label !== undefined;
|
|
@@ -28812,9 +28910,13 @@ class XlsxBaseExtractor {
|
|
|
28812
28910
|
/**
|
|
28813
28911
|
* Get the list of all the XLSX files in the XLSX file structure
|
|
28814
28912
|
*/
|
|
28815
|
-
|
|
28816
|
-
const
|
|
28817
|
-
|
|
28913
|
+
getListOfXMLFiles() {
|
|
28914
|
+
const XMLFiles = Object.entries(this.xlsxFileStructure)
|
|
28915
|
+
.filter(([key]) => key !== "images")
|
|
28916
|
+
.map(([_, value]) => value)
|
|
28917
|
+
.flat()
|
|
28918
|
+
.filter(isDefined$1);
|
|
28919
|
+
return XMLFiles;
|
|
28818
28920
|
}
|
|
28819
28921
|
/**
|
|
28820
28922
|
* Return an array containing the return value of the given function applied to all the XML elements
|
|
@@ -28986,20 +29088,31 @@ class XlsxBaseExtractor {
|
|
|
28986
29088
|
return color;
|
|
28987
29089
|
}
|
|
28988
29090
|
/**
|
|
28989
|
-
* Returns the
|
|
29091
|
+
* Returns the xml file targeted by a relationship.
|
|
28990
29092
|
*/
|
|
28991
29093
|
getTargetXmlFile(relationship) {
|
|
28992
29094
|
if (!relationship)
|
|
28993
29095
|
throw new Error("Undefined target file");
|
|
28994
|
-
|
|
28995
|
-
target = target.replace("../", "");
|
|
28996
|
-
target = target.replace("./", "");
|
|
29096
|
+
const target = this.processRelationshipTargetName(relationship.target);
|
|
28997
29097
|
// Use "endsWith" because targets are relative paths, and we know the files by their absolute path.
|
|
28998
|
-
const f = this.
|
|
29098
|
+
const f = this.getListOfXMLFiles().find((f) => f.file.fileName.endsWith(target));
|
|
28999
29099
|
if (!f || !f.file)
|
|
29000
29100
|
throw new Error("Cannot find target file");
|
|
29001
29101
|
return f;
|
|
29002
29102
|
}
|
|
29103
|
+
/**
|
|
29104
|
+
* Returns the image parameters targeted by a relationship.
|
|
29105
|
+
*/
|
|
29106
|
+
getTargetImageFile(relationship) {
|
|
29107
|
+
if (!relationship)
|
|
29108
|
+
throw new Error("Undefined target file");
|
|
29109
|
+
const target = this.processRelationshipTargetName(relationship.target);
|
|
29110
|
+
// Use "endsWith" because targets are relative paths, and we know the files by their absolute path.
|
|
29111
|
+
const f = this.xlsxFileStructure.images.find((f) => f.fileName.endsWith(target));
|
|
29112
|
+
if (!f)
|
|
29113
|
+
throw new Error("Cannot find target file");
|
|
29114
|
+
return f;
|
|
29115
|
+
}
|
|
29003
29116
|
/**
|
|
29004
29117
|
* Wrapper of querySelector, but we'll remove the namespaces from the query if areNamespacesIgnored is true.
|
|
29005
29118
|
*
|
|
@@ -29046,6 +29159,10 @@ class XlsxBaseExtractor {
|
|
|
29046
29159
|
return clrScheme[colorId].value;
|
|
29047
29160
|
}
|
|
29048
29161
|
}
|
|
29162
|
+
/** Remove signs of relative path. */
|
|
29163
|
+
processRelationshipTargetName(targetName) {
|
|
29164
|
+
return targetName.replace(/\.+\//, "");
|
|
29165
|
+
}
|
|
29049
29166
|
}
|
|
29050
29167
|
|
|
29051
29168
|
/**
|
|
@@ -29275,15 +29392,16 @@ class XlsxFigureExtractor extends XlsxBaseExtractor {
|
|
|
29275
29392
|
throw new Error("Only twoCellAnchor are supported for xlsx drawings.");
|
|
29276
29393
|
}
|
|
29277
29394
|
const chartElement = this.querySelector(figureElement, "c:chart");
|
|
29278
|
-
|
|
29279
|
-
|
|
29395
|
+
const imageElement = this.querySelector(figureElement, "a:blip");
|
|
29396
|
+
if (!chartElement && !imageElement) {
|
|
29397
|
+
throw new Error("Only chart and image figures are currently supported.");
|
|
29280
29398
|
}
|
|
29281
29399
|
return {
|
|
29282
29400
|
anchors: [
|
|
29283
29401
|
this.extractFigureAnchor("xdr:from", figureElement),
|
|
29284
29402
|
this.extractFigureAnchor("xdr:to", figureElement),
|
|
29285
29403
|
],
|
|
29286
|
-
data: this.extractChart(chartElement),
|
|
29404
|
+
data: chartElement ? this.extractChart(chartElement) : this.extractImage(figureElement),
|
|
29287
29405
|
};
|
|
29288
29406
|
});
|
|
29289
29407
|
}
|
|
@@ -29308,6 +29426,24 @@ class XlsxFigureExtractor extends XlsxBaseExtractor {
|
|
|
29308
29426
|
}
|
|
29309
29427
|
return chartDefinition;
|
|
29310
29428
|
}
|
|
29429
|
+
extractImage(figureElement) {
|
|
29430
|
+
const imageElement = this.querySelector(figureElement, "a:blip");
|
|
29431
|
+
const imageId = this.extractAttr(imageElement, "r:embed", { required: true }).asString();
|
|
29432
|
+
const image = this.getTargetImageFile(this.relationships[imageId]);
|
|
29433
|
+
if (!image) {
|
|
29434
|
+
throw new Error("Unable to extract image");
|
|
29435
|
+
}
|
|
29436
|
+
const shapePropertyElement = this.querySelector(figureElement, "a:xfrm");
|
|
29437
|
+
const extension = image.fileName.split(".").at(-1);
|
|
29438
|
+
return {
|
|
29439
|
+
imageSrc: image.imageSrc,
|
|
29440
|
+
mimetype: extension ? IMAGE_EXTENSION_TO_MIMETYPE_MAPPING[extension] : undefined,
|
|
29441
|
+
size: {
|
|
29442
|
+
cx: this.extractChildAttr(shapePropertyElement, "a:ext", "cx", { required: true }).asNum(),
|
|
29443
|
+
cy: this.extractChildAttr(shapePropertyElement, "a:ext", "cy", { required: true }).asNum(),
|
|
29444
|
+
},
|
|
29445
|
+
};
|
|
29446
|
+
}
|
|
29311
29447
|
}
|
|
29312
29448
|
|
|
29313
29449
|
/**
|
|
@@ -29877,14 +30013,22 @@ const EXCEL_IMPORT_VERSION = 12;
|
|
|
29877
30013
|
class XlsxReader {
|
|
29878
30014
|
warningManager;
|
|
29879
30015
|
xmls;
|
|
30016
|
+
images;
|
|
29880
30017
|
constructor(files) {
|
|
29881
30018
|
this.warningManager = new XLSXImportWarningManager();
|
|
29882
30019
|
this.xmls = {};
|
|
30020
|
+
this.images = [];
|
|
29883
30021
|
for (let key of Object.keys(files)) {
|
|
29884
30022
|
// Random files can be in xlsx (like a bin file for printer settings)
|
|
29885
30023
|
if (key.endsWith(".xml") || key.endsWith(".rels")) {
|
|
29886
30024
|
this.xmls[key] = parseXML(new XMLString(files[key]));
|
|
29887
30025
|
}
|
|
30026
|
+
else if (key.includes("media/image")) {
|
|
30027
|
+
this.images.push({
|
|
30028
|
+
fileName: key,
|
|
30029
|
+
imageSrc: files[key]["imageSrc"],
|
|
30030
|
+
});
|
|
30031
|
+
}
|
|
29888
30032
|
}
|
|
29889
30033
|
}
|
|
29890
30034
|
convertXlsx() {
|
|
@@ -29937,6 +30081,7 @@ class XlsxReader {
|
|
|
29937
30081
|
tables: getXLSXFilesOfType(CONTENT_TYPES.table, this.xmls),
|
|
29938
30082
|
pivots: getXLSXFilesOfType(CONTENT_TYPES.pivot, this.xmls),
|
|
29939
30083
|
externalLinks: getXLSXFilesOfType(CONTENT_TYPES.externalLink, this.xmls),
|
|
30084
|
+
images: this.images,
|
|
29940
30085
|
};
|
|
29941
30086
|
if (!xlsxFileStructure.workbook.rels) {
|
|
29942
30087
|
throw Error(_lt("Cannot find workbook relations file"));
|
|
@@ -33087,7 +33232,7 @@ class ImagePlugin extends CorePlugin {
|
|
|
33087
33232
|
handle(cmd) {
|
|
33088
33233
|
switch (cmd.type) {
|
|
33089
33234
|
case "CREATE_IMAGE":
|
|
33090
|
-
this.
|
|
33235
|
+
this.addImage(cmd.figureId, cmd.sheetId, cmd.position, cmd.size);
|
|
33091
33236
|
this.history.update("images", cmd.sheetId, cmd.figureId, cmd.definition);
|
|
33092
33237
|
this.syncedImages.add(cmd.definition.path);
|
|
33093
33238
|
break;
|
|
@@ -33151,7 +33296,7 @@ class ImagePlugin extends CorePlugin {
|
|
|
33151
33296
|
// ---------------------------------------------------------------------------
|
|
33152
33297
|
// Private
|
|
33153
33298
|
// ---------------------------------------------------------------------------
|
|
33154
|
-
|
|
33299
|
+
addImage(id, sheetId, position, size) {
|
|
33155
33300
|
const figure = {
|
|
33156
33301
|
id,
|
|
33157
33302
|
x: position.x,
|
|
@@ -35658,7 +35803,6 @@ class PositionBitsEncoder {
|
|
|
35658
35803
|
}
|
|
35659
35804
|
}
|
|
35660
35805
|
|
|
35661
|
-
const functions = functionRegistry.content;
|
|
35662
35806
|
//#region
|
|
35663
35807
|
// ---------------------------------------------------------------------------
|
|
35664
35808
|
// INTRODUCTION
|
|
@@ -35880,9 +36024,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
35880
36024
|
let isExported = true;
|
|
35881
36025
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
35882
36026
|
if (formulaCell) {
|
|
35883
|
-
isExported = formulaCell.compiledFormula.tokens
|
|
35884
|
-
.filter((tk) => tk.type === "FUNCTION")
|
|
35885
|
-
.every((tk) => functions[tk.value.toUpperCase()].isExported);
|
|
36027
|
+
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
35886
36028
|
isFormula = isExported;
|
|
35887
36029
|
if (!isExported) {
|
|
35888
36030
|
newContent = value.toString();
|
|
@@ -44288,7 +44430,7 @@ class ImageProvider {
|
|
|
44288
44430
|
async requestImage() {
|
|
44289
44431
|
const file = await this.getImageFromUser();
|
|
44290
44432
|
const path = await this.fileStore.upload(file);
|
|
44291
|
-
const size = await this.
|
|
44433
|
+
const size = await this.getImageOriginalSize(path);
|
|
44292
44434
|
return { path, size, mimetype: file.type };
|
|
44293
44435
|
}
|
|
44294
44436
|
getImageFromUser() {
|
|
@@ -44307,7 +44449,7 @@ class ImageProvider {
|
|
|
44307
44449
|
input.click();
|
|
44308
44450
|
});
|
|
44309
44451
|
}
|
|
44310
|
-
|
|
44452
|
+
getImageOriginalSize(path) {
|
|
44311
44453
|
return new Promise((resolve, reject) => {
|
|
44312
44454
|
const image = new Image();
|
|
44313
44455
|
image.src = path;
|
|
@@ -45792,6 +45934,10 @@ css /* scss */ `
|
|
|
45792
45934
|
top: 20%;
|
|
45793
45935
|
}
|
|
45794
45936
|
}
|
|
45937
|
+
|
|
45938
|
+
.user-select-text {
|
|
45939
|
+
user-select: text;
|
|
45940
|
+
}
|
|
45795
45941
|
`;
|
|
45796
45942
|
class TopBarComposer extends Component {
|
|
45797
45943
|
static template = "o-spreadsheet-TopBarComposer";
|
|
@@ -48830,6 +48976,8 @@ function createImageDrawing(figure, sheet, imageRelId) {
|
|
|
48830
48976
|
["name", `Image ${imageId}`],
|
|
48831
48977
|
["title", "Image"],
|
|
48832
48978
|
];
|
|
48979
|
+
const cx = convertDotValueToEMU(figure.width);
|
|
48980
|
+
const cy = convertDotValueToEMU(figure.height);
|
|
48833
48981
|
return escapeXml /*xml*/ `
|
|
48834
48982
|
<xdr:twoCellAnchor editAs="oneCell">
|
|
48835
48983
|
<xdr:from>
|
|
@@ -48856,6 +49004,9 @@ function createImageDrawing(figure, sheet, imageRelId) {
|
|
|
48856
49004
|
</a:stretch>
|
|
48857
49005
|
</xdr:blipFill>
|
|
48858
49006
|
<xdr:spPr>
|
|
49007
|
+
<a:xfrm>
|
|
49008
|
+
<a:ext cx="${cx}" cy="${cy}" />
|
|
49009
|
+
</a:xfrm>
|
|
48859
49010
|
<a:prstGeom prst="rect">
|
|
48860
49011
|
<a:avLst/>
|
|
48861
49012
|
</a:prstGeom>
|
|
@@ -49375,7 +49526,7 @@ function createWorksheets(data, construct) {
|
|
|
49375
49526
|
const mimeType = image.data.mimetype;
|
|
49376
49527
|
if (mimeType === undefined)
|
|
49377
49528
|
continue;
|
|
49378
|
-
const extension =
|
|
49529
|
+
const extension = IMAGE_MIMETYPE_TO_EXTENSION_MAPPING[mimeType];
|
|
49379
49530
|
// only support exporting images with mimetypes specified in the mapping
|
|
49380
49531
|
if (extension === undefined)
|
|
49381
49532
|
continue;
|
|
@@ -49511,7 +49662,7 @@ function createRelsFiles(relsFiles) {
|
|
|
49511
49662
|
function createContentTypes(files) {
|
|
49512
49663
|
const overrideNodes = [];
|
|
49513
49664
|
// hard-code supported image mimetypes
|
|
49514
|
-
const imageDefaultNodes = Object.entries(
|
|
49665
|
+
const imageDefaultNodes = Object.entries(IMAGE_MIMETYPE_TO_EXTENSION_MAPPING).map(([mimetype, extension]) => createDefaultXMLElement(extension, mimetype));
|
|
49515
49666
|
for (const file of files) {
|
|
49516
49667
|
if ("contentType" in file && file.contentType) {
|
|
49517
49668
|
overrideNodes.push(createOverride("/" + file.path, CONTENT_TYPES[file.contentType]));
|
|
@@ -50117,9 +50268,9 @@ const constants = {
|
|
|
50117
50268
|
DEFAULT_LOCALE,
|
|
50118
50269
|
};
|
|
50119
50270
|
|
|
50120
|
-
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
50271
|
+
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
50121
50272
|
|
|
50122
50273
|
|
|
50123
|
-
__info__.version = '16.4.0-alpha.
|
|
50124
|
-
__info__.date = '2023-
|
|
50125
|
-
__info__.hash = '
|
|
50274
|
+
__info__.version = '16.4.0-alpha.7';
|
|
50275
|
+
__info__.date = '2023-07-04T13:46:24.130Z';
|
|
50276
|
+
__info__.hash = 'b04cf78';
|