@odoo/o-spreadsheet 17.0.83 → 17.0.85
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 +328 -307
- package/dist/o-spreadsheet.d.ts +5 -5
- package/dist/o-spreadsheet.esm.js +328 -307
- package/dist/o-spreadsheet.iife.js +328 -307
- package/dist/o-spreadsheet.iife.min.js +274 -274
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.0.
|
|
6
|
-
* @date 2026-01-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.85
|
|
6
|
+
* @date 2026-01-21T11:02:43.920Z
|
|
7
|
+
* @hash 0343060
|
|
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';
|
|
@@ -272,6 +272,7 @@ const DEFAULT_STYLE = {
|
|
|
272
272
|
fillColor: "",
|
|
273
273
|
textColor: "",
|
|
274
274
|
};
|
|
275
|
+
const DEFAULT_NUMBER_STYLE = { ...DEFAULT_STYLE, align: "right" };
|
|
275
276
|
const DEFAULT_VERTICAL_ALIGN = DEFAULT_STYLE.verticalAlign;
|
|
276
277
|
const DEFAULT_WRAPPING_MODE = DEFAULT_STYLE.wrapping;
|
|
277
278
|
// Fonts
|
|
@@ -4554,17 +4555,318 @@ function isSheetNameEqual(name1, name2) {
|
|
|
4554
4555
|
getUnquotedSheetName(name2.trim().toUpperCase()));
|
|
4555
4556
|
}
|
|
4556
4557
|
|
|
4558
|
+
/**
|
|
4559
|
+
* Registry
|
|
4560
|
+
*
|
|
4561
|
+
* The Registry class is basically just a mapping from a string key to an object.
|
|
4562
|
+
* It is really not much more than an object. It is however useful for the
|
|
4563
|
+
* following reasons:
|
|
4564
|
+
*
|
|
4565
|
+
* 1. it let us react and execute code when someone add something to the registry
|
|
4566
|
+
* (for example, the FunctionRegistry subclass this for this purpose)
|
|
4567
|
+
* 2. it throws an error when the get operation fails
|
|
4568
|
+
* 3. it provides a chained API to add items to the registry.
|
|
4569
|
+
*/
|
|
4570
|
+
class Registry {
|
|
4571
|
+
content = {};
|
|
4572
|
+
/**
|
|
4573
|
+
* Add an item to the registry
|
|
4574
|
+
*
|
|
4575
|
+
* Note that this also returns the registry, so another add method call can
|
|
4576
|
+
* be chained
|
|
4577
|
+
*/
|
|
4578
|
+
add(key, value) {
|
|
4579
|
+
this.content[key] = value;
|
|
4580
|
+
return this;
|
|
4581
|
+
}
|
|
4582
|
+
/**
|
|
4583
|
+
* Get an item from the registry
|
|
4584
|
+
*/
|
|
4585
|
+
get(key) {
|
|
4586
|
+
/**
|
|
4587
|
+
* Note: key in {} is ~12 times slower than {}[key].
|
|
4588
|
+
* So, we check the absence of key only when the direct access returns
|
|
4589
|
+
* a falsy value. It's done to ensure that the registry can contains falsy values
|
|
4590
|
+
*/
|
|
4591
|
+
const content = this.content[key];
|
|
4592
|
+
if (!content) {
|
|
4593
|
+
if (!(key in this.content)) {
|
|
4594
|
+
throw new Error(`Cannot find ${key} in this registry!`);
|
|
4595
|
+
}
|
|
4596
|
+
}
|
|
4597
|
+
return content;
|
|
4598
|
+
}
|
|
4599
|
+
/**
|
|
4600
|
+
* Check if the key is already in the registry
|
|
4601
|
+
*/
|
|
4602
|
+
contains(key) {
|
|
4603
|
+
return key in this.content;
|
|
4604
|
+
}
|
|
4605
|
+
/**
|
|
4606
|
+
* Get a list of all elements in the registry
|
|
4607
|
+
*/
|
|
4608
|
+
getAll() {
|
|
4609
|
+
return Object.values(this.content);
|
|
4610
|
+
}
|
|
4611
|
+
/**
|
|
4612
|
+
* Get a list of all keys in the registry
|
|
4613
|
+
*/
|
|
4614
|
+
getKeys() {
|
|
4615
|
+
return Object.keys(this.content);
|
|
4616
|
+
}
|
|
4617
|
+
/**
|
|
4618
|
+
* Remove an item from the registry
|
|
4619
|
+
*/
|
|
4620
|
+
remove(key) {
|
|
4621
|
+
delete this.content[key];
|
|
4622
|
+
}
|
|
4623
|
+
}
|
|
4624
|
+
|
|
4625
|
+
/**
|
|
4626
|
+
* Add the `https` prefix to the url if it's missing
|
|
4627
|
+
*/
|
|
4628
|
+
function withHttps(url) {
|
|
4629
|
+
return !/^https?:\/\//i.test(url) ? `https://${url}` : url;
|
|
4630
|
+
}
|
|
4631
|
+
const urlRegistry = new Registry();
|
|
4632
|
+
function createWebLink(url, label) {
|
|
4633
|
+
url = withHttps(url);
|
|
4634
|
+
return {
|
|
4635
|
+
url,
|
|
4636
|
+
label: label || url,
|
|
4637
|
+
isExternal: true,
|
|
4638
|
+
isUrlEditable: true,
|
|
4639
|
+
};
|
|
4640
|
+
}
|
|
4641
|
+
urlRegistry.add("sheet_URL", {
|
|
4642
|
+
match: (url) => isSheetUrl(url),
|
|
4643
|
+
createLink: (url, label) => {
|
|
4644
|
+
return {
|
|
4645
|
+
label,
|
|
4646
|
+
url,
|
|
4647
|
+
isExternal: false,
|
|
4648
|
+
isUrlEditable: false,
|
|
4649
|
+
};
|
|
4650
|
+
},
|
|
4651
|
+
urlRepresentation(url, getters) {
|
|
4652
|
+
const sheetId = parseSheetUrl(url);
|
|
4653
|
+
return getters.tryGetSheetName(sheetId) || _t("Invalid sheet");
|
|
4654
|
+
},
|
|
4655
|
+
open(url, env) {
|
|
4656
|
+
const sheetId = parseSheetUrl(url);
|
|
4657
|
+
env.model.dispatch("ACTIVATE_SHEET", {
|
|
4658
|
+
sheetIdFrom: env.model.getters.getActiveSheetId(),
|
|
4659
|
+
sheetIdTo: sheetId,
|
|
4660
|
+
});
|
|
4661
|
+
},
|
|
4662
|
+
sequence: 0,
|
|
4663
|
+
});
|
|
4664
|
+
const WebUrlSpec = {
|
|
4665
|
+
createLink: createWebLink,
|
|
4666
|
+
match: (url) => isWebLink(url),
|
|
4667
|
+
open: (url) => window.open(url, "_blank"),
|
|
4668
|
+
urlRepresentation: (url) => url,
|
|
4669
|
+
sequence: 0,
|
|
4670
|
+
};
|
|
4671
|
+
function findMatchingSpec(url) {
|
|
4672
|
+
return (urlRegistry
|
|
4673
|
+
.getAll()
|
|
4674
|
+
.sort((a, b) => a.sequence - b.sequence)
|
|
4675
|
+
.find((urlType) => urlType.match(url)) || WebUrlSpec);
|
|
4676
|
+
}
|
|
4677
|
+
function urlRepresentation(link, getters) {
|
|
4678
|
+
return findMatchingSpec(link.url).urlRepresentation(link.url, getters);
|
|
4679
|
+
}
|
|
4680
|
+
function openLink(link, env) {
|
|
4681
|
+
findMatchingSpec(link.url).open(link.url, env);
|
|
4682
|
+
}
|
|
4683
|
+
function detectLink(value) {
|
|
4684
|
+
if (typeof value !== "string") {
|
|
4685
|
+
return undefined;
|
|
4686
|
+
}
|
|
4687
|
+
if (isMarkdownLink(value)) {
|
|
4688
|
+
const { label, url } = parseMarkdownLink(value);
|
|
4689
|
+
return findMatchingSpec(url).createLink(url, label);
|
|
4690
|
+
}
|
|
4691
|
+
else if (isWebLink(value)) {
|
|
4692
|
+
return createWebLink(value);
|
|
4693
|
+
}
|
|
4694
|
+
return undefined;
|
|
4695
|
+
}
|
|
4696
|
+
|
|
4697
|
+
function evaluateLiteral(content, localeFormat) {
|
|
4698
|
+
return createEvaluatedCell(parseLiteral(content || "", localeFormat.locale), localeFormat);
|
|
4699
|
+
}
|
|
4700
|
+
function parseLiteral(content, locale) {
|
|
4701
|
+
if (content.startsWith("=")) {
|
|
4702
|
+
throw new Error(`Cannot parse "${content}" because it's not a literal value. It's a formula`);
|
|
4703
|
+
}
|
|
4704
|
+
if (isNumber(content, DEFAULT_LOCALE)) {
|
|
4705
|
+
return toNumber(content, DEFAULT_LOCALE);
|
|
4706
|
+
}
|
|
4707
|
+
else if (isDateTime(content, locale)) {
|
|
4708
|
+
return toNumber(content, locale);
|
|
4709
|
+
}
|
|
4710
|
+
else if (isBoolean(content)) {
|
|
4711
|
+
return content.toUpperCase() === "TRUE" ? true : false;
|
|
4712
|
+
}
|
|
4713
|
+
return content;
|
|
4714
|
+
}
|
|
4715
|
+
function createEvaluatedCell(value, localeFormat) {
|
|
4716
|
+
const link = detectLink(value);
|
|
4717
|
+
if (link) {
|
|
4718
|
+
return {
|
|
4719
|
+
..._createEvaluatedCell(parseLiteral(link.label, localeFormat.locale), {
|
|
4720
|
+
format: localeFormat.format ||
|
|
4721
|
+
detectDateFormat(link.label, localeFormat.locale) ||
|
|
4722
|
+
detectNumberFormat(link.label),
|
|
4723
|
+
locale: localeFormat.locale,
|
|
4724
|
+
}),
|
|
4725
|
+
link,
|
|
4726
|
+
};
|
|
4727
|
+
}
|
|
4728
|
+
return _createEvaluatedCell(value, localeFormat);
|
|
4729
|
+
}
|
|
4730
|
+
function _createEvaluatedCell(value, localeFormat) {
|
|
4731
|
+
try {
|
|
4732
|
+
for (const builder of builders) {
|
|
4733
|
+
const evaluateCell = builder(value, localeFormat);
|
|
4734
|
+
if (evaluateCell) {
|
|
4735
|
+
return evaluateCell;
|
|
4736
|
+
}
|
|
4737
|
+
}
|
|
4738
|
+
return textCell((value || "").toString(), localeFormat);
|
|
4739
|
+
}
|
|
4740
|
+
catch (error) {
|
|
4741
|
+
return errorCell(new EvaluationError(CellErrorType.GenericError, error.message || DEFAULT_ERROR_MESSAGE));
|
|
4742
|
+
}
|
|
4743
|
+
}
|
|
4744
|
+
function textCell(value, localeFormat) {
|
|
4745
|
+
return {
|
|
4746
|
+
type: CellValueType.text,
|
|
4747
|
+
value,
|
|
4748
|
+
format: localeFormat.format,
|
|
4749
|
+
isAutoSummable: true,
|
|
4750
|
+
defaultAlign: "left",
|
|
4751
|
+
formattedValue: formatValue(value, localeFormat),
|
|
4752
|
+
};
|
|
4753
|
+
}
|
|
4754
|
+
function numberCell(value, localeFormat) {
|
|
4755
|
+
return {
|
|
4756
|
+
type: CellValueType.number,
|
|
4757
|
+
value: value || 0, // necessary to avoid "-0" and NaN values,
|
|
4758
|
+
format: localeFormat.format,
|
|
4759
|
+
isAutoSummable: true,
|
|
4760
|
+
defaultAlign: "right",
|
|
4761
|
+
formattedValue: formatValue(value, localeFormat),
|
|
4762
|
+
};
|
|
4763
|
+
}
|
|
4764
|
+
const EMPTY_EVALUATED_CELL = {
|
|
4765
|
+
type: CellValueType.empty,
|
|
4766
|
+
value: "",
|
|
4767
|
+
format: undefined,
|
|
4768
|
+
isAutoSummable: true,
|
|
4769
|
+
defaultAlign: "left",
|
|
4770
|
+
formattedValue: "",
|
|
4771
|
+
};
|
|
4772
|
+
function emptyCell(localeFormat) {
|
|
4773
|
+
if (localeFormat.format === undefined) {
|
|
4774
|
+
// share the same object to save memory
|
|
4775
|
+
return EMPTY_EVALUATED_CELL;
|
|
4776
|
+
}
|
|
4777
|
+
return {
|
|
4778
|
+
type: CellValueType.empty,
|
|
4779
|
+
value: "",
|
|
4780
|
+
format: localeFormat.format,
|
|
4781
|
+
isAutoSummable: true,
|
|
4782
|
+
defaultAlign: "left",
|
|
4783
|
+
formattedValue: "",
|
|
4784
|
+
};
|
|
4785
|
+
}
|
|
4786
|
+
function dateTimeCell(value, localeFormat) {
|
|
4787
|
+
const formattedValue = formatValue(value, localeFormat);
|
|
4788
|
+
return {
|
|
4789
|
+
type: CellValueType.number,
|
|
4790
|
+
value,
|
|
4791
|
+
format: localeFormat.format,
|
|
4792
|
+
isAutoSummable: false,
|
|
4793
|
+
defaultAlign: "right",
|
|
4794
|
+
formattedValue,
|
|
4795
|
+
};
|
|
4796
|
+
}
|
|
4797
|
+
function booleanCell(value, localeFormat) {
|
|
4798
|
+
const formattedValue = value ? "TRUE" : "FALSE";
|
|
4799
|
+
return {
|
|
4800
|
+
type: CellValueType.boolean,
|
|
4801
|
+
value,
|
|
4802
|
+
format: localeFormat.format,
|
|
4803
|
+
isAutoSummable: false,
|
|
4804
|
+
defaultAlign: "center",
|
|
4805
|
+
formattedValue,
|
|
4806
|
+
};
|
|
4807
|
+
}
|
|
4808
|
+
function errorCell(error) {
|
|
4809
|
+
return {
|
|
4810
|
+
type: CellValueType.error,
|
|
4811
|
+
value: error.errorType,
|
|
4812
|
+
error,
|
|
4813
|
+
isAutoSummable: false,
|
|
4814
|
+
defaultAlign: "center",
|
|
4815
|
+
formattedValue: error.errorType,
|
|
4816
|
+
};
|
|
4817
|
+
}
|
|
4818
|
+
const builders = [
|
|
4819
|
+
function createEmpty(value, localeFormat) {
|
|
4820
|
+
if (value === "") {
|
|
4821
|
+
return emptyCell(localeFormat);
|
|
4822
|
+
}
|
|
4823
|
+
return undefined;
|
|
4824
|
+
},
|
|
4825
|
+
function createDateTime(value, localeFormat) {
|
|
4826
|
+
if (!!localeFormat.format &&
|
|
4827
|
+
typeof value === "number" &&
|
|
4828
|
+
isDateTimeFormat(localeFormat.format)) {
|
|
4829
|
+
return dateTimeCell(value, localeFormat);
|
|
4830
|
+
}
|
|
4831
|
+
return undefined;
|
|
4832
|
+
},
|
|
4833
|
+
function createNumber(value, localeFormat) {
|
|
4834
|
+
if (typeof value === "number") {
|
|
4835
|
+
return numberCell(value, localeFormat);
|
|
4836
|
+
}
|
|
4837
|
+
else if (value === null) {
|
|
4838
|
+
return numberCell(0, localeFormat);
|
|
4839
|
+
}
|
|
4840
|
+
return undefined;
|
|
4841
|
+
},
|
|
4842
|
+
function createBoolean(value, localeFormat) {
|
|
4843
|
+
if (typeof value === "boolean") {
|
|
4844
|
+
return booleanCell(value, localeFormat);
|
|
4845
|
+
}
|
|
4846
|
+
return undefined;
|
|
4847
|
+
},
|
|
4848
|
+
];
|
|
4849
|
+
|
|
4557
4850
|
function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
|
|
4558
4851
|
return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
|
|
4559
4852
|
}
|
|
4560
4853
|
/**
|
|
4561
4854
|
* Get the default height of the cell given its style.
|
|
4562
4855
|
*/
|
|
4563
|
-
function getDefaultCellHeight(ctx, cell, colSize) {
|
|
4856
|
+
function getDefaultCellHeight(ctx, cell, locale, colSize) {
|
|
4564
4857
|
if (!cell || (!cell.isFormula && !cell.content)) {
|
|
4565
4858
|
return DEFAULT_CELL_HEIGHT;
|
|
4566
4859
|
}
|
|
4567
|
-
|
|
4860
|
+
let content = "";
|
|
4861
|
+
try {
|
|
4862
|
+
if (!cell.isFormula) {
|
|
4863
|
+
const localeFormat = { format: cell.format, locale };
|
|
4864
|
+
content = formatValue(parseLiteral(cell.content, locale), localeFormat);
|
|
4865
|
+
}
|
|
4866
|
+
}
|
|
4867
|
+
catch {
|
|
4868
|
+
content = CellErrorType.GenericError;
|
|
4869
|
+
}
|
|
4568
4870
|
return getCellContentHeight(ctx, content, cell.style, colSize);
|
|
4569
4871
|
}
|
|
4570
4872
|
function getCellContentHeight(ctx, content, style, colSize) {
|
|
@@ -4868,7 +5170,8 @@ function createAction(item) {
|
|
|
4868
5170
|
return children
|
|
4869
5171
|
.map((child) => (typeof child === "function" ? child(env) : child))
|
|
4870
5172
|
.flat()
|
|
4871
|
-
.map(createAction)
|
|
5173
|
+
.map(createAction)
|
|
5174
|
+
.sort((a, b) => a.sequence - b.sequence);
|
|
4872
5175
|
}
|
|
4873
5176
|
: () => [],
|
|
4874
5177
|
isReadonlyAllowed: item.isReadonlyAllowed || false,
|
|
@@ -5829,298 +6132,6 @@ ScorecardChart.props = {
|
|
|
5829
6132
|
figure: Object,
|
|
5830
6133
|
};
|
|
5831
6134
|
|
|
5832
|
-
/**
|
|
5833
|
-
* Registry
|
|
5834
|
-
*
|
|
5835
|
-
* The Registry class is basically just a mapping from a string key to an object.
|
|
5836
|
-
* It is really not much more than an object. It is however useful for the
|
|
5837
|
-
* following reasons:
|
|
5838
|
-
*
|
|
5839
|
-
* 1. it let us react and execute code when someone add something to the registry
|
|
5840
|
-
* (for example, the FunctionRegistry subclass this for this purpose)
|
|
5841
|
-
* 2. it throws an error when the get operation fails
|
|
5842
|
-
* 3. it provides a chained API to add items to the registry.
|
|
5843
|
-
*/
|
|
5844
|
-
class Registry {
|
|
5845
|
-
content = {};
|
|
5846
|
-
/**
|
|
5847
|
-
* Add an item to the registry
|
|
5848
|
-
*
|
|
5849
|
-
* Note that this also returns the registry, so another add method call can
|
|
5850
|
-
* be chained
|
|
5851
|
-
*/
|
|
5852
|
-
add(key, value) {
|
|
5853
|
-
this.content[key] = value;
|
|
5854
|
-
return this;
|
|
5855
|
-
}
|
|
5856
|
-
/**
|
|
5857
|
-
* Get an item from the registry
|
|
5858
|
-
*/
|
|
5859
|
-
get(key) {
|
|
5860
|
-
/**
|
|
5861
|
-
* Note: key in {} is ~12 times slower than {}[key].
|
|
5862
|
-
* So, we check the absence of key only when the direct access returns
|
|
5863
|
-
* a falsy value. It's done to ensure that the registry can contains falsy values
|
|
5864
|
-
*/
|
|
5865
|
-
const content = this.content[key];
|
|
5866
|
-
if (!content) {
|
|
5867
|
-
if (!(key in this.content)) {
|
|
5868
|
-
throw new Error(`Cannot find ${key} in this registry!`);
|
|
5869
|
-
}
|
|
5870
|
-
}
|
|
5871
|
-
return content;
|
|
5872
|
-
}
|
|
5873
|
-
/**
|
|
5874
|
-
* Check if the key is already in the registry
|
|
5875
|
-
*/
|
|
5876
|
-
contains(key) {
|
|
5877
|
-
return key in this.content;
|
|
5878
|
-
}
|
|
5879
|
-
/**
|
|
5880
|
-
* Get a list of all elements in the registry
|
|
5881
|
-
*/
|
|
5882
|
-
getAll() {
|
|
5883
|
-
return Object.values(this.content);
|
|
5884
|
-
}
|
|
5885
|
-
/**
|
|
5886
|
-
* Get a list of all keys in the registry
|
|
5887
|
-
*/
|
|
5888
|
-
getKeys() {
|
|
5889
|
-
return Object.keys(this.content);
|
|
5890
|
-
}
|
|
5891
|
-
/**
|
|
5892
|
-
* Remove an item from the registry
|
|
5893
|
-
*/
|
|
5894
|
-
remove(key) {
|
|
5895
|
-
delete this.content[key];
|
|
5896
|
-
}
|
|
5897
|
-
}
|
|
5898
|
-
|
|
5899
|
-
/**
|
|
5900
|
-
* Add the `https` prefix to the url if it's missing
|
|
5901
|
-
*/
|
|
5902
|
-
function withHttps(url) {
|
|
5903
|
-
return !/^https?:\/\//i.test(url) ? `https://${url}` : url;
|
|
5904
|
-
}
|
|
5905
|
-
const urlRegistry = new Registry();
|
|
5906
|
-
function createWebLink(url, label) {
|
|
5907
|
-
url = withHttps(url);
|
|
5908
|
-
return {
|
|
5909
|
-
url,
|
|
5910
|
-
label: label || url,
|
|
5911
|
-
isExternal: true,
|
|
5912
|
-
isUrlEditable: true,
|
|
5913
|
-
};
|
|
5914
|
-
}
|
|
5915
|
-
urlRegistry.add("sheet_URL", {
|
|
5916
|
-
match: (url) => isSheetUrl(url),
|
|
5917
|
-
createLink: (url, label) => {
|
|
5918
|
-
return {
|
|
5919
|
-
label,
|
|
5920
|
-
url,
|
|
5921
|
-
isExternal: false,
|
|
5922
|
-
isUrlEditable: false,
|
|
5923
|
-
};
|
|
5924
|
-
},
|
|
5925
|
-
urlRepresentation(url, getters) {
|
|
5926
|
-
const sheetId = parseSheetUrl(url);
|
|
5927
|
-
return getters.tryGetSheetName(sheetId) || _t("Invalid sheet");
|
|
5928
|
-
},
|
|
5929
|
-
open(url, env) {
|
|
5930
|
-
const sheetId = parseSheetUrl(url);
|
|
5931
|
-
env.model.dispatch("ACTIVATE_SHEET", {
|
|
5932
|
-
sheetIdFrom: env.model.getters.getActiveSheetId(),
|
|
5933
|
-
sheetIdTo: sheetId,
|
|
5934
|
-
});
|
|
5935
|
-
},
|
|
5936
|
-
sequence: 0,
|
|
5937
|
-
});
|
|
5938
|
-
const WebUrlSpec = {
|
|
5939
|
-
createLink: createWebLink,
|
|
5940
|
-
match: (url) => isWebLink(url),
|
|
5941
|
-
open: (url) => window.open(url, "_blank"),
|
|
5942
|
-
urlRepresentation: (url) => url,
|
|
5943
|
-
sequence: 0,
|
|
5944
|
-
};
|
|
5945
|
-
function findMatchingSpec(url) {
|
|
5946
|
-
return (urlRegistry
|
|
5947
|
-
.getAll()
|
|
5948
|
-
.sort((a, b) => a.sequence - b.sequence)
|
|
5949
|
-
.find((urlType) => urlType.match(url)) || WebUrlSpec);
|
|
5950
|
-
}
|
|
5951
|
-
function urlRepresentation(link, getters) {
|
|
5952
|
-
return findMatchingSpec(link.url).urlRepresentation(link.url, getters);
|
|
5953
|
-
}
|
|
5954
|
-
function openLink(link, env) {
|
|
5955
|
-
findMatchingSpec(link.url).open(link.url, env);
|
|
5956
|
-
}
|
|
5957
|
-
function detectLink(value) {
|
|
5958
|
-
if (typeof value !== "string") {
|
|
5959
|
-
return undefined;
|
|
5960
|
-
}
|
|
5961
|
-
if (isMarkdownLink(value)) {
|
|
5962
|
-
const { label, url } = parseMarkdownLink(value);
|
|
5963
|
-
return findMatchingSpec(url).createLink(url, label);
|
|
5964
|
-
}
|
|
5965
|
-
else if (isWebLink(value)) {
|
|
5966
|
-
return createWebLink(value);
|
|
5967
|
-
}
|
|
5968
|
-
return undefined;
|
|
5969
|
-
}
|
|
5970
|
-
|
|
5971
|
-
function evaluateLiteral(content, localeFormat) {
|
|
5972
|
-
return createEvaluatedCell(parseLiteral(content || "", localeFormat.locale), localeFormat);
|
|
5973
|
-
}
|
|
5974
|
-
function parseLiteral(content, locale) {
|
|
5975
|
-
if (content.startsWith("=")) {
|
|
5976
|
-
throw new Error(`Cannot parse "${content}" because it's not a literal value. It's a formula`);
|
|
5977
|
-
}
|
|
5978
|
-
if (isNumber(content, DEFAULT_LOCALE)) {
|
|
5979
|
-
return toNumber(content, DEFAULT_LOCALE);
|
|
5980
|
-
}
|
|
5981
|
-
else if (isDateTime(content, locale)) {
|
|
5982
|
-
return toNumber(content, locale);
|
|
5983
|
-
}
|
|
5984
|
-
else if (isBoolean(content)) {
|
|
5985
|
-
return content.toUpperCase() === "TRUE" ? true : false;
|
|
5986
|
-
}
|
|
5987
|
-
return content;
|
|
5988
|
-
}
|
|
5989
|
-
function createEvaluatedCell(value, localeFormat) {
|
|
5990
|
-
const link = detectLink(value);
|
|
5991
|
-
if (link) {
|
|
5992
|
-
return {
|
|
5993
|
-
..._createEvaluatedCell(parseLiteral(link.label, localeFormat.locale), {
|
|
5994
|
-
format: localeFormat.format ||
|
|
5995
|
-
detectDateFormat(link.label, localeFormat.locale) ||
|
|
5996
|
-
detectNumberFormat(link.label),
|
|
5997
|
-
locale: localeFormat.locale,
|
|
5998
|
-
}),
|
|
5999
|
-
link,
|
|
6000
|
-
};
|
|
6001
|
-
}
|
|
6002
|
-
return _createEvaluatedCell(value, localeFormat);
|
|
6003
|
-
}
|
|
6004
|
-
function _createEvaluatedCell(value, localeFormat) {
|
|
6005
|
-
try {
|
|
6006
|
-
for (const builder of builders) {
|
|
6007
|
-
const evaluateCell = builder(value, localeFormat);
|
|
6008
|
-
if (evaluateCell) {
|
|
6009
|
-
return evaluateCell;
|
|
6010
|
-
}
|
|
6011
|
-
}
|
|
6012
|
-
return textCell((value || "").toString(), localeFormat);
|
|
6013
|
-
}
|
|
6014
|
-
catch (error) {
|
|
6015
|
-
return errorCell(new EvaluationError(CellErrorType.GenericError, error.message || DEFAULT_ERROR_MESSAGE));
|
|
6016
|
-
}
|
|
6017
|
-
}
|
|
6018
|
-
function textCell(value, localeFormat) {
|
|
6019
|
-
return {
|
|
6020
|
-
type: CellValueType.text,
|
|
6021
|
-
value,
|
|
6022
|
-
format: localeFormat.format,
|
|
6023
|
-
isAutoSummable: true,
|
|
6024
|
-
defaultAlign: "left",
|
|
6025
|
-
formattedValue: formatValue(value, localeFormat),
|
|
6026
|
-
};
|
|
6027
|
-
}
|
|
6028
|
-
function numberCell(value, localeFormat) {
|
|
6029
|
-
return {
|
|
6030
|
-
type: CellValueType.number,
|
|
6031
|
-
value: value || 0, // necessary to avoid "-0" and NaN values,
|
|
6032
|
-
format: localeFormat.format,
|
|
6033
|
-
isAutoSummable: true,
|
|
6034
|
-
defaultAlign: "right",
|
|
6035
|
-
formattedValue: formatValue(value, localeFormat),
|
|
6036
|
-
};
|
|
6037
|
-
}
|
|
6038
|
-
const EMPTY_EVALUATED_CELL = {
|
|
6039
|
-
type: CellValueType.empty,
|
|
6040
|
-
value: "",
|
|
6041
|
-
format: undefined,
|
|
6042
|
-
isAutoSummable: true,
|
|
6043
|
-
defaultAlign: "left",
|
|
6044
|
-
formattedValue: "",
|
|
6045
|
-
};
|
|
6046
|
-
function emptyCell(localeFormat) {
|
|
6047
|
-
if (localeFormat.format === undefined) {
|
|
6048
|
-
// share the same object to save memory
|
|
6049
|
-
return EMPTY_EVALUATED_CELL;
|
|
6050
|
-
}
|
|
6051
|
-
return {
|
|
6052
|
-
type: CellValueType.empty,
|
|
6053
|
-
value: "",
|
|
6054
|
-
format: localeFormat.format,
|
|
6055
|
-
isAutoSummable: true,
|
|
6056
|
-
defaultAlign: "left",
|
|
6057
|
-
formattedValue: "",
|
|
6058
|
-
};
|
|
6059
|
-
}
|
|
6060
|
-
function dateTimeCell(value, localeFormat) {
|
|
6061
|
-
const formattedValue = formatValue(value, localeFormat);
|
|
6062
|
-
return {
|
|
6063
|
-
type: CellValueType.number,
|
|
6064
|
-
value,
|
|
6065
|
-
format: localeFormat.format,
|
|
6066
|
-
isAutoSummable: false,
|
|
6067
|
-
defaultAlign: "right",
|
|
6068
|
-
formattedValue,
|
|
6069
|
-
};
|
|
6070
|
-
}
|
|
6071
|
-
function booleanCell(value, localeFormat) {
|
|
6072
|
-
const formattedValue = value ? "TRUE" : "FALSE";
|
|
6073
|
-
return {
|
|
6074
|
-
type: CellValueType.boolean,
|
|
6075
|
-
value,
|
|
6076
|
-
format: localeFormat.format,
|
|
6077
|
-
isAutoSummable: false,
|
|
6078
|
-
defaultAlign: "center",
|
|
6079
|
-
formattedValue,
|
|
6080
|
-
};
|
|
6081
|
-
}
|
|
6082
|
-
function errorCell(error) {
|
|
6083
|
-
return {
|
|
6084
|
-
type: CellValueType.error,
|
|
6085
|
-
value: error.errorType,
|
|
6086
|
-
error,
|
|
6087
|
-
isAutoSummable: false,
|
|
6088
|
-
defaultAlign: "center",
|
|
6089
|
-
formattedValue: error.errorType,
|
|
6090
|
-
};
|
|
6091
|
-
}
|
|
6092
|
-
const builders = [
|
|
6093
|
-
function createEmpty(value, localeFormat) {
|
|
6094
|
-
if (value === "") {
|
|
6095
|
-
return emptyCell(localeFormat);
|
|
6096
|
-
}
|
|
6097
|
-
return undefined;
|
|
6098
|
-
},
|
|
6099
|
-
function createDateTime(value, localeFormat) {
|
|
6100
|
-
if (!!localeFormat.format &&
|
|
6101
|
-
typeof value === "number" &&
|
|
6102
|
-
isDateTimeFormat(localeFormat.format)) {
|
|
6103
|
-
return dateTimeCell(value, localeFormat);
|
|
6104
|
-
}
|
|
6105
|
-
return undefined;
|
|
6106
|
-
},
|
|
6107
|
-
function createNumber(value, localeFormat) {
|
|
6108
|
-
if (typeof value === "number") {
|
|
6109
|
-
return numberCell(value, localeFormat);
|
|
6110
|
-
}
|
|
6111
|
-
else if (value === null) {
|
|
6112
|
-
return numberCell(0, localeFormat);
|
|
6113
|
-
}
|
|
6114
|
-
return undefined;
|
|
6115
|
-
},
|
|
6116
|
-
function createBoolean(value, localeFormat) {
|
|
6117
|
-
if (typeof value === "boolean") {
|
|
6118
|
-
return booleanCell(value, localeFormat);
|
|
6119
|
-
}
|
|
6120
|
-
return undefined;
|
|
6121
|
-
},
|
|
6122
|
-
];
|
|
6123
|
-
|
|
6124
6135
|
/**
|
|
6125
6136
|
* An AutofillModifierImplementation is used to describe how to handle a
|
|
6126
6137
|
* AutofillModifier.
|
|
@@ -32642,6 +32653,7 @@ function extractStyle(cell, data) {
|
|
|
32642
32653
|
? V_ALIGNMENT_EXPORT_CONVERSION_MAP[style.verticalAlign]
|
|
32643
32654
|
: undefined,
|
|
32644
32655
|
wrapText: style.wrapping === "wrap" || cell.content?.includes(NEWLINE) ? true : undefined,
|
|
32656
|
+
shrinkToFit: style.wrapping === "clip" ? true : undefined,
|
|
32645
32657
|
},
|
|
32646
32658
|
};
|
|
32647
32659
|
styles.font["strike"] = !!style?.strikethrough || undefined;
|
|
@@ -32668,6 +32680,7 @@ function normalizeStyle(construct, styles) {
|
|
|
32668
32680
|
vertical: styles.alignment.vertical,
|
|
32669
32681
|
horizontal: styles.alignment.horizontal,
|
|
32670
32682
|
wrapText: styles.alignment.wrapText,
|
|
32683
|
+
shrinkToFit: styles.alignment.shrinkToFit,
|
|
32671
32684
|
},
|
|
32672
32685
|
};
|
|
32673
32686
|
return pushElement(style, construct.styles);
|
|
@@ -36411,7 +36424,7 @@ class CellPlugin extends CorePlugin {
|
|
|
36411
36424
|
for (const position of positions) {
|
|
36412
36425
|
const cell = this.getters.getCell(position);
|
|
36413
36426
|
const xc = toXC(position.col, position.row);
|
|
36414
|
-
const style = this.
|
|
36427
|
+
const style = this.extractCustomStyle(cell);
|
|
36415
36428
|
cells[xc] = {
|
|
36416
36429
|
style: Object.keys(style).length ? getItemId(style, styles) : undefined,
|
|
36417
36430
|
format: cell.format ? getItemId(cell.format, formats) : undefined,
|
|
@@ -36432,10 +36445,14 @@ class CellPlugin extends CorePlugin {
|
|
|
36432
36445
|
exportForExcel(data) {
|
|
36433
36446
|
this.export(data);
|
|
36434
36447
|
}
|
|
36435
|
-
|
|
36436
|
-
const cleanedStyle = { ...style };
|
|
36437
|
-
|
|
36438
|
-
|
|
36448
|
+
extractCustomStyle(cell) {
|
|
36449
|
+
const cleanedStyle = { ...cell.style };
|
|
36450
|
+
const defaultStyle = isNumber(cell.content, DEFAULT_LOCALE)
|
|
36451
|
+
? DEFAULT_NUMBER_STYLE
|
|
36452
|
+
: DEFAULT_STYLE;
|
|
36453
|
+
for (const property in cleanedStyle) {
|
|
36454
|
+
if ((property !== "align" || !cell.isFormula) &&
|
|
36455
|
+
cleanedStyle[property] === defaultStyle[property]) {
|
|
36439
36456
|
delete cleanedStyle[property];
|
|
36440
36457
|
}
|
|
36441
36458
|
}
|
|
@@ -43576,6 +43593,7 @@ class HeaderSizeUIPlugin extends UIPlugin {
|
|
|
43576
43593
|
handle(cmd) {
|
|
43577
43594
|
switch (cmd.type) {
|
|
43578
43595
|
case "START":
|
|
43596
|
+
case "UPDATE_LOCALE":
|
|
43579
43597
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
43580
43598
|
this.initializeSheet(sheetId);
|
|
43581
43599
|
}
|
|
@@ -43681,7 +43699,7 @@ class HeaderSizeUIPlugin extends UIPlugin {
|
|
|
43681
43699
|
}
|
|
43682
43700
|
const cell = this.getters.getCell(position);
|
|
43683
43701
|
const colSize = this.getters.getColSize(position.sheetId, position.col);
|
|
43684
|
-
return getDefaultCellHeight(this.ctx, cell, colSize);
|
|
43702
|
+
return getDefaultCellHeight(this.ctx, cell, this.getters.getLocale(), colSize);
|
|
43685
43703
|
}
|
|
43686
43704
|
isInMultiRowMerge(position) {
|
|
43687
43705
|
const merge = this.getters.getMerge(position);
|
|
@@ -57301,6 +57319,9 @@ function addStyles(styles) {
|
|
|
57301
57319
|
if (style.alignment && style.alignment.wrapText) {
|
|
57302
57320
|
alignAttrs.push(["wrapText", "1"]);
|
|
57303
57321
|
}
|
|
57322
|
+
if (style.alignment && style.alignment.shrinkToFit) {
|
|
57323
|
+
alignAttrs.push(["shrinkToFit", "1"]);
|
|
57324
|
+
}
|
|
57304
57325
|
if (alignAttrs.length > 0) {
|
|
57305
57326
|
attributes.push(["applyAlignment", "1"]); // for Libre Office
|
|
57306
57327
|
styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)}><alignment ${formatAttributes(alignAttrs)} /></xf> `);
|
|
@@ -58502,6 +58523,6 @@ const constants = {
|
|
|
58502
58523
|
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 };
|
|
58503
58524
|
|
|
58504
58525
|
|
|
58505
|
-
__info__.version = "17.0.
|
|
58506
|
-
__info__.date = "2026-01-
|
|
58507
|
-
__info__.hash = "
|
|
58526
|
+
__info__.version = "17.0.85";
|
|
58527
|
+
__info__.date = "2026-01-21T11:02:43.920Z";
|
|
58528
|
+
__info__.hash = "0343060";
|