@odoo/o-spreadsheet 17.0.28 → 17.0.30
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 +98 -58
- package/dist/o-spreadsheet.d.ts +6 -3
- package/dist/o-spreadsheet.esm.js +98 -58
- package/dist/o-spreadsheet.iife.js +98 -58
- package/dist/o-spreadsheet.iife.min.js +168 -168
- package/dist/o_spreadsheet.xml +4 -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 2024-07-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.30
|
|
6
|
+
* @date 2024-07-11T06:34:04.932Z
|
|
7
|
+
* @hash a8eacf4
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -659,7 +659,7 @@ function getAddHeaderStartIndex(position, base) {
|
|
|
659
659
|
/**
|
|
660
660
|
* Compares two objects.
|
|
661
661
|
*/
|
|
662
|
-
function deepEquals(o1, o2
|
|
662
|
+
function deepEquals(o1, o2) {
|
|
663
663
|
if (o1 === o2)
|
|
664
664
|
return true;
|
|
665
665
|
if ((o1 && !o2) || (o2 && !o1))
|
|
@@ -675,17 +675,13 @@ function deepEquals(o1, o2, ignoreFunctions) {
|
|
|
675
675
|
}
|
|
676
676
|
}
|
|
677
677
|
for (const key in o1) {
|
|
678
|
-
|
|
679
|
-
if (typeOfO1Key !== typeof o2[key])
|
|
678
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
680
679
|
return false;
|
|
681
|
-
if (
|
|
682
|
-
if (!deepEquals(o1[key], o2[key]
|
|
680
|
+
if (typeof o1[key] === "object") {
|
|
681
|
+
if (!deepEquals(o1[key], o2[key]))
|
|
683
682
|
return false;
|
|
684
683
|
}
|
|
685
684
|
else {
|
|
686
|
-
if (ignoreFunctions && typeOfO1Key === "function") {
|
|
687
|
-
continue;
|
|
688
|
-
}
|
|
689
685
|
if (o1[key] !== o2[key])
|
|
690
686
|
return false;
|
|
691
687
|
}
|
|
@@ -756,11 +752,9 @@ class JetSet extends Set {
|
|
|
756
752
|
return this;
|
|
757
753
|
}
|
|
758
754
|
deleteMany(iterable) {
|
|
759
|
-
let wasDeleted = false;
|
|
760
755
|
for (const element of iterable) {
|
|
761
|
-
|
|
756
|
+
super.delete(element);
|
|
762
757
|
}
|
|
763
|
-
return wasDeleted;
|
|
764
758
|
}
|
|
765
759
|
}
|
|
766
760
|
/**
|
|
@@ -1817,7 +1811,7 @@ const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSepa
|
|
|
1817
1811
|
});
|
|
1818
1812
|
const getNumberRegex = memoize(function getNumberRegex(locale) {
|
|
1819
1813
|
const decimalSeparator = escapeRegExp(locale.decimalSeparator);
|
|
1820
|
-
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator);
|
|
1814
|
+
const thousandsSeparator = escapeRegExp(locale.thousandsSeparator || "");
|
|
1821
1815
|
const pIntegerAndDecimals = `(\\d+(${thousandsSeparator}\\d{3,})*(${decimalSeparator}\\d*)?)`; // pattern that match integer number with or without decimal digits
|
|
1822
1816
|
const pOnlyDecimals = `(${decimalSeparator}\\d+)`; // pattern that match only expression with decimal digits
|
|
1823
1817
|
const pScientificFormat = "(e(\\+|-)?\\d+)?"; // pattern that match scientific format between zero and one time (should be placed before pPercentFormat)
|
|
@@ -1844,7 +1838,7 @@ function isNumber(value, locale) {
|
|
|
1844
1838
|
return getNumberRegex(locale).test(value.trim());
|
|
1845
1839
|
}
|
|
1846
1840
|
const getInvaluableSymbolsRegexp = memoize(function getInvaluableSymbolsRegexp(locale) {
|
|
1847
|
-
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator)}]`, "g");
|
|
1841
|
+
return new RegExp(`[\$€${escapeRegExp(locale.thousandsSeparator || "")}]`, "g");
|
|
1848
1842
|
});
|
|
1849
1843
|
/**
|
|
1850
1844
|
* Convert a string into a number. It assumes that the string actually represents
|
|
@@ -2546,6 +2540,9 @@ function getPredicate(descr, isQuery, locale) {
|
|
|
2546
2540
|
return result;
|
|
2547
2541
|
}
|
|
2548
2542
|
function operandToRegExp(operand) {
|
|
2543
|
+
if (operand === "*") {
|
|
2544
|
+
return /.+/;
|
|
2545
|
+
}
|
|
2549
2546
|
let exp = "";
|
|
2550
2547
|
let predecessor = "";
|
|
2551
2548
|
for (let char of operand) {
|
|
@@ -2569,9 +2566,9 @@ function operandToRegExp(operand) {
|
|
|
2569
2566
|
}
|
|
2570
2567
|
return new RegExp("^" + exp + "$", "i");
|
|
2571
2568
|
}
|
|
2572
|
-
function evaluatePredicate(value, criterion) {
|
|
2569
|
+
function evaluatePredicate(value = "", criterion) {
|
|
2573
2570
|
const { operator, operand } = criterion;
|
|
2574
|
-
if (
|
|
2571
|
+
if (operand === undefined || value === null || operand === null) {
|
|
2575
2572
|
return false;
|
|
2576
2573
|
}
|
|
2577
2574
|
if (typeof operand === "number" && operator === "=") {
|
|
@@ -4784,7 +4781,6 @@ class ChartJsComponent extends owl.Component {
|
|
|
4784
4781
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
4785
4782
|
canvas = owl.useRef("graphContainer");
|
|
4786
4783
|
chart;
|
|
4787
|
-
currentRuntime;
|
|
4788
4784
|
get background() {
|
|
4789
4785
|
return this.chartRuntime.background;
|
|
4790
4786
|
}
|
|
@@ -4801,17 +4797,10 @@ class ChartJsComponent extends owl.Component {
|
|
|
4801
4797
|
setup() {
|
|
4802
4798
|
owl.onMounted(() => {
|
|
4803
4799
|
const runtime = this.chartRuntime;
|
|
4804
|
-
this.currentRuntime = runtime;
|
|
4805
4800
|
// Note: chartJS modify the runtime in place, so it's important to give it a copy
|
|
4806
4801
|
this.createChart(deepCopy(runtime.chartJsConfig));
|
|
4807
4802
|
});
|
|
4808
|
-
owl.useEffect(() =>
|
|
4809
|
-
const runtime = this.chartRuntime;
|
|
4810
|
-
if (!deepEquals(runtime, this.currentRuntime, "ignoreFunctions")) {
|
|
4811
|
-
this.currentRuntime = runtime;
|
|
4812
|
-
this.updateChartJs(deepCopy(runtime));
|
|
4813
|
-
}
|
|
4814
|
-
});
|
|
4803
|
+
owl.useEffect(() => this.updateChartJs(deepCopy(this.chartRuntime)), () => [this.chartRuntime]);
|
|
4815
4804
|
}
|
|
4816
4805
|
createChart(chartData) {
|
|
4817
4806
|
const canvas = this.canvas.el;
|
|
@@ -7679,19 +7668,22 @@ class TokenizingChars {
|
|
|
7679
7668
|
}
|
|
7680
7669
|
|
|
7681
7670
|
function isValidLocale(locale) {
|
|
7682
|
-
if (!
|
|
7683
|
-
typeof locale
|
|
7684
|
-
typeof locale.
|
|
7685
|
-
typeof locale.code === "string" &&
|
|
7686
|
-
typeof locale.thousandsSeparator === "string" &&
|
|
7687
|
-
typeof locale.decimalSeparator === "string" &&
|
|
7688
|
-
typeof locale.dateFormat === "string" &&
|
|
7689
|
-
typeof locale.timeFormat === "string" &&
|
|
7690
|
-
typeof locale.formulaArgSeparator === "string")) {
|
|
7671
|
+
if (!locale ||
|
|
7672
|
+
typeof locale !== "object" ||
|
|
7673
|
+
!(!locale.thousandsSeparator || typeof locale.thousandsSeparator === "string")) {
|
|
7691
7674
|
return false;
|
|
7692
7675
|
}
|
|
7693
|
-
|
|
7694
|
-
|
|
7676
|
+
for (const property of [
|
|
7677
|
+
"code",
|
|
7678
|
+
"name",
|
|
7679
|
+
"decimalSeparator",
|
|
7680
|
+
"dateFormat",
|
|
7681
|
+
"timeFormat",
|
|
7682
|
+
"formulaArgSeparator",
|
|
7683
|
+
]) {
|
|
7684
|
+
if (!locale[property] || typeof locale[property] !== "string") {
|
|
7685
|
+
return false;
|
|
7686
|
+
}
|
|
7695
7687
|
}
|
|
7696
7688
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
7697
7689
|
return false;
|
|
@@ -7789,7 +7781,10 @@ function canonicalizeNumberLiteral(content, locale) {
|
|
|
7789
7781
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
7790
7782
|
return content;
|
|
7791
7783
|
}
|
|
7792
|
-
|
|
7784
|
+
if (locale.thousandsSeparator) {
|
|
7785
|
+
content = content.replaceAll(locale.thousandsSeparator, "");
|
|
7786
|
+
}
|
|
7787
|
+
return content.replace(locale.decimalSeparator, ".");
|
|
7793
7788
|
}
|
|
7794
7789
|
/**
|
|
7795
7790
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -8435,7 +8430,7 @@ function truncateLabel(label) {
|
|
|
8435
8430
|
/**
|
|
8436
8431
|
* Get a default chart js configuration
|
|
8437
8432
|
*/
|
|
8438
|
-
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels }) {
|
|
8433
|
+
function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true }) {
|
|
8439
8434
|
const options = {
|
|
8440
8435
|
// https://www.chartjs.org/docs/latest/general/responsive.html
|
|
8441
8436
|
responsive: true,
|
|
@@ -9467,15 +9462,6 @@ function createLineChartRuntime(chart, getters) {
|
|
|
9467
9462
|
}
|
|
9468
9463
|
const colors = new ChartColors();
|
|
9469
9464
|
for (let [index, { label, data }] of dataSetsValues.entries()) {
|
|
9470
|
-
if (["linear", "time"].includes(axisType)) {
|
|
9471
|
-
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
9472
|
-
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
9473
|
-
}
|
|
9474
|
-
const color = colors.next();
|
|
9475
|
-
let backgroundRGBA = colorToRGBA(color);
|
|
9476
|
-
if (chart.stacked) {
|
|
9477
|
-
backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
|
|
9478
|
-
}
|
|
9479
9465
|
if (chart.cumulative) {
|
|
9480
9466
|
let accumulator = 0;
|
|
9481
9467
|
data = data.map((value) => {
|
|
@@ -9486,6 +9472,15 @@ function createLineChartRuntime(chart, getters) {
|
|
|
9486
9472
|
return value;
|
|
9487
9473
|
});
|
|
9488
9474
|
}
|
|
9475
|
+
if (["linear", "time"].includes(axisType)) {
|
|
9476
|
+
// Replace empty string labels by undefined to make sure chartJS doesn't decide that "" is the same as 0
|
|
9477
|
+
data = data.map((y, index) => ({ x: labels[index] || undefined, y }));
|
|
9478
|
+
}
|
|
9479
|
+
const color = colors.next();
|
|
9480
|
+
let backgroundRGBA = colorToRGBA(color);
|
|
9481
|
+
if (chart.stacked) {
|
|
9482
|
+
backgroundRGBA.a = LINE_FILL_TRANSPARENCY;
|
|
9483
|
+
}
|
|
9489
9484
|
const backgroundColor = rgbaToHex(backgroundRGBA);
|
|
9490
9485
|
const dataset = {
|
|
9491
9486
|
label,
|
|
@@ -24283,7 +24278,13 @@ class SettingsPanel extends owl.Component {
|
|
|
24283
24278
|
}
|
|
24284
24279
|
async loadLocales() {
|
|
24285
24280
|
this.loadedLocales = (await this.env.loadLocales())
|
|
24286
|
-
.filter(
|
|
24281
|
+
.filter((locale) => {
|
|
24282
|
+
const isValid = isValidLocale(locale);
|
|
24283
|
+
if (!isValid) {
|
|
24284
|
+
console.warn(`Invalid locale: ${locale["code"]} ${locale}`);
|
|
24285
|
+
}
|
|
24286
|
+
return isValid;
|
|
24287
|
+
})
|
|
24287
24288
|
.sort((a, b) => a.name.localeCompare(b.name));
|
|
24288
24289
|
}
|
|
24289
24290
|
get numberFormatPreview() {
|
|
@@ -30066,6 +30067,7 @@ class Grid extends owl.Component {
|
|
|
30066
30067
|
return;
|
|
30067
30068
|
}
|
|
30068
30069
|
if (clipboardData.types.indexOf(ClipboardMIMEType.PlainText) > -1) {
|
|
30070
|
+
ev.preventDefault();
|
|
30069
30071
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
30070
30072
|
const target = this.env.model.getters.getSelectedZones();
|
|
30071
30073
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
@@ -34641,6 +34643,21 @@ class BordersPlugin extends CorePlugin {
|
|
|
34641
34643
|
return [];
|
|
34642
34644
|
return Object.keys(sheetBorders).map((index) => parseInt(index, 10));
|
|
34643
34645
|
}
|
|
34646
|
+
/**
|
|
34647
|
+
* Get all the rows which contains at least a border
|
|
34648
|
+
*/
|
|
34649
|
+
getRowsWithBorders(sheetId) {
|
|
34650
|
+
const sheetBorders = this.borders[sheetId]?.filter(isDefined$1);
|
|
34651
|
+
if (!sheetBorders)
|
|
34652
|
+
return [];
|
|
34653
|
+
const rowsWithBorders = new Set();
|
|
34654
|
+
for (const rowBorders of sheetBorders) {
|
|
34655
|
+
for (const rowBorder in rowBorders) {
|
|
34656
|
+
rowsWithBorders.add(parseInt(rowBorder, 10));
|
|
34657
|
+
}
|
|
34658
|
+
}
|
|
34659
|
+
return Array.from(rowsWithBorders);
|
|
34660
|
+
}
|
|
34644
34661
|
/**
|
|
34645
34662
|
* Get the range of all the rows in the sheet
|
|
34646
34663
|
*/
|
|
@@ -34690,7 +34707,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
34690
34707
|
destructive: false,
|
|
34691
34708
|
});
|
|
34692
34709
|
}
|
|
34693
|
-
this.
|
|
34710
|
+
this.getRowsWithBorders(sheetId)
|
|
34694
34711
|
.filter((row) => row >= start)
|
|
34695
34712
|
.sort((a, b) => (delta < 0 ? a - b : b - a)) // start by the end when moving up
|
|
34696
34713
|
.forEach((row) => {
|
|
@@ -35154,7 +35171,7 @@ function parseExpression(tokens, parent_priority = 0) {
|
|
|
35154
35171
|
* Parse an expression (as a string) into an AST.
|
|
35155
35172
|
*/
|
|
35156
35173
|
function parse(str) {
|
|
35157
|
-
return parseTokens(
|
|
35174
|
+
return parseTokens(rangeTokenize(str));
|
|
35158
35175
|
}
|
|
35159
35176
|
function parseTokens(tokens) {
|
|
35160
35177
|
tokens = tokens.filter((x) => x.type !== "SPACE");
|
|
@@ -41672,6 +41689,7 @@ class Evaluator {
|
|
|
41672
41689
|
}
|
|
41673
41690
|
finally {
|
|
41674
41691
|
this.cellsBeingComputed.delete(cellId);
|
|
41692
|
+
this.nextPositionsToUpdate.delete(positionId);
|
|
41675
41693
|
}
|
|
41676
41694
|
}
|
|
41677
41695
|
computeAndSave(position) {
|
|
@@ -41713,11 +41731,36 @@ class Evaluator {
|
|
|
41713
41731
|
forEachSpreadPositionInMatrix(nbColumns, nbRows,
|
|
41714
41732
|
// thanks to the isMatrix check above, we know that formulaReturn is MatrixFunctionReturn
|
|
41715
41733
|
this.spreadValues(formulaPosition, formulaReturn));
|
|
41734
|
+
this.invalidatePositionsDependingOnSpread(formulaPosition, nbColumns, nbRows);
|
|
41716
41735
|
return createEvaluatedCell(formulaReturn[0][0].value, {
|
|
41717
41736
|
format: cellData.format || formulaReturn[0][0]?.format,
|
|
41718
41737
|
locale: this.getters.getLocale(),
|
|
41719
41738
|
});
|
|
41720
41739
|
}
|
|
41740
|
+
invalidatePositionsDependingOnSpread(arrayFormulaPosition, nbColumns, nbRows) {
|
|
41741
|
+
// the result matrix is split in 2 zones to exclude the array formula position
|
|
41742
|
+
const top = arrayFormulaPosition.row;
|
|
41743
|
+
const left = arrayFormulaPosition.col;
|
|
41744
|
+
const bottom = top + nbRows - 1;
|
|
41745
|
+
const leftColumnZone = {
|
|
41746
|
+
top: top + 1,
|
|
41747
|
+
bottom,
|
|
41748
|
+
left,
|
|
41749
|
+
right: left,
|
|
41750
|
+
};
|
|
41751
|
+
const rightPartZone = {
|
|
41752
|
+
top,
|
|
41753
|
+
bottom,
|
|
41754
|
+
left: left + 1,
|
|
41755
|
+
right: left + nbColumns - 1,
|
|
41756
|
+
};
|
|
41757
|
+
const sheetId = arrayFormulaPosition.sheetId;
|
|
41758
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn([
|
|
41759
|
+
{ sheetId, zone: rightPartZone },
|
|
41760
|
+
{ sheetId, zone: leftColumnZone },
|
|
41761
|
+
]);
|
|
41762
|
+
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
41763
|
+
}
|
|
41721
41764
|
assertSheetHasEnoughSpaceToSpreadFormulaResult({ sheetId, col, row }, matrixResult) {
|
|
41722
41765
|
const numberOfCols = this.getters.getNumberCols(sheetId);
|
|
41723
41766
|
const numberOfRows = this.getters.getNumberRows(sheetId);
|
|
@@ -41766,9 +41809,6 @@ class Evaluator {
|
|
|
41766
41809
|
});
|
|
41767
41810
|
const positionId = this.encoder.encode(position);
|
|
41768
41811
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
41769
|
-
// check if formula dependencies present in the spread zone
|
|
41770
|
-
// if so, they need to be recomputed
|
|
41771
|
-
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
41772
41812
|
};
|
|
41773
41813
|
}
|
|
41774
41814
|
invalidateSpreading(positionId) {
|
|
@@ -57538,6 +57578,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57538
57578
|
exports.tokenize = tokenize;
|
|
57539
57579
|
|
|
57540
57580
|
|
|
57541
|
-
__info__.version = "17.0.
|
|
57542
|
-
__info__.date = "2024-07-
|
|
57543
|
-
__info__.hash = "
|
|
57581
|
+
__info__.version = "17.0.30";
|
|
57582
|
+
__info__.date = "2024-07-11T06:34:04.932Z";
|
|
57583
|
+
__info__.hash = "a8eacf4";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -996,7 +996,7 @@ declare function lazy<T>(fn: (() => T) | T): Lazy<T>;
|
|
|
996
996
|
/**
|
|
997
997
|
* Compares two objects.
|
|
998
998
|
*/
|
|
999
|
-
declare function deepEquals(o1: any, o2: any
|
|
999
|
+
declare function deepEquals(o1: any, o2: any): boolean;
|
|
1000
1000
|
|
|
1001
1001
|
interface ConstructorArgs {
|
|
1002
1002
|
readonly zone: Readonly<Zone | UnboundedZone>;
|
|
@@ -2819,7 +2819,7 @@ type LocaleCode = string & Alias;
|
|
|
2819
2819
|
interface Locale {
|
|
2820
2820
|
name: string;
|
|
2821
2821
|
code: LocaleCode;
|
|
2822
|
-
thousandsSeparator
|
|
2822
|
+
thousandsSeparator?: string;
|
|
2823
2823
|
decimalSeparator: string;
|
|
2824
2824
|
dateFormat: string;
|
|
2825
2825
|
timeFormat: string;
|
|
@@ -3317,6 +3317,10 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
|
|
|
3317
3317
|
* Get all the columns which contains at least a border
|
|
3318
3318
|
*/
|
|
3319
3319
|
private getColumnsWithBorders;
|
|
3320
|
+
/**
|
|
3321
|
+
* Get all the rows which contains at least a border
|
|
3322
|
+
*/
|
|
3323
|
+
private getRowsWithBorders;
|
|
3320
3324
|
/**
|
|
3321
3325
|
* Get the range of all the rows in the sheet
|
|
3322
3326
|
*/
|
|
@@ -5956,7 +5960,6 @@ declare class ChartJsComponent extends Component<Props$B, SpreadsheetChildEnv> {
|
|
|
5956
5960
|
static template: string;
|
|
5957
5961
|
private canvas;
|
|
5958
5962
|
private chart?;
|
|
5959
|
-
private currentRuntime;
|
|
5960
5963
|
get background(): string;
|
|
5961
5964
|
get canvasStyle(): string;
|
|
5962
5965
|
get chartRuntime(): ChartJSRuntime;
|