@odoo/o-spreadsheet 16.3.35 → 16.3.37

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.
@@ -2488,8 +2488,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
2488
2488
  /**
2489
2489
  * Create a range from a xc. If the xc is empty, this function returns undefined.
2490
2490
  */
2491
- function createRange(getters, sheetId, range) {
2492
- return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
2491
+ function createValidRange(getters, sheetId, xc) {
2492
+ if (!xc)
2493
+ return;
2494
+ const range = getters.getRangeFromSheetXC(sheetId, xc);
2495
+ return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
2493
2496
  }
2494
2497
 
2495
2498
  /** Methods from Odoo Web Utils */
@@ -5262,6 +5265,7 @@ const FilterMenuPopoverBuilder = {
5262
5265
  };
5263
5266
 
5264
5267
  const macRegex = /Mac/i;
5268
+ const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
5265
5269
  /**
5266
5270
  * Return true if the event was triggered from
5267
5271
  * a child element.
@@ -5308,6 +5312,31 @@ function setElementScrollTop(el, scroll) {
5308
5312
  function getOpenedMenus() {
5309
5313
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5310
5314
  }
5315
+ const letterRegex = /^[a-zA-Z]$/;
5316
+ /**
5317
+ * Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
5318
+ *
5319
+ * @argument ev - The keyboard event to transform
5320
+ * @argument mode - Use either ev.key of ev.code to get the string shortcut
5321
+ *
5322
+ * @example
5323
+ * event : { ctrlKey: true, key: "a" } => "Ctrl+A"
5324
+ * event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
5325
+ */
5326
+ function keyboardEventToShortcutString(ev, mode = "key") {
5327
+ let keyDownString = "";
5328
+ if (!MODIFIER_KEYS.includes(ev.key)) {
5329
+ if (isCtrlKey(ev))
5330
+ keyDownString += "Ctrl+";
5331
+ if (ev.altKey)
5332
+ keyDownString += "Alt+";
5333
+ if (ev.shiftKey)
5334
+ keyDownString += "Shift+";
5335
+ }
5336
+ const key = mode === "key" ? ev.key : ev.code;
5337
+ keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
5338
+ return keyDownString;
5339
+ }
5311
5340
  function isMacOS() {
5312
5341
  return Boolean(macRegex.test(navigator.userAgent));
5313
5342
  }
@@ -7027,7 +7056,7 @@ class BarChart extends AbstractChart {
7027
7056
  constructor(definition, sheetId, getters) {
7028
7057
  super(definition, sheetId, getters);
7029
7058
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7030
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
7059
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
7031
7060
  this.background = definition.background;
7032
7061
  this.verticalAxisPosition = definition.verticalAxisPosition;
7033
7062
  this.legendPosition = definition.legendPosition;
@@ -7271,7 +7300,7 @@ class GaugeChart extends AbstractChart {
7271
7300
  type = "gauge";
7272
7301
  constructor(definition, sheetId, getters) {
7273
7302
  super(definition, sheetId, getters);
7274
- this.dataRange = createRange(this.getters, this.sheetId, definition.dataRange);
7303
+ this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
7275
7304
  this.sectionRule = definition.sectionRule;
7276
7305
  this.background = definition.background;
7277
7306
  }
@@ -7607,7 +7636,7 @@ class LineChart extends AbstractChart {
7607
7636
  constructor(definition, sheetId, getters) {
7608
7637
  super(definition, sheetId, getters);
7609
7638
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7610
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
7639
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
7611
7640
  this.background = definition.background;
7612
7641
  this.verticalAxisPosition = definition.verticalAxisPosition;
7613
7642
  this.legendPosition = definition.legendPosition;
@@ -7903,7 +7932,7 @@ class PieChart extends AbstractChart {
7903
7932
  constructor(definition, sheetId, getters) {
7904
7933
  super(definition, sheetId, getters);
7905
7934
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7906
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
7935
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
7907
7936
  this.background = definition.background;
7908
7937
  this.legendPosition = definition.legendPosition;
7909
7938
  this.aggregated = definition.aggregated;
@@ -8070,8 +8099,8 @@ class ScorecardChart extends AbstractChart {
8070
8099
  type = "scorecard";
8071
8100
  constructor(definition, sheetId, getters) {
8072
8101
  super(definition, sheetId, getters);
8073
- this.keyValue = createRange(getters, sheetId, definition.keyValue);
8074
- this.baseline = createRange(getters, sheetId, definition.baseline);
8102
+ this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
8103
+ this.baseline = createValidRange(getters, sheetId, definition.baseline);
8075
8104
  this.baselineMode = definition.baselineMode;
8076
8105
  this.baselineDescr = definition.baselineDescr;
8077
8106
  this.background = definition.background;
@@ -18102,7 +18131,7 @@ class LineBarPieConfigPanel extends owl.Component {
18102
18131
  }
18103
18132
  const getters = this.env.model.getters;
18104
18133
  const sheetId = getters.getActiveSheetId();
18105
- const labelRange = createRange(getters, sheetId, this.labelRange);
18134
+ const labelRange = createValidRange(getters, sheetId, this.labelRange);
18106
18135
  const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
18107
18136
  if (dataSets.length) {
18108
18137
  return dataSets[0].dataRange.zone.top + 1;
@@ -20266,14 +20295,14 @@ class FigureComponent extends owl.Component {
20266
20295
  }
20267
20296
  onKeyDown(ev) {
20268
20297
  const figure = this.props.figure;
20269
- switch (ev.key) {
20298
+ const keyDownShortcut = keyboardEventToShortcutString(ev);
20299
+ switch (keyDownShortcut) {
20270
20300
  case "Delete":
20271
20301
  this.env.model.dispatch("DELETE_FIGURE", {
20272
20302
  sheetId: this.env.model.getters.getActiveSheetId(),
20273
20303
  id: figure.id,
20274
20304
  });
20275
20305
  this.props.onFigureDeleted();
20276
- ev.stopPropagation();
20277
20306
  ev.preventDefault();
20278
20307
  ev.stopPropagation();
20279
20308
  break;
@@ -20294,7 +20323,22 @@ class FigureComponent extends owl.Component {
20294
20323
  x: figure.x + delta[0],
20295
20324
  y: figure.y + delta[1],
20296
20325
  });
20326
+ ev.preventDefault();
20327
+ ev.stopPropagation();
20328
+ break;
20329
+ case "Ctrl+A":
20330
+ // Maybe in the future we will implement a way to select all figures
20331
+ ev.preventDefault();
20297
20332
  ev.stopPropagation();
20333
+ break;
20334
+ case "Ctrl+Y":
20335
+ case "Ctrl+Z":
20336
+ if (keyDownShortcut === "Ctrl+Y") {
20337
+ this.env.model.dispatch("REQUEST_REDO");
20338
+ }
20339
+ else if (keyDownShortcut === "Ctrl+Z") {
20340
+ this.env.model.dispatch("REQUEST_UNDO");
20341
+ }
20298
20342
  ev.preventDefault();
20299
20343
  ev.stopPropagation();
20300
20344
  break;
@@ -21088,7 +21132,7 @@ class Composer extends owl.Component {
21088
21132
  Enter: this.processEnterKey,
21089
21133
  Escape: this.processEscapeKey,
21090
21134
  F2: () => console.warn("Not implemented"),
21091
- F4: this.processF4Key,
21135
+ F4: (ev) => this.processF4Key(ev),
21092
21136
  Tab: (ev) => this.processTabKey(ev),
21093
21137
  };
21094
21138
  setup() {
@@ -21205,9 +21249,10 @@ class Composer extends owl.Component {
21205
21249
  processEscapeKey() {
21206
21250
  this.env.model.dispatch("STOP_EDITION", { cancel: true });
21207
21251
  }
21208
- processF4Key() {
21252
+ processF4Key(ev) {
21209
21253
  this.env.model.dispatch("CYCLE_EDITION_REFERENCES");
21210
21254
  this.processContent();
21255
+ ev.stopPropagation();
21211
21256
  }
21212
21257
  onCompositionStart() {
21213
21258
  this.compositionActive = true;
@@ -31898,7 +31943,12 @@ class MergePlugin extends CorePlugin {
31898
31943
  * if they have at least a common cell
31899
31944
  */
31900
31945
  doesIntersectMerge(sheetId, zone) {
31901
- return positions(zone).some(({ col, row }) => this.getMerge({ sheetId, col, row }) !== undefined);
31946
+ for (const merge of this.getMerges(sheetId)) {
31947
+ if (overlap(zone, merge)) {
31948
+ return true;
31949
+ }
31950
+ }
31951
+ return false;
31902
31952
  }
31903
31953
  /**
31904
31954
  * Returns true if two columns have at least one merge in common
@@ -32510,6 +32560,9 @@ class RangeAdapter {
32510
32560
  if (range.invalidXc) {
32511
32561
  return range.invalidXc;
32512
32562
  }
32563
+ if (!this.getters.tryGetSheet(range.sheetId)) {
32564
+ return INCORRECT_RANGE_STRING;
32565
+ }
32513
32566
  if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
32514
32567
  return INCORRECT_RANGE_STRING;
32515
32568
  }
@@ -40608,7 +40661,7 @@ class ClipboardPlugin extends UIPlugin {
40608
40661
  case "ADD_COLUMNS_ROWS": {
40609
40662
  this.status = "invisible";
40610
40663
  // If we add a col/row inside or before the cut area, we invalidate the clipboard
40611
- if (this.state?.operation !== "CUT") {
40664
+ if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
40612
40665
  return;
40613
40666
  }
40614
40667
  const isClipboardDirty = this.state.isColRowDirtyingClipboard(cmd.position === "before" ? cmd.base : cmd.base + 1, cmd.dimension);
@@ -40620,7 +40673,7 @@ class ClipboardPlugin extends UIPlugin {
40620
40673
  case "REMOVE_COLUMNS_ROWS": {
40621
40674
  this.status = "invisible";
40622
40675
  // If we remove a col/row inside or before the cut area, we invalidate the clipboard
40623
- if (this.state?.operation !== "CUT") {
40676
+ if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
40624
40677
  return;
40625
40678
  }
40626
40679
  for (let el of cmd.elements) {
@@ -42523,9 +42576,11 @@ class BottomBarSheet extends owl.Component {
42523
42576
  if (ev.key === "Enter") {
42524
42577
  ev.preventDefault();
42525
42578
  this.stopEdition();
42579
+ this.env.focusableElement.focus();
42526
42580
  }
42527
42581
  if (ev.key === "Escape") {
42528
42582
  this.cancelEdition();
42583
+ this.env.focusableElement.focus();
42529
42584
  }
42530
42585
  }
42531
42586
  onClickSheetName(ev) {
@@ -44270,6 +44325,10 @@ class Spreadsheet extends owl.Component {
44270
44325
  });
44271
44326
  owl.useExternalListener(window, "resize", () => this.render(true));
44272
44327
  owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
44328
+ // For some reason, the wheel event is not properly registered inside templates
44329
+ // in Chromium-based browsers based on chromium 125
44330
+ // This hack ensures the event declared in the template is properly registered/working
44331
+ owl.useExternalListener(document.body, "wheel", () => { });
44273
44332
  this.bindModelEvents();
44274
44333
  owl.onMounted(() => {
44275
44334
  this.checkViewportSize();
@@ -46309,6 +46368,12 @@ function addFormula(cell) {
46309
46368
  else {
46310
46369
  // Shouldn't we always output the value then ?
46311
46370
  const value = cell.value;
46371
+ // If the cell contains a non-exported formula and that is evaluates to
46372
+ // nothing* ,we don't export it.
46373
+ // * non-falsy value are relevant and so are 0 and FALSE, which only leaves
46374
+ // the empty string.
46375
+ if (value === "")
46376
+ return undefined;
46312
46377
  const type = getCellType(value);
46313
46378
  attrs.push(["t", type]);
46314
46379
  node = escapeXml /*xml*/ `<v>${value}</v>`;
@@ -47112,7 +47177,11 @@ function addRows(construct, data, sheet) {
47112
47177
  let cellNode = escapeXml ``;
47113
47178
  // Either formula or static value inside the cell
47114
47179
  if (cell.isFormula) {
47115
- ({ attrs: additionalAttrs, node: cellNode } = addFormula(cell));
47180
+ const res = addFormula(cell);
47181
+ if (!res) {
47182
+ continue;
47183
+ }
47184
+ ({ attrs: additionalAttrs, node: cellNode } = res);
47116
47185
  }
47117
47186
  else if (cell.content && isMarkdownLink(cell.content)) {
47118
47187
  const { label } = parseMarkdownLink(cell.content);
@@ -48093,6 +48162,6 @@ exports.setTranslationMethod = setTranslationMethod;
48093
48162
  exports.tokenize = tokenize;
48094
48163
 
48095
48164
 
48096
- __info__.version = '16.3.35';
48097
- __info__.date = '2024-05-15T09:15:19.399Z';
48098
- __info__.hash = '255caa0';
48165
+ __info__.version = '16.3.37';
48166
+ __info__.date = '2024-06-03T14:49:37.305Z';
48167
+ __info__.hash = 'e7bf8e1';
@@ -2484,8 +2484,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
2484
2484
  /**
2485
2485
  * Create a range from a xc. If the xc is empty, this function returns undefined.
2486
2486
  */
2487
- function createRange(getters, sheetId, range) {
2488
- return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
2487
+ function createValidRange(getters, sheetId, xc) {
2488
+ if (!xc)
2489
+ return;
2490
+ const range = getters.getRangeFromSheetXC(sheetId, xc);
2491
+ return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
2489
2492
  }
2490
2493
 
2491
2494
  /** Methods from Odoo Web Utils */
@@ -5258,6 +5261,7 @@ const FilterMenuPopoverBuilder = {
5258
5261
  };
5259
5262
 
5260
5263
  const macRegex = /Mac/i;
5264
+ const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
5261
5265
  /**
5262
5266
  * Return true if the event was triggered from
5263
5267
  * a child element.
@@ -5304,6 +5308,31 @@ function setElementScrollTop(el, scroll) {
5304
5308
  function getOpenedMenus() {
5305
5309
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5306
5310
  }
5311
+ const letterRegex = /^[a-zA-Z]$/;
5312
+ /**
5313
+ * Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
5314
+ *
5315
+ * @argument ev - The keyboard event to transform
5316
+ * @argument mode - Use either ev.key of ev.code to get the string shortcut
5317
+ *
5318
+ * @example
5319
+ * event : { ctrlKey: true, key: "a" } => "Ctrl+A"
5320
+ * event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
5321
+ */
5322
+ function keyboardEventToShortcutString(ev, mode = "key") {
5323
+ let keyDownString = "";
5324
+ if (!MODIFIER_KEYS.includes(ev.key)) {
5325
+ if (isCtrlKey(ev))
5326
+ keyDownString += "Ctrl+";
5327
+ if (ev.altKey)
5328
+ keyDownString += "Alt+";
5329
+ if (ev.shiftKey)
5330
+ keyDownString += "Shift+";
5331
+ }
5332
+ const key = mode === "key" ? ev.key : ev.code;
5333
+ keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
5334
+ return keyDownString;
5335
+ }
5307
5336
  function isMacOS() {
5308
5337
  return Boolean(macRegex.test(navigator.userAgent));
5309
5338
  }
@@ -7023,7 +7052,7 @@ class BarChart extends AbstractChart {
7023
7052
  constructor(definition, sheetId, getters) {
7024
7053
  super(definition, sheetId, getters);
7025
7054
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7026
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
7055
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
7027
7056
  this.background = definition.background;
7028
7057
  this.verticalAxisPosition = definition.verticalAxisPosition;
7029
7058
  this.legendPosition = definition.legendPosition;
@@ -7267,7 +7296,7 @@ class GaugeChart extends AbstractChart {
7267
7296
  type = "gauge";
7268
7297
  constructor(definition, sheetId, getters) {
7269
7298
  super(definition, sheetId, getters);
7270
- this.dataRange = createRange(this.getters, this.sheetId, definition.dataRange);
7299
+ this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
7271
7300
  this.sectionRule = definition.sectionRule;
7272
7301
  this.background = definition.background;
7273
7302
  }
@@ -7603,7 +7632,7 @@ class LineChart extends AbstractChart {
7603
7632
  constructor(definition, sheetId, getters) {
7604
7633
  super(definition, sheetId, getters);
7605
7634
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7606
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
7635
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
7607
7636
  this.background = definition.background;
7608
7637
  this.verticalAxisPosition = definition.verticalAxisPosition;
7609
7638
  this.legendPosition = definition.legendPosition;
@@ -7899,7 +7928,7 @@ class PieChart extends AbstractChart {
7899
7928
  constructor(definition, sheetId, getters) {
7900
7929
  super(definition, sheetId, getters);
7901
7930
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
7902
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
7931
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
7903
7932
  this.background = definition.background;
7904
7933
  this.legendPosition = definition.legendPosition;
7905
7934
  this.aggregated = definition.aggregated;
@@ -8066,8 +8095,8 @@ class ScorecardChart extends AbstractChart {
8066
8095
  type = "scorecard";
8067
8096
  constructor(definition, sheetId, getters) {
8068
8097
  super(definition, sheetId, getters);
8069
- this.keyValue = createRange(getters, sheetId, definition.keyValue);
8070
- this.baseline = createRange(getters, sheetId, definition.baseline);
8098
+ this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
8099
+ this.baseline = createValidRange(getters, sheetId, definition.baseline);
8071
8100
  this.baselineMode = definition.baselineMode;
8072
8101
  this.baselineDescr = definition.baselineDescr;
8073
8102
  this.background = definition.background;
@@ -18098,7 +18127,7 @@ class LineBarPieConfigPanel extends Component {
18098
18127
  }
18099
18128
  const getters = this.env.model.getters;
18100
18129
  const sheetId = getters.getActiveSheetId();
18101
- const labelRange = createRange(getters, sheetId, this.labelRange);
18130
+ const labelRange = createValidRange(getters, sheetId, this.labelRange);
18102
18131
  const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
18103
18132
  if (dataSets.length) {
18104
18133
  return dataSets[0].dataRange.zone.top + 1;
@@ -20262,14 +20291,14 @@ class FigureComponent extends Component {
20262
20291
  }
20263
20292
  onKeyDown(ev) {
20264
20293
  const figure = this.props.figure;
20265
- switch (ev.key) {
20294
+ const keyDownShortcut = keyboardEventToShortcutString(ev);
20295
+ switch (keyDownShortcut) {
20266
20296
  case "Delete":
20267
20297
  this.env.model.dispatch("DELETE_FIGURE", {
20268
20298
  sheetId: this.env.model.getters.getActiveSheetId(),
20269
20299
  id: figure.id,
20270
20300
  });
20271
20301
  this.props.onFigureDeleted();
20272
- ev.stopPropagation();
20273
20302
  ev.preventDefault();
20274
20303
  ev.stopPropagation();
20275
20304
  break;
@@ -20290,7 +20319,22 @@ class FigureComponent extends Component {
20290
20319
  x: figure.x + delta[0],
20291
20320
  y: figure.y + delta[1],
20292
20321
  });
20322
+ ev.preventDefault();
20323
+ ev.stopPropagation();
20324
+ break;
20325
+ case "Ctrl+A":
20326
+ // Maybe in the future we will implement a way to select all figures
20327
+ ev.preventDefault();
20293
20328
  ev.stopPropagation();
20329
+ break;
20330
+ case "Ctrl+Y":
20331
+ case "Ctrl+Z":
20332
+ if (keyDownShortcut === "Ctrl+Y") {
20333
+ this.env.model.dispatch("REQUEST_REDO");
20334
+ }
20335
+ else if (keyDownShortcut === "Ctrl+Z") {
20336
+ this.env.model.dispatch("REQUEST_UNDO");
20337
+ }
20294
20338
  ev.preventDefault();
20295
20339
  ev.stopPropagation();
20296
20340
  break;
@@ -21084,7 +21128,7 @@ class Composer extends Component {
21084
21128
  Enter: this.processEnterKey,
21085
21129
  Escape: this.processEscapeKey,
21086
21130
  F2: () => console.warn("Not implemented"),
21087
- F4: this.processF4Key,
21131
+ F4: (ev) => this.processF4Key(ev),
21088
21132
  Tab: (ev) => this.processTabKey(ev),
21089
21133
  };
21090
21134
  setup() {
@@ -21201,9 +21245,10 @@ class Composer extends Component {
21201
21245
  processEscapeKey() {
21202
21246
  this.env.model.dispatch("STOP_EDITION", { cancel: true });
21203
21247
  }
21204
- processF4Key() {
21248
+ processF4Key(ev) {
21205
21249
  this.env.model.dispatch("CYCLE_EDITION_REFERENCES");
21206
21250
  this.processContent();
21251
+ ev.stopPropagation();
21207
21252
  }
21208
21253
  onCompositionStart() {
21209
21254
  this.compositionActive = true;
@@ -31894,7 +31939,12 @@ class MergePlugin extends CorePlugin {
31894
31939
  * if they have at least a common cell
31895
31940
  */
31896
31941
  doesIntersectMerge(sheetId, zone) {
31897
- return positions(zone).some(({ col, row }) => this.getMerge({ sheetId, col, row }) !== undefined);
31942
+ for (const merge of this.getMerges(sheetId)) {
31943
+ if (overlap(zone, merge)) {
31944
+ return true;
31945
+ }
31946
+ }
31947
+ return false;
31898
31948
  }
31899
31949
  /**
31900
31950
  * Returns true if two columns have at least one merge in common
@@ -32506,6 +32556,9 @@ class RangeAdapter {
32506
32556
  if (range.invalidXc) {
32507
32557
  return range.invalidXc;
32508
32558
  }
32559
+ if (!this.getters.tryGetSheet(range.sheetId)) {
32560
+ return INCORRECT_RANGE_STRING;
32561
+ }
32509
32562
  if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
32510
32563
  return INCORRECT_RANGE_STRING;
32511
32564
  }
@@ -40604,7 +40657,7 @@ class ClipboardPlugin extends UIPlugin {
40604
40657
  case "ADD_COLUMNS_ROWS": {
40605
40658
  this.status = "invisible";
40606
40659
  // If we add a col/row inside or before the cut area, we invalidate the clipboard
40607
- if (this.state?.operation !== "CUT") {
40660
+ if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
40608
40661
  return;
40609
40662
  }
40610
40663
  const isClipboardDirty = this.state.isColRowDirtyingClipboard(cmd.position === "before" ? cmd.base : cmd.base + 1, cmd.dimension);
@@ -40616,7 +40669,7 @@ class ClipboardPlugin extends UIPlugin {
40616
40669
  case "REMOVE_COLUMNS_ROWS": {
40617
40670
  this.status = "invisible";
40618
40671
  // If we remove a col/row inside or before the cut area, we invalidate the clipboard
40619
- if (this.state?.operation !== "CUT") {
40672
+ if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
40620
40673
  return;
40621
40674
  }
40622
40675
  for (let el of cmd.elements) {
@@ -42519,9 +42572,11 @@ class BottomBarSheet extends Component {
42519
42572
  if (ev.key === "Enter") {
42520
42573
  ev.preventDefault();
42521
42574
  this.stopEdition();
42575
+ this.env.focusableElement.focus();
42522
42576
  }
42523
42577
  if (ev.key === "Escape") {
42524
42578
  this.cancelEdition();
42579
+ this.env.focusableElement.focus();
42525
42580
  }
42526
42581
  }
42527
42582
  onClickSheetName(ev) {
@@ -44266,6 +44321,10 @@ class Spreadsheet extends Component {
44266
44321
  });
44267
44322
  useExternalListener(window, "resize", () => this.render(true));
44268
44323
  useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
44324
+ // For some reason, the wheel event is not properly registered inside templates
44325
+ // in Chromium-based browsers based on chromium 125
44326
+ // This hack ensures the event declared in the template is properly registered/working
44327
+ useExternalListener(document.body, "wheel", () => { });
44269
44328
  this.bindModelEvents();
44270
44329
  onMounted(() => {
44271
44330
  this.checkViewportSize();
@@ -46305,6 +46364,12 @@ function addFormula(cell) {
46305
46364
  else {
46306
46365
  // Shouldn't we always output the value then ?
46307
46366
  const value = cell.value;
46367
+ // If the cell contains a non-exported formula and that is evaluates to
46368
+ // nothing* ,we don't export it.
46369
+ // * non-falsy value are relevant and so are 0 and FALSE, which only leaves
46370
+ // the empty string.
46371
+ if (value === "")
46372
+ return undefined;
46308
46373
  const type = getCellType(value);
46309
46374
  attrs.push(["t", type]);
46310
46375
  node = escapeXml /*xml*/ `<v>${value}</v>`;
@@ -47108,7 +47173,11 @@ function addRows(construct, data, sheet) {
47108
47173
  let cellNode = escapeXml ``;
47109
47174
  // Either formula or static value inside the cell
47110
47175
  if (cell.isFormula) {
47111
- ({ attrs: additionalAttrs, node: cellNode } = addFormula(cell));
47176
+ const res = addFormula(cell);
47177
+ if (!res) {
47178
+ continue;
47179
+ }
47180
+ ({ attrs: additionalAttrs, node: cellNode } = res);
47112
47181
  }
47113
47182
  else if (cell.content && isMarkdownLink(cell.content)) {
47114
47183
  const { label } = parseMarkdownLink(cell.content);
@@ -48061,6 +48130,6 @@ function addFunction(functionName, functionDescription) {
48061
48130
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
48062
48131
 
48063
48132
 
48064
- __info__.version = '16.3.35';
48065
- __info__.date = '2024-05-15T09:15:19.399Z';
48066
- __info__.hash = '255caa0';
48133
+ __info__.version = '16.3.37';
48134
+ __info__.date = '2024-06-03T14:49:37.305Z';
48135
+ __info__.hash = 'e7bf8e1';