@odoo/o-spreadsheet 18.0.49 → 18.0.53

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.
@@ -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 18.0.49
6
- * @date 2025-11-24T07:40:04.646Z
7
- * @hash b4ef5b7
5
+ * @version 18.0.53
6
+ * @date 2025-12-26T10:18:09.933Z
7
+ * @hash 7ca8390
8
8
  */
9
9
 
10
10
  'use strict';
@@ -3272,7 +3272,6 @@ const invalidateEvaluationCommands = new Set([
3272
3272
  "REDO",
3273
3273
  "ADD_MERGE",
3274
3274
  "REMOVE_MERGE",
3275
- "DUPLICATE_SHEET",
3276
3275
  "UPDATE_LOCALE",
3277
3276
  "ADD_PIVOT",
3278
3277
  "UPDATE_PIVOT",
@@ -5841,17 +5840,41 @@ function toCriterionDateNumber(dateValue) {
5841
5840
  const today = DateTime.now();
5842
5841
  switch (dateValue) {
5843
5842
  case "today":
5844
- return jsDateToNumber(today);
5845
- case "yesterday":
5846
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 1)));
5847
- case "tomorrow":
5848
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() + 1)));
5843
+ return Math.floor(jsDateToNumber(today));
5844
+ case "yesterday": {
5845
+ today.setDate(today.getDate() - 1);
5846
+ return Math.floor(jsDateToNumber(today));
5847
+ }
5848
+ case "tomorrow": {
5849
+ today.setDate(today.getDate() + 1);
5850
+ return Math.floor(jsDateToNumber(today));
5851
+ }
5849
5852
  case "lastWeek":
5850
- return jsDateToNumber(DateTime.fromTimestamp(today.setDate(today.getDate() - 7)));
5851
- case "lastMonth":
5852
- return jsDateToNumber(DateTime.fromTimestamp(today.setMonth(today.getMonth() - 1)));
5853
+ today.setDate(today.getDate() - 6);
5854
+ return Math.floor(jsDateToNumber(today));
5855
+ case "lastMonth": {
5856
+ const lastMonth = today.getMonth() === 0 ? 11 : today.getMonth() - 1;
5857
+ const dateInLastMonth = new DateTime(today.getFullYear(), lastMonth, 1);
5858
+ if (today.getDate() > getDaysInMonth(dateInLastMonth)) {
5859
+ today.setDate(1);
5860
+ }
5861
+ else {
5862
+ today.setDate(today.getDate() + 1);
5863
+ today.setMonth(today.getMonth() - 1);
5864
+ }
5865
+ return Math.floor(jsDateToNumber(today));
5866
+ }
5853
5867
  case "lastYear":
5854
- return jsDateToNumber(DateTime.fromTimestamp(today.setFullYear(today.getFullYear() - 1)));
5868
+ // Handle leap year case
5869
+ if (today.getMonth() === 1 && today.getDate() === 29) {
5870
+ today.setDate(28);
5871
+ today.setFullYear(today.getFullYear() - 1);
5872
+ }
5873
+ else {
5874
+ today.setDate(today.getDate() + 1);
5875
+ today.setFullYear(today.getFullYear() - 1);
5876
+ }
5877
+ return Math.floor(jsDateToNumber(today));
5855
5878
  }
5856
5879
  }
5857
5880
  /** Get all the dates values of a criterion converted to numbers, converting date values such as "today" to actual dates */
