@odoo/o-spreadsheet 19.3.14 → 19.3.16
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 +130 -33
- package/dist/o_spreadsheet.css +3 -3
- package/dist/o_spreadsheet.esm.js +130 -33
- package/dist/o_spreadsheet.iife.js +130 -33
- package/dist/o_spreadsheet.min.iife.js +260 -260
- package/dist/o_spreadsheet.xml +3 -3
- package/dist/types/components/figures/chart/chartJs/chartjs_geo_projection_plugin.d.ts +12 -0
- package/dist/types/functions/function_registry.d.ts +3 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/plugins/core/squisher.d.ts +2 -1
- package/package.json +1 -1
package/dist/o_spreadsheet.cjs
CHANGED
|
@@ -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.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.16
|
|
6
|
+
* @date 2026-08-12T09:15:31.627Z
|
|
7
|
+
* @hash 464be42
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
@@ -4259,19 +4259,58 @@ function applyVectorization(formula, args, acceptToVectorize = void 0) {
|
|
|
4259
4259
|
}
|
|
4260
4260
|
}
|
|
4261
4261
|
if (countVectorizedCol === 1 && countVectorizedRow === 1) return formula(...args);
|
|
4262
|
-
const
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4262
|
+
const argsBuffer = new Array(args.length);
|
|
4263
|
+
const argGetters = [];
|
|
4264
|
+
const vectorizedIndices = [];
|
|
4265
|
+
for (let k = 0; k < args.length; k++) {
|
|
4266
|
+
const arg = args[k];
|
|
4267
|
+
switch (vectorArgsType?.[k]) {
|
|
4268
|
+
case "matrix":
|
|
4269
|
+
argGetters.push((i, j) => arg[i][j]);
|
|
4270
|
+
vectorizedIndices.push(k);
|
|
4271
|
+
break;
|
|
4272
|
+
case "horizontal":
|
|
4273
|
+
argGetters.push((i) => arg[i][0]);
|
|
4274
|
+
vectorizedIndices.push(k);
|
|
4275
|
+
break;
|
|
4276
|
+
case "vertical":
|
|
4277
|
+
argGetters.push((_i, j) => arg[0][j]);
|
|
4278
|
+
vectorizedIndices.push(k);
|
|
4279
|
+
break;
|
|
4280
|
+
case void 0:
|
|
4281
|
+
argsBuffer[k] = arg;
|
|
4282
|
+
break;
|
|
4268
4283
|
}
|
|
4269
|
-
}
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4274
|
-
|
|
4284
|
+
}
|
|
4285
|
+
const nbVectorized = vectorizedIndices.length;
|
|
4286
|
+
let callFormula;
|
|
4287
|
+
switch (argsBuffer.length) {
|
|
4288
|
+
case 1:
|
|
4289
|
+
callFormula = () => formula(argsBuffer[0]);
|
|
4290
|
+
break;
|
|
4291
|
+
case 2:
|
|
4292
|
+
callFormula = () => formula(argsBuffer[0], argsBuffer[1]);
|
|
4293
|
+
break;
|
|
4294
|
+
case 3:
|
|
4295
|
+
callFormula = () => formula(argsBuffer[0], argsBuffer[1], argsBuffer[2]);
|
|
4296
|
+
break;
|
|
4297
|
+
default: callFormula = () => formula(...argsBuffer);
|
|
4298
|
+
}
|
|
4299
|
+
const result = new Array(countVectorizedCol);
|
|
4300
|
+
for (let col = 0; col < countVectorizedCol; col++) {
|
|
4301
|
+
const column = new Array(countVectorizedRow);
|
|
4302
|
+
result[col] = column;
|
|
4303
|
+
for (let row = 0; row < countVectorizedRow; row++) {
|
|
4304
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4305
|
+
column[row] = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4306
|
+
continue;
|
|
4307
|
+
}
|
|
4308
|
+
for (let k = 0; k < nbVectorized; k++) argsBuffer[vectorizedIndices[k]] = argGetters[k](col, row);
|
|
4309
|
+
const singleCellComputeResult = callFormula();
|
|
4310
|
+
column[row] = isMatrix(singleCellComputeResult) ? singleCellComputeResult[0][0] : singleCellComputeResult;
|
|
4311
|
+
}
|
|
4312
|
+
}
|
|
4313
|
+
return result;
|
|
4275
4314
|
}
|
|
4276
4315
|
/**
|
|
4277
4316
|
* This function allows to visit arguments and stop the visit if necessary.
|
|
@@ -4618,12 +4657,15 @@ function emptyDataErrorMessage(argName) {
|
|
|
4618
4657
|
//#endregion
|
|
4619
4658
|
//#region src/functions/create_compute_function.ts
|
|
4620
4659
|
function createComputeFunction(descr) {
|
|
4660
|
+
let currentArgDefinitions = [];
|
|
4621
4661
|
function vectorizedCompute(...args) {
|
|
4622
4662
|
const acceptToVectorize = [];
|
|
4663
|
+
currentArgDefinitions = new Array(args.length);
|
|
4623
4664
|
const argsToFocus = argTargeting(descr, args.length);
|
|
4624
4665
|
for (let i = 0; i < args.length; i++) {
|
|
4625
4666
|
const argIndex = argsToFocus[i].index;
|
|
4626
4667
|
const argDefinition = descr.args[argIndex];
|
|
4668
|
+
currentArgDefinitions[i] = argDefinition;
|
|
4627
4669
|
const arg = args[i];
|
|
4628
4670
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", descr.name, (i + 1).toString()));
|
|
4629
4671
|
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
@@ -4636,10 +4678,9 @@ function createComputeFunction(descr) {
|
|
|
4636
4678
|
return result;
|
|
4637
4679
|
}
|
|
4638
4680
|
function errorHandlingCompute(...args) {
|
|
4639
|
-
const argsToFocus = argTargeting(descr, args.length);
|
|
4640
4681
|
for (let i = 0; i < args.length; i++) {
|
|
4641
4682
|
const arg = args[i];
|
|
4642
|
-
if (!
|
|
4683
|
+
if (!currentArgDefinitions[i].acceptErrors && !isMatrix(arg) && isEvaluationError(arg?.value)) return arg;
|
|
4643
4684
|
}
|
|
4644
4685
|
try {
|
|
4645
4686
|
return computeFunctionToObject.apply(this, args);
|
|
@@ -4703,6 +4744,9 @@ var FunctionRegistry = class extends Registry {
|
|
|
4703
4744
|
}
|
|
4704
4745
|
};
|
|
4705
4746
|
const functionRegistry = new FunctionRegistry();
|
|
4747
|
+
/** Formulas using one of these functions are never squished: they are always exported
|
|
4748
|
+
* as a full formula string, and they don't become the base formula of the next cells. */
|
|
4749
|
+
const NonSquishableFunctionRegistry = new Registry();
|
|
4706
4750
|
|
|
4707
4751
|
//#endregion
|
|
4708
4752
|
//#region src/types/locale.ts
|
|
@@ -8968,6 +9012,25 @@ const funnelTooltipPositioner = function(elements) {
|
|
|
8968
9012
|
};
|
|
8969
9013
|
};
|
|
8970
9014
|
|
|
9015
|
+
//#endregion
|
|
9016
|
+
//#region src/components/figures/chart/chartJs/chartjs_geo_projection_plugin.ts
|
|
9017
|
+
/**
|
|
9018
|
+
* ChartJS plugin to apply custom changes to a d3 projection.
|
|
9019
|
+
*
|
|
9020
|
+
* We pass the projection as a string instead of a customized d3 object so
|
|
9021
|
+
* Chart.js creates a fresh projection instance. Custom changes (e.g. rotation)
|
|
9022
|
+
* are then applied in `beforeUpdate`.
|
|
9023
|
+
*
|
|
9024
|
+
* This is important because Chart.js mutates the projection instance at runtime,
|
|
9025
|
+
* and a customize d3 projection object would not be copied during deepCopy.
|
|
9026
|
+
*/
|
|
9027
|
+
const geoProjectionPlugin = {
|
|
9028
|
+
id: "geoProjection",
|
|
9029
|
+
beforeUpdate(chart) {
|
|
9030
|
+
if (chart.options?.scales?.projection?.projection === "conicConformal") chart.scales?.projection?.projection?.rotate([100, 0]);
|
|
9031
|
+
}
|
|
9032
|
+
};
|
|
9033
|
+
|
|
8971
9034
|
//#endregion
|
|
8972
9035
|
//#region src/components/figures/chart/chartJs/chartjs_minor_grid_plugin.ts
|
|
8973
9036
|
const chartMinorGridPlugin = {
|
|
@@ -10025,7 +10088,7 @@ function getGeoChartScales(definition, args) {
|
|
|
10025
10088
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
10026
10089
|
return {
|
|
10027
10090
|
projection: {
|
|
10028
|
-
projection:
|
|
10091
|
+
projection: region?.defaultProjection || "mercator",
|
|
10029
10092
|
axis: "x"
|
|
10030
10093
|
},
|
|
10031
10094
|
color: {
|
|
@@ -10077,10 +10140,6 @@ function getFunnelChartScales(definition, args) {
|
|
|
10077
10140
|
}
|
|
10078
10141
|
};
|
|
10079
10142
|
}
|
|
10080
|
-
function getGeoChartProjection(projection) {
|
|
10081
|
-
if (projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
|
|
10082
|
-
return projection;
|
|
10083
|
-
}
|
|
10084
10143
|
function getChartAxisTitleRuntime(design) {
|
|
10085
10144
|
if (design?.title?.text) {
|
|
10086
10145
|
const { text, color, align, italic, bold } = design.title;
|
|
@@ -10965,6 +11024,10 @@ chartJsExtensionRegistry.add("chartBackgroundPlugin", {
|
|
|
10965
11024
|
register: (Chart) => Chart.register(chartBackgroundPlugin),
|
|
10966
11025
|
unregister: (Chart) => Chart.unregister(chartBackgroundPlugin)
|
|
10967
11026
|
});
|
|
11027
|
+
chartJsExtensionRegistry.add("geoProjectionPlugin", {
|
|
11028
|
+
register: (Chart) => Chart.register(geoProjectionPlugin),
|
|
11029
|
+
unregister: (Chart) => Chart.unregister(geoProjectionPlugin)
|
|
11030
|
+
});
|
|
10968
11031
|
var ChartJsComponent = class extends _odoo_owl.Component {
|
|
10969
11032
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10970
11033
|
static props = {
|
|
@@ -18292,7 +18355,7 @@ var FigureComponent = class extends _odoo_owl.Component {
|
|
|
18292
18355
|
case "ArrowLeft":
|
|
18293
18356
|
case "ArrowRight":
|
|
18294
18357
|
case "ArrowUp":
|
|
18295
|
-
const { col, row, offset } = this.postionInBoundary(this.props.figureUI, ev.key);
|
|
18358
|
+
const { col, row, offset } = this.postionInBoundary(this.env.model.getters.getActiveSheetId(), this.props.figureUI, ev.key);
|
|
18296
18359
|
this.env.model.dispatch("UPDATE_FIGURE", {
|
|
18297
18360
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
18298
18361
|
figureId: this.props.figureUI.id,
|
|
@@ -18316,34 +18379,52 @@ var FigureComponent = class extends _odoo_owl.Component {
|
|
|
18316
18379
|
break;
|
|
18317
18380
|
}
|
|
18318
18381
|
}
|
|
18319
|
-
postionInBoundary(
|
|
18320
|
-
|
|
18321
|
-
let { col, row, offset } = position;
|
|
18382
|
+
postionInBoundary(sheetId, figure, key) {
|
|
18383
|
+
let { col, row, offset } = figure;
|
|
18322
18384
|
offset = { ...offset };
|
|
18385
|
+
const maxAnchor = this.env.model.getters.getMaxAnchorOffset(sheetId, figure.height, figure.width);
|
|
18323
18386
|
switch (key) {
|
|
18324
18387
|
case "ArrowUp":
|
|
18325
18388
|
if (offset.y === 0) {
|
|
18326
18389
|
row--;
|
|
18390
|
+
while (row > 0 && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row--;
|
|
18327
18391
|
offset.y = this.env.model.getters.getRowSize(sheetId, row) - 1;
|
|
18328
18392
|
} else offset.y--;
|
|
18329
18393
|
break;
|
|
18330
18394
|
case "ArrowLeft":
|
|
18331
18395
|
if (offset.x === 0) {
|
|
18332
18396
|
col--;
|
|
18397
|
+
while (col > 0 && this.env.model.getters.isColHiddenByUser(sheetId, col)) col--;
|
|
18333
18398
|
offset.x = this.env.model.getters.getColSize(sheetId, col) - 1;
|
|
18334
18399
|
} else offset.x--;
|
|
18335
18400
|
break;
|
|
18336
18401
|
case "ArrowDown":
|
|
18337
18402
|
if (offset.y === this.env.model.getters.getRowSize(sheetId, row)) {
|
|
18338
18403
|
row++;
|
|
18404
|
+
while (row <= maxAnchor.row && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row++;
|
|
18339
18405
|
offset.y = 0;
|
|
18340
18406
|
} else offset.y++;
|
|
18341
18407
|
break;
|
|
18342
18408
|
case "ArrowRight": if (offset.x === this.env.model.getters.getColSize(sheetId, row)) {
|
|
18343
18409
|
col++;
|
|
18410
|
+
while (col <= maxAnchor.col && this.env.model.getters.isColHiddenByUser(sheetId, col)) col++;
|
|
18344
18411
|
offset.x = 0;
|
|
18345
18412
|
} else offset.x++;
|
|
18346
18413
|
}
|
|
18414
|
+
if (col < 0) {
|
|
18415
|
+
col = 0;
|
|
18416
|
+
offset.x = 0;
|
|
18417
|
+
} else if (col > maxAnchor.col || col === maxAnchor.col && offset.x > maxAnchor.offset.x) {
|
|
18418
|
+
col = maxAnchor.col;
|
|
18419
|
+
offset.x = maxAnchor.offset.x;
|
|
18420
|
+
}
|
|
18421
|
+
if (row < 0) {
|
|
18422
|
+
row = 0;
|
|
18423
|
+
offset.y = 0;
|
|
18424
|
+
} else if (row > maxAnchor.row || row === maxAnchor.row && offset.y > maxAnchor.offset.y) {
|
|
18425
|
+
row = maxAnchor.row;
|
|
18426
|
+
offset.y = maxAnchor.offset.y;
|
|
18427
|
+
}
|
|
18347
18428
|
return {
|
|
18348
18429
|
col,
|
|
18349
18430
|
row,
|
|
@@ -44683,7 +44764,13 @@ var CellComposerStore = class extends AbstractComposerStore {
|
|
|
44683
44764
|
const cell = this.getters.getEvaluatedCell(position);
|
|
44684
44765
|
if (cell.link && !isFormula(content)) content = markdownLink(content, cell.link.url);
|
|
44685
44766
|
const currentFormat = this.getters.getCell(position)?.format;
|
|
44686
|
-
const
|
|
44767
|
+
const isCurrentFormatDate = currentFormat && isDateTimeFormat(currentFormat);
|
|
44768
|
+
const contentDateFormat = detectDateFormat(content, this.getters.getLocale());
|
|
44769
|
+
let afterFormat;
|
|
44770
|
+
if (currentFormat !== "@") {
|
|
44771
|
+
if (contentDateFormat && !isCurrentFormatDate) afterFormat = contentDateFormat;
|
|
44772
|
+
else if (isCurrentFormatDate && isNumber(content, this.getters.getLocale())) afterFormat = "";
|
|
44773
|
+
}
|
|
44687
44774
|
this.addHeadersForSpreadingFormula(content);
|
|
44688
44775
|
result = this.model.dispatch("UPDATE_CELL", {
|
|
44689
44776
|
...this.currentEditedCell,
|
|
@@ -49780,7 +49867,8 @@ var Squisher = class {
|
|
|
49780
49867
|
* The result of this method is:
|
|
49781
49868
|
* - if the cell is not a formula, returns the content as is and resets the base formula
|
|
49782
49869
|
* - if the cell is a formula:
|
|
49783
|
-
* - if there is no previous formula, or the normalized formula is different from the previous one
|
|
49870
|
+
* - if there is no previous formula, or the normalized formula is different from the previous one or it contains blacklisted functions (see NonSquishableFunctionRegistry),
|
|
49871
|
+
* resets the base formula to this one and returns the full formula string
|
|
49784
49872
|
* - else, compares the literal values and range dependencies to the previous formula, and for each parameter:
|
|
49785
49873
|
* - for numbers: returns a relative change (+N or -N) if possible, else the full number or "=" if unchanged
|
|
49786
49874
|
* - for strings: returns the full string if changed, else "="
|
|
@@ -49788,6 +49876,10 @@ var Squisher = class {
|
|
|
49788
49876
|
* */
|
|
49789
49877
|
squish(cell, forSheetId) {
|
|
49790
49878
|
if (cell.isFormula) {
|
|
49879
|
+
if (NonSquishableFunctionRegistry.getAll().some((functionName) => cell.compiledFormula.usesSymbol(functionName))) {
|
|
49880
|
+
this.resetBaseFormula();
|
|
49881
|
+
return cell.compiledFormula.toFormulaString(this.getters, this.rangeToStringOptions);
|
|
49882
|
+
}
|
|
49791
49883
|
let numbers = [];
|
|
49792
49884
|
let strings = [];
|
|
49793
49885
|
let references = [];
|
|
@@ -61153,7 +61245,7 @@ var Session = class extends EventBus {
|
|
|
61153
61245
|
}
|
|
61154
61246
|
message = {
|
|
61155
61247
|
...message,
|
|
61156
|
-
commands:
|
|
61248
|
+
commands: revision.commands
|
|
61157
61249
|
};
|
|
61158
61250
|
}
|
|
61159
61251
|
if (this.isReplayingInitialRevisions) throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
|
|
@@ -66397,6 +66489,10 @@ function inverseCreateFigure(cmd) {
|
|
|
66397
66489
|
}
|
|
66398
66490
|
function inverseCreateChart(cmd) {
|
|
66399
66491
|
return [{
|
|
66492
|
+
type: "DELETE_CHART",
|
|
66493
|
+
chartId: cmd.chartId,
|
|
66494
|
+
sheetId: cmd.sheetId
|
|
66495
|
+
}, {
|
|
66400
66496
|
type: "DELETE_FIGURE",
|
|
66401
66497
|
figureId: cmd.figureId,
|
|
66402
66498
|
sheetId: cmd.sheetId
|
|
@@ -84608,7 +84704,8 @@ const registries = {
|
|
|
84608
84704
|
supportedPivotPositionalFormulaRegistry,
|
|
84609
84705
|
pivotToFunctionValueRegistry,
|
|
84610
84706
|
migrationStepRegistry,
|
|
84611
|
-
chartJsExtensionRegistry
|
|
84707
|
+
chartJsExtensionRegistry,
|
|
84708
|
+
NonSquishableFunctionRegistry
|
|
84612
84709
|
};
|
|
84613
84710
|
const helpers = {
|
|
84614
84711
|
arg,
|
|
@@ -84861,6 +84958,6 @@ exports.stores = stores;
|
|
|
84861
84958
|
exports.tokenColors = tokenColors;
|
|
84862
84959
|
exports.tokenize = tokenize;
|
|
84863
84960
|
|
|
84864
|
-
__info__.version = "19.3.
|
|
84865
|
-
__info__.date = "2026-
|
|
84866
|
-
__info__.hash = "
|
|
84961
|
+
__info__.version = "19.3.16";
|
|
84962
|
+
__info__.date = "2026-08-12T09:15:31.627Z";
|
|
84963
|
+
__info__.hash = "464be42";
|
package/dist/o_spreadsheet.css
CHANGED
|
@@ -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.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.16
|
|
6
|
+
* @date 2026-08-12T09:15:33.329Z
|
|
7
|
+
* @hash 464be42
|
|
8
8
|
*/
|
|
9
9
|
:root {
|
|
10
10
|
--os-gray-100: light-dark(#f9fafb, #1b1d26);
|
|
@@ -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.3.
|
|
6
|
-
* @date 2026-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 19.3.16
|
|
6
|
+
* @date 2026-08-12T09:15:31.627Z
|
|
7
|
+
* @hash 464be42
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { App, Component, blockDom, markRaw, onMounted, onPatched, onWillPatch, onWillStart, onWillUnmount, onWillUpdateProps, status, toRaw, useChildSubEnv, useComponent, useEffect, useEnv, useExternalListener, useRef, useState, useSubEnv, whenReady, xml } from "@odoo/owl";
|
|
@@ -4258,19 +4258,58 @@ function applyVectorization(formula, args, acceptToVectorize = void 0) {
|
|
|
4258
4258
|
}
|
|
4259
4259
|
}
|
|
4260
4260
|
if (countVectorizedCol === 1 && countVectorizedRow === 1) return formula(...args);
|
|
4261
|
-
const
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4261
|
+
const argsBuffer = new Array(args.length);
|
|
4262
|
+
const argGetters = [];
|
|
4263
|
+
const vectorizedIndices = [];
|
|
4264
|
+
for (let k = 0; k < args.length; k++) {
|
|
4265
|
+
const arg = args[k];
|
|
4266
|
+
switch (vectorArgsType?.[k]) {
|
|
4267
|
+
case "matrix":
|
|
4268
|
+
argGetters.push((i, j) => arg[i][j]);
|
|
4269
|
+
vectorizedIndices.push(k);
|
|
4270
|
+
break;
|
|
4271
|
+
case "horizontal":
|
|
4272
|
+
argGetters.push((i) => arg[i][0]);
|
|
4273
|
+
vectorizedIndices.push(k);
|
|
4274
|
+
break;
|
|
4275
|
+
case "vertical":
|
|
4276
|
+
argGetters.push((_i, j) => arg[0][j]);
|
|
4277
|
+
vectorizedIndices.push(k);
|
|
4278
|
+
break;
|
|
4279
|
+
case void 0:
|
|
4280
|
+
argsBuffer[k] = arg;
|
|
4281
|
+
break;
|
|
4267
4282
|
}
|
|
4268
|
-
}
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
|
|
4283
|
+
}
|
|
4284
|
+
const nbVectorized = vectorizedIndices.length;
|
|
4285
|
+
let callFormula;
|
|
4286
|
+
switch (argsBuffer.length) {
|
|
4287
|
+
case 1:
|
|
4288
|
+
callFormula = () => formula(argsBuffer[0]);
|
|
4289
|
+
break;
|
|
4290
|
+
case 2:
|
|
4291
|
+
callFormula = () => formula(argsBuffer[0], argsBuffer[1]);
|
|
4292
|
+
break;
|
|
4293
|
+
case 3:
|
|
4294
|
+
callFormula = () => formula(argsBuffer[0], argsBuffer[1], argsBuffer[2]);
|
|
4295
|
+
break;
|
|
4296
|
+
default: callFormula = () => formula(...argsBuffer);
|
|
4297
|
+
}
|
|
4298
|
+
const result = new Array(countVectorizedCol);
|
|
4299
|
+
for (let col = 0; col < countVectorizedCol; col++) {
|
|
4300
|
+
const column = new Array(countVectorizedRow);
|
|
4301
|
+
result[col] = column;
|
|
4302
|
+
for (let row = 0; row < countVectorizedRow; row++) {
|
|
4303
|
+
if (col > vectorizedColLimit - 1 || row > vectorizedRowLimit - 1) {
|
|
4304
|
+
column[row] = new NotAvailableError(_t("Array arguments to [[FUNCTION_NAME]] are of different size."));
|
|
4305
|
+
continue;
|
|
4306
|
+
}
|
|
4307
|
+
for (let k = 0; k < nbVectorized; k++) argsBuffer[vectorizedIndices[k]] = argGetters[k](col, row);
|
|
4308
|
+
const singleCellComputeResult = callFormula();
|
|
4309
|
+
column[row] = isMatrix(singleCellComputeResult) ? singleCellComputeResult[0][0] : singleCellComputeResult;
|
|
4310
|
+
}
|
|
4311
|
+
}
|
|
4312
|
+
return result;
|
|
4274
4313
|
}
|
|
4275
4314
|
/**
|
|
4276
4315
|
* This function allows to visit arguments and stop the visit if necessary.
|
|
@@ -4617,12 +4656,15 @@ function emptyDataErrorMessage(argName) {
|
|
|
4617
4656
|
//#endregion
|
|
4618
4657
|
//#region src/functions/create_compute_function.ts
|
|
4619
4658
|
function createComputeFunction(descr) {
|
|
4659
|
+
let currentArgDefinitions = [];
|
|
4620
4660
|
function vectorizedCompute(...args) {
|
|
4621
4661
|
const acceptToVectorize = [];
|
|
4662
|
+
currentArgDefinitions = new Array(args.length);
|
|
4622
4663
|
const argsToFocus = argTargeting(descr, args.length);
|
|
4623
4664
|
for (let i = 0; i < args.length; i++) {
|
|
4624
4665
|
const argIndex = argsToFocus[i].index;
|
|
4625
4666
|
const argDefinition = descr.args[argIndex];
|
|
4667
|
+
currentArgDefinitions[i] = argDefinition;
|
|
4626
4668
|
const arg = args[i];
|
|
4627
4669
|
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) throw new BadExpressionError(_t("Function %s expects the parameter '%s' to be reference to a cell or range.", descr.name, (i + 1).toString()));
|
|
4628
4670
|
acceptToVectorize.push(!argDefinition.acceptMatrix);
|
|
@@ -4635,10 +4677,9 @@ function createComputeFunction(descr) {
|
|
|
4635
4677
|
return result;
|
|
4636
4678
|
}
|
|
4637
4679
|
function errorHandlingCompute(...args) {
|
|
4638
|
-
const argsToFocus = argTargeting(descr, args.length);
|
|
4639
4680
|
for (let i = 0; i < args.length; i++) {
|
|
4640
4681
|
const arg = args[i];
|
|
4641
|
-
if (!
|
|
4682
|
+
if (!currentArgDefinitions[i].acceptErrors && !isMatrix(arg) && isEvaluationError(arg?.value)) return arg;
|
|
4642
4683
|
}
|
|
4643
4684
|
try {
|
|
4644
4685
|
return computeFunctionToObject.apply(this, args);
|
|
@@ -4702,6 +4743,9 @@ var FunctionRegistry = class extends Registry {
|
|
|
4702
4743
|
}
|
|
4703
4744
|
};
|
|
4704
4745
|
const functionRegistry = new FunctionRegistry();
|
|
4746
|
+
/** Formulas using one of these functions are never squished: they are always exported
|
|
4747
|
+
* as a full formula string, and they don't become the base formula of the next cells. */
|
|
4748
|
+
const NonSquishableFunctionRegistry = new Registry();
|
|
4705
4749
|
|
|
4706
4750
|
//#endregion
|
|
4707
4751
|
//#region src/types/locale.ts
|
|
@@ -8967,6 +9011,25 @@ const funnelTooltipPositioner = function(elements) {
|
|
|
8967
9011
|
};
|
|
8968
9012
|
};
|
|
8969
9013
|
|
|
9014
|
+
//#endregion
|
|
9015
|
+
//#region src/components/figures/chart/chartJs/chartjs_geo_projection_plugin.ts
|
|
9016
|
+
/**
|
|
9017
|
+
* ChartJS plugin to apply custom changes to a d3 projection.
|
|
9018
|
+
*
|
|
9019
|
+
* We pass the projection as a string instead of a customized d3 object so
|
|
9020
|
+
* Chart.js creates a fresh projection instance. Custom changes (e.g. rotation)
|
|
9021
|
+
* are then applied in `beforeUpdate`.
|
|
9022
|
+
*
|
|
9023
|
+
* This is important because Chart.js mutates the projection instance at runtime,
|
|
9024
|
+
* and a customize d3 projection object would not be copied during deepCopy.
|
|
9025
|
+
*/
|
|
9026
|
+
const geoProjectionPlugin = {
|
|
9027
|
+
id: "geoProjection",
|
|
9028
|
+
beforeUpdate(chart) {
|
|
9029
|
+
if (chart.options?.scales?.projection?.projection === "conicConformal") chart.scales?.projection?.projection?.rotate([100, 0]);
|
|
9030
|
+
}
|
|
9031
|
+
};
|
|
9032
|
+
|
|
8970
9033
|
//#endregion
|
|
8971
9034
|
//#region src/components/figures/chart/chartJs/chartjs_minor_grid_plugin.ts
|
|
8972
9035
|
const chartMinorGridPlugin = {
|
|
@@ -10024,7 +10087,7 @@ function getGeoChartScales(definition, args) {
|
|
|
10024
10087
|
const format = axisFormats?.y || axisFormats?.y1;
|
|
10025
10088
|
return {
|
|
10026
10089
|
projection: {
|
|
10027
|
-
projection:
|
|
10090
|
+
projection: region?.defaultProjection || "mercator",
|
|
10028
10091
|
axis: "x"
|
|
10029
10092
|
},
|
|
10030
10093
|
color: {
|
|
@@ -10076,10 +10139,6 @@ function getFunnelChartScales(definition, args) {
|
|
|
10076
10139
|
}
|
|
10077
10140
|
};
|
|
10078
10141
|
}
|
|
10079
|
-
function getGeoChartProjection(projection) {
|
|
10080
|
-
if (projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
|
|
10081
|
-
return projection;
|
|
10082
|
-
}
|
|
10083
10142
|
function getChartAxisTitleRuntime(design) {
|
|
10084
10143
|
if (design?.title?.text) {
|
|
10085
10144
|
const { text, color, align, italic, bold } = design.title;
|
|
@@ -10964,6 +11023,10 @@ chartJsExtensionRegistry.add("chartBackgroundPlugin", {
|
|
|
10964
11023
|
register: (Chart) => Chart.register(chartBackgroundPlugin),
|
|
10965
11024
|
unregister: (Chart) => Chart.unregister(chartBackgroundPlugin)
|
|
10966
11025
|
});
|
|
11026
|
+
chartJsExtensionRegistry.add("geoProjectionPlugin", {
|
|
11027
|
+
register: (Chart) => Chart.register(geoProjectionPlugin),
|
|
11028
|
+
unregister: (Chart) => Chart.unregister(geoProjectionPlugin)
|
|
11029
|
+
});
|
|
10967
11030
|
var ChartJsComponent = class extends Component {
|
|
10968
11031
|
static template = "o-spreadsheet-ChartJsComponent";
|
|
10969
11032
|
static props = {
|
|
@@ -18291,7 +18354,7 @@ var FigureComponent = class extends Component {
|
|
|
18291
18354
|
case "ArrowLeft":
|
|
18292
18355
|
case "ArrowRight":
|
|
18293
18356
|
case "ArrowUp":
|
|
18294
|
-
const { col, row, offset } = this.postionInBoundary(this.props.figureUI, ev.key);
|
|
18357
|
+
const { col, row, offset } = this.postionInBoundary(this.env.model.getters.getActiveSheetId(), this.props.figureUI, ev.key);
|
|
18295
18358
|
this.env.model.dispatch("UPDATE_FIGURE", {
|
|
18296
18359
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
18297
18360
|
figureId: this.props.figureUI.id,
|
|
@@ -18315,34 +18378,52 @@ var FigureComponent = class extends Component {
|
|
|
18315
18378
|
break;
|
|
18316
18379
|
}
|
|
18317
18380
|
}
|
|
18318
|
-
postionInBoundary(
|
|
18319
|
-
|
|
18320
|
-
let { col, row, offset } = position;
|
|
18381
|
+
postionInBoundary(sheetId, figure, key) {
|
|
18382
|
+
let { col, row, offset } = figure;
|
|
18321
18383
|
offset = { ...offset };
|
|
18384
|
+
const maxAnchor = this.env.model.getters.getMaxAnchorOffset(sheetId, figure.height, figure.width);
|
|
18322
18385
|
switch (key) {
|
|
18323
18386
|
case "ArrowUp":
|
|
18324
18387
|
if (offset.y === 0) {
|
|
18325
18388
|
row--;
|
|
18389
|
+
while (row > 0 && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row--;
|
|
18326
18390
|
offset.y = this.env.model.getters.getRowSize(sheetId, row) - 1;
|
|
18327
18391
|
} else offset.y--;
|
|
18328
18392
|
break;
|
|
18329
18393
|
case "ArrowLeft":
|
|
18330
18394
|
if (offset.x === 0) {
|
|
18331
18395
|
col--;
|
|
18396
|
+
while (col > 0 && this.env.model.getters.isColHiddenByUser(sheetId, col)) col--;
|
|
18332
18397
|
offset.x = this.env.model.getters.getColSize(sheetId, col) - 1;
|
|
18333
18398
|
} else offset.x--;
|
|
18334
18399
|
break;
|
|
18335
18400
|
case "ArrowDown":
|
|
18336
18401
|
if (offset.y === this.env.model.getters.getRowSize(sheetId, row)) {
|
|
18337
18402
|
row++;
|
|
18403
|
+
while (row <= maxAnchor.row && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row++;
|
|
18338
18404
|
offset.y = 0;
|
|
18339
18405
|
} else offset.y++;
|
|
18340
18406
|
break;
|
|
18341
18407
|
case "ArrowRight": if (offset.x === this.env.model.getters.getColSize(sheetId, row)) {
|
|
18342
18408
|
col++;
|
|
18409
|
+
while (col <= maxAnchor.col && this.env.model.getters.isColHiddenByUser(sheetId, col)) col++;
|
|
18343
18410
|
offset.x = 0;
|
|
18344
18411
|
} else offset.x++;
|
|
18345
18412
|
}
|
|
18413
|
+
if (col < 0) {
|
|
18414
|
+
col = 0;
|
|
18415
|
+
offset.x = 0;
|
|
18416
|
+
} else if (col > maxAnchor.col || col === maxAnchor.col && offset.x > maxAnchor.offset.x) {
|
|
18417
|
+
col = maxAnchor.col;
|
|
18418
|
+
offset.x = maxAnchor.offset.x;
|
|
18419
|
+
}
|
|
18420
|
+
if (row < 0) {
|
|
18421
|
+
row = 0;
|
|
18422
|
+
offset.y = 0;
|
|
18423
|
+
} else if (row > maxAnchor.row || row === maxAnchor.row && offset.y > maxAnchor.offset.y) {
|
|
18424
|
+
row = maxAnchor.row;
|
|
18425
|
+
offset.y = maxAnchor.offset.y;
|
|
18426
|
+
}
|
|
18346
18427
|
return {
|
|
18347
18428
|
col,
|
|
18348
18429
|
row,
|
|
@@ -44682,7 +44763,13 @@ var CellComposerStore = class extends AbstractComposerStore {
|
|
|
44682
44763
|
const cell = this.getters.getEvaluatedCell(position);
|
|
44683
44764
|
if (cell.link && !isFormula(content)) content = markdownLink(content, cell.link.url);
|
|
44684
44765
|
const currentFormat = this.getters.getCell(position)?.format;
|
|
44685
|
-
const
|
|
44766
|
+
const isCurrentFormatDate = currentFormat && isDateTimeFormat(currentFormat);
|
|
44767
|
+
const contentDateFormat = detectDateFormat(content, this.getters.getLocale());
|
|
44768
|
+
let afterFormat;
|
|
44769
|
+
if (currentFormat !== "@") {
|
|
44770
|
+
if (contentDateFormat && !isCurrentFormatDate) afterFormat = contentDateFormat;
|
|
44771
|
+
else if (isCurrentFormatDate && isNumber(content, this.getters.getLocale())) afterFormat = "";
|
|
44772
|
+
}
|
|
44686
44773
|
this.addHeadersForSpreadingFormula(content);
|
|
44687
44774
|
result = this.model.dispatch("UPDATE_CELL", {
|
|
44688
44775
|
...this.currentEditedCell,
|
|
@@ -49779,7 +49866,8 @@ var Squisher = class {
|
|
|
49779
49866
|
* The result of this method is:
|
|
49780
49867
|
* - if the cell is not a formula, returns the content as is and resets the base formula
|
|
49781
49868
|
* - if the cell is a formula:
|
|
49782
|
-
* - if there is no previous formula, or the normalized formula is different from the previous one
|
|
49869
|
+
* - if there is no previous formula, or the normalized formula is different from the previous one or it contains blacklisted functions (see NonSquishableFunctionRegistry),
|
|
49870
|
+
* resets the base formula to this one and returns the full formula string
|
|
49783
49871
|
* - else, compares the literal values and range dependencies to the previous formula, and for each parameter:
|
|
49784
49872
|
* - for numbers: returns a relative change (+N or -N) if possible, else the full number or "=" if unchanged
|
|
49785
49873
|
* - for strings: returns the full string if changed, else "="
|
|
@@ -49787,6 +49875,10 @@ var Squisher = class {
|
|
|
49787
49875
|
* */
|
|
49788
49876
|
squish(cell, forSheetId) {
|
|
49789
49877
|
if (cell.isFormula) {
|
|
49878
|
+
if (NonSquishableFunctionRegistry.getAll().some((functionName) => cell.compiledFormula.usesSymbol(functionName))) {
|
|
49879
|
+
this.resetBaseFormula();
|
|
49880
|
+
return cell.compiledFormula.toFormulaString(this.getters, this.rangeToStringOptions);
|
|
49881
|
+
}
|
|
49790
49882
|
let numbers = [];
|
|
49791
49883
|
let strings = [];
|
|
49792
49884
|
let references = [];
|
|
@@ -60968,7 +61060,7 @@ var Session = class extends EventBus {
|
|
|
60968
61060
|
}
|
|
60969
61061
|
message = {
|
|
60970
61062
|
...message,
|
|
60971
|
-
commands:
|
|
61063
|
+
commands: revision.commands
|
|
60972
61064
|
};
|
|
60973
61065
|
}
|
|
60974
61066
|
if (this.isReplayingInitialRevisions) throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
|
|
@@ -66212,6 +66304,10 @@ function inverseCreateFigure(cmd) {
|
|
|
66212
66304
|
}
|
|
66213
66305
|
function inverseCreateChart(cmd) {
|
|
66214
66306
|
return [{
|
|
66307
|
+
type: "DELETE_CHART",
|
|
66308
|
+
chartId: cmd.chartId,
|
|
66309
|
+
sheetId: cmd.sheetId
|
|
66310
|
+
}, {
|
|
66215
66311
|
type: "DELETE_FIGURE",
|
|
66216
66312
|
figureId: cmd.figureId,
|
|
66217
66313
|
sheetId: cmd.sheetId
|
|
@@ -84423,7 +84519,8 @@ const registries = {
|
|
|
84423
84519
|
supportedPivotPositionalFormulaRegistry,
|
|
84424
84520
|
pivotToFunctionValueRegistry,
|
|
84425
84521
|
migrationStepRegistry,
|
|
84426
|
-
chartJsExtensionRegistry
|
|
84522
|
+
chartJsExtensionRegistry,
|
|
84523
|
+
NonSquishableFunctionRegistry
|
|
84427
84524
|
};
|
|
84428
84525
|
const helpers = {
|
|
84429
84526
|
arg,
|
|
@@ -84618,6 +84715,6 @@ const chartHelpers = {
|
|
|
84618
84715
|
//#endregion
|
|
84619
84716
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, ClientDisconnectedError, CommandResult, CompiledFormula, CorePlugin, CoreViewPlugin, DEFAULT_LOCALE, DEFAULT_LOCALES, DispatchResult, EvaluationError, LocalTransportService, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, canExecuteInReadonly, categories, chartHelpers, components, constants, convertAstNodes, coreTypes, createAutocompleteArgumentsProvider, findCellInNewZone, functionCache, getCaretDownSvg, getCaretUpSvg, helpers, hooks, invalidateCFEvaluationCommands, invalidateChartEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, isCoreCommand, isSheetDependent, iterateAstNodes, links, load, lockedSheetAllowedCommands, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
84620
84717
|
|
|
84621
|
-
__info__.version = "19.3.
|
|
84622
|
-
__info__.date = "2026-
|
|
84623
|
-
__info__.hash = "
|
|
84718
|
+
__info__.version = "19.3.16";
|
|
84719
|
+
__info__.date = "2026-08-12T09:15:31.627Z";
|
|
84720
|
+
__info__.hash = "464be42";
|