@odoo/o-spreadsheet 17.0.60 → 17.0.62

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.0.60
6
- * @date 2025-05-02T12:28:49.842Z
7
- * @hash 29510cc
5
+ * @version 17.0.62
6
+ * @date 2025-05-13T17:48:40.925Z
7
+ * @hash 23805e7
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -1814,7 +1814,7 @@
1814
1814
  */
1815
1815
  const getFormulaNumberRegex = memoize(function getFormulaNumberRegex(decimalSeparator) {
1816
1816
  decimalSeparator = escapeRegExp(decimalSeparator);
1817
- return new RegExp(`(^-?\\d+(${decimalSeparator}?\\d*(e\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
1817
+ return new RegExp(`(^-?\\d+(${decimalSeparator}?\\d*(e(\\+|-)?\\d+)?)?|^-?${decimalSeparator}\\d+)(?!\\w|!)`);
1818
1818
  });
1819
1819
  const getNumberRegex = memoize(function getNumberRegex(locale) {
1820
1820
  const decimalSeparator = escapeRegExp(locale.decimalSeparator);
@@ -4485,6 +4485,32 @@
4485
4485
  })
4486
4486
  .filter(isDefined$1);
4487
4487
  }
4488
+ function getNextSheetName(existingNames, baseName = "Sheet") {
4489
+ let i = 1;
4490
+ let name = `${baseName}${i}`;
4491
+ while (existingNames.includes(name)) {
4492
+ name = `${baseName}${i}`;
4493
+ i++;
4494
+ }
4495
+ return name;
4496
+ }
4497
+ function getDuplicateSheetName(nameToDuplicate, existingNames) {
4498
+ let i = 1;
4499
+ const baseName = _t("Copy of %s", nameToDuplicate);
4500
+ let name = baseName.toString();
4501
+ while (existingNames.includes(name)) {
4502
+ name = `${baseName} (${i})`;
4503
+ i++;
4504
+ }
4505
+ return name;
4506
+ }
4507
+ function isSheetNameEqual(name1, name2) {
4508
+ if (name1 === undefined || name2 === undefined) {
4509
+ return false;
4510
+ }
4511
+ return (getUnquotedSheetName(name1.trim().toUpperCase()) ===
4512
+ getUnquotedSheetName(name2.trim().toUpperCase()));
4513
+ }
4488
4514
 
4489
4515
  function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4490
4516
  return numberOfLines * (textLineHeight + MIN_CELL_TEXT_MARGIN) - MIN_CELL_TEXT_MARGIN;
@@ -8027,10 +8053,13 @@
8027
8053
  name: _t("Duplicate"),
8028
8054
  execute: (env) => {
8029
8055
  const sheetIdFrom = env.model.getters.getActiveSheetId();
8056
+ const sheetNameFrom = env.model.getters.getSheetName(sheetIdFrom);
8030
8057
  const sheetIdTo = env.model.uuidGenerator.smallUuid();
8058
+ const sheetNameTo = env.model.getters.getDuplicateSheetName(sheetNameFrom);
8031
8059
  env.model.dispatch("DUPLICATE_SHEET", {
8032
8060
  sheetId: sheetIdFrom,
8033
8061
  sheetIdTo,
8062
+ sheetNameTo,
8034
8063
  });
8035
8064
  env.model.dispatch("ACTIVATE_SHEET", { sheetIdFrom, sheetIdTo });
8036
8065
  },
@@ -18962,6 +18991,9 @@
18962
18991
  return value === null || value === undefined;
18963
18992
  }
18964
18993
  const getNeutral = { number: 0, string: "", boolean: false };
18994
+ function areAlmostEqual(value1, value2, epsilon = 2e-16) {
18995
+ return Math.abs(value1 - value2) < epsilon;
18996
+ }
18965
18997
  const EQ = {
18966
18998
  description: _t("Equal."),
18967
18999
  args: [
@@ -18978,6 +19010,9 @@
18978
19010
  if (typeof value2 === "string") {
18979
19011
  value2 = value2.toUpperCase();
18980
19012
  }
19013
+ if (typeof value1 === "number" && typeof value2 === "number") {
19014
+ return areAlmostEqual(value1, value2);
19015
+ }
18981
19016
  return value1 === value2;
18982
19017
  },
18983
19018
  };
@@ -19012,6 +19047,9 @@
19012
19047
  returns: ["BOOLEAN"],
19013
19048
  compute: function (value1, value2) {
19014
19049
  return applyRelationalOperator(value1, value2, (v1, v2) => {
19050
+ if (typeof v1 === "number" && typeof v2 === "number") {
19051
+ return !areAlmostEqual(v1, v2) && v1 > v2;
19052
+ }
19015
19053
  return v1 > v2;
19016
19054
  });
19017
19055
  },
@@ -19028,6 +19066,9 @@
19028
19066
  returns: ["BOOLEAN"],
19029
19067
  compute: function (value1, value2) {
19030
19068
  return applyRelationalOperator(value1, value2, (v1, v2) => {
19069
+ if (typeof v1 === "number" && typeof v2 === "number") {
19070
+ return areAlmostEqual(v1, v2) || v1 > v2;
19071
+ }
19031
19072
  return v1 >= v2;
19032
19073
  });
19033
19074
  },
@@ -27068,7 +27109,6 @@
27068
27109
  searchTermUpperCase === "FALSE") {
27069
27110
  return;
27070
27111
  }
27071
- this.autoCompleteState.showProvider = true;
27072
27112
  this.autoCompleteState.type = "function";
27073
27113
  let values = Object.entries(functionRegistry.content)
27074
27114
  .filter(([_, { hidden }]) => !hidden)
@@ -27084,6 +27124,9 @@
27084
27124
  if (searchTerm) {
27085
27125
  values = fuzzyLookup(searchTerm, values, (t) => t.text).slice(0, AUTOCOMPLETE_ENTRIES);
27086
27126
  }
27127
+ if (values.length) {
27128
+ this.autoCompleteState.showProvider = true;
27129
+ }
27087
27130
  this.autoCompleteState.values = values.slice(0, AUTOCOMPLETE_ENTRIES);
27088
27131
  this.autoCompleteState.getHtmlContent = (value) => getHtmlContentFromPattern(searchTerm, value, COMPOSER_ASSISTANT_COLOR, "o-semi-bold");
27089
27132
  this.autoCompleteState.selectedIndex = 0;
@@ -27148,6 +27191,13 @@
27148
27191
  this.props.onInputContextMenu?.(ev);
27149
27192
  }
27150
27193
  }
27194
+ onWheel(event) {
27195
+ // detect if scrollbar is available
27196
+ if (this.composerRef.el &&
27197
+ this.composerRef.el.scrollHeight > this.composerRef.el.clientHeight) {
27198
+ event.stopPropagation();
27199
+ }
27200
+ }
27151
27201
  // ---------------------------------------------------------------------------
27152
27202
  // Private
27153
27203
  // ---------------------------------------------------------------------------
@@ -27456,12 +27506,15 @@
27456
27506
  });
27457
27507
  }
27458
27508
  get composerProps() {
27509
+ // Remove the wrapper border width
27510
+ const maxHeight = this.props.gridDims.height - this.rect.y - 2 * COMPOSER_BORDER_WIDTH;
27459
27511
  return {
27460
27512
  focus: this.props.focus,
27461
27513
  isDefaultFocus: true,
27462
27514
  onComposerContentFocused: this.props.onComposerContentFocused,
27463
27515
  onComposerCellFocused: this.props.onComposerCellFocused,
27464
27516
  onInputContextMenu: this.props.onInputContextMenu,
27517
+ inputStyle: `max-height: ${maxHeight}px;`,
27465
27518
  };
27466
27519
  }
27467
27520
  get containerStyle() {
@@ -31736,7 +31789,7 @@
31736
31789
  ({ xc, sheetName } = splitReference(reference));
31737
31790
  let rangeSheetIndex;
31738
31791
  if (sheetName) {
31739
- const index = data.sheets.findIndex((sheet) => sheet.name === sheetName);
31792
+ const index = data.sheets.findIndex((sheet) => isSheetNameEqual(sheet.name, sheetName));
31740
31793
  if (index < 0) {
31741
31794
  throw new Error("Unable to find a sheet with the name " + sheetName);
31742
31795
  }
@@ -31942,7 +31995,7 @@
31942
31995
  formula = formula.replace(externalReferenceRegex, (match, externalRefId, sheetName, cellRef) => {
31943
31996
  externalRefId = Number(externalRefId) - 1;
31944
31997
  cellRef = cellRef.replace(/\$/g, "");
31945
- const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => name === sheetName);
31998
+ const sheetIndex = data.externalBooks[externalRefId].sheetNames.findIndex((name) => isSheetNameEqual(name, sheetName));
31946
31999
  if (sheetIndex === -1) {
31947
32000
  return match;
31948
32001
  }
@@ -32277,7 +32330,7 @@
32277
32330
  */
32278
32331
  function convertTableFormulaReferences(convertedSheets, xlsxSheets) {
32279
32332
  for (let tableSheet of convertedSheets) {
32280
- const tables = xlsxSheets.find((s) => s.sheetName === tableSheet.name).tables;
32333
+ const tables = xlsxSheets.find((s) => isSheetNameEqual(s.sheetName, tableSheet.name)).tables;
32281
32334
  for (let table of tables) {
32282
32335
  const tabRef = table.name + "[";
32283
32336
  for (let sheet of convertedSheets) {
@@ -34354,6 +34407,7 @@
34354
34407
  initialMessages = dropCommands(initialMessages, "SORT_CELLS");
34355
34408
  initialMessages = dropCommands(initialMessages, "SET_DECIMAL");
34356
34409
  initialMessages = fixChartDefinitions(data, initialMessages);
34410
+ initialMessages = fixTranslatedDuplicateSheetName(data, initialMessages);
34357
34411
  return initialMessages;
34358
34412
  }
34359
34413
  /**
@@ -34473,6 +34527,40 @@
34473
34527
  }
34474
34528
  return data;
34475
34529
  }
34530
+ function fixTranslatedDuplicateSheetName(data, initialMessages) {
34531
+ const sheetNames = {};
34532
+ for (const sheet of data.sheets || []) {
34533
+ sheetNames[sheet.id] = sheet.name;
34534
+ }
34535
+ const messages = [];
34536
+ for (const message of initialMessages) {
34537
+ if (message.type === "REMOTE_REVISION") {
34538
+ const commands = [];
34539
+ for (const cmd of message.commands) {
34540
+ switch (cmd.type) {
34541
+ case "DUPLICATE_SHEET":
34542
+ cmd.sheetNameTo =
34543
+ cmd.sheetNameTo ??
34544
+ getDuplicateSheetName(sheetNames[cmd.sheetId], Object.values(sheetNames));
34545
+ break;
34546
+ case "CREATE_SHEET":
34547
+ case "RENAME_SHEET":
34548
+ sheetNames[cmd.sheetId] = cmd.name || getNextSheetName(Object.values(sheetNames));
34549
+ break;
34550
+ }
34551
+ commands.push(cmd);
34552
+ }
34553
+ messages.push({
34554
+ ...message,
34555
+ commands,
34556
+ });
34557
+ }
34558
+ else {
34559
+ messages.push(message);
34560
+ }
34561
+ }
34562
+ return initialMessages;
34563
+ }
34476
34564
  // -----------------------------------------------------------------------------
34477
34565
  // Helpers
34478
34566
  // -----------------------------------------------------------------------------
@@ -36703,9 +36791,7 @@
36703
36791
  : "Success" /* CommandResult.Success */;
36704
36792
  }
36705
36793
  checkChartExists(cmd) {
36706
- return this.getters.getFigureSheetId(cmd.id)
36707
- ? "Success" /* CommandResult.Success */
36708
- : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
36794
+ return this.isChartDefined(cmd.id) ? "Success" /* CommandResult.Success */ : "ChartDoesNotExist" /* CommandResult.ChartDoesNotExist */;
36709
36795
  }
36710
36796
  }
36711
36797
 
@@ -39212,7 +39298,7 @@
39212
39298
  if (range.sheetId === cmd.sheetId) {
39213
39299
  return { changeType: "CHANGE", range };
39214
39300
  }
39215
- if (cmd.name && range.invalidSheetName === cmd.name) {
39301
+ if (isSheetNameEqual(range.invalidSheetName, cmd.name)) {
39216
39302
  const invalidSheetName = undefined;
39217
39303
  const sheetId = cmd.sheetId;
39218
39304
  const newRange = range.clone({ sheetId, invalidSheetName });
@@ -39504,6 +39590,7 @@
39504
39590
  "getCommandZones",
39505
39591
  "getUnboundedZone",
39506
39592
  "checkElementsIncludeAllNonFrozenHeaders",
39593
+ "getDuplicateSheetName",
39507
39594
  ];
39508
39595
  sheetIdsMapName = {};
39509
39596
  orderedSheetIds = [];
@@ -39528,7 +39615,11 @@
39528
39615
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
39529
39616
  }
39530
39617
  case "DUPLICATE_SHEET": {
39531
- return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
39618
+ if (this.sheets[cmd.sheetIdTo])
39619
+ return "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */;
39620
+ if (this.orderedSheetIds.map(this.getSheetName.bind(this)).includes(cmd.sheetNameTo))
39621
+ return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
39622
+ return "Success" /* CommandResult.Success */;
39532
39623
  }
39533
39624
  case "MOVE_SHEET":
39534
39625
  try {
@@ -39601,7 +39692,7 @@
39601
39692
  this.showSheet(cmd.sheetId);
39602
39693
  break;
39603
39694
  case "DUPLICATE_SHEET":
39604
- this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo);
39695
+ this.duplicateSheet(cmd.sheetId, cmd.sheetIdTo, cmd.sheetNameTo);
39605
39696
  break;
39606
39697
  case "DELETE_SHEET":
39607
39698
  this.deleteSheet(this.sheets[cmd.sheetId]);
@@ -39736,7 +39827,7 @@
39736
39827
  if (name) {
39737
39828
  const unquotedName = getUnquotedSheetName(name);
39738
39829
  for (const key in this.sheetIdsMapName) {
39739
- if (key.toUpperCase() === unquotedName.toUpperCase()) {
39830
+ if (isSheetNameEqual(key, unquotedName)) {
39740
39831
  return this.sheetIdsMapName[key];
39741
39832
  }
39742
39833
  }
@@ -39811,14 +39902,8 @@
39811
39902
  return dimension === "COL" ? this.getNumberCols(sheetId) : this.getNumberRows(sheetId);
39812
39903
  }
39813
39904
  getNextSheetName(baseName = "Sheet") {
39814
- let i = 1;
39815
39905
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
39816
- let name = `${baseName}${i}`;
39817
- while (names.includes(name)) {
39818
- name = `${baseName}${i}`;
39819
- i++;
39820
- }
39821
- return name;
39906
+ return getNextSheetName(names, baseName);
39822
39907
  }
39823
39908
  getSheetSize(sheetId) {
39824
39909
  return {
@@ -40014,7 +40099,7 @@
40014
40099
  }
40015
40100
  const { orderedSheetIds, sheets } = this;
40016
40101
  const name = cmd.name && cmd.name.trim().toLowerCase();
40017
- if (orderedSheetIds.find((id) => sheets[id]?.name.toLowerCase() === name && id !== cmd.sheetId)) {
40102
+ if (orderedSheetIds.find((id) => isSheetNameEqual(sheets[id]?.name, name) && id !== cmd.sheetId)) {
40018
40103
  return "DuplicatedSheetName" /* CommandResult.DuplicatedSheetName */;
40019
40104
  }
40020
40105
  if (FORBIDDEN_IN_EXCEL_REGEX.test(name)) {
@@ -40078,9 +40163,8 @@
40078
40163
  showSheet(sheetId) {
40079
40164
  this.history.update("sheets", sheetId, "isVisible", true);
40080
40165
  }
40081
- duplicateSheet(fromId, toId) {
40166
+ duplicateSheet(fromId, toId, toName) {
40082
40167
  const sheet = this.getSheet(fromId);
40083
- const toName = this.getDuplicateSheetName(sheet.name);
40084
40168
  const newSheet = deepCopy(sheet);
40085
40169
  newSheet.id = toId;
40086
40170
  newSheet.name = toName;
@@ -40112,15 +40196,8 @@
40112
40196
  this.history.update("sheetIdsMapName", sheetIdsMapName);
40113
40197
  }
40114
40198
  getDuplicateSheetName(sheetName) {
40115
- let i = 1;
40116
40199
  const names = this.orderedSheetIds.map(this.getSheetName.bind(this));
40117
- const baseName = _t("Copy of %s", sheetName);
40118
- let name = baseName.toString();
40119
- while (names.includes(name)) {
40120
- name = `${baseName} (${i})`;
40121
- i++;
40122
- }
40123
- return name;
40200
+ return getDuplicateSheetName(sheetName, names);
40124
40201
  }
40125
40202
  deleteSheet(sheet) {
40126
40203
  const name = sheet.name;
@@ -49746,7 +49823,7 @@
49746
49823
  .find((token) => {
49747
49824
  const { xc, sheetName: sheet } = splitReference(token.value);
49748
49825
  const sheetName = sheet || this.getters.getSheetName(this.sheetId);
49749
- if (this.getters.getSheetName(activeSheetId) !== sheetName) {
49826
+ if (!isSheetNameEqual(this.getters.getSheetName(activeSheetId), sheetName)) {
49750
49827
  return false;
49751
49828
  }
49752
49829
  const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
@@ -58251,9 +58328,9 @@
58251
58328
  exports.tokenize = tokenize;
58252
58329
 
58253
58330
 
58254
- __info__.version = "17.0.60";
58255
- __info__.date = "2025-05-02T12:28:49.842Z";
58256
- __info__.hash = "29510cc";
58331
+ __info__.version = "17.0.62";
58332
+ __info__.date = "2025-05-13T17:48:40.925Z";
58333
+ __info__.hash = "23805e7";
58257
58334
 
58258
58335
 
58259
58336
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);