@odoo/o-spreadsheet 17.4.34 → 17.4.35

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 17.4.34
6
- * @date 2025-05-12T05:23:37.387Z
7
- * @hash e3ac48a
5
+ * @version 17.4.35
6
+ * @date 2025-05-13T17:49:44.553Z
7
+ * @hash 534c5f4
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -1914,7 +1914,7 @@ function isDateAfter(date, dateAfter) {
1914
1914
  */
1915
1915
  const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
1916
1916
  decimalSeparator = escapeRegExp(decimalSeparator);
1917
- return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
1917
+ return new RegExp(`(?:^-?\\d+(?:${decimalSeparator}?\\d*(?:e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
1918
1918
  });
1919
1919
  const getNumberRegex = memoize(function getNumberRegex(locale) {
1920
1920
  const decimalSeparator = escapeRegExp(locale.decimalSeparator);
@@ -5209,6 +5209,13 @@ function getDuplicateSheetName(nameToDuplicate, existingNames) {
5209
5209
  }
5210
5210
  return name;
5211
5211
  }
5212
+ function isSheetNameEqual(name1, name2) {
5213
+ if (name1 === undefined || name2 === undefined) {
5214
+ return false;
5215
+ }
5216
+ return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
5217
+ getUnquotedSheetName(name2.trim().toUpperCase()));
5218
+ }
5212
5219
 
5213
5220
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
5214
5221
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -6510,10 +6517,9 @@ const AGGREGATOR_NAMES = {
6510
6517
  avg: _t("Average"),
6511
6518
  sum: _t("Sum"),
6512
6519
  };
6513
- const NUMBER_CHAR_AGGREGATORS = ["max", "min", "avg", "sum", "count_distinct", "count"];
6514
6520
  const AGGREGATORS_BY_FIELD_TYPE = {
6515
- integer: NUMBER_CHAR_AGGREGATORS,
6516
- char: NUMBER_CHAR_AGGREGATORS,
6521
+ integer: ["max", "min", "avg", "sum", "count_distinct", "count"],
6522
+ char: ["count_distinct", "count"],
6517
6523
  boolean: ["count_distinct", "count", "bool_and", "bool_or"],
6518
6524
  };
6519
6525
  const AGGREGATORS = {};
@@ -6727,8 +6733,11 @@ class CellClipboardHandler extends AbstractCellClipboardHandler {
6727
6733
  const evaluatedCell = this.getters.getEvaluatedCell(position);
6728
6734
  const pivotId = this.getters.getPivotIdFromPosition(position);
6729
6735
  const spreader = this.getters.getArrayFormulaSpreadingOn(position);
6730
- if (pivotId) {
6731
- if (spreader && (!deepEquals(spreader, position) || !isCopyingOneCell)) {
6736
+ if (pivotId && spreader) {
6737
+ const pivotZone = this.getters.getSpreadZone(spreader);
6738
+ if ((!deepEquals(spreader, position) || !isCopyingOneCell) &&
6739
+ pivotZone &&
6740
+ !data.zones.some((z) => isZoneInside(pivotZone, z))) {
6732
6741
  const pivotCell = this.getters.getPivotCellFromPosition(position);
6733
6742
  const formulaPivotId = this.getters.getPivotFormulaId(pivotId);
6734
6743
  const pivotFormula = createPivotFormula(formulaPivotId, pivotCell);
@@ -9450,7 +9459,10 @@ function proxifyStoreMutation(store, callback) {
9450
9459
  const functionProxy = new Proxy(value, {
9451
9460
  // trap the function call
9452
9461
  apply(target, thisArg, argArray) {
9453
- Reflect.apply(target, thisStore, argArray);
9462
+ const res = Reflect.apply(target, thisStore, argArray);
9463
+ if (res === "noStateChange") {
9464
+ return;
9465
+ }
9454
9466
  callback();
9455
9467
  },
9456
9468
  });
@@ -9472,7 +9484,7 @@ function getDependencyContainer(env) {
9472
9484
  const ModelStore = createAbstractStore("Model");
9473
9485
 
9474
9486
  class RendererStore {
9475
- mutators = ["register", "unRegister"];
9487
+ mutators = ["register", "unRegister", "drawLayer"];
9476
9488
  renderers = {};
9477
9489
  register(renderer) {
9478
9490
  if (!renderer.renderingLayers.length) {
@@ -9492,14 +9504,14 @@ class RendererStore {
9492
9504
  }
9493
9505
  drawLayer(context, layer) {
9494
9506
  const renderers = this.renderers[layer];
9495
- if (!renderers) {
9496
- return;
9497
- }
9498
- for (const renderer of renderers) {
9499
- context.ctx.save();
9500
- renderer.drawLayer(context, layer);
9501
- context.ctx.restore();
9507
+ if (renderers) {
9508
+ for (const renderer of renderers) {
9509
+ context.ctx.save();
9510
+ renderer.drawLayer(context, layer);
9511
+ context.ctx.restore();
9512
+ }
9502
9513
  }
9514
+ return "noStateChange";
9503
9515
  }
9504
9516
  }
9505
9517
 
@@ -10112,7 +10124,7 @@ class ComposerStore extends SpreadsheetStore {
10112
10124
  .find((token) => {
10113
10125
  const { xc, sheetName: sheet } = splitReference(token.value);
10114
10126
  const sheetName = sheet || this.getters.getSheetName(this.sheetId);
10115
- if (this.getters.getSheetName(activeSheetId) !== sheetName) {
10127
+ if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
10116
10128
  return false;
10117
10129
  }
10118
10130
  const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
@@ -10417,27 +10429,30 @@ class ComposerFocusStore extends SpreadsheetStore {
10417
10429
  }
10418
10430
  focusTopBarComposer(selection) {
10419
10431
  if (this.getters.isReadonly()) {
10420
- return;
10432
+ return "noStateChange";
10421
10433
  }
10422
10434
  this.topBarFocus = "contentFocus";
10423
10435
  this.gridFocusMode = "inactive";
10424
- this.setComposerContent({ selection } || {});
10436
+ this.setComposerContent({ selection });
10437
+ return;
10425
10438
  }
10426
10439
  focusGridComposerContent() {
10427
10440
  if (this.getters.isReadonly()) {
10428
- return;
10441
+ return "noStateChange";
10429
10442
  }
10430
10443
  this.topBarFocus = "inactive";
10431
10444
  this.gridFocusMode = "contentFocus";
10432
10445
  this.setComposerContent({});
10446
+ return;
10433
10447
  }
10434
10448
  focusGridComposerCell(content, selection) {
10435
10449
  if (this.getters.isReadonly()) {
10436
- return;
10450
+ return "noStateChange";
10437
10451
  }
10438
10452
  this.topBarFocus = "inactive";
10439
10453
  this.gridFocusMode = "cellFocus";
10440
- this.setComposerContent({ content, selection } || {});
10454
+ this.setComposerContent({ content, selection });
10455
+ return;
10441
10456
  }
10442
10457
  /**
10443
10458
  * Start the edition or update the content if it's already started.
@@ -20322,6 +20337,9 @@ function isEmpty(data) {
20322
20337
  return data === undefined || data.value === null;
20323
20338
  }
20324
20339
  const getNeutral = { number: 0, string: "", boolean: false };
20340
+ function areAlmostEqual(value1, value2, epsilon = 2e-16) {
20341
+ return Math.abs(value1 - value2) < epsilon;
20342
+ }
20325
20343
  const EQ = {
20326
20344
  description: _t("Equal."),
20327
20345
  args: [
@@ -20343,6 +20361,9 @@ const EQ = {
20343
20361
  if (isEvaluationError(_value2)) {
20344
20362
  throw value2;
20345
20363
  }
20364
+ if (typeof _value1 === "number" && typeof _value2 === "number") {
20365
+ return areAlmostEqual(_value1, _value2);
20366
+ }
20346
20367
  return _value1 === _value2;
20347
20368
  },
20348
20369
  };
@@ -20382,6 +20403,9 @@ const GT = {
20382
20403
  ],
20383
20404
  compute: function (value1, value2) {
20384
20405
  return applyRelationalOperator(value1, value2, (v1, v2) => {
20406
+ if (typeof v1 === "number" && typeof v2 === "number") {
20407
+ return !areAlmostEqual(v1, v2) && v1 > v2;
20408
+ }
20385
20409
  return v1 > v2;
20386
20410
  });
20387
20411
  },
@@ -20397,6 +20421,9 @@ const GTE = {
20397
20421
  ],
20398
20422
  compute: function (value1, value2) {
20399
20423
  return applyRelationalOperator(value1, value2, (v1, v2) => {
20424
+ if (typeof v1 === "number" && typeof v2 === "number") {
20425
+ return areAlmostEqual(v1, v2) || v1 > v2;
20426
+ }
20400
20427
  return v1 >= v2;
20401
20428
  });
20402
20429
  },
@@ -21497,10 +21524,18 @@ autoCompleteProviders.add("functions", {
21497
21524
  });
21498
21525
 
21499
21526
  class DOMFocusableElementStore {
21500
- mutators = ["setFocusableElement"];
21527
+ mutators = ["setFocusableElement", "focus"];
21501
21528
  focusableElement = undefined;
21502
21529
  setFocusableElement(element) {
21503
21530
  this.focusableElement = element;
21531
+ return "noStateChange";
21532
+ }
21533
+ focus() {
21534
+ if (this.focusableElement === document.activeElement) {
21535
+ return "noStateChange";
21536
+ }
21537
+ this.focusableElement?.focus();
21538
+ return;
21504
21539
  }
21505
21540
  }
21506
21541
 
@@ -21757,12 +21792,20 @@ class HoveredCellStore extends SpreadsheetStore {
21757
21792
  }
21758
21793
  }
21759
21794
  hover(position) {
21795
+ if (position.col === this.col && position.row === this.row) {
21796
+ return "noStateChange";
21797
+ }
21760
21798
  this.col = position.col;
21761
21799
  this.row = position.row;
21800
+ return;
21762
21801
  }
21763
21802
  clear() {
21803
+ if (this.col === undefined && this.row === undefined) {
21804
+ return "noStateChange";
21805
+ }
21764
21806
  this.col = undefined;
21765
21807
  this.row = undefined;
21808
+ return;
21766
21809
  }
21767
21810
  }
21768
21811
 
@@ -21784,7 +21827,11 @@ class CellPopoverStore extends SpreadsheetStore {
21784
21827
  this.persistentPopover = { col, row, sheetId, type };
21785
21828
  }
21786
21829
  close() {
21830
+ if (!this.persistentPopover) {
21831
+ return "noStateChange";
21832
+ }
21787
21833
  this.persistentPopover = undefined;
21834
+ return;
21788
21835
  }
21789
21836
  get persistentCellPopover() {
21790
21837
  return ((this.persistentPopover && { isOpen: true, ...this.persistentPopover }) || { isOpen: false });
@@ -37460,7 +37507,12 @@ class SpreadsheetPivot {
37460
37507
  entry[field.name] = { value: null, type: CellValueType.empty };
37461
37508
  }
37462
37509
  else {
37463
- entry[field.name] = cell;
37510
+ if (field.type === "char") {
37511
+ entry[field.name] = { ...cell, value: cell.formattedValue || null };
37512
+ }
37513
+ else {
37514
+ entry[field.name] = cell;
37515
+ }
37464
37516
  }
37465
37517
  }
37466
37518
  entry["__count"] = { value: 1, type: CellValueType.number };
@@ -39655,7 +39707,7 @@ class GridComposer extends Component {
39655
39707
  this.isEditing = isEditing;
39656
39708
  if (!isEditing) {
39657
39709
  this.rect = this.defaultRect;
39658
- this.DOMFocusableElementStore.focusableElement?.focus();
39710
+ this.DOMFocusableElementStore.focus();
39659
39711
  return;
39660
39712
  }
39661
39713
  const position = this.env.model.getters.getActivePosition();
@@ -42091,10 +42143,6 @@ function useGridDrawing(refName, model, canvasSize) {
42091
42143
  ctx.scale(dpr, dpr);
42092
42144
  for (const layer of OrderedLayers()) {
42093
42145
  model.drawLayer(renderingContext, layer);
42094
- // @ts-ignore 'drawLayer' is not declated as a mutator because:
42095
- // it does not mutate anything. Most importantly it's used
42096
- // during rendering. Invoking a mutator during rendering would
42097
- // trigger another rendering, ultimately resulting in an infinite loop.
42098
42146
  rendererStore.drawLayer(renderingContext, layer);
42099
42147
  }
42100
42148
  }
@@ -42717,7 +42765,7 @@ class Grid extends Component {
42717
42765
  this.cellPopovers = useStore(CellPopoverStore);
42718
42766
  useEffect(() => {
42719
42767
  if (!this.sidePanel.isOpen) {
42720
- this.DOMFocusableElementStore.focusableElement?.focus();
42768
+ this.DOMFocusableElementStore.focus();
42721
42769
  }
42722
42770
  }, () => [this.sidePanel.isOpen]);
42723
42771
  }
@@ -42921,7 +42969,7 @@ class Grid extends Component {
42921
42969
  focusDefaultElement() {
42922
42970
  if (!this.env.model.getters.getSelectedFigureId() &&
42923
42971
  this.composerStore.editionMode === "inactive") {
42924
- this.DOMFocusableElementStore.focusableElement?.focus();
42972
+ this.DOMFocusableElementStore.focus();
42925
42973
  }
42926
42974
  }
42927
42975
  get gridEl() {
@@ -44658,7 +44706,7 @@ function getRangeSize(reference, defaultSheetIndex, data) {
44658
44706
  ({ xc, sheetName } = splitReference(reference));
44659
44707
  let rangeSheetIndex;
44660
44708
  if (sheetName) {
44661
- const index = data.sheets.findIndex((sheet) => sheet.name === sheetName);
44709
+ const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
44662
44710
  if (index < 0) {
44663
44711
  throw new Error("Unable to find a sheet with the name " + sheetName);
44664
44712
  }
@@ -44879,7 +44927,7 @@ function convertFormula(formula, data) {
44879
44927
  formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
44880
44928
  externalRefId = Number(externalRefId) - 1;
44881
44929
  cellRef = cellRef.replace(/\$/g, "");
44882
- const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name === sheetName);
44930
+ const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
44883
44931
  if (sheetIndex === -1) {
44884
44932
  return match;
44885
44933
  }
@@ -45208,7 +45256,7 @@ function convertPivotTableConfig(pivotTable) {
45208
45256
  */
45209
45257
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
45210
45258
  for (let tableSheet of convertedSheets) {
45211
- const tables = xlsxSheets.find((s) => s.sheetName === tableSheet.name).tables;
45259
+ const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
45212
45260
  for (let table of tables) {
45213
45261
  const tabRef = table.name + "[";
45214
45262
  for (let sheet of convertedSheets) {
@@ -50885,7 +50933,7 @@ class RangeAdapter {
50885
50933
  if (range.sheetId === cmd.sheetId) {
50886
50934
  return { changeType: "CHANGE", range };
50887
50935
  }
50888
- if (cmd.name && range.invalidSheetName === cmd.name) {
50936
+ if (isSheetNameEqual(range.invalidSheetName, cmd.name)) {
50889
50937
  const invalidSheetName = undefined;
50890
50938
  const sheetId = cmd.sheetId;
50891
50939
  const newRange = range.clone({ sheetId, invalidSheetName });
@@ -51456,7 +51504,7 @@ class SheetPlugin extends CorePlugin {
51456
51504
  if (name) {
51457
51505
  const unquotedName = getUnquotedSheetName(name);
51458
51506
  for (const key in this.sheetIdsMapName) {
51459
- if (key.toUpperCase() === unquotedName.toUpperCase()) {
51507
+ if (isSheetNameEqual(key, unquotedName)) {
51460
51508
  return this.sheetIdsMapName[key];
51461
51509
  }
51462
51510
  }
@@ -51704,7 +51752,7 @@ class SheetPlugin extends CorePlugin {
51704
51752
  }
51705
51753
  const { orderedSheetIds, sheets } = this;
51706
51754
  const name = cmd.name && cmd.name.trim().toLowerCase();
51707
- if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
51755
+ if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
51708
51756
  return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
51709
51757
  }
51710
51758
  if (FORBIDDEN_SHEETNAME_CHARS_IN_EXCEL_REGEX.test(name)) {
@@ -63036,11 +63084,11 @@ class BottomBarSheet extends Component {
63036
63084
  if (ev.key === "Enter") {
63037
63085
  ev.preventDefault();
63038
63086
  this.stopEdition();
63039
- this.DOMFocusableElementStore.focusableElement?.focus();
63087
+ this.DOMFocusableElementStore.focus();
63040
63088
  }
63041
63089
  if (ev.key === "Escape") {
63042
63090
  this.cancelEdition();
63043
- this.DOMFocusableElementStore.focusableElement?.focus();
63091
+ this.DOMFocusableElementStore.focus();
63044
63092
  }
63045
63093
  }
63046
63094
  onMouseEventSheetName(ev) {
@@ -69470,6 +69518,6 @@ const constants = {
69470
69518
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
69471
69519
 
69472
69520
 
69473
- __info__.version = "17.4.34";
69474
- __info__.date = "2025-05-12T05:23:37.387Z";
69475
- __info__.hash = "e3ac48a";
69521
+ __info__.version = "17.4.35";
69522
+ __info__.date = "2025-05-13T17:49:44.553Z";
69523
+ __info__.hash = "534c5f4";