@@ -31849,7 +31872,6 @@ class ChartFigure extends owl.Component {
31849
31872
  static template = "o-spreadsheet-ChartFigure";
31850
31873
  static props = {
31851
31874
  figure: Object,
31852
- onFigureDeleted: Function,
31853
31875
  };
31854
31876
  static components = {};
31855
31877
  onDoubleClick() {
@@ -31873,7 +31895,6 @@ class ImageFigure extends owl.Component {
31873
31895
  static template = "o-spreadsheet-ImageFigure";
31874
31896
  static props = {
31875
31897
  figure: Object,
31876
- onFigureDeleted: Function,
31877
31898
  };
31878
31899
  static components = {};
31879
31900
  // ---------------------------------------------------------------------------
@@ -31931,7 +31952,7 @@ figureRegistry.add("image", {
31931
31952
  borderWidth: 0,
31932
31953
  menuBuilder: getImageMenuRegistry,
31933
31954
  });
31934
- function getChartMenu(figureId, onFigureDeleted, env) {
31955
+ function getChartMenu(figureId, env) {
31935
31956
  const menuItemSpecs = [
31936
31957
  {
31937
31958
  id: "edit",
@@ -31945,11 +31966,11 @@ function getChartMenu(figureId, onFigureDeleted, env) {
31945
31966
  },
31946
31967
  getCopyMenuItem(figureId, env),
31947
31968
  getCutMenuItem(figureId, env),
31948
- getDeleteMenuItem(figureId, onFigureDeleted, env),
31969
+ getDeleteMenuItem(figureId, env),
31949
31970
  ];
31950
31971
  return createActions(menuItemSpecs);
31951
31972
  }
31952
- function getImageMenuRegistry(figureId, onFigureDeleted, env) {
31973
+ function getImageMenuRegistry(figureId, env) {
31953
31974
  const menuItemSpecs = [
31954
31975
  getCopyMenuItem(figureId, env),
31955
31976
  getCutMenuItem(figureId, env),
@@ -31975,7 +31996,7 @@ function getImageMenuRegistry(figureId, onFigureDeleted, env) {
31975
31996
  },
31976
31997
  icon: "o-spreadsheet-Icon.REFRESH",
31977
31998
  },
31978
- getDeleteMenuItem(figureId, onFigureDeleted, env),
31999
+ getDeleteMenuItem(figureId, env),
31979
32000
  ];
31980
32001
  return createActions(menuItemSpecs);
31981
32002
  }
@@ -32007,7 +32028,7 @@ function getCutMenuItem(figureId, env) {
32007
32028
  icon: "o-spreadsheet-Icon.CUT",
32008
32029
  };
32009
32030
  }
32010
- function getDeleteMenuItem(figureId, onFigureDeleted, env) {
32031
+ function getDeleteMenuItem(figureId, env) {
32011
32032
  return {
32012
32033
  id: "delete",
32013
32034
  name: _t("Delete"),
@@ -32017,7 +32038,6 @@ function getDeleteMenuItem(figureId, onFigureDeleted, env) {
32017
32038
  sheetId: env.model.getters.getActiveSheetId(),
32018
32039
  id: figureId,
32019
32040
  });
32020
- onFigureDeleted();
32021
32041
  },
32022
32042
  icon: "o-spreadsheet-Icon.TRASH",
32023
32043
  };
@@ -39380,7 +39400,7 @@ class AbstractComposerStore extends SpreadsheetStore {
39380
39400
  }
39381
39401
  this.selectionStart = start;
39382
39402
  this.selectionEnd = end;
39383
- this.editionMode = "editing";
39403
+ this.stopComposerRangeSelection();
39384
39404
  }
39385
39405
  stopComposerRangeSelection() {
39386
39406
  if (this.isSelectingRange) {
@@ -40351,14 +40371,15 @@ function useHighlights(highlightProvider) {
40351
40371
  }
40352
40372
 
40353
40373
  css /* scss */ `
40354
- .o-cf-preview {
40374
+ .o-spreadsheet .o-cf-preview {
40355
40375
  &.o-cf-cursor-ptr {
40356
40376
  cursor: pointer;
40357
40377
  }
40358
40378
 
40359
40379
  border-bottom: 1px solid ${GRAY_300};
40360
- height: 60px;
40380
+ height: 80px;
40361
40381
  padding: 10px;
40382
+ box-sizing: border-box;
40362
40383
  position: relative;
40363
40384
  cursor: pointer;
40364
40385
  &:hover,
@@ -40372,7 +40393,6 @@ css /* scss */ `
40372
40393
  .o-cf-preview-icon {
40373
40394
  border: 1px solid ${GRAY_300};
40374
40395
  background-color: #fff;
40375
- position: absolute;
40376
40396
  height: 50px;
40377
40397
  width: 50px;
40378
40398
  .o-icon {
@@ -40381,12 +40401,6 @@ css /* scss */ `
40381
40401
  }
40382
40402
  }
40383
40403
  .o-cf-preview-description {
40384
- left: 65px;
40385
- margin-bottom: auto;
40386
- margin-right: 8px;
40387
- margin-top: auto;
40388
- position: relative;
40389
- width: 142px;
40390
40404
  .o-cf-preview-description-rule {
40391
40405
  margin-bottom: 4px;
40392
40406
  max-height: 2.8em;
@@ -40396,16 +40410,11 @@ css /* scss */ `
40396
40410
  font-size: 12px;
40397
40411
  }
40398
40412
  }
40399
- .o-cf-delete {
40400
- left: 90%;
40401
- top: 39%;
40402
- position: absolute;
40403
- }
40404
40413
  &:not(:hover):not(.o-cf-dragging) .o-cf-drag-handle {
40405
40414
  display: none !important;
40406
40415
  }
40407
40416
  .o-cf-drag-handle {
40408
- left: -8px;
40417
+ left: 2px;
40409
40418
  cursor: move;
40410
40419
  .o-icon {
40411
40420
  width: 6px;
@@ -41290,7 +41299,7 @@ dataValidationEvaluatorRegistry.add("dateIs", {
41290
41299
  return false;
41291
41300
  }
41292
41301
  if (["lastWeek", "lastMonth", "lastYear"].includes(criterion.dateValue)) {
41293
- const today = jsDateToRoundNumber(DateTime.now());
41302
+ const today = Math.floor(jsDateToNumber(DateTime.now()));
41294
41303
  return isDateBetween(dateValue, today, criterionValue);
41295
41304
  }
41296
41305
  return areDatesSameDay(dateValue, criterionValue);
@@ -44990,12 +44999,41 @@ const dateGranularities = [
44990
44999
  pivotRegistry.add("SPREADSHEET", {
44991
45000
  ui: SpreadsheetPivot,
44992
45001
  definition: SpreadsheetPivotRuntimeDefinition,
44993
- externalData: false,
44994
45002
  dateGranularities: [...dateGranularities],
44995
45003
  datetimeGranularities: [...dateGranularities, "hour_number", "minute_number", "second_number"],
44996
45004
  isMeasureCandidate: (field) => !["datetime", "boolean"].includes(field.type),
44997
45005
  isGroupable: () => true,
45006
+ adaptRanges: (getters, definition, applyChange) => {
45007
+ if (definition.type !== "SPREADSHEET" || !definition.dataSet) {
45008
+ return definition;
45009
+ }
45010
+ const { sheetId, zone } = definition.dataSet;
45011
+ const range = getters.getRangeFromZone(sheetId, zone);
45012
+ const adaptedRange = adaptPivotRange(range, applyChange);
45013
+ if (adaptedRange === range) {
45014
+ return definition;
45015
+ }
45016
+ const dataSet = adaptedRange && {
45017
+ sheetId: adaptedRange.sheetId,
45018
+ zone: adaptedRange.zone,
45019
+ };
45020
+ return { ...definition, dataSet };
45021
+ },
44998
45022
  });
45023
+ function adaptPivotRange(range, applyChange) {
45024
+ if (!range) {
45025
+ return undefined;
45026
+ }
45027
+ const change = applyChange(range);
45028
+ switch (change.changeType) {
45029
+ case "NONE":
45030
+ return range;
45031
+ case "REMOVE":
45032
+ return undefined;
45033
+ default:
45034
+ return change.range;
45035
+ }
45036
+ }
44999
45037
 
45000
45038
  class PivotSidePanelStore extends SpreadsheetStore {
45001
45039
  pivotId;
@@ -46611,13 +46649,11 @@ class FigureComponent extends owl.Component {
46611
46649
  static props = {
46612
46650
  figure: Object,
46613
46651
  style: { type: String, optional: true },
46614
- onFigureDeleted: { type: Function, optional: true },
46615
46652
  onMouseDown: { type: Function, optional: true },
46616
46653
  onClickAnchor: { type: Function, optional: true },
46617
46654
  };
46618
46655
  static components = { Menu };
46619
46656
  static defaultProps = {
46620
- onFigureDeleted: () => { },
46621
46657
  onMouseDown: () => { },
46622
46658
  onClickAnchor: () => { },
46623
46659
  };
@@ -46691,9 +46727,6 @@ class FigureComponent extends owl.Component {
46691
46727
  el?.focus({ preventScroll: true });
46692
46728
  }
46693
46729
  }, () => [this.env.model.getters.getSelectedFigureId(), this.props.figure.id, this.figureRef.el]);
46694
- owl.onWillUnmount(() => {
46695
- this.props.onFigureDeleted();
46696
- });
46697
46730
  }
46698
46731
  clickAnchor(dirX, dirY, ev) {
46699
46732
  this.props.onClickAnchor(dirX, dirY, ev);
@@ -46711,7 +46744,6 @@ class FigureComponent extends owl.Component {
46711
46744
  sheetId: this.env.model.getters.getActiveSheetId(),
46712
46745
  id: figure.id,
46713
46746
  });
46714
- this.props.onFigureDeleted();
46715
46747
  ev.preventDefault();
46716
46748
  ev.stopPropagation();
46717
46749
  break;
@@ -46775,7 +46807,7 @@ class FigureComponent extends owl.Component {
46775
46807
  this.menuState.position = position;
46776
46808
  this.menuState.menuItems = figureRegistry
46777
46809
  .get(this.props.figure.tag)
46778
- .menuBuilder(this.props.figure.id, this.props.onFigureDeleted, this.env);
46810
+ .menuBuilder(this.props.figure.id, this.env);
46779
46811
  }
46780
46812
  }
46781
46813
 
@@ -46888,21 +46920,20 @@ class ArrayFormulaHighlight extends SpreadsheetStore {
46888
46920
  this.highlightStore.register(this);
46889
46921
  }
46890
46922
  get highlights() {
46891
- let zone;
46892
46923
  const position = this.model.getters.getActivePosition();
46893
- const cell = this.getters.getEvaluatedCell(position);
46894
46924
  const spreader = this.model.getters.getArrayFormulaSpreadingOn(position);
46895
- zone = spreader
46925
+ const zone = spreader
46896
46926
  ? this.model.getters.getSpreadZone(spreader, { ignoreSpillError: true })
46897
46927
  : this.model.getters.getSpreadZone(position, { ignoreSpillError: true });
46898
46928
  if (!zone) {
46899
46929
  return [];
46900
46930
  }
46931
+ const isArrayFormulaBlocked = this.model.getters.isArrayFormulaSpillBlocked(spreader ?? position);
46901
46932
  return [
46902
46933
  {
46903
46934
  sheetId: position.sheetId,
46904
46935
  zone,
46905
- dashed: cell.value === CellErrorType.SpilledBlocked,
46936
+ dashed: isArrayFormulaBlocked,
46906
46937
  color: "#17A2B8",
46907
46938
  noFill: true,
46908
46939
  thinLine: true,
@@ -47975,9 +48006,7 @@ css /*SCSS*/ `
47975
48006
  */
47976
48007
  class FiguresContainer extends owl.Component {
47977
48008
  static template = "o-spreadsheet-FiguresContainer";
47978
- static props = {
47979
- onFigureDeleted: Function,
47980
- };
48009
+ static props = {};
47981
48010
  static components = { FigureComponent };
47982
48011
  dnd = owl.useState({
47983
48012
  draggedFigure: undefined,
@@ -48334,16 +48363,16 @@ css /* scss */ `
48334
48363
  `;
48335
48364
  class GridAddRowsFooter extends owl.Component {
48336
48365
  static template = "o-spreadsheet-GridAddRowsFooter";
48337
- static props = {
48338
- focusGrid: Function,
48339
- };
48366
+ static props = {};
48340
48367
  static components = { ValidationMessages };
48368
+ DOMFocusableElementStore;
48341
48369
  inputRef = owl.useRef("inputRef");
48342
48370
  state = owl.useState({
48343
48371
  inputValue: "100",
48344
48372
  errorFlag: false,
48345
48373
  });
48346
48374
  setup() {
48375
+ this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
48347
48376
  owl.useExternalListener(window, "click", this.onExternalClick, { capture: true });
48348
48377
  }
48349
48378
  get addRowsPosition() {
@@ -48361,7 +48390,7 @@ class GridAddRowsFooter extends owl.Component {
48361
48390
  }
48362
48391
  onKeydown(ev) {
48363
48392
  if (ev.key.toUpperCase() === "ESCAPE") {
48364
- this.props.focusGrid();
48393
+ this.focusDefaultElement();
48365
48394
  }
48366
48395
  else if (ev.key.toUpperCase() === "ENTER") {
48367
48396
  this.onConfirm();
@@ -48387,7 +48416,7 @@ class GridAddRowsFooter extends owl.Component {
48387
48416
  quantity,
48388
48417
  dimension: "ROW",
48389
48418
  });
48390
- this.props.focusGrid();
48419
+ this.focusDefaultElement();
48391
48420
  // After adding new rows, scroll down to the new last row
48392
48421
  const { scrollX } = this.env.model.getters.getActiveSheetDOMScrollInfo();
48393
48422
  const { end } = this.env.model.getters.getRowDimensions(activeSheetId, rowNumber + quantity - 1);
@@ -48400,7 +48429,12 @@ class GridAddRowsFooter extends owl.Component {
48400
48429
  if (this.inputRef.el !== document.activeElement || ev.target === this.inputRef.el) {
48401
48430
  return;
48402
48431
  }
48403
- this.props.focusGrid();
48432
+ this.focusDefaultElement();
48433
+ }
48434
+ focusDefaultElement() {
48435
+ if (document.activeElement === this.inputRef.el) {
48436
+ this.DOMFocusableElementStore.focus();
48437
+ }
48404
48438
  }
48405
48439
  }
48406
48440
 
@@ -48589,7 +48623,6 @@ class GridOverlay extends owl.Component {
48589
48623
  onCellClicked: { type: Function, optional: true },
48590
48624
  onCellRightClicked: { type: Function, optional: true },
48591
48625
  onGridResized: { type: Function, optional: true },
48592
- onFigureDeleted: { type: Function, optional: true },
48593
48626
  onGridMoved: Function,
48594
48627
  gridOverlayDimensions: String,
48595
48628
  };
@@ -48605,7 +48638,6 @@ class GridOverlay extends owl.Component {
48605
48638
  onCellClicked: () => { },
48606
48639
  onCellRightClicked: () => { },
48607
48640
  onGridResized: () => { },
48608
- onFigureDeleted: () => { },
48609
48641
  };
48610
48642
  gridOverlay = owl.useRef("gridOverlay");
48611
48643
  gridOverlayRect = useAbsoluteBoundingRect(this.gridOverlay);
@@ -54962,6 +54994,7 @@ function rangeToMerge(mergeId, range) {
54962
54994
  class RangeAdapter {
54963
54995
  getters;
54964
54996
  providers = [];
54997
+ isAdaptingRanges = false;
54965
54998
  constructor(getters) {
54966
54999
  this.getters = getters;
54967
55000
  }
@@ -54990,6 +55023,9 @@ class RangeAdapter {
54990
55023
  }
54991
55024
  beforeHandle(command) { }
54992
55025
  handle(cmd) {
55026
+ if (this.isAdaptingRanges) {
55027
+ throw new Error("Plugins cannot dispatch commands during adaptRanges phase");
55028
+ }
54993
55029
  switch (cmd.type) {
54994
55030
  case "REMOVE_COLUMNS_ROWS": {
54995
55031
  let start = cmd.dimension === "COL" ? "left" : "top";
@@ -55145,10 +55181,12 @@ class RangeAdapter {
55145
55181
  return adaptedRange;
55146
55182
  }
55147
55183
  executeOnAllRanges(adaptRange, sheetId) {
55184
+ this.isAdaptingRanges = true;
55148
55185
  const func = this.verifyRangeRemoved(adaptRange);
55149
55186
  for (const provider of this.providers) {
55150
55187
  provider(func, sheetId);
55151
55188
  }
55189
+ this.isAdaptingRanges = false;
55152
55190
  }
55153
55191
  /**
55154
55192
  * Stores the functions bound to each plugin to be able to iterate over all ranges of the application,
@@ -57255,6 +57293,18 @@ class PivotCorePlugin extends CorePlugin {
57255
57293
  }
57256
57294
  }
57257
57295
  adaptRanges(applyChange) {
57296
+ for (const pivotId in this.pivots) {
57297
+ const definition = deepCopy(this.pivots[pivotId]?.definition);
57298
+ if (!definition) {
57299
+ continue;
57300
+ }
57301
+ const newDefinition = pivotRegistry
57302
+ .get(definition.type)
57303
+ ?.adaptRanges?.(this.getters, definition, applyChange);
57304
+ if (newDefinition && !deepEquals(definition, newDefinition)) {
57305
+ this.history.update("pivots", pivotId, "definition", newDefinition);
57306
+ }
57307
+ }
57258
57308
  for (const sheetId in this.compiledMeasureFormulas) {
57259
57309
  for (const formulaString in this.compiledMeasureFormulas[sheetId]) {
57260
57310
  const compiledFormula = this.compiledMeasureFormulas[sheetId][formulaString];
@@ -57499,20 +57549,6 @@ class SettingsPlugin extends CorePlugin {
57499
57549
  }
57500
57550
  }
57501
57551
 
57502
- function adaptPivotRange(range, applyChange) {
57503
- if (!range) {
57504
- return undefined;
57505
- }
57506
- const change = applyChange(range);
57507
- switch (change.changeType) {
57508
- case "NONE":
57509
- return range;
57510
- case "REMOVE":
57511
- return undefined;
57512
- default:
57513
- return change.range;
57514
- }
57515
- }
57516
57552
  class SpreadsheetPivotCorePlugin extends CorePlugin {
57517
57553
  allowDispatch(cmd) {
57518
57554
  switch (cmd.type) {
@@ -57523,24 +57559,6 @@ class SpreadsheetPivotCorePlugin extends CorePlugin {
57523
57559
  }
57524
57560
  return "Success" /* CommandResult.Success */;
57525
57561
  }
57526
- adaptRanges(applyChange) {
57527
- for (const pivotId of this.getters.getPivotIds()) {
57528
- const definition = this.getters.getPivotCoreDefinition(pivotId);
57529
- if (definition.type !== "SPREADSHEET") {
57530
- continue;
57531
- }
57532
- if (definition.dataSet) {
57533
- const { sheetId, zone } = definition.dataSet;
57534
- const range = this.getters.getRangeFromZone(sheetId, zone);
57535
- const adaptedRange = adaptPivotRange(range, applyChange);
57536
- const dataSet = adaptedRange && {
57537
- sheetId: adaptedRange.sheetId,
57538
- zone: adaptedRange.zone,
57539
- };
57540
- this.dispatch("UPDATE_PIVOT", { pivotId, pivot: { ...definition, dataSet } });
57541
- }
57542
- }
57543
- }
57544
57562
  checkDataSetValidity(definition) {
57545
57563
  if (definition.type === "SPREADSHEET" && definition.dataSet) {
57546
57564
  const { zone, sheetId } = definition.dataSet;
@@ -58898,6 +58916,9 @@ class Evaluator {
58898
58916
  const arrayFormulas = this.spreadingRelations.searchFormulaPositionsSpreadingOn(position.sheetId, positionToZone(position));
58899
58917
  return Array.from(arrayFormulas).find((position) => !this.blockedArrayFormulas.has(position));
58900
58918
  }
58919
+ isArrayFormulaSpillBlocked(position) {
58920
+ return this.blockedArrayFormulas.has(position);
58921
+ }
58901
58922
  updateDependencies(position) {
58902
58923
  // removing dependencies is slow because it requires
58903
58924
  // to traverse the entire r-tree.
@@ -58909,13 +58930,8 @@ class Evaluator {
58909
58930
  addDependencies(position, dependencies) {
58910
58931
  this.formulaDependencies().addDependencies(position, dependencies);
58911
58932
  for (const range of dependencies) {
58912
- const sheetId = range.sheetId;
58913
- const { left, bottom, right, top } = range.zone;
58914
- for (let col = left; col <= right; col++) {
58915
- for (let row = top; row <= bottom; row++) {
58916
- this.computeAndSave({ sheetId, col, row });
58917
- }
58918
- }
58933
+ // ensure that all ranges are computed
58934
+ this.compilationParams.ensureRange(range);
58919
58935
  }
58920
58936
  }
58921
58937
  updateCompilationParameters() {
@@ -59114,6 +59130,10 @@ class Evaluator {
59114
59130
  this.assertSheetHasEnoughSpaceToSpreadFormulaResult(formulaPosition, formulaReturn);
59115
59131
  const nbColumns = formulaReturn.length;
59116
59132
  const nbRows = formulaReturn[0].length;
59133
+ if (nbRows === 0) {
59134
+ // empty matrix
59135
+ return createEvaluatedCell({ value: 0 }, this.getters.getLocale(), cellData);
59136
+ }
59117
59137
  const resultZone = {
59118
59138
  top: formulaPosition.row,
59119
59139
  bottom: formulaPosition.row + nbRows - 1,
@@ -59386,6 +59406,7 @@ class EvaluationPlugin extends UIPlugin {
59386
59406
  "getEvaluatedCellsPositions",
59387
59407
  "getSpreadZone",
59388
59408
  "getArrayFormulaSpreadingOn",
59409
+ "isArrayFormulaSpillBlocked",
59389
59410
  "isEmpty",
59390
59411
  ];
59391
59412
  shouldRebuildDependenciesGraph = true;
@@ -59498,6 +59519,9 @@ class EvaluationPlugin extends UIPlugin {
59498
59519
  getArrayFormulaSpreadingOn(position) {
59499
59520
  return this.evaluator.getArrayFormulaSpreadingOn(position);
59500
59521
  }
59522
+ isArrayFormulaSpillBlocked(position) {
59523
+ return this.evaluator.isArrayFormulaSpillBlocked(position);
59524
+ }
59501
59525
  /**
59502
59526
  * Check if a zone only contains empty cells
59503
59527
  */
@@ -61288,9 +61312,7 @@ class PivotUIPlugin extends UIPlugin {
61288
61312
  handle(cmd) {
61289
61313
  if (invalidateEvaluationCommands.has(cmd.type)) {
61290
61314
  for (const pivotId of this.getters.getPivotIds()) {
61291
- if (!pivotRegistry.get(this.getters.getPivotCoreDefinition(pivotId).type).externalData) {
61292
- this.setupPivot(pivotId, { recreate: true });
61293
- }
61315
+ this.setupPivot(pivotId, { recreate: true });
61294
61316
  }
61295
61317
  }
61296
61318
  switch (cmd.type) {
@@ -61495,7 +61517,7 @@ class PivotUIPlugin extends UIPlugin {
61495
61517
  pivot.init({ reload: true });
61496
61518
  }
61497
61519
  setupPivot(pivotId, { recreate } = { recreate: false }) {
61498
- const definition = this.getters.getPivotCoreDefinition(pivotId);
61520
+ const definition = deepCopy(this.getters.getPivotCoreDefinition(pivotId));
61499
61521
  if (!(pivotId in this.pivots)) {
61500
61522
  const Pivot = withPivotPresentationLayer(pivotRegistry.get(definition.type).ui);
61501
61523
  this.pivots[pivotId] = new Pivot(this.custom, { definition, getters: this.getters });
@@ -70289,7 +70311,7 @@ class Spreadsheet extends owl.Component {
70289
70311
  document.activeElement?.contains(this.spreadsheetRef.el)) {
70290
70312
  this.focusGrid();
70291
70313
  }
70292
- }, () => [this.env.model.getters.getActiveSheetId()]);
70314
+ });
70293
70315
  owl.useExternalListener(window, "resize", () => this.render(true));
70294
70316
  // For some reason, the wheel event is not properly registered inside templates
70295
70317
  // in Chromium-based browsers based on chromium 125
@@ -74772,6 +74794,6 @@ exports.tokenColors = tokenColors;
74772
74794
  exports.tokenize = tokenize;
74773
74795
 
74774
74796
 
74775
- __info__.version = "18.0.49";
74776
- __info__.date = "2025-11-24T07:40:04.646Z";
74777
- __info__.hash = "b4ef5b7";
74797
+ __info__.version = "18.0.53";
74798
+ __info__.date = "2025-12-26T10:18:09.933Z";
74799
+ __info__.hash = "7ca8390";