@odoo/o-spreadsheet 16.4.34 → 16.4.36

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.
@@ -3233,8 +3233,11 @@
3233
3233
  /**
3234
3234
  * Create a range from a xc. If the xc is empty, this function returns undefined.
3235
3235
  */
3236
- function createRange(getters, sheetId, range) {
3237
- return range ? getters.getRangeFromSheetXC(sheetId, range) : undefined;
3236
+ function createValidRange(getters, sheetId, xc) {
3237
+ if (!xc)
3238
+ return;
3239
+ const range = getters.getRangeFromSheetXC(sheetId, xc);
3240
+ return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
3238
3241
  }
3239
3242
  /**
3240
3243
  * Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
@@ -5701,6 +5704,7 @@
5701
5704
  };
5702
5705
 
5703
5706
  const macRegex = /Mac/i;
5707
+ const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
5704
5708
  /**
5705
5709
  * Return true if the event was triggered from
5706
5710
  * a child element.
@@ -5739,6 +5743,31 @@
5739
5743
  function getOpenedMenus() {
5740
5744
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5741
5745
  }
5746
+ const letterRegex = /^[a-zA-Z]$/;
5747
+ /**
5748
+ * Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
5749
+ *
5750
+ * @argument ev - The keyboard event to transform
5751
+ * @argument mode - Use either ev.key of ev.code to get the string shortcut
5752
+ *
5753
+ * @example
5754
+ * event : { ctrlKey: true, key: "a" } => "Ctrl+A"
5755
+ * event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
5756
+ */
5757
+ function keyboardEventToShortcutString(ev, mode = "key") {
5758
+ let keyDownString = "";
5759
+ if (!MODIFIER_KEYS.includes(ev.key)) {
5760
+ if (isCtrlKey(ev))
5761
+ keyDownString += "Ctrl+";
5762
+ if (ev.altKey)
5763
+ keyDownString += "Alt+";
5764
+ if (ev.shiftKey)
5765
+ keyDownString += "Shift+";
5766
+ }
5767
+ const key = mode === "key" ? ev.key : ev.code;
5768
+ keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
5769
+ return keyDownString;
5770
+ }
5742
5771
  function isMacOS() {
5743
5772
  return Boolean(macRegex.test(navigator.userAgent));
5744
5773
  }
@@ -5757,8 +5786,7 @@
5757
5786
  */
5758
5787
  function useSpreadsheetRect() {
5759
5788
  const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
5760
- let spreadsheetElement = document.querySelector(".o-spreadsheet");
5761
- updatePosition();
5789
+ let spreadsheetElement = null;
5762
5790
  function updatePosition() {
5763
5791
  if (!spreadsheetElement) {
5764
5792
  spreadsheetElement = document.querySelector(".o-spreadsheet");
@@ -16539,7 +16567,7 @@
16539
16567
  constructor(definition, sheetId, getters) {
16540
16568
  super(definition, sheetId, getters);
16541
16569
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
16542
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
16570
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
16543
16571
  this.background = definition.background;
16544
16572
  this.verticalAxisPosition = definition.verticalAxisPosition;
16545
16573
  this.legendPosition = definition.legendPosition;
@@ -16784,7 +16812,7 @@
16784
16812
  type = "gauge";
16785
16813
  constructor(definition, sheetId, getters) {
16786
16814
  super(definition, sheetId, getters);
16787
- this.dataRange = createRange(this.getters, this.sheetId, definition.dataRange);
16815
+ this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
16788
16816
  this.sectionRule = definition.sectionRule;
16789
16817
  this.background = definition.background;
16790
16818
  }
@@ -17123,7 +17151,7 @@
17123
17151
  constructor(definition, sheetId, getters) {
17124
17152
  super(definition, sheetId, getters);
17125
17153
  this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
17126
- this.labelRange = createRange(this.getters, sheetId, definition.labelRange);
17154
+ this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
17127
17155
  this.background = definition.background;
17128
17156
  this.verticalAxisPosition = definition.verticalAxisPosition;
17129
17157
  this.legendPosition = definition.legendPosition;
@@ -17421,7 +17449,7 @@
17421
17449
  constructor(definition, sheetId, getters) {
17422
17450
  super(definition, sheetId, getters);
17423
17451
  this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
17424
- this.labelRange = createRange(getters, sheetId, definition.labelRange);
17452
+ this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
17425
17453
  this.background = definition.background;
17426
17454
  this.legendPosition = definition.legendPosition;
17427
17455
  this.aggregated = definition.aggregated;
@@ -17589,8 +17617,8 @@
17589
17617
  type = "scorecard";
17590
17618
  constructor(definition, sheetId, getters) {
17591
17619
  super(definition, sheetId, getters);
17592
- this.keyValue = createRange(getters, sheetId, definition.keyValue);
17593
- this.baseline = createRange(getters, sheetId, definition.baseline);
17620
+ this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
17621
+ this.baseline = createValidRange(getters, sheetId, definition.baseline);
17594
17622
  this.baselineMode = definition.baselineMode;
17595
17623
  this.baselineDescr = definition.baselineDescr;
17596
17624
  this.background = definition.background;
@@ -20949,7 +20977,7 @@
20949
20977
  }
20950
20978
  const getters = this.env.model.getters;
20951
20979
  const sheetId = getters.getActiveSheetId();
20952
- const labelRange = createRange(getters, sheetId, this.labelRange);
20980
+ const labelRange = createValidRange(getters, sheetId, this.labelRange);
20953
20981
  const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
20954
20982
  if (dataSets.length) {
20955
20983
  return dataSets[0].dataRange.zone.top + 1;
@@ -23414,14 +23442,14 @@
23414
23442
  }
23415
23443
  onKeyDown(ev) {
23416
23444
  const figure = this.props.figure;
23417
- switch (ev.key) {
23445
+ const keyDownShortcut = keyboardEventToShortcutString(ev);
23446
+ switch (keyDownShortcut) {
23418
23447
  case "Delete":
23419
23448
  this.env.model.dispatch("DELETE_FIGURE", {
23420
23449
  sheetId: this.env.model.getters.getActiveSheetId(),
23421
23450
  id: figure.id,
23422
23451
  });
23423
23452
  this.props.onFigureDeleted();
23424
- ev.stopPropagation();
23425
23453
  ev.preventDefault();
23426
23454
  ev.stopPropagation();
23427
23455
  break;
@@ -23442,7 +23470,22 @@
23442
23470
  x: figure.x + delta[0],
23443
23471
  y: figure.y + delta[1],
23444
23472
  });
23473
+ ev.preventDefault();
23445
23474
  ev.stopPropagation();
23475
+ break;
23476
+ case "Ctrl+A":
23477
+ // Maybe in the future we will implement a way to select all figures
23478
+ ev.preventDefault();
23479
+ ev.stopPropagation();
23480
+ break;
23481
+ case "Ctrl+Y":
23482
+ case "Ctrl+Z":
23483
+ if (keyDownShortcut === "Ctrl+Y") {
23484
+ this.env.model.dispatch("REQUEST_REDO");
23485
+ }
23486
+ else if (keyDownShortcut === "Ctrl+Z") {
23487
+ this.env.model.dispatch("REQUEST_UNDO");
23488
+ }
23446
23489
  ev.preventDefault();
23447
23490
  ev.stopPropagation();
23448
23491
  break;
@@ -24313,8 +24356,15 @@
24313
24356
  }
24314
24357
  onPaste(ev) {
24315
24358
  if (this.env.model.getters.getEditionMode() !== "inactive") {
24359
+ // let the browser clipboard work
24316
24360
  ev.stopPropagation();
24317
24361
  }
24362
+ else {
24363
+ // the user meant to paste in the sheet, not open the composer with the pasted content
24364
+ // While we're not editing, we still have the focus and should therefore prevent
24365
+ // the native "paste" to occur.
24366
+ ev.preventDefault();
24367
+ }
24318
24368
  }
24319
24369
  /*
24320
24370
  * Triggered automatically by the content-editable between the keydown and key up
@@ -24323,10 +24373,6 @@
24323
24373
  if (!this.shouldProcessInputEvents) {
24324
24374
  return;
24325
24375
  }
24326
- if (ev.inputType === "insertFromPaste" &&
24327
- this.env.model.getters.getEditionMode() === "inactive") {
24328
- return;
24329
- }
24330
24376
  ev.stopPropagation();
24331
24377
  let content;
24332
24378
  if (this.env.model.getters.getEditionMode() === "inactive") {
@@ -24757,10 +24803,7 @@
24757
24803
  }
24758
24804
  get containerStyle() {
24759
24805
  if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
24760
- return `
24761
- position: absolute;
24762
- z-index: -1000;
24763
- `;
24806
+ return `z-index: -1000;`;
24764
24807
  }
24765
24808
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
24766
24809
  const cell = this.env.model.getters.getActiveCell();
@@ -34590,6 +34633,9 @@
34590
34633
  if (range.invalidXc) {
34591
34634
  return range.invalidXc;
34592
34635
  }
34636
+ if (!this.getters.tryGetSheet(range.sheetId)) {
34637
+ return INCORRECT_RANGE_STRING;
34638
+ }
34593
34639
  if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
34594
34640
  return INCORRECT_RANGE_STRING;
34595
34641
  }
@@ -37641,16 +37687,22 @@
37641
37687
  let newContent = undefined;
37642
37688
  let newFormat = undefined;
37643
37689
  let isExported = true;
37690
+ const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
37644
37691
  const formulaCell = this.getCorrespondingFormulaCell(position);
37645
37692
  if (formulaCell) {
37646
37693
  isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
37647
37694
  isFormula = isExported;
37648
37695
  if (!isExported) {
37649
- newContent = value.toString();
37650
- newFormat = evaluatedCell.format;
37696
+ // If the cell contains a non-exported formula and that is evaluates to
37697
+ // nothing* ,we don't export it.
37698
+ // * non-falsy value are relevant and so are 0 and FALSE, which only leaves
37699
+ // the empty string.
37700
+ if (value !== "") {
37701
+ newContent = value.toString();
37702
+ newFormat = evaluatedCell.format;
37703
+ }
37651
37704
  }
37652
37705
  }
37653
- const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
37654
37706
  const exportedCellData = exportedSheetData.cells[xc] || {};
37655
37707
  const format = newFormat
37656
37708
  ? getItemId(newFormat, data.formats)
@@ -46521,9 +46573,11 @@
46521
46573
  if (ev.key === "Enter") {
46522
46574
  ev.preventDefault();
46523
46575
  this.stopEdition();
46576
+ this.env.focusableElement.focus();
46524
46577
  }
46525
46578
  if (ev.key === "Escape") {
46526
46579
  this.cancelEdition();
46580
+ this.env.focusableElement.focus();
46527
46581
  }
46528
46582
  }
46529
46583
  onClickSheetName(ev) {
@@ -51139,7 +51193,11 @@
51139
51193
  let cellNode = escapeXml ``;
51140
51194
  // Either formula or static value inside the cell
51141
51195
  if (cell.isFormula) {
51142
- ({ attrs: additionalAttrs, node: cellNode } = addFormula(cell));
51196
+ const res = addFormula(cell);
51197
+ if (!res) {
51198
+ continue;
51199
+ }
51200
+ ({ attrs: additionalAttrs, node: cellNode } = res);
51143
51201
  }
51144
51202
  else if (cell.content && isMarkdownLink(cell.content)) {
51145
51203
  const { label } = parseMarkdownLink(cell.content);
@@ -52136,9 +52194,9 @@
52136
52194
  Object.defineProperty(exports, '__esModule', { value: true });
52137
52195
 
52138
52196
 
52139
- __info__.version = '16.4.34';
52140
- __info__.date = '2024-05-24T11:27:29.421Z';
52141
- __info__.hash = '5e74805';
52197
+ __info__.version = '16.4.36';
52198
+ __info__.date = '2024-06-10T09:33:43.623Z';
52199
+ __info__.hash = '3b15ed5';
52142
52200
 
52143
52201
 
52144
52202
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);