@odoo/o-spreadsheet 19.0.5 → 19.0.6
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 +211 -125
- package/dist/o-spreadsheet.d.ts +19 -5
- package/dist/o-spreadsheet.esm.js +211 -125
- package/dist/o-spreadsheet.iife.js +211 -125
- package/dist/o-spreadsheet.iife.min.js +101 -100
- package/dist/o_spreadsheet.xml +13 -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 19.0.
|
|
6
|
-
* @date 2025-10-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.0.6
|
|
6
|
+
* @date 2025-10-16T06:39:36.282Z
|
|
7
|
+
* @hash 0d4315a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -4514,7 +4514,17 @@
|
|
|
4514
4514
|
return toMatrix(data).map((row) => {
|
|
4515
4515
|
return row.map((cell) => {
|
|
4516
4516
|
if (typeof cell.value !== "number") {
|
|
4517
|
-
|
|
4517
|
+
let message = "";
|
|
4518
|
+
if (typeof cell === "object") {
|
|
4519
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got an empty value.", argName);
|
|
4520
|
+
}
|
|
4521
|
+
else if (typeof cell === "string") {
|
|
4522
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a string.", argName);
|
|
4523
|
+
}
|
|
4524
|
+
else if (typeof cell === "boolean") {
|
|
4525
|
+
message = _t("Function [[FUNCTION_NAME]] expects number values for %s, but got a boolean.", argName);
|
|
4526
|
+
}
|
|
4527
|
+
throw new EvaluationError(message);
|
|
4518
4528
|
}
|
|
4519
4529
|
return cell.value;
|
|
4520
4530
|
});
|
|
@@ -9529,7 +9539,7 @@
|
|
|
9529
9539
|
pasteCell(origin, target, clipboardOption) {
|
|
9530
9540
|
const { sheetId, col, row } = target;
|
|
9531
9541
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
9532
|
-
const originFormat = origin?.format
|
|
9542
|
+
const originFormat = origin?.format || origin.evaluatedCell.format;
|
|
9533
9543
|
if (clipboardOption?.pasteOption === "asValue") {
|
|
9534
9544
|
this.dispatch("UPDATE_CELL", {
|
|
9535
9545
|
...target,
|
|
@@ -13902,7 +13912,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13902
13912
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
13903
13913
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
13904
13914
|
}
|
|
13905
|
-
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "
|
|
13915
|
+
return expM(predictLinearValues(logM(toNumberMatrix(knownDataY, "known_data_y")), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b)));
|
|
13906
13916
|
},
|
|
13907
13917
|
};
|
|
13908
13918
|
// -----------------------------------------------------------------------------
|
|
@@ -13975,7 +13985,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13975
13985
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13976
13986
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13977
13987
|
}
|
|
13978
|
-
return fullLinearRegression(toNumberMatrix(dataX, "
|
|
13988
|
+
return fullLinearRegression(toNumberMatrix(dataX, "data_x"), toNumberMatrix(dataY, "data_y"), toBoolean(calculateB), toBoolean(verbose));
|
|
13979
13989
|
},
|
|
13980
13990
|
isExported: true,
|
|
13981
13991
|
};
|
|
@@ -13994,7 +14004,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
13994
14004
|
if (dataY.length === 0 || dataY[0].length === 0) {
|
|
13995
14005
|
return new EvaluationError(emptyDataErrorMessage("data_y"));
|
|
13996
14006
|
}
|
|
13997
|
-
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "
|
|
14007
|
+
const coeffs = fullLinearRegression(toNumberMatrix(dataX, "data_x"), logM(toNumberMatrix(dataY, "data_y")), toBoolean(calculateB), toBoolean(verbose));
|
|
13998
14008
|
for (let i = 0; i < coeffs.length; i++) {
|
|
13999
14009
|
coeffs[i][0] = Math.exp(coeffs[i][0]);
|
|
14000
14010
|
}
|
|
@@ -14615,7 +14625,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
14615
14625
|
if (knownDataY.length === 0 || knownDataY[0].length === 0) {
|
|
14616
14626
|
return new EvaluationError(emptyDataErrorMessage("known_data_y"));
|
|
14617
14627
|
}
|
|
14618
|
-
return predictLinearValues(toNumberMatrix(knownDataY, "
|
|
14628
|
+
return predictLinearValues(toNumberMatrix(knownDataY, "known_data_y"), toNumberMatrix(knownDataX, "known_data_x"), toNumberMatrix(newDataX, "new_data_y"), toBoolean(b));
|
|
14619
14629
|
},
|
|
14620
14630
|
};
|
|
14621
14631
|
// -----------------------------------------------------------------------------
|
|
@@ -23136,6 +23146,10 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
23136
23146
|
}
|
|
23137
23147
|
const ctx = chart.ctx;
|
|
23138
23148
|
ctx.save();
|
|
23149
|
+
const { left, top, height, width } = chart.chartArea;
|
|
23150
|
+
ctx.beginPath();
|
|
23151
|
+
ctx.rect(left, top, width, height);
|
|
23152
|
+
ctx.clip();
|
|
23139
23153
|
ctx.textAlign = "center";
|
|
23140
23154
|
ctx.textBaseline = "middle";
|
|
23141
23155
|
ctx.miterLimit = 1; // Avoid sharp artifacts on strokeText
|
|
@@ -24179,7 +24193,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24179
24193
|
this.chart.update();
|
|
24180
24194
|
}
|
|
24181
24195
|
hasChartDataChanged() {
|
|
24182
|
-
return !deepEquals(this.currentRuntime
|
|
24196
|
+
return !deepEquals(this.getChartDataInRuntime(this.currentRuntime), this.getChartDataInRuntime(this.chartRuntime));
|
|
24183
24197
|
}
|
|
24184
24198
|
enableAnimationInChartData(chartData) {
|
|
24185
24199
|
return {
|
|
@@ -24187,6 +24201,17 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
24187
24201
|
options: { ...chartData.options, animation: { animateRotate: true } },
|
|
24188
24202
|
};
|
|
24189
24203
|
}
|
|
24204
|
+
getChartDataInRuntime(runtime) {
|
|
24205
|
+
const data = runtime.chartJsConfig.data;
|
|
24206
|
+
return {
|
|
24207
|
+
labels: data.labels,
|
|
24208
|
+
dataset: data.datasets.map((dataset) => ({
|
|
24209
|
+
data: dataset.data,
|
|
24210
|
+
label: dataset.label,
|
|
24211
|
+
tree: dataset.tree,
|
|
24212
|
+
})),
|
|
24213
|
+
};
|
|
24214
|
+
}
|
|
24190
24215
|
get animationChartId() {
|
|
24191
24216
|
return this.props.isFullScreen ? this.props.chartId + "-fullscreen" : this.props.chartId;
|
|
24192
24217
|
}
|
|
@@ -25610,6 +25635,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
25610
25635
|
parser: luxonFormat,
|
|
25611
25636
|
displayFormats,
|
|
25612
25637
|
unit: timeUnit ?? false,
|
|
25638
|
+
tooltipFormat: luxonFormat,
|
|
25613
25639
|
};
|
|
25614
25640
|
}
|
|
25615
25641
|
/**
|
|
@@ -26678,6 +26704,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
26678
26704
|
};
|
|
26679
26705
|
Object.assign(scales.x, axis);
|
|
26680
26706
|
scales.x.ticks.maxTicksLimit = 15;
|
|
26707
|
+
delete scales?.x?.ticks?.callback;
|
|
26681
26708
|
}
|
|
26682
26709
|
else if (axisType === "linear") {
|
|
26683
26710
|
scales.x.type = "linear";
|
|
@@ -32363,7 +32390,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32363
32390
|
}
|
|
32364
32391
|
openContextMenu(ev) {
|
|
32365
32392
|
this.menuState.isOpen = true;
|
|
32366
|
-
this.menuState.anchorRect =
|
|
32393
|
+
this.menuState.anchorRect = getBoundingRectAsPOJO(ev.currentTarget);
|
|
32367
32394
|
const figureId = this.env.model.getters.getFigureIdFromChartId(this.props.chartId);
|
|
32368
32395
|
this.menuState.menuItems = getChartMenuActions(figureId, () => { }, this.env);
|
|
32369
32396
|
}
|
|
@@ -32395,6 +32422,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32395
32422
|
onFigureDeleted: Function,
|
|
32396
32423
|
editFigureStyle: { type: Function, optional: true },
|
|
32397
32424
|
isFullScreen: { type: Boolean, optional: true },
|
|
32425
|
+
openContextMenu: { type: Function, optional: true },
|
|
32398
32426
|
};
|
|
32399
32427
|
static components = { ChartDashboardMenu, MenuPopover };
|
|
32400
32428
|
carouselTabsRef = owl.useRef("carouselTabs");
|
|
@@ -32528,6 +32556,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32528
32556
|
get visibleCarouselItems() {
|
|
32529
32557
|
return this.carousel.items.filter((item) => item.type === "carouselDataView" && this.props.isFullScreen ? false : true);
|
|
32530
32558
|
}
|
|
32559
|
+
openContextMenu(event) {
|
|
32560
|
+
const target = event.currentTarget;
|
|
32561
|
+
if (target) {
|
|
32562
|
+
this.props.openContextMenu?.(getBoundingRectAsPOJO(target));
|
|
32563
|
+
}
|
|
32564
|
+
}
|
|
32531
32565
|
}
|
|
32532
32566
|
|
|
32533
32567
|
class ChartFigure extends owl.Component {
|
|
@@ -32537,6 +32571,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32537
32571
|
onFigureDeleted: Function,
|
|
32538
32572
|
editFigureStyle: { type: Function, optional: true },
|
|
32539
32573
|
isFullScreen: { type: Boolean, optional: true },
|
|
32574
|
+
openContextMenu: { type: Function, optional: true },
|
|
32540
32575
|
};
|
|
32541
32576
|
static components = { ChartDashboardMenu };
|
|
32542
32577
|
onDoubleClick() {
|
|
@@ -32569,6 +32604,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
32569
32604
|
figureUI: Object,
|
|
32570
32605
|
onFigureDeleted: Function,
|
|
32571
32606
|
editFigureStyle: { type: Function, optional: true },
|
|
32607
|
+
openContextMenu: { type: Function, optional: true },
|
|
32572
32608
|
};
|
|
32573
32609
|
static components = {};
|
|
32574
32610
|
// ---------------------------------------------------------------------------
|
|
@@ -34620,8 +34656,11 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
34620
34656
|
}
|
|
34621
34657
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
34622
34658
|
this.props.composerStore.stopComposerRangeSelection();
|
|
34623
|
-
this.props.
|
|
34624
|
-
this.props.
|
|
34659
|
+
const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
|
|
34660
|
+
this.props.onComposerContentFocused(newSelection);
|
|
34661
|
+
if (!isCurrentlyInactive) {
|
|
34662
|
+
this.props.composerStore.changeComposerCursorSelection(newSelection.start, newSelection.end);
|
|
34663
|
+
}
|
|
34625
34664
|
this.processTokenAtCursor();
|
|
34626
34665
|
}
|
|
34627
34666
|
onDblClick() {
|
|
@@ -35116,13 +35155,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35116
35155
|
}
|
|
35117
35156
|
}
|
|
35118
35157
|
startEdition(text, selection) {
|
|
35119
|
-
if (selection) {
|
|
35120
|
-
const content = text || this.getComposerContent(this.getters.getActivePosition());
|
|
35121
|
-
const validSelection = this.isSelectionValid(content.length, selection.start, selection.end);
|
|
35122
|
-
if (!validSelection) {
|
|
35123
|
-
return;
|
|
35124
|
-
}
|
|
35125
|
-
}
|
|
35126
35158
|
const { col, row } = this.getters.getActivePosition();
|
|
35127
35159
|
this.model.dispatch("SELECT_FIGURE", { figureId: null });
|
|
35128
35160
|
this.model.dispatch("SCROLL_TO_CELL", { col, row });
|
|
@@ -35179,7 +35211,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35179
35211
|
// ---------------------------------------------------------------------------
|
|
35180
35212
|
get currentContent() {
|
|
35181
35213
|
if (this.editionMode === "inactive") {
|
|
35182
|
-
return this.getComposerContent(this.getters.getActivePosition());
|
|
35214
|
+
return this.getComposerContent(this.getters.getActivePosition()).text;
|
|
35183
35215
|
}
|
|
35184
35216
|
return this._currentContent;
|
|
35185
35217
|
}
|
|
@@ -35378,8 +35410,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35378
35410
|
this.sheetId = sheetId;
|
|
35379
35411
|
this.row = row;
|
|
35380
35412
|
this.editionMode = "editing";
|
|
35381
|
-
|
|
35382
|
-
this.
|
|
35413
|
+
const { text, adjustedSelection } = this.getComposerContent({ sheetId, col, row }, selection);
|
|
35414
|
+
this.initialContent = text;
|
|
35415
|
+
this.setContent(str || this.initialContent, adjustedSelection ?? selection);
|
|
35383
35416
|
this.colorIndexByRange = {};
|
|
35384
35417
|
const zone = positionToZone({ col: this.col, row: this.row });
|
|
35385
35418
|
this.captureSelection(zone, col, row);
|
|
@@ -35856,7 +35889,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35856
35889
|
constructor(get, args) {
|
|
35857
35890
|
super(get);
|
|
35858
35891
|
this.args = args;
|
|
35859
|
-
this._currentContent = this.getComposerContent();
|
|
35892
|
+
this._currentContent = this.getComposerContent().text;
|
|
35860
35893
|
}
|
|
35861
35894
|
getAutoCompleteProviders() {
|
|
35862
35895
|
const providersDefinitions = super.getAutoCompleteProviders();
|
|
@@ -35893,7 +35926,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
35893
35926
|
})
|
|
35894
35927
|
.join("");
|
|
35895
35928
|
}
|
|
35896
|
-
return localizeContent(content, this.getters.getLocale());
|
|
35929
|
+
return { text: localizeContent(content, this.getters.getLocale()) };
|
|
35897
35930
|
}
|
|
35898
35931
|
stopEdition() {
|
|
35899
35932
|
this._stopEdition();
|
|
@@ -39571,6 +39604,74 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
39571
39604
|
return path2D;
|
|
39572
39605
|
}
|
|
39573
39606
|
|
|
39607
|
+
/**
|
|
39608
|
+
* Get the relative path between two files
|
|
39609
|
+
*
|
|
39610
|
+
* Eg.:
|
|
39611
|
+
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
39612
|
+
*/
|
|
39613
|
+
function getRelativePath(from, to) {
|
|
39614
|
+
const fromPathParts = from.split("/");
|
|
39615
|
+
const toPathParts = to.split("/");
|
|
39616
|
+
let relPath = "";
|
|
39617
|
+
let startIndex = 0;
|
|
39618
|
+
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
39619
|
+
if (fromPathParts[i] === toPathParts[i]) {
|
|
39620
|
+
startIndex++;
|
|
39621
|
+
}
|
|
39622
|
+
else {
|
|
39623
|
+
relPath += "../";
|
|
39624
|
+
}
|
|
39625
|
+
}
|
|
39626
|
+
relPath += toPathParts.slice(startIndex).join("/");
|
|
39627
|
+
return relPath;
|
|
39628
|
+
}
|
|
39629
|
+
/**
|
|
39630
|
+
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
39631
|
+
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
39632
|
+
*
|
|
39633
|
+
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
39634
|
+
*/
|
|
39635
|
+
function arrayToObject(array, indexOffset = 0) {
|
|
39636
|
+
const obj = {};
|
|
39637
|
+
for (let i = 0; i < array.length; i++) {
|
|
39638
|
+
if (array[i]) {
|
|
39639
|
+
obj[i + indexOffset] = array[i];
|
|
39640
|
+
}
|
|
39641
|
+
}
|
|
39642
|
+
return obj;
|
|
39643
|
+
}
|
|
39644
|
+
/**
|
|
39645
|
+
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
39646
|
+
* Replace with characters understandable by JS
|
|
39647
|
+
*/
|
|
39648
|
+
function fixXlsxUnicode(str) {
|
|
39649
|
+
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
39650
|
+
return String.fromCharCode(parseInt(code, 16));
|
|
39651
|
+
});
|
|
39652
|
+
}
|
|
39653
|
+
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
39654
|
+
function getSheetDataHeader(sheetData, dimension, index) {
|
|
39655
|
+
if (dimension === "COL") {
|
|
39656
|
+
if (!sheetData.cols[index]) {
|
|
39657
|
+
sheetData.cols[index] = {};
|
|
39658
|
+
}
|
|
39659
|
+
return sheetData.cols[index];
|
|
39660
|
+
}
|
|
39661
|
+
if (!sheetData.rows[index]) {
|
|
39662
|
+
sheetData.rows[index] = {};
|
|
39663
|
+
}
|
|
39664
|
+
return sheetData.rows[index];
|
|
39665
|
+
}
|
|
39666
|
+
/** Prefix the string by "=" if the string looks like a formula */
|
|
39667
|
+
function prefixFormulaWithEqual(formula) {
|
|
39668
|
+
if (formula[0] === "=") {
|
|
39669
|
+
return formula;
|
|
39670
|
+
}
|
|
39671
|
+
const tokens = tokenize(formula);
|
|
39672
|
+
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
39673
|
+
}
|
|
39674
|
+
|
|
39574
39675
|
/**
|
|
39575
39676
|
* Map of the different types of conversions warnings and their name in error messages
|
|
39576
39677
|
*/
|
|
@@ -40093,66 +40194,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40093
40194
|
*/
|
|
40094
40195
|
const DEFAULT_SYSTEM_COLOR = "FF000000";
|
|
40095
40196
|
|
|
40096
|
-
/**
|
|
40097
|
-
* Get the relative path between two files
|
|
40098
|
-
*
|
|
40099
|
-
* Eg.:
|
|
40100
|
-
* from "folder1/file1.txt" to "folder2/file2.txt" => "../folder2/file2.txt"
|
|
40101
|
-
*/
|
|
40102
|
-
function getRelativePath(from, to) {
|
|
40103
|
-
const fromPathParts = from.split("/");
|
|
40104
|
-
const toPathParts = to.split("/");
|
|
40105
|
-
let relPath = "";
|
|
40106
|
-
let startIndex = 0;
|
|
40107
|
-
for (let i = 0; i < fromPathParts.length - 1; i++) {
|
|
40108
|
-
if (fromPathParts[i] === toPathParts[i]) {
|
|
40109
|
-
startIndex++;
|
|
40110
|
-
}
|
|
40111
|
-
else {
|
|
40112
|
-
relPath += "../";
|
|
40113
|
-
}
|
|
40114
|
-
}
|
|
40115
|
-
relPath += toPathParts.slice(startIndex).join("/");
|
|
40116
|
-
return relPath;
|
|
40117
|
-
}
|
|
40118
|
-
/**
|
|
40119
|
-
* Convert an array of element into an object where the objects keys were the elements position in the array.
|
|
40120
|
-
* Can give an offset as argument, and all the array indexes will we shifted by this offset in the returned object.
|
|
40121
|
-
*
|
|
40122
|
-
* eg. : ["a", "b"] => {0:"a", 1:"b"}
|
|
40123
|
-
*/
|
|
40124
|
-
function arrayToObject(array, indexOffset = 0) {
|
|
40125
|
-
const obj = {};
|
|
40126
|
-
for (let i = 0; i < array.length; i++) {
|
|
40127
|
-
if (array[i]) {
|
|
40128
|
-
obj[i + indexOffset] = array[i];
|
|
40129
|
-
}
|
|
40130
|
-
}
|
|
40131
|
-
return obj;
|
|
40132
|
-
}
|
|
40133
|
-
/**
|
|
40134
|
-
* In xlsx we can have string with unicode characters with the format _x00fa_.
|
|
40135
|
-
* Replace with characters understandable by JS
|
|
40136
|
-
*/
|
|
40137
|
-
function fixXlsxUnicode(str) {
|
|
40138
|
-
return str.replace(/_x([0-9a-zA-Z]{4})_/g, (match, code) => {
|
|
40139
|
-
return String.fromCharCode(parseInt(code, 16));
|
|
40140
|
-
});
|
|
40141
|
-
}
|
|
40142
|
-
/** Get a header in the SheetData. Create the header if it doesn't exist in the SheetData */
|
|
40143
|
-
function getSheetDataHeader(sheetData, dimension, index) {
|
|
40144
|
-
if (dimension === "COL") {
|
|
40145
|
-
if (!sheetData.cols[index]) {
|
|
40146
|
-
sheetData.cols[index] = {};
|
|
40147
|
-
}
|
|
40148
|
-
return sheetData.cols[index];
|
|
40149
|
-
}
|
|
40150
|
-
if (!sheetData.rows[index]) {
|
|
40151
|
-
sheetData.rows[index] = {};
|
|
40152
|
-
}
|
|
40153
|
-
return sheetData.rows[index];
|
|
40154
|
-
}
|
|
40155
|
-
|
|
40156
40197
|
const XLSX_DATE_FORMAT_REGEX = /^(yy|yyyy|m{1,5}|d{1,4}|h{1,2}|s{1,2}|am\/pm|a\/m|\s|-|\/|\.|:)+$/i;
|
|
40157
40198
|
/**
|
|
40158
40199
|
* Convert excel format to o_spreadsheet format
|
|
@@ -40367,9 +40408,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40367
40408
|
if (!rule.operator || !rule.formula || rule.formula.length === 0)
|
|
40368
40409
|
continue;
|
|
40369
40410
|
operator = CF_OPERATOR_TYPE_CONVERSION_MAP[rule.operator];
|
|
40370
|
-
values.push(
|
|
40411
|
+
values.push(prefixFormulaWithEqual(rule.formula[0]));
|
|
40371
40412
|
if (rule.formula.length === 2) {
|
|
40372
|
-
values.push(
|
|
40413
|
+
values.push(prefixFormulaWithEqual(rule.formula[1]));
|
|
40373
40414
|
}
|
|
40374
40415
|
break;
|
|
40375
40416
|
}
|
|
@@ -40527,11 +40568,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
40527
40568
|
? ICON_SETS[iconSet].neutral
|
|
40528
40569
|
: ICON_SETS[iconSet].good;
|
|
40529
40570
|
}
|
|
40530
|
-
/** Prefix the string by "=" if the string looks like a formula */
|
|
40531
|
-
function prefixFormula(formula) {
|
|
40532
|
-
const tokens = tokenize(formula);
|
|
40533
|
-
return tokens.length === 1 && tokens[0].type !== "REFERENCE" ? formula : "=" + formula;
|
|
40534
|
-
}
|
|
40535
40571
|
// ---------------------------------------------------------------------------
|
|
40536
40572
|
// Warnings
|
|
40537
40573
|
// ---------------------------------------------------------------------------
|
|
@@ -41007,7 +41043,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41007
41043
|
dvRules.push(decimalRule);
|
|
41008
41044
|
break;
|
|
41009
41045
|
case "list":
|
|
41010
|
-
const listRule =
|
|
41046
|
+
const listRule = convertListRule(dvId++, dv);
|
|
41011
41047
|
dvRules.push(listRule);
|
|
41012
41048
|
break;
|
|
41013
41049
|
case "date":
|
|
@@ -41027,9 +41063,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41027
41063
|
return dvRules;
|
|
41028
41064
|
}
|
|
41029
41065
|
function convertDecimalRule(id, dv) {
|
|
41030
|
-
const values = [dv.formula1.toString()];
|
|
41066
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
41031
41067
|
if (dv.formula2) {
|
|
41032
|
-
values.push(dv.formula2.toString());
|
|
41068
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
41033
41069
|
}
|
|
41034
41070
|
return {
|
|
41035
41071
|
id: id.toString(),
|
|
@@ -41041,7 +41077,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41041
41077
|
},
|
|
41042
41078
|
};
|
|
41043
41079
|
}
|
|
41044
|
-
function
|
|
41080
|
+
function convertListRule(id, dv) {
|
|
41045
41081
|
const formula1 = dv.formula1.toString();
|
|
41046
41082
|
const isRangeRule = rangeReference.test(formula1);
|
|
41047
41083
|
return {
|
|
@@ -41057,9 +41093,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41057
41093
|
}
|
|
41058
41094
|
function convertDateRule(id, dv) {
|
|
41059
41095
|
let criterion;
|
|
41060
|
-
const values = [dv.formula1.toString()];
|
|
41096
|
+
const values = [prefixFormulaWithEqual(dv.formula1.toString())];
|
|
41061
41097
|
if (dv.formula2) {
|
|
41062
|
-
values.push(dv.formula2.toString());
|
|
41098
|
+
values.push(prefixFormulaWithEqual(dv.formula2.toString()));
|
|
41063
41099
|
criterion = {
|
|
41064
41100
|
type: XLSX_DV_DATE_OPERATOR_TO_DV_TYPE_MAPPING[dv.operator],
|
|
41065
41101
|
values: getDateCriterionFormattedValues(values, DEFAULT_LOCALE),
|
|
@@ -41086,7 +41122,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
41086
41122
|
isBlocking: dv.errorStyle !== "warning",
|
|
41087
41123
|
criterion: {
|
|
41088
41124
|
type: "customFormula",
|
|
41089
|
-
values: [
|
|
41125
|
+
values: [prefixFormulaWithEqual(dv.formula1.toString())],
|
|
41090
41126
|
},
|
|
41091
41127
|
};
|
|
41092
41128
|
}
|
|
@@ -49750,39 +49786,63 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49750
49786
|
this.model.dispatch("AUTOFILL_TABLE_COLUMN", { ...this.currentEditedCell });
|
|
49751
49787
|
this.setContent("");
|
|
49752
49788
|
}
|
|
49753
|
-
getComposerContent(position) {
|
|
49789
|
+
getComposerContent(position, selection) {
|
|
49754
49790
|
const locale = this.getters.getLocale();
|
|
49755
49791
|
const cell = this.getters.getCell(position);
|
|
49756
49792
|
if (cell?.isFormula) {
|
|
49757
49793
|
const prettifiedContent = this.getPrettifiedFormula(cell);
|
|
49758
|
-
|
|
49794
|
+
// when a formula is prettified (multi lines, indented), adapt the cursor position
|
|
49795
|
+
// to take into account line breaks and tabs
|
|
49796
|
+
function adjustCursorIndex(targetIndex) {
|
|
49797
|
+
let adjustedIndex = 0;
|
|
49798
|
+
let originalIndex = 0;
|
|
49799
|
+
while (originalIndex < targetIndex) {
|
|
49800
|
+
adjustedIndex++;
|
|
49801
|
+
const char = prettifiedContent[adjustedIndex];
|
|
49802
|
+
if (char !== "\n" && char !== "\t") {
|
|
49803
|
+
originalIndex++;
|
|
49804
|
+
}
|
|
49805
|
+
}
|
|
49806
|
+
return adjustedIndex;
|
|
49807
|
+
}
|
|
49808
|
+
let adjustedSelection = selection;
|
|
49809
|
+
if (selection) {
|
|
49810
|
+
adjustedSelection = {
|
|
49811
|
+
start: adjustCursorIndex(selection.start),
|
|
49812
|
+
end: adjustCursorIndex(selection.end),
|
|
49813
|
+
};
|
|
49814
|
+
}
|
|
49815
|
+
return {
|
|
49816
|
+
text: localizeFormula(prettifiedContent, locale),
|
|
49817
|
+
adjustedSelection,
|
|
49818
|
+
};
|
|
49759
49819
|
}
|
|
49760
49820
|
const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
|
|
49761
49821
|
if (spreader) {
|
|
49762
|
-
return "";
|
|
49822
|
+
return { text: "" };
|
|
49763
49823
|
}
|
|
49764
49824
|
const { format, value, type, formattedValue } = this.getters.getEvaluatedCell(position);
|
|
49765
49825
|
switch (type) {
|
|
49766
49826
|
case CellValueType.empty:
|
|
49767
|
-
return "";
|
|
49827
|
+
return { text: "" };
|
|
49768
49828
|
case CellValueType.text:
|
|
49769
49829
|
case CellValueType.error:
|
|
49770
|
-
return value;
|
|
49830
|
+
return { text: value };
|
|
49771
49831
|
case CellValueType.boolean:
|
|
49772
|
-
return formattedValue;
|
|
49832
|
+
return { text: formattedValue };
|
|
49773
49833
|
case CellValueType.number:
|
|
49774
49834
|
if (format && isDateTimeFormat(format)) {
|
|
49775
49835
|
if (parseDateTime(formattedValue, locale) !== null) {
|
|
49776
49836
|
// formatted string can be parsed again
|
|
49777
|
-
return formattedValue;
|
|
49837
|
+
return { text: formattedValue };
|
|
49778
49838
|
}
|
|
49779
49839
|
// display a simplified and parsable string otherwise
|
|
49780
49840
|
const timeFormat = Number.isInteger(value)
|
|
49781
49841
|
? locale.dateFormat
|
|
49782
49842
|
: getDateTimeFormat(locale);
|
|
49783
|
-
return formatValue(value, { locale, format: timeFormat });
|
|
49843
|
+
return { text: formatValue(value, { locale, format: timeFormat }) };
|
|
49784
49844
|
}
|
|
49785
|
-
return this.numberComposerContent(value, format, locale);
|
|
49845
|
+
return { text: this.numberComposerContent(value, format, locale) };
|
|
49786
49846
|
}
|
|
49787
49847
|
}
|
|
49788
49848
|
getPrettifiedFormula(cell) {
|
|
@@ -49951,8 +50011,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
49951
50011
|
},
|
|
49952
50012
|
focus: this.focus,
|
|
49953
50013
|
isDefaultFocus: true,
|
|
49954
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
50014
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
49955
50015
|
focusMode: "contentFocus",
|
|
50016
|
+
selection,
|
|
49956
50017
|
}),
|
|
49957
50018
|
onComposerCellFocused: (content) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
49958
50019
|
focusMode: "cellFocus",
|
|
@@ -57358,12 +57419,13 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57358
57419
|
onCloseSidePanel: { type: Function, optional: true },
|
|
57359
57420
|
};
|
|
57360
57421
|
state = owl.useState({ rule: this.defaultDataValidationRule, errors: [] });
|
|
57422
|
+
editingSheetId;
|
|
57361
57423
|
setup() {
|
|
57424
|
+
this.editingSheetId = this.env.model.getters.getActiveSheetId();
|
|
57362
57425
|
if (this.props.rule) {
|
|
57363
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
57364
57426
|
this.state.rule = {
|
|
57365
57427
|
...this.props.rule,
|
|
57366
|
-
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range,
|
|
57428
|
+
ranges: this.props.rule.ranges.map((range) => this.env.model.getters.getRangeString(range, this.editingSheetId)),
|
|
57367
57429
|
};
|
|
57368
57430
|
this.state.rule.criterion.type = this.props.rule.criterion.type;
|
|
57369
57431
|
}
|
|
@@ -57397,7 +57459,6 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57397
57459
|
const locale = this.env.model.getters.getLocale();
|
|
57398
57460
|
const criterion = rule.criterion;
|
|
57399
57461
|
const criterionEvaluator = criterionEvaluatorRegistry.get(criterion.type);
|
|
57400
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
57401
57462
|
const values = criterion.values
|
|
57402
57463
|
.slice(0, criterionEvaluator.numberOfValues(criterion))
|
|
57403
57464
|
.map((value) => value?.trim())
|
|
@@ -57405,8 +57466,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57405
57466
|
.map((value) => canonicalizeContent(value, locale));
|
|
57406
57467
|
rule.criterion = { ...criterion, values };
|
|
57407
57468
|
return {
|
|
57408
|
-
sheetId,
|
|
57409
|
-
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(
|
|
57469
|
+
sheetId: this.editingSheetId,
|
|
57470
|
+
ranges: this.state.rule.ranges.map((xc) => this.env.model.getters.getRangeDataFromXc(this.editingSheetId, xc)),
|
|
57410
57471
|
rule,
|
|
57411
57472
|
};
|
|
57412
57473
|
}
|
|
@@ -57933,6 +57994,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
57933
57994
|
.o-button {
|
|
57934
57995
|
height: 19px;
|
|
57935
57996
|
width: 19px;
|
|
57997
|
+
box-sizing: content-box;
|
|
57936
57998
|
.o-icon {
|
|
57937
57999
|
height: 14px;
|
|
57938
58000
|
width: 14px;
|
|
@@ -68755,7 +68817,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68755
68817
|
* in the correct order they should be evaluated.
|
|
68756
68818
|
* This is called a topological ordering (excluding cycles)
|
|
68757
68819
|
*/
|
|
68758
|
-
getCellsDependingOn(ranges) {
|
|
68820
|
+
getCellsDependingOn(ranges, ignore) {
|
|
68759
68821
|
const visited = this.createEmptyPositionSet();
|
|
68760
68822
|
const queue = Array.from(ranges).reverse();
|
|
68761
68823
|
while (queue.length > 0) {
|
|
@@ -68770,7 +68832,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
68770
68832
|
const impactedPositions = this.rTree.search(range).map((dep) => dep.data);
|
|
68771
68833
|
const nextInQueue = {};
|
|
68772
68834
|
for (const position of impactedPositions) {
|
|
68773
|
-
if (!visited.has(position)) {
|
|
68835
|
+
if (!visited.has(position) && !ignore.has(position)) {
|
|
68774
68836
|
if (!nextInQueue[position.sheetId]) {
|
|
68775
68837
|
nextInQueue[position.sheetId] = [];
|
|
68776
68838
|
}
|
|
@@ -69328,7 +69390,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69328
69390
|
}
|
|
69329
69391
|
invalidatePositionsDependingOnSpread(sheetId, resultZone) {
|
|
69330
69392
|
// the result matrix is split in 2 zones to exclude the array formula position
|
|
69331
|
-
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })));
|
|
69393
|
+
const invalidatedPositions = this.formulaDependencies().getCellsDependingOn(excludeTopLeft(resultZone).map((zone) => ({ sheetId, zone })), this.nextPositionsToUpdate);
|
|
69332
69394
|
invalidatedPositions.delete({ sheetId, col: resultZone.left, row: resultZone.top });
|
|
69333
69395
|
this.nextPositionsToUpdate.addMany(invalidatedPositions);
|
|
69334
69396
|
}
|
|
@@ -69446,7 +69508,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
69446
69508
|
for (const sheetId in zonesBySheetIds) {
|
|
69447
69509
|
ranges.push(...zonesBySheetIds[sheetId].map((zone) => ({ sheetId, zone })));
|
|
69448
69510
|
}
|
|
69449
|
-
return this.formulaDependencies().getCellsDependingOn(ranges);
|
|
69511
|
+
return this.formulaDependencies().getCellsDependingOn(ranges, this.nextPositionsToUpdate);
|
|
69450
69512
|
}
|
|
69451
69513
|
}
|
|
69452
69514
|
function forEachSpreadPositionInMatrix(nbColumns, nbRows, callback) {
|
|
@@ -70957,7 +71019,8 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
70957
71019
|
const topLeft = { col: unionZone.left, row: unionZone.top, sheetId };
|
|
70958
71020
|
const parentSpreadingCell = this.getters.getArrayFormulaSpreadingOn(topLeft);
|
|
70959
71021
|
if (!parentSpreadingCell) {
|
|
70960
|
-
|
|
71022
|
+
const evaluatedCell = this.getters.getEvaluatedCell(topLeft);
|
|
71023
|
+
return (evaluatedCell.value === CellErrorType.SpilledBlocked && !evaluatedCell.errorOriginPosition);
|
|
70961
71024
|
}
|
|
70962
71025
|
else if (deepEquals(parentSpreadingCell, topLeft) && getZoneArea(unionZone) === 1) {
|
|
70963
71026
|
return true;
|
|
@@ -82129,6 +82192,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82129
82192
|
static components = { Menu };
|
|
82130
82193
|
rootItems = topbarMenuRegistry.getMenuItems();
|
|
82131
82194
|
menuRef = owl.useRef("menu");
|
|
82195
|
+
containerRef = owl.useRef("container");
|
|
82132
82196
|
state = owl.useState({
|
|
82133
82197
|
menuItems: this.rootItems,
|
|
82134
82198
|
title: _t("Menu Bar"),
|
|
@@ -82136,6 +82200,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82136
82200
|
});
|
|
82137
82201
|
setup() {
|
|
82138
82202
|
owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
|
|
82203
|
+
owl.onMounted(this.updateShadows);
|
|
82139
82204
|
}
|
|
82140
82205
|
onExternalClick(ev) {
|
|
82141
82206
|
if (!this.menuRef.el?.contains(ev.target)) {
|
|
@@ -82148,6 +82213,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82148
82213
|
this.state.parentState = { ...this.state };
|
|
82149
82214
|
this.state.menuItems = children;
|
|
82150
82215
|
this.state.title = menu.name(this.env);
|
|
82216
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
82151
82217
|
}
|
|
82152
82218
|
else {
|
|
82153
82219
|
this.state.menuItems = this.rootItems;
|
|
@@ -82169,6 +82235,19 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82169
82235
|
height: `${this.props.height}px`,
|
|
82170
82236
|
});
|
|
82171
82237
|
}
|
|
82238
|
+
updateShadows() {
|
|
82239
|
+
if (!this.containerRef.el) {
|
|
82240
|
+
return;
|
|
82241
|
+
}
|
|
82242
|
+
this.containerRef.el.classList.remove("scroll-top", "scroll-bottom");
|
|
82243
|
+
const maxScroll = this.containerRef.el.scrollHeight - this.containerRef.el.clientHeight || 0;
|
|
82244
|
+
if (this.containerRef.el.scrollTop < maxScroll - 1) {
|
|
82245
|
+
this.containerRef.el.classList.add("scroll-bottom");
|
|
82246
|
+
}
|
|
82247
|
+
if (this.containerRef.el.scrollTop > 0) {
|
|
82248
|
+
this.containerRef.el.classList.add("scroll-top");
|
|
82249
|
+
}
|
|
82250
|
+
}
|
|
82172
82251
|
onClickBack() {
|
|
82173
82252
|
if (!this.state.parentState) {
|
|
82174
82253
|
this.props.onClose();
|
|
@@ -82177,6 +82256,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82177
82256
|
this.state.menuItems = this.state.parentState.menuItems;
|
|
82178
82257
|
this.state.title = this.state.parentState.title;
|
|
82179
82258
|
this.state.parentState = this.state.parentState.parentState;
|
|
82259
|
+
this.containerRef.el?.scrollTo({ top: 0 });
|
|
82180
82260
|
}
|
|
82181
82261
|
get backTitle() {
|
|
82182
82262
|
return this.state.parentState ? _t("Go to previous menu") : _t("Close menu bar");
|
|
@@ -82233,7 +82313,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82233
82313
|
: "inactive";
|
|
82234
82314
|
}
|
|
82235
82315
|
get showFxIcon() {
|
|
82236
|
-
return this.focus === "inactive" &&
|
|
82316
|
+
return (this.focus === "inactive" &&
|
|
82317
|
+
!this.composerStore.currentContent &&
|
|
82318
|
+
!this.composerStore.placeholder);
|
|
82237
82319
|
}
|
|
82238
82320
|
get rect() {
|
|
82239
82321
|
return this.composerRef.el
|
|
@@ -82250,8 +82332,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82250
82332
|
},
|
|
82251
82333
|
focus: this.focus,
|
|
82252
82334
|
composerStore: this.composerStore,
|
|
82253
|
-
onComposerContentFocused: () => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
82335
|
+
onComposerContentFocused: (selection) => this.composerFocusStore.focusComposer(this.composerInterface, {
|
|
82254
82336
|
focusMode: "contentFocus",
|
|
82337
|
+
selection,
|
|
82255
82338
|
}),
|
|
82256
82339
|
isDefaultFocus: false,
|
|
82257
82340
|
inputStyle: cssPropertiesToCss({
|
|
@@ -82259,6 +82342,7 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82259
82342
|
"max-height": `130px`,
|
|
82260
82343
|
}),
|
|
82261
82344
|
showAssistant: !isIOS(), // Hide assistant on iOS as it breaks visually
|
|
82345
|
+
placeholder: this.composerStore.placeholder,
|
|
82262
82346
|
};
|
|
82263
82347
|
}
|
|
82264
82348
|
get symbols() {
|
|
@@ -82321,7 +82405,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
82321
82405
|
: "inactive";
|
|
82322
82406
|
}
|
|
82323
82407
|
get showFxIcon() {
|
|
82324
|
-
return this.focus === "inactive" &&
|
|
82408
|
+
return (this.focus === "inactive" &&
|
|
82409
|
+
!this.composerStore.currentContent &&
|
|
82410
|
+
!this.composerStore.placeholder);
|
|
82325
82411
|
}
|
|
82326
82412
|
get composerStyle() {
|
|
82327
82413
|
const style = {
|
|
@@ -88537,9 +88623,9 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
88537
88623
|
exports.tokenize = tokenize;
|
|
88538
88624
|
|
|
88539
88625
|
|
|
88540
|
-
__info__.version = "19.0.
|
|
88541
|
-
__info__.date = "2025-10-
|
|
88542
|
-
__info__.hash = "
|
|
88626
|
+
__info__.version = "19.0.6";
|
|
88627
|
+
__info__.date = "2025-10-16T06:39:36.282Z";
|
|
88628
|
+
__info__.hash = "0d4315a";
|
|
88543
88629
|
|
|
88544
88630
|
|
|
88545
88631
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|