@odoo/o-spreadsheet 17.2.8 → 17.2.9

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.
@@ -3,9 +3,9 @@
3
3
  /**
4
4
  * This file is generated by o-spreadsheet build tools. Do not edit it.
5
5
  * @see https://github.com/odoo/o-spreadsheet
6
- * @version 17.2.8
7
- * @date 2024-05-24T11:29:49.320Z
8
- * @hash bfbcaa0
6
+ * @version 17.2.9
7
+ * @date 2024-06-03T14:56:21.684Z
8
+ * @hash 086af6d
9
9
  */
10
10
 
11
11
  (function (exports, owl) {
@@ -2659,7 +2659,7 @@
2659
2659
  return false;
2660
2660
  }
2661
2661
  if (typeof operand === "number" && operator === "=") {
2662
- return toString(value) === toString(operand);
2662
+ return value.toString() === operand.toString();
2663
2663
  }
2664
2664
  if (operator === "<>" || operator === "=") {
2665
2665
  let result;
@@ -2719,14 +2719,13 @@
2719
2719
  if (countArg % 2 === 1) {
2720
2720
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
2721
2721
  }
2722
- const dimRow = args[0].length;
2723
- const dimCol = args[0][0].length;
2722
+ const firstArg = toMatrix(args[0]);
2723
+ const dimRow = firstArg.length;
2724
+ const dimCol = firstArg[0].length;
2724
2725
  let predicates = [];
2725
2726
  for (let i = 0; i < countArg - 1; i += 2) {
2726
- const criteriaRange = args[i];
2727
- if (!isMatrix(criteriaRange) ||
2728
- criteriaRange.length !== dimRow ||
2729
- criteriaRange[0].length !== dimCol) {
2727
+ const criteriaRange = toMatrix(args[i]);
2728
+ if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
2730
2729
  throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
2731
2730
  }
2732
2731
  const description = toString(args[i + 1]);
@@ -2740,7 +2739,7 @@
2740
2739
  for (let j = 0; j < dimCol; j++) {
2741
2740
  let validatedPredicates = true;
2742
2741
  for (let k = 0; k < countArg - 1; k += 2) {
2743
- const criteriaValue = args[k][i][j].value;
2742
+ const criteriaValue = toMatrix(args[k])[i][j].value;
2744
2743
  const criterion = predicates[k / 2];
2745
2744
  validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2746
2745
  if (!validatedPredicates) {
@@ -4457,8 +4456,11 @@
4457
4456
  /**
4458
4457
  * Create a range from a xc. If the xc is empty, this function returns undefined.
4459
4458
  */
4460
- function createRange(getters, sheetId, range) {
4461
- return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
4459
+ function createValidRange(getters, sheetId, xc) {
4460
+ if (!xc)
4461
+ return;
4462
+ const range = getters.getRangeFromSheetXC(sheetId, xc);
4463
+ return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
4462
4464
  }
4463
4465
  /**
4464
4466
  * Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
@@ -9645,8 +9647,8 @@ stores.inject(MyMetaStore, storeInstance);
9645
9647
  type = "scorecard";
9646
9648
  constructor(definition, sheetId, getters) {
9647
9649
  super(definition, sheetId, getters);
9648
- this.keyValue = createRange(getters, sheetId, definition.keyValue);
9649
- this.baseline = createRange(getters, sheetId, definition.baseline);
9650
+ this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
9651
+ this.baseline = createValidRange(getters, sheetId, definition.baseline);
9650
9652
  this.baselineMode = definition.baselineMode;
9651
9653
  this.baselineDescr = definition.baselineDescr;
9652
9654
  this.background = definition.background;
@@ -10216,6 +10218,9 @@ stores.inject(MyMetaStore, storeInstance);
10216
10218
  if (types.some((t) => t.startsWith("RANGE"))) {
10217
10219
  result.acceptMatrix = true;
10218
10220
  }
10221
+ if (types.every((t) => t.startsWith("RANGE"))) {
10222
+ result.acceptMatrixOnly = true;
10223
+ }
10219
10224
  return result;
10220
10225
  }
10221
10226
  /**
@@ -10497,11 +10502,16 @@ stores.inject(MyMetaStore, storeInstance);
10497
10502
  compute: function (array, ...columns) {
10498
10503
  const _array = toMatrix(array);
10499
10504
  const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
10500
- assert(() => _columns.every((col) => col > 0 && col <= _array.length), _t("The columns arguments must be between 1 and %s (got %s).", _array.length.toString(), (_columns.find((col) => col <= 0 || col > _array.length) || 0).toString()));
10505
+ const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
10506
+ assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
10501
10507
  const result = Array(_columns.length);
10502
10508
  for (let col = 0; col < _columns.length; col++) {
10503
- const colIndex = _columns[col] - 1; // -1 because columns arguments are 1-indexed
10504
- result[col] = _array[colIndex];
10509
+ if (_columns[col] > 0) {
10510
+ result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
10511
+ }
10512
+ else {
10513
+ result[col] = _array[_array.length + _columns[col]];
10514
+ }
10505
10515
  }
10506
10516
  return result;
10507
10517
  },
@@ -10522,8 +10532,14 @@ stores.inject(MyMetaStore, storeInstance);
10522
10532
  const _array = toMatrix(array);
10523
10533
  const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
10524
10534
  const _nbColumns = _array.length;
10525
- assert(() => _rows.every((row) => row > 0 && row <= _array[0].length), _t("The rows arguments must be between 1 and %s (got %s).", _array[0].length.toString(), (_rows.find((row) => row <= 0 || row > _array[0].length) || 0).toString()));
10526
- return generateMatrix(_nbColumns, _rows.length, (col, row) => _array[col][_rows[row] - 1]); // -1 because rows arguments are 1-indexed
10535
+ const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
10536
+ assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
10537
+ return generateMatrix(_nbColumns, _rows.length, (col, row) => {
10538
+ if (_rows[row] > 0) {
10539
+ return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
10540
+ }
10541
+ return _array[col][_array[col].length + _rows[row]];
10542
+ });
10527
10543
  },
10528
10544
  isExported: true,
10529
10545
  };
@@ -11431,7 +11447,7 @@ stores.inject(MyMetaStore, storeInstance);
11431
11447
  compute: function (range, ...args) {
11432
11448
  let uniqueValues = new Set();
11433
11449
  visitMatchingRanges(args, (i, j) => {
11434
- const data = range[i][j];
11450
+ const data = range[i]?.[j];
11435
11451
  if (isDefined(data)) {
11436
11452
  uniqueValues.add(data.value);
11437
11453
  }
@@ -12061,7 +12077,7 @@ stores.inject(MyMetaStore, storeInstance);
12061
12077
  }
12062
12078
  let sum = 0;
12063
12079
  visitMatchingRanges([criteriaRange, criterion], (i, j) => {
12064
- const value = sumRange[i][j].value;
12080
+ const value = sumRange[i]?.[j]?.value;
12065
12081
  if (typeof value === "number") {
12066
12082
  sum += value;
12067
12083
  }
@@ -12086,7 +12102,7 @@ stores.inject(MyMetaStore, storeInstance);
12086
12102
  compute: function (sumRange, ...criters) {
12087
12103
  let sum = 0;
12088
12104
  visitMatchingRanges(criters, (i, j) => {
12089
- const value = sumRange[i][j].value;
12105
+ const value = sumRange[i]?.[j]?.value;
12090
12106
  if (typeof value === "number") {
12091
12107
  sum += value;
12092
12108
  }
@@ -12633,7 +12649,7 @@ stores.inject(MyMetaStore, storeInstance);
12633
12649
  let count = 0;
12634
12650
  let sum = 0;
12635
12651
  visitMatchingRanges([criteriaRange, criterion], (i, j) => {
12636
- const value = _averageRange[i][j].value;
12652
+ const value = _averageRange[i]?.[j]?.value;
12637
12653
  if (typeof value === "number") {
12638
12654
  count += 1;
12639
12655
  sum += value;
@@ -12662,7 +12678,7 @@ stores.inject(MyMetaStore, storeInstance);
12662
12678
  let count = 0;
12663
12679
  let sum = 0;
12664
12680
  visitMatchingRanges(args, (i, j) => {
12665
- const value = _averageRange[i][j].value;
12681
+ const value = _averageRange[i]?.[j]?.value;
12666
12682
  if (typeof value === "number") {
12667
12683
  count += 1;
12668
12684
  sum += value;
@@ -12967,7 +12983,7 @@ stores.inject(MyMetaStore, storeInstance);
12967
12983
  compute: function (range, ...args) {
12968
12984
  let result = -Infinity;
12969
12985
  visitMatchingRanges(args, (i, j) => {
12970
- const value = range[i][j].value;
12986
+ const value = range[i]?.[j]?.value;
12971
12987
  if (typeof value === "number") {
12972
12988
  result = result < value ? value : result;
12973
12989
  }
@@ -13050,7 +13066,7 @@ stores.inject(MyMetaStore, storeInstance);
13050
13066
  compute: function (range, ...args) {
13051
13067
  let result = Infinity;
13052
13068
  visitMatchingRanges(args, (i, j) => {
13053
- const value = range[i][j].value;
13069
+ const value = range[i]?.[j]?.value;
13054
13070
  if (typeof value === "number") {
13055
13071
  result = result > value ? value : result;
13056
13072
  }
@@ -18802,6 +18818,9 @@ stores.inject(MyMetaStore, storeInstance);
18802
18818
  }
18803
18819
  args[i] = arg[0][0];
18804
18820
  }
18821
+ if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
18822
+ throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
18823
+ }
18805
18824
  }
18806
18825
  return descr.compute.apply(this, args);
18807
18826
  }
@@ -19804,7 +19823,7 @@ stores.inject(MyMetaStore, storeInstance);
19804
19823
  constructor(definition, sheetId, getters) {
19805
19824
  super(definition, sheetId, getters);
19806
19825
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
19807
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
19826
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
19808
19827
  this.background = definition.background;
19809
19828
  this.verticalAxisPosition = definition.verticalAxisPosition;
19810
19829
  this.legendPosition = definition.legendPosition;
@@ -20048,7 +20067,7 @@ stores.inject(MyMetaStore, storeInstance);
20048
20067
  type = "gauge";
20049
20068
  constructor(definition, sheetId, getters) {
20050
20069
  super(definition, sheetId, getters);
20051
- this.dataRange = createRange(this.getters, this.sheetId, definition.dataRange);
20070
+ this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
20052
20071
  this.sectionRule = definition.sectionRule;
20053
20072
  this.background = definition.background;
20054
20073
  }
@@ -20569,7 +20588,7 @@ stores.inject(MyMetaStore, storeInstance);
20569
20588
  constructor(definition, sheetId, getters) {
20570
20589
  super(definition, sheetId, getters);
20571
20590
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
20572
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
20591
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
20573
20592
  this.background = definition.background;
20574
20593
  this.verticalAxisPosition = definition.verticalAxisPosition;
20575
20594
  this.legendPosition = definition.legendPosition;
@@ -20684,7 +20703,7 @@ stores.inject(MyMetaStore, storeInstance);
20684
20703
  constructor(definition, sheetId, getters) {
20685
20704
  super(definition, sheetId, getters);
20686
20705
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
20687
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
20706
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
20688
20707
  this.background = definition.background;
20689
20708
  this.legendPosition = definition.legendPosition;
20690
20709
  this.aggregated = definition.aggregated;
@@ -20886,7 +20905,7 @@ stores.inject(MyMetaStore, storeInstance);
20886
20905
  constructor(definition, sheetId, getters) {
20887
20906
  super(definition, sheetId, getters);
20888
20907
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
20889
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
20908
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
20890
20909
  this.background = definition.background;
20891
20910
  this.verticalAxisPosition = definition.verticalAxisPosition;
20892
20911
  this.legendPosition = definition.legendPosition;
@@ -20972,13 +20991,6 @@ stores.inject(MyMetaStore, storeInstance);
20972
20991
  // have less options than the line chart (it only works with linear labels)
20973
20992
  chartJsConfig.type = "line";
20974
20993
  const configOptions = chartJsConfig.options;
20975
- configOptions.elements = {
20976
- point: {
20977
- radius: 3,
20978
- hoverRadius: 3,
20979
- hitRadius: 8,
20980
- },
20981
- };
20982
20994
  const locale = getters.getLocale();
20983
20995
  configOptions.plugins.tooltip.callbacks.title = () => "";
20984
20996
  configOptions.plugins.tooltip.callbacks.label = (tooltipItem) => {
@@ -26812,7 +26824,7 @@ stores.inject(MyMetaStore, storeInstance);
26812
26824
  }
26813
26825
  const getters = this.env.model.getters;
26814
26826
  const sheetId = getters.getActiveSheetId();
26815
- const labelRange = createRange(getters, sheetId, this.labelRange);
26827
+ const labelRange = createValidRange(getters, sheetId, this.labelRange);
26816
26828
  const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
26817
26829
  if (dataSets.length) {
26818
26830
  return dataSets[0].dataRange.zone.top + 1;
@@ -26841,15 +26853,23 @@ stores.inject(MyMetaStore, storeInstance);
26841
26853
  }
26842
26854
  }
26843
26855
 
26856
+ /**
26857
+ * Start listening to pointer events and apply the given callbacks.
26858
+ *
26859
+ * @returns A function to remove the listeners.
26860
+ */
26844
26861
  function startDnd(onMouseMove, onMouseUp, onMouseDown = () => { }) {
26845
- const _onMouseUp = (ev) => {
26846
- onMouseUp(ev);
26862
+ const removeListeners = () => {
26847
26863
  window.removeEventListener("pointerdown", onMouseDown);
26848
26864
  window.removeEventListener("pointerup", _onMouseUp);
26849
26865
  window.removeEventListener("dragstart", _onDragStart);
26850
26866
  window.removeEventListener("pointermove", onMouseMove);
26851
26867
  window.removeEventListener("wheel", onMouseMove);
26852
26868
  };
26869
+ const _onMouseUp = (ev) => {
26870
+ onMouseUp(ev);
26871
+ removeListeners();
26872
+ };
26853
26873
  function _onDragStart(ev) {
26854
26874
  ev.preventDefault();
26855
26875
  }
@@ -26861,6 +26881,7 @@ stores.inject(MyMetaStore, storeInstance);
26861
26881
  // preventDefault() is not allowed in passive event handler.
26862
26882
  // https://chromestatus.com/feature/6662647093133312
26863
26883
  window.addEventListener("wheel", onMouseMove, { passive: false });
26884
+ return removeListeners;
26864
26885
  }
26865
26886
  /**
26866
26887
  * Function to be used during a pointerdown event, this function allows to
@@ -28055,6 +28076,7 @@ stores.inject(MyMetaStore, storeInstance);
28055
28076
  state.itemsStyle = {};
28056
28077
  document.body.style.cursor = previousCursor;
28057
28078
  args.onCancel?.();
28079
+ cleanUp();
28058
28080
  };
28059
28081
  const onDragEnd = (itemId, indexAtEnd) => {
28060
28082
  state.draggedItemId = undefined;
@@ -28075,7 +28097,8 @@ stores.inject(MyMetaStore, storeInstance);
28075
28097
  onDragEnd,
28076
28098
  onCancel: state.cancel,
28077
28099
  });
28078
- startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
28100
+ const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
28101
+ cleanupFns.push(stopListening);
28079
28102
  const onScroll = dndHelper.onScroll.bind(dndHelper);
28080
28103
  args.containerEl.addEventListener("scroll", onScroll);
28081
28104
  cleanupFns.push(() => args.containerEl.removeEventListener("scroll", onScroll));
@@ -28152,7 +28175,7 @@ stores.inject(MyMetaStore, storeInstance);
28152
28175
  this.moveDraggedItemToPosition(this.currentMousePosition + this.scrollOffset);
28153
28176
  }
28154
28177
  onMouseMove(ev) {
28155
- if (ev.button !== -1) {
28178
+ if (ev.button > 1) {
28156
28179
  this.onCancel();
28157
28180
  return;
28158
28181
  }
@@ -31322,14 +31345,14 @@ stores.inject(MyMetaStore, storeInstance);
31322
31345
  }
31323
31346
  onKeyDown(ev) {
31324
31347
  const figure = this.props.figure;
31325
- switch (ev.key) {
31348
+ const keyDownShortcut = keyboardEventToShortcutString(ev);
31349
+ switch (keyDownShortcut) {
31326
31350
  case "Delete":
31327
31351
  this.env.model.dispatch("DELETE_FIGURE", {
31328
31352
  sheetId: this.env.model.getters.getActiveSheetId(),
31329
31353
  id: figure.id,
31330
31354
  });
31331
31355
  this.props.onFigureDeleted();
31332
- ev.stopPropagation();
31333
31356
  ev.preventDefault();
31334
31357
  ev.stopPropagation();
31335
31358
  break;
@@ -31350,7 +31373,22 @@ stores.inject(MyMetaStore, storeInstance);
31350
31373
  x: figure.x + delta[0],
31351
31374
  y: figure.y + delta[1],
31352
31375
  });
31376
+ ev.preventDefault();
31377
+ ev.stopPropagation();
31378
+ break;
31379
+ case "Ctrl+A":
31380
+ // Maybe in the future we will implement a way to select all figures
31381
+ ev.preventDefault();
31353
31382
  ev.stopPropagation();
31383
+ break;
31384
+ case "Ctrl+Y":
31385
+ case "Ctrl+Z":
31386
+ if (keyDownShortcut === "Ctrl+Y") {
31387
+ this.env.model.dispatch("REQUEST_REDO");
31388
+ }
31389
+ else if (keyDownShortcut === "Ctrl+Z") {
31390
+ this.env.model.dispatch("REQUEST_UNDO");
31391
+ }
31354
31392
  ev.preventDefault();
31355
31393
  ev.stopPropagation();
31356
31394
  break;
@@ -41138,12 +41176,6 @@ stores.inject(MyMetaStore, storeInstance);
41138
41176
  // detect when an argument need to be evaluated as a meta argument
41139
41177
  const isMeta = argTypes.includes("META");
41140
41178
  const hasRange = argTypes.some((t) => isRangeType(t));
41141
- const isRangeOnly = argTypes.every((t) => isRangeType(t));
41142
- if (isRangeOnly) {
41143
- if (!isRangeInput(currentArg)) {
41144
- throw new BadExpressionError(_t("Function %s expects the parameter %s to be reference to a cell or range, not a %s.", functionName, (i + 1).toString(), currentArg.type.toLowerCase()));
41145
- }
41146
- }
41147
41179
  compiledArgs.push(compileAST(currentArg, isMeta, hasRange, {
41148
41180
  functionName,
41149
41181
  paramIndex: i + 1,
@@ -41314,16 +41346,6 @@ stores.inject(MyMetaStore, storeInstance);
41314
41346
  function isRangeType(type) {
41315
41347
  return type.startsWith("RANGE");
41316
41348
  }
41317
- function isRangeInput(arg) {
41318
- if (arg.type === "REFERENCE") {
41319
- return true;
41320
- }
41321
- if (arg.type === "FUNCALL") {
41322
- const fnDef = functions$1[arg.value.toUpperCase()];
41323
- return fnDef && isRangeType(fnDef.returns[0]);
41324
- }
41325
- return false;
41326
- }
41327
41349
 
41328
41350
  const functions = functionRegistry.content;
41329
41351
  function isExportableToExcel(tokens) {
@@ -44061,6 +44083,9 @@ stores.inject(MyMetaStore, storeInstance);
44061
44083
  if (range.invalidXc) {
44062
44084
  return range.invalidXc;
44063
44085
  }
44086
+ if (!this.getters.tryGetSheet(range.sheetId)) {
44087
+ return CellErrorType.InvalidReference;
44088
+ }
44064
44089
  if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
44065
44090
  return CellErrorType.InvalidReference;
44066
44091
  }
@@ -47445,7 +47470,6 @@ stores.inject(MyMetaStore, storeInstance);
47445
47470
  *
47446
47471
  */
47447
47472
  class SpreadingRelation {
47448
- createEmptyPositionSet;
47449
47473
  /**
47450
47474
  * Internal structure:
47451
47475
  * For something like
@@ -47476,9 +47500,6 @@ stores.inject(MyMetaStore, storeInstance);
47476
47500
  */
47477
47501
  resultsToArrayFormulas = new PositionMap();
47478
47502
  arrayFormulasToResults = new PositionMap();
47479
- constructor(createEmptyPositionSet) {
47480
- this.createEmptyPositionSet = createEmptyPositionSet;
47481
- }
47482
47503
  getFormulaPositionsSpreadingOn(resultPosition) {
47483
47504
  return this.resultsToArrayFormulas.get(resultPosition) || EMPTY_ARRAY;
47484
47505
  }
@@ -47497,13 +47518,13 @@ stores.inject(MyMetaStore, storeInstance);
47497
47518
  */
47498
47519
  addRelation({ arrayFormulaPosition, resultPosition, }) {
47499
47520
  if (!this.resultsToArrayFormulas.has(resultPosition)) {
47500
- this.resultsToArrayFormulas.set(resultPosition, this.createEmptyPositionSet());
47521
+ this.resultsToArrayFormulas.set(resultPosition, []);
47501
47522
  }
47502
- this.resultsToArrayFormulas.get(resultPosition)?.add(arrayFormulaPosition);
47523
+ this.resultsToArrayFormulas.get(resultPosition)?.push(arrayFormulaPosition);
47503
47524
  if (!this.arrayFormulasToResults.has(arrayFormulaPosition)) {
47504
- this.arrayFormulasToResults.set(arrayFormulaPosition, this.createEmptyPositionSet());
47525
+ this.arrayFormulasToResults.set(arrayFormulaPosition, []);
47505
47526
  }
47506
- this.arrayFormulasToResults.get(arrayFormulaPosition)?.add(resultPosition);
47527
+ this.arrayFormulasToResults.get(arrayFormulaPosition)?.push(resultPosition);
47507
47528
  }
47508
47529
  hasArrayFormulaResult(position) {
47509
47530
  return this.resultsToArrayFormulas.has(position);
@@ -47524,7 +47545,7 @@ stores.inject(MyMetaStore, storeInstance);
47524
47545
  evaluatedCells = new PositionMap();
47525
47546
  formulaDependencies = lazy(new FormulaDependencyGraph(this.createEmptyPositionSet.bind(this)));
47526
47547
  blockedArrayFormulas = new PositionSet({});
47527
- spreadingRelations = new SpreadingRelation(this.createEmptyPositionSet.bind(this));
47548
+ spreadingRelations = new SpreadingRelation();
47528
47549
  constructor(context, getters) {
47529
47550
  this.context = context;
47530
47551
  this.getters = getters;
@@ -47601,7 +47622,7 @@ stores.inject(MyMetaStore, storeInstance);
47601
47622
  }
47602
47623
  buildDependencyGraph() {
47603
47624
  this.blockedArrayFormulas = this.createEmptyPositionSet();
47604
- this.spreadingRelations = new SpreadingRelation(this.createEmptyPositionSet.bind(this));
47625
+ this.spreadingRelations = new SpreadingRelation();
47605
47626
  this.formulaDependencies = lazy(() => {
47606
47627
  const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position)
47607
47628
  .filter((range) => !range.invalidSheetName && !range.invalidXc)
@@ -48090,16 +48111,22 @@ stores.inject(MyMetaStore, storeInstance);
48090
48111
  let newContent = undefined;
48091
48112
  let newFormat = undefined;
48092
48113
  let isExported = true;
48114
+ const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
48093
48115
  const formulaCell = this.getCorrespondingFormulaCell(position);
48094
48116
  if (formulaCell) {
48095
48117
  isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
48096
48118
  isFormula = isExported;
48097
48119
  if (!isExported) {
48098
- newContent = (value ?? "").toString();
48099
- newFormat = evaluatedCell.format;
48120
+ // If the cell contains a non-exported formula and that is evaluates to
48121
+ // nothing* ,we don't export it.
48122
+ // * non-falsy value are relevant and so are 0 and FALSE, which only leaves
48123
+ // the empty string.
48124
+ if (value !== "") {
48125
+ newContent = (value ?? "").toString();
48126
+ newFormat = evaluatedCell.format;
48127
+ }
48100
48128
  }
48101
48129
  }
48102
- const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
48103
48130
  const exportedCellData = exportedSheetData.cells[xc] || {};
48104
48131
  const format = newFormat
48105
48132
  ? getItemId(newFormat, data.formats)
@@ -52089,7 +52116,7 @@ stores.inject(MyMetaStore, storeInstance);
52089
52116
  paintFormatStatus = "inactive";
52090
52117
  originSheetId;
52091
52118
  copiedData;
52092
- _isCutOperation;
52119
+ _isCutOperation = false;
52093
52120
  // ---------------------------------------------------------------------------
52094
52121
  // Command Handling
52095
52122
  // ---------------------------------------------------------------------------
@@ -52101,14 +52128,17 @@ stores.inject(MyMetaStore, storeInstance);
52101
52128
  case "PASTE_FROM_OS_CLIPBOARD": {
52102
52129
  const copiedData = this.convertOSClipboardData(cmd.text);
52103
52130
  const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
52104
- return this.isPasteAllowed(cmd.target, copiedData, { pasteOption });
52131
+ return this.isPasteAllowed(cmd.target, copiedData, { pasteOption, isCutOperation: false });
52105
52132
  }
52106
52133
  case "PASTE": {
52107
52134
  if (!this.copiedData) {
52108
52135
  return "EmptyClipboard" /* CommandResult.EmptyClipboard */;
52109
52136
  }
52110
52137
  const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
52111
- return this.isPasteAllowed(cmd.target, this.copiedData, { pasteOption });
52138
+ return this.isPasteAllowed(cmd.target, this.copiedData, {
52139
+ pasteOption: pasteOption,
52140
+ isCutOperation: this._isCutOperation,
52141
+ });
52112
52142
  }
52113
52143
  case "COPY_PASTE_CELLS_ABOVE": {
52114
52144
  const zones = this.getters.getSelectedZones();
@@ -52126,13 +52156,13 @@ stores.inject(MyMetaStore, storeInstance);
52126
52156
  }
52127
52157
  case "INSERT_CELL": {
52128
52158
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
52129
- const copiedData = this.copy("CUT", cut);
52130
- return this.isPasteAllowed(paste, copiedData, {});
52159
+ const copiedData = this.copy(cut);
52160
+ return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
52131
52161
  }
52132
52162
  case "DELETE_CELL": {
52133
52163
  const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
52134
- const copiedData = this.copy("CUT", cut);
52135
- return this.isPasteAllowed(paste, copiedData, {});
52164
+ const copiedData = this.copy(cut);
52165
+ return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
52136
52166
  }
52137
52167
  case "ACTIVATE_PAINT_FORMAT": {
52138
52168
  if (this.paintFormatStatus !== "inactive") {
@@ -52150,23 +52180,27 @@ stores.inject(MyMetaStore, storeInstance);
52150
52180
  const zones = this.getters.getSelectedZones();
52151
52181
  this.status = "visible";
52152
52182
  this.originSheetId = this.getters.getActiveSheetId();
52153
- this.copiedData = this.copy(cmd.type, zones);
52183
+ this.copiedData = this.copy(zones);
52184
+ this._isCutOperation = cmd.type === "CUT";
52154
52185
  break;
52155
52186
  case "PASTE_FROM_OS_CLIPBOARD": {
52187
+ this._isCutOperation = false;
52156
52188
  this.copiedData = this.convertOSClipboardData(cmd.text);
52157
52189
  const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
52158
- this.paste(cmd.target, {
52190
+ this.paste(cmd.target, this.copiedData, {
52159
52191
  pasteOption,
52160
52192
  selectTarget: true,
52193
+ isCutOperation: false,
52161
52194
  });
52162
52195
  this.status = "invisible";
52163
52196
  break;
52164
52197
  }
52165
52198
  case "PASTE": {
52166
52199
  const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
52167
- this.paste(cmd.target, {
52200
+ this.paste(cmd.target, this.copiedData, {
52168
52201
  pasteOption,
52169
52202
  selectTarget: true,
52203
+ isCutOperation: this._isCutOperation,
52170
52204
  });
52171
52205
  if (this.paintFormatStatus === "oneOff") {
52172
52206
  this.paintFormatStatus = "inactive";
@@ -52187,9 +52221,9 @@ stores.inject(MyMetaStore, storeInstance);
52187
52221
  top: multipleRowsInSelection ? zone.top : zone.top - 1,
52188
52222
  };
52189
52223
  this.originSheetId = this.getters.getActiveSheetId();
52190
- this.copiedData = this.copy("COPY", [copyTarget]);
52191
- this.paste([zone], {
52192
- pasteOption: undefined,
52224
+ const copiedData = this.copy([copyTarget]);
52225
+ this.paste([zone], copiedData, {
52226
+ isCutOperation: false,
52193
52227
  selectTarget: true,
52194
52228
  });
52195
52229
  }
@@ -52204,9 +52238,9 @@ stores.inject(MyMetaStore, storeInstance);
52204
52238
  left: multipleColsInSelection ? zone.left : zone.left - 1,
52205
52239
  };
52206
52240
  this.originSheetId = this.getters.getActiveSheetId();
52207
- this.copiedData = this.copy("COPY", [copyTarget]);
52208
- this.paste([zone], {
52209
- pasteOption: undefined,
52241
+ const copiedData = this.copy([copyTarget]);
52242
+ this.paste([zone], copiedData, {
52243
+ isCutOperation: false,
52210
52244
  selectTarget: true,
52211
52245
  });
52212
52246
  }
@@ -52222,14 +52256,14 @@ stores.inject(MyMetaStore, storeInstance);
52222
52256
  }
52223
52257
  break;
52224
52258
  }
52225
- this.copiedData = this.copy("CUT", cut);
52226
- this.paste(paste, {});
52259
+ const copiedData = this.copy(cut);
52260
+ this.paste(paste, copiedData, { isCutOperation: true });
52227
52261
  break;
52228
52262
  }
52229
52263
  case "INSERT_CELL": {
52230
52264
  const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
52231
- this.copiedData = this.copy("CUT", cut);
52232
- this.paste(paste, {});
52265
+ const copiedData = this.copy(cut);
52266
+ this.paste(paste, copiedData, { isCutOperation: true });
52233
52267
  break;
52234
52268
  }
52235
52269
  case "ADD_COLUMNS_ROWS": {
@@ -52261,7 +52295,8 @@ stores.inject(MyMetaStore, storeInstance);
52261
52295
  break;
52262
52296
  }
52263
52297
  case "REPEAT_PASTE": {
52264
- this.paste(cmd.target, {
52298
+ this.paste(cmd.target, this.copiedData, {
52299
+ isCutOperation: false,
52265
52300
  pasteOption: cmd.pasteOption,
52266
52301
  selectTarget: true,
52267
52302
  });
@@ -52269,7 +52304,7 @@ stores.inject(MyMetaStore, storeInstance);
52269
52304
  }
52270
52305
  case "ACTIVATE_PAINT_FORMAT": {
52271
52306
  const zones = this.getters.getSelectedZones();
52272
- this.copiedData = this.copy("COPY", zones);
52307
+ this.copiedData = this.copy(zones);
52273
52308
  this.status = "visible";
52274
52309
  if (cmd.persistent) {
52275
52310
  this.paintFormatStatus = "persistent";
@@ -52300,7 +52335,6 @@ stores.inject(MyMetaStore, storeInstance);
52300
52335
  }
52301
52336
  }
52302
52337
  convertOSClipboardData(clipboardData) {
52303
- this._isCutOperation = false;
52304
52338
  const handlers = clipboardHandlersRegistries.figureHandlers
52305
52339
  .getAll()
52306
52340
  .map((handler) => new handler(this.getters, this.dispatch));
@@ -52338,7 +52372,6 @@ stores.inject(MyMetaStore, storeInstance);
52338
52372
  for (const handler of this.selectClipboardHandlers(copiedData)) {
52339
52373
  const result = handler.isPasteAllowed(this.getters.getActiveSheetId(), target, copiedData, {
52340
52374
  ...options,
52341
- isCutOperation: this.isCutOperation(),
52342
52375
  });
52343
52376
  if (result !== "Success" /* CommandResult.Success */) {
52344
52377
  return result;
@@ -52361,9 +52394,8 @@ stores.inject(MyMetaStore, storeInstance);
52361
52394
  }
52362
52395
  return false;
52363
52396
  }
52364
- copy(operation, zones) {
52397
+ copy(zones) {
52365
52398
  let copiedData = {};
52366
- this._isCutOperation = operation === "CUT";
52367
52399
  const clipboardData = this.getClipboardData(zones);
52368
52400
  for (const handler of this.selectClipboardHandlers(clipboardData)) {
52369
52401
  const data = handler.copy(clipboardData);
@@ -52371,8 +52403,8 @@ stores.inject(MyMetaStore, storeInstance);
52371
52403
  }
52372
52404
  return copiedData;
52373
52405
  }
52374
- paste(zones, options) {
52375
- if (!this.copiedData) {
52406
+ paste(zones, copiedData, options) {
52407
+ if (!copiedData) {
52376
52408
  return;
52377
52409
  }
52378
52410
  let zone = undefined;
@@ -52380,12 +52412,9 @@ stores.inject(MyMetaStore, storeInstance);
52380
52412
  let target = {
52381
52413
  zones,
52382
52414
  };
52383
- const handlers = this.selectClipboardHandlers(this.copiedData);
52415
+ const handlers = this.selectClipboardHandlers(copiedData);
52384
52416
  for (const handler of handlers) {
52385
- const currentTarget = handler.getPasteTarget(zones, this.copiedData, {
52386
- ...options,
52387
- isCutOperation: this.isCutOperation(),
52388
- });
52417
+ const currentTarget = handler.getPasteTarget(zones, copiedData, options);
52389
52418
  if (currentTarget.figureId) {
52390
52419
  target.figureId = currentTarget.figureId;
52391
52420
  }
@@ -52401,7 +52430,7 @@ stores.inject(MyMetaStore, storeInstance);
52401
52430
  if (zone !== undefined) {
52402
52431
  this.addMissingDimensions(this.getters.getActiveSheetId(), zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
52403
52432
  }
52404
- handlers.forEach((handler) => handler.paste(target, this.copiedData, { ...options, isCutOperation: this.isCutOperation() }));
52433
+ handlers.forEach((handler) => handler.paste(target, copiedData, options));
52405
52434
  if (!options?.selectTarget) {
52406
52435
  return;
52407
52436
  }
@@ -54871,6 +54900,7 @@ stores.inject(MyMetaStore, storeInstance);
54871
54900
  sheetDivRef = owl.useRef("sheetDiv");
54872
54901
  sheetNameRef = owl.useRef("sheetNameSpan");
54873
54902
  editionState = "initializing";
54903
+ DOMFocusableElementStore;
54874
54904
  setup() {
54875
54905
  owl.onMounted(() => {
54876
54906
  if (this.isSheetActive) {
@@ -54883,6 +54913,7 @@ stores.inject(MyMetaStore, storeInstance);
54883
54913
  this.focusInputAndSelectContent();
54884
54914
  }
54885
54915
  });
54916
+ this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
54886
54917
  }
54887
54918
  focusInputAndSelectContent() {
54888
54919
  if (!this.state.isEditing || !this.sheetNameRef.el)
@@ -54924,9 +54955,11 @@ stores.inject(MyMetaStore, storeInstance);
54924
54955
  if (ev.key === "Enter") {
54925
54956
  ev.preventDefault();
54926
54957
  this.stopEdition();
54958
+ this.DOMFocusableElementStore.focus();
54927
54959
  }
54928
54960
  if (ev.key === "Escape") {
54929
54961
  this.cancelEdition();
54962
+ this.DOMFocusableElementStore.focus();
54930
54963
  }
54931
54964
  }
54932
54965
  onClickSheetName(ev) {
@@ -59649,7 +59682,11 @@ stores.inject(MyMetaStore, storeInstance);
59649
59682
  let cellNode = escapeXml ``;
59650
59683
  // Either formula or static value inside the cell
59651
59684
  if (cell.isFormula) {
59652
- ({ attrs: additionalAttrs, node: cellNode } = addFormula(cell));
59685
+ const res = addFormula(cell);
59686
+ if (!res) {
59687
+ continue;
59688
+ }
59689
+ ({ attrs: additionalAttrs, node: cellNode } = res);
59653
59690
  }
59654
59691
  else if (cell.content && isMarkdownLink(cell.content)) {
59655
59692
  const { label } = parseMarkdownLink(cell.content);
@@ -60729,9 +60766,9 @@ stores.inject(MyMetaStore, storeInstance);
60729
60766
  exports.tokenize = tokenize;
60730
60767
 
60731
60768
 
60732
- __info__.version = "17.2.8";
60733
- __info__.date = "2024-05-24T11:29:49.320Z";
60734
- __info__.hash = "bfbcaa0";
60769
+ __info__.version = "17.2.9";
60770
+ __info__.date = "2024-06-03T14:56:21.684Z";
60771
+ __info__.hash = "086af6d";
60735
60772
 
60736
60773
 
60737
60774
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);