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