@odoo/o-spreadsheet 16.1.8 → 16.1.10

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.
@@ -1020,6 +1020,10 @@
1020
1020
  }
1021
1021
  return true;
1022
1022
  }
1023
+ /** Check if the given array contains all the values of the other array. */
1024
+ function includesAll(arr, values) {
1025
+ return values.every((value) => arr.includes(value));
1026
+ }
1023
1027
  /**
1024
1028
  * Return an object with all the keys in the object that have a falsy value removed.
1025
1029
  */
@@ -1659,12 +1663,77 @@
1659
1663
  * - all digit stored in the decimal part of the number
1660
1664
  *
1661
1665
  * The 'maxDecimal' parameter allows to indicate the number of digits to not
1662
- * exceed in the decimal part, in which case digits are rounded
1666
+ * exceed in the decimal part, in which case digits are rounded.
1663
1667
  *
1664
- * Intl.Numberformat is used to properly handle all the roundings.
1665
- * e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
1666
1668
  **/
1667
1669
  function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
1670
+ const asString = value.toString();
1671
+ if (asString.includes("e"))
1672
+ return splitNumberIntl(value, maxDecimals);
1673
+ if (Number.isInteger(value)) {
1674
+ return { integerDigits: asString, decimalDigits: undefined };
1675
+ }
1676
+ const indexOfDot = asString.indexOf(".");
1677
+ let integerDigits = asString.substring(0, indexOfDot);
1678
+ let decimalDigits = asString.substring(indexOfDot + 1);
1679
+ if (maxDecimals === 0) {
1680
+ if (Number(decimalDigits[0]) >= 5) {
1681
+ integerDigits = (Number(integerDigits) + 1).toString();
1682
+ }
1683
+ return { integerDigits, decimalDigits: undefined };
1684
+ }
1685
+ if (decimalDigits.length > maxDecimals) {
1686
+ const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
1687
+ decimalDigits = roundedDecimalDigits;
1688
+ if (roundedIntegerDigits !== "0") {
1689
+ integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
1690
+ }
1691
+ }
1692
+ return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
1693
+ }
1694
+ /**
1695
+ * Return the given string minus the trailing "0" characters.
1696
+ *
1697
+ * @param numberString : a string of integers
1698
+ * @returns the numberString, minus the eventual zeroes at the end
1699
+ */
1700
+ function removeTrailingZeroes(numberString) {
1701
+ let i = numberString.length - 1;
1702
+ while (i >= 0 && numberString[i] === "0") {
1703
+ i--;
1704
+ }
1705
+ return numberString.slice(0, i + 1) || undefined;
1706
+ }
1707
+ /**
1708
+ * Limit the size of the decimal part of a number to the given number of digits.
1709
+ */
1710
+ function limitDecimalDigits(decimalDigits, maxDecimals) {
1711
+ let integerDigits = "0";
1712
+ let resultDecimalDigits = decimalDigits;
1713
+ // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1714
+ // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1715
+ let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1716
+ const i = maxDecimals;
1717
+ if (Number(Number(decimalDigits[i]) < 5)) {
1718
+ return { integerDigits, decimalDigits: slicedDecimalDigits };
1719
+ }
1720
+ // round up
1721
+ const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1722
+ if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1723
+ integerDigits = (Number(integerDigits) + 1).toString();
1724
+ resultDecimalDigits = undefined;
1725
+ }
1726
+ else {
1727
+ resultDecimalDigits = slicedRoundedUp;
1728
+ }
1729
+ return { integerDigits, decimalDigits: resultDecimalDigits };
1730
+ }
1731
+ /**
1732
+ * Split numbers into decimal/integer digits using Intl.NumberFormat.
1733
+ * Supports numbers with a lot of digits that are transformed to scientific notation by
1734
+ * number.toString(), but is slow.
1735
+ */
1736
+ function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
1668
1737
  let formatter = numberRepresentation[maxDecimals];
1669
1738
  if (!formatter) {
1670
1739
  formatter = new Intl.NumberFormat("en-US", {
@@ -3556,6 +3625,8 @@
3556
3625
  CommandResult[CommandResult["InvalidSelectionStep"] = 83] = "InvalidSelectionStep";
3557
3626
  CommandResult[CommandResult["DuplicatedChartId"] = 84] = "DuplicatedChartId";
3558
3627
  CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
3628
+ CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
3629
+ CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
3559
3630
  })(exports.CommandResult || (exports.CommandResult = {}));
3560
3631
 
3561
3632
  var DIRECTION;
@@ -5903,13 +5974,16 @@
5903
5974
  }
5904
5975
  });
5905
5976
  }
5977
+ get visibleMenuItems() {
5978
+ return this.props.menuItems.filter((x) => x.isVisible(this.env));
5979
+ }
5906
5980
  get subMenuPosition() {
5907
5981
  const position = Object.assign({}, this.subMenu.position);
5908
5982
  position.y -= this.subMenu.scrollOffset || 0;
5909
5983
  return position;
5910
5984
  }
5911
5985
  get menuHeight() {
5912
- const menuItems = this.props.menuItems;
5986
+ const menuItems = this.visibleMenuItems;
5913
5987
  let menuItemsHeight = this.getMenuItemsHeight(menuItems);
5914
5988
  // We don't display separator at the end of a menu
5915
5989
  if (menuItems[menuItems.length - 1].separator) {
@@ -5951,7 +6025,7 @@
5951
6025
  * and the menu item at a given index.
5952
6026
  */
5953
6027
  subMenuVerticalPosition(menuIndex) {
5954
- const menusAbove = this.props.menuItems.slice(0, menuIndex);
6028
+ const menusAbove = this.visibleMenuItems.slice(0, menuIndex);
5955
6029
  return this.position.y + this.getMenuItemsHeight(menusAbove) + MENU_VERTICAL_PADDING;
5956
6030
  }
5957
6031
  onExternalClick(ev) {
@@ -6123,7 +6197,7 @@
6123
6197
  openContextMenu(position) {
6124
6198
  const registry = this.getMenuItemRegistry();
6125
6199
  this.menuState.isOpen = true;
6126
- this.menuState.menuItems = registry.getAll().filter((x) => x.isVisible(this.env));
6200
+ this.menuState.menuItems = registry.getAll();
6127
6201
  this.menuState.position = position;
6128
6202
  }
6129
6203
  get chartComponent() {
@@ -7254,6 +7328,11 @@
7254
7328
  name: REMOVE_COLUMNS_NAME,
7255
7329
  sequence: 90,
7256
7330
  action: REMOVE_COLUMNS_ACTION,
7331
+ isVisible: (env) => {
7332
+ const sheetId = env.model.getters.getActiveSheetId();
7333
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
7334
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
7335
+ },
7257
7336
  })
7258
7337
  .add("clear_column", {
7259
7338
  name: DELETE_CONTENT_COLUMNS_NAME,
@@ -7266,9 +7345,8 @@
7266
7345
  action: HIDE_COLUMNS_ACTION,
7267
7346
  isVisible: (env) => {
7268
7347
  const sheetId = env.model.getters.getActiveSheetId();
7269
- const hiddenCols = env.model.getters.getHiddenColsGroups(sheetId).flat();
7270
- return (env.model.getters.getNumberCols(sheetId) >
7271
- hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
7348
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
7349
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
7272
7350
  },
7273
7351
  separator: true,
7274
7352
  })
@@ -7342,6 +7420,11 @@
7342
7420
  name: REMOVE_ROWS_NAME,
7343
7421
  sequence: 70,
7344
7422
  action: REMOVE_ROWS_ACTION,
7423
+ isVisible: (env) => {
7424
+ const sheetId = env.model.getters.getActiveSheetId();
7425
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
7426
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
7427
+ },
7345
7428
  })
7346
7429
  .add("clear_row", {
7347
7430
  name: DELETE_CONTENT_ROWS_NAME,
@@ -7354,9 +7437,8 @@
7354
7437
  action: HIDE_ROWS_ACTION,
7355
7438
  isVisible: (env) => {
7356
7439
  const sheetId = env.model.getters.getActiveSheetId();
7357
- const hiddenRows = env.model.getters.getHiddenRowsGroups(sheetId).flat();
7358
- return (env.model.getters.getNumberRows(sheetId) >
7359
- hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
7440
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
7441
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
7360
7442
  },
7361
7443
  separator: true,
7362
7444
  })
@@ -14414,7 +14496,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
14414
14496
  base (number) ${_lt("The number to raise to the exponent power.")}
14415
14497
  exponent (number) ${_lt("The exponent to raise base to.")}
14416
14498
  `),
14417
- returns: ["BOOLEAN"],
14499
+ returns: ["NUMBER"],
14418
14500
  compute: function (base, exponent) {
14419
14501
  return POWER.compute(base, exponent);
14420
14502
  },
@@ -16929,14 +17011,31 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
16929
17011
  * */
16930
17012
  getCurrentSelection() {
16931
17013
  let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
16932
- let startSizeBefore = this.findSizeBeforeElement(startElement);
16933
- let endSizeBefore = this.findSizeBeforeElement(endElement);
17014
+ let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
17015
+ let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
16934
17016
  return {
16935
- start: startSizeBefore + startSelectionOffset,
16936
- end: endSizeBefore + endSelectionOffset,
17017
+ start: startSizeBefore,
17018
+ end: endSizeBefore,
16937
17019
  };
16938
17020
  }
16939
- findSizeBeforeElement(nodeToFind) {
17021
+ /**
17022
+ * Computes the text 'index' inside this.el based on the currently selected node and its offset.
17023
+ * The selected node is either a Text node or an Element node.
17024
+ *
17025
+ * case 1 -Text node:
17026
+ * the offset is the number of characters from the start of the node. We have to add this offset to the
17027
+ * content length of all previous nodes.
17028
+ *
17029
+ * case 2 - Element node:
17030
+ * the offset is the number of child nodes before the selected node. We have to add the content length of
17031
+ * all the bnodes prior to the selected node as well as the content of the child node before the offset.
17032
+ *
17033
+ * See the MDN documentation for more details.
17034
+ * https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
17035
+ * https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
17036
+ *
17037
+ */
17038
+ findSelectionIndex(nodeToFind, nodeOffset) {
16940
17039
  let it = this.iterateChildren(this.el);
16941
17040
  let usedCharacters = 0;
16942
17041
  let current = it.next();
@@ -16948,6 +17047,19 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
16948
17047
  }
16949
17048
  current = it.next();
16950
17049
  }
17050
+ if (current.value === nodeToFind) {
17051
+ if (!current.value.hasChildNodes()) {
17052
+ usedCharacters += nodeOffset;
17053
+ }
17054
+ else {
17055
+ const children = [...current.value.childNodes].slice(0, nodeOffset);
17056
+ for (const child of children) {
17057
+ if (!child.textContent)
17058
+ continue;
17059
+ usedCharacters += child.textContent.length;
17060
+ }
17061
+ }
17062
+ }
16951
17063
  return usedCharacters;
16952
17064
  }
16953
17065
  getStartAndEndSelection() {
@@ -23539,8 +23651,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23539
23651
  },
23540
23652
  "CTRL+END": () => {
23541
23653
  const sheetId = this.env.model.getters.getActiveSheetId();
23542
- const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", range(0, this.env.model.getters.getNumberCols(sheetId)).reverse());
23543
- const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", range(0, this.env.model.getters.getNumberRows(sheetId)).reverse());
23654
+ const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
23655
+ const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
23544
23656
  this.env.model.selection.selectCell(col, row);
23545
23657
  },
23546
23658
  "SHIFT+ ": () => {
@@ -23620,9 +23732,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23620
23732
  this.focus();
23621
23733
  }
23622
23734
  focus() {
23735
+ var _a;
23623
23736
  if (!this.env.model.getters.getSelectedFigureId() &&
23624
23737
  this.env.model.getters.getEditionMode() === "inactive") {
23625
- this.hiddenInput.el.focus();
23738
+ (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
23626
23739
  }
23627
23740
  }
23628
23741
  get gridEl() {
@@ -23823,9 +23936,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23823
23936
  }
23824
23937
  this.menuState.isOpen = true;
23825
23938
  this.menuState.position = { x, y };
23826
- this.menuState.menuItems = registries$1[type]
23827
- .getAll()
23828
- .filter((item) => !item.isVisible || item.isVisible(this.env));
23939
+ this.menuState.menuItems = registries$1[type].getAll();
23829
23940
  }
23830
23941
  copy(cut, ev) {
23831
23942
  if (!this.gridEl.contains(document.activeElement)) {
@@ -25079,7 +25190,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
25079
25190
  if (cell.style) {
25080
25191
  style = data.styles[cell.style];
25081
25192
  }
25082
- const format = cell.format ? data.formats[cell.format] : undefined;
25193
+ const format = extractFormat(cell, data);
25083
25194
  const exportedBorder = {};
25084
25195
  if (cell.border) {
25085
25196
  const border = data.borders[cell.border];
@@ -25113,6 +25224,22 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
25113
25224
  styles.font["italic"] = !!(style === null || style === void 0 ? void 0 : style.italic) || undefined;
25114
25225
  return styles;
25115
25226
  }
25227
+ function extractFormat(cell, data) {
25228
+ if (cell.format) {
25229
+ return data.formats[cell.format];
25230
+ }
25231
+ if (cell.isFormula) {
25232
+ const tokens = tokenize(cell.content || "");
25233
+ const functions = functionRegistry.content;
25234
+ const isExported = tokens
25235
+ .filter((tk) => tk.type === "FUNCTION")
25236
+ .every((tk) => functions[tk.value.toUpperCase()].isExported);
25237
+ if (!isExported) {
25238
+ return cell.computedFormat;
25239
+ }
25240
+ }
25241
+ return undefined;
25242
+ }
25116
25243
  function normalizeStyle(construct, styles) {
25117
25244
  const { id: fontId } = pushElement(styles["font"], construct.fonts);
25118
25245
  const { id: fillId } = pushElement(styles["fill"], construct.fills);
@@ -27194,7 +27321,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
27194
27321
  }
27195
27322
  }
27196
27323
  }
27197
- data = JSON.parse(JSON.stringify(data));
27324
+ data = deepCopy(data);
27198
27325
  // apply migrations, if needed
27199
27326
  if ("version" in data) {
27200
27327
  if (data.version < CURRENT_VERSION) {
@@ -29854,7 +29981,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29854
29981
  allowDispatch(cmd) {
29855
29982
  switch (cmd.type) {
29856
29983
  case "HIDE_COLUMNS_ROWS": {
29857
- if (!this.hiddenHeaders[cmd.sheetId]) {
29984
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
29858
29985
  return 27 /* CommandResult.InvalidSheetId */;
29859
29986
  }
29860
29987
  const hiddenGroup = cmd.dimension === "COL"
@@ -29863,10 +29990,25 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29863
29990
  const elements = cmd.dimension === "COL"
29864
29991
  ? this.getters.getNumberCols(cmd.sheetId)
29865
29992
  : this.getters.getNumberRows(cmd.sheetId);
29866
- return (hiddenGroup || []).flat().concat(cmd.elements).length < elements
29867
- ? 0 /* CommandResult.Success */
29868
- : 66 /* CommandResult.TooManyHiddenElements */;
29993
+ const hiddenElements = new Set((hiddenGroup || []).flat().concat(cmd.elements));
29994
+ if (hiddenElements.size >= elements) {
29995
+ return 66 /* CommandResult.TooManyHiddenElements */;
29996
+ }
29997
+ else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
29998
+ return 86 /* CommandResult.InvalidHeaderIndex */;
29999
+ }
30000
+ else {
30001
+ return 0 /* CommandResult.Success */;
30002
+ }
29869
30003
  }
30004
+ case "REMOVE_COLUMNS_ROWS":
30005
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
30006
+ return 27 /* CommandResult.InvalidSheetId */;
30007
+ }
30008
+ if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
30009
+ return 8 /* CommandResult.NotEnoughElements */;
30010
+ }
30011
+ return 0 /* CommandResult.Success */;
29870
30012
  }
29871
30013
  return 0 /* CommandResult.Success */;
29872
30014
  }
@@ -29913,6 +30055,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29913
30055
  }
29914
30056
  return;
29915
30057
  }
30058
+ canRemoveHeaders(sheetId, dimension, elements) {
30059
+ const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
30060
+ return !includesAll(elements, visibleHeaders);
30061
+ }
29916
30062
  isRowHiddenByUser(sheetId, index) {
29917
30063
  return this.hiddenHeaders[sheetId].ROW[index];
29918
30064
  }
@@ -29957,6 +30103,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29957
30103
  }
29958
30104
  return consecutiveIndexes;
29959
30105
  }
30106
+ getAllVisibleHeaders(sheetId, dimension) {
30107
+ return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
30108
+ }
29960
30109
  import(data) {
29961
30110
  var _a, _b;
29962
30111
  for (let sheet of data.sheets) {
@@ -30004,6 +30153,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30004
30153
  }
30005
30154
  }
30006
30155
  HeaderVisibilityPlugin.getters = [
30156
+ "canRemoveHeaders",
30007
30157
  "getHiddenColsGroups",
30008
30158
  "getHiddenRowsGroups",
30009
30159
  "isRowHiddenByUser",
@@ -31013,13 +31163,27 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31013
31163
  return this.orderedSheetIds.length > 1
31014
31164
  ? 0 /* CommandResult.Success */
31015
31165
  : 9 /* CommandResult.NotEnoughSheets */;
31166
+ case "ADD_COLUMNS_ROWS":
31167
+ const elements = cmd.dimension === "COL"
31168
+ ? this.getNumberCols(cmd.sheetId)
31169
+ : this.getNumberRows(cmd.sheetId);
31170
+ if (cmd.base < 0 || cmd.base > elements) {
31171
+ return 86 /* CommandResult.InvalidHeaderIndex */;
31172
+ }
31173
+ else if (cmd.quantity <= 0) {
31174
+ return 87 /* CommandResult.InvalidQuantity */;
31175
+ }
31176
+ return 0 /* CommandResult.Success */;
31016
31177
  case "REMOVE_COLUMNS_ROWS": {
31017
- const length = cmd.dimension === "COL"
31178
+ const elements = cmd.dimension === "COL"
31018
31179
  ? this.getNumberCols(cmd.sheetId)
31019
31180
  : this.getNumberRows(cmd.sheetId);
31020
- return length > cmd.elements.length
31021
- ? 0 /* CommandResult.Success */
31022
- : 8 /* CommandResult.NotEnoughElements */;
31181
+ if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
31182
+ return 86 /* CommandResult.InvalidHeaderIndex */;
31183
+ }
31184
+ else {
31185
+ return 0 /* CommandResult.Success */;
31186
+ }
31023
31187
  }
31024
31188
  case "FREEZE_ROWS": {
31025
31189
  return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
@@ -31491,7 +31655,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31491
31655
  duplicateSheet(fromId, toId) {
31492
31656
  const sheet = this.getSheet(fromId);
31493
31657
  const toName = this.getDuplicateSheetName(sheet.name);
31494
- const newSheet = JSON.parse(JSON.stringify(sheet));
31658
+ const newSheet = deepCopy(sheet);
31495
31659
  newSheet.id = toId;
31496
31660
  newSheet.name = toName;
31497
31661
  for (let col = 0; col <= newSheet.numberOfCols; col++) {
@@ -31618,10 +31782,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31618
31782
  }
31619
31783
  }
31620
31784
  moveCellOnColumnsDeletion(sheet, deletedColumn) {
31621
- for (let [index, row] of Object.entries(sheet.rows)) {
31622
- const rowIndex = parseInt(index, 10);
31785
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31786
+ const row = sheet.rows[rowIndex];
31623
31787
  for (let i in row.cells) {
31624
- const colIndex = parseInt(i, 10);
31788
+ const colIndex = Number(i);
31625
31789
  const cellId = row.cells[i];
31626
31790
  if (cellId) {
31627
31791
  if (colIndex === deletedColumn) {
@@ -31648,11 +31812,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31648
31812
  */
31649
31813
  moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
31650
31814
  const commands = [];
31651
- for (const [index, row] of Object.entries(sheet.rows)) {
31652
- const rowIndex = parseInt(index, 10);
31815
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31816
+ const row = sheet.rows[rowIndex];
31653
31817
  if (dimension !== "rows" || rowIndex >= addedElement) {
31654
31818
  for (let i in row.cells) {
31655
- const colIndex = parseInt(i, 10);
31819
+ const colIndex = Number(i);
31656
31820
  const cellId = row.cells[i];
31657
31821
  if (cellId) {
31658
31822
  if (dimension === "rows" || colIndex >= addedElement) {
@@ -31682,11 +31846,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31682
31846
  */
31683
31847
  moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
31684
31848
  const numberRows = deleteToRow - deleteFromRow + 1;
31685
- for (let [index, row] of Object.entries(sheet.rows)) {
31686
- const rowIndex = parseInt(index, 10);
31849
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
31850
+ const row = sheet.rows[rowIndex];
31687
31851
  if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
31688
31852
  for (let i in row.cells) {
31689
- const colIndex = parseInt(i, 10);
31853
+ const colIndex = Number(i);
31690
31854
  const cellId = row.cells[i];
31691
31855
  if (cellId) {
31692
31856
  this.dispatch("CLEAR_CELL", {
@@ -31699,7 +31863,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31699
31863
  }
31700
31864
  if (rowIndex > deleteToRow) {
31701
31865
  for (let i in row.cells) {
31702
- const colIndex = parseInt(i, 10);
31866
+ const colIndex = Number(i);
31703
31867
  const cellId = row.cells[i];
31704
31868
  if (cellId) {
31705
31869
  this.dispatch("UPDATE_CELL_POSITION", {
@@ -31717,7 +31881,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
31717
31881
  const rows = [];
31718
31882
  const cellsQueue = sheet.rows.map((row) => row.cells);
31719
31883
  for (let i in sheet.rows) {
31720
- if (parseInt(i, 10) === index) {
31884
+ if (Number(i) === index) {
31721
31885
  continue;
31722
31886
  }
31723
31887
  rows.push({
@@ -32269,8 +32433,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32269
32433
  const cell = this.getters.getCell(position);
32270
32434
  if (cell) {
32271
32435
  const exportedCellData = sheet.cells[xc];
32272
- exportedCellData.value = this.getEvaluatedCell(position).value;
32436
+ const evaluatedCell = this.getEvaluatedCell(position);
32437
+ exportedCellData.value = evaluatedCell.value;
32273
32438
  exportedCellData.isFormula = cell.isFormula && !this.isBadExpression(cell.content);
32439
+ if (cell.format !== evaluatedCell.format) {
32440
+ exportedCellData.computedFormat = evaluatedCell.format;
32441
+ }
32274
32442
  }
32275
32443
  }
32276
32444
  }
@@ -32860,13 +33028,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32860
33028
  return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
32861
33029
  }
32862
33030
  intersectZoneWithViewport(sheetId, zone) {
32863
- const colsRange = range(zone.left, zone.right + 1);
32864
- const rowsRange = range(zone.top, zone.bottom + 1);
32865
33031
  return {
32866
- left: this.getters.findVisibleHeader(sheetId, "COL", colsRange),
32867
- right: this.getters.findVisibleHeader(sheetId, "COL", colsRange.reverse()),
32868
- top: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange),
32869
- bottom: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange.reverse()),
33032
+ left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
33033
+ right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
33034
+ top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
33035
+ bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
32870
33036
  };
32871
33037
  }
32872
33038
  updateFilter({ col, row, values, sheetId }) {
@@ -34972,13 +35138,33 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34972
35138
  getNextVisibleCellPosition({ sheetId, col, row }) {
34973
35139
  return {
34974
35140
  sheetId,
34975
- col: this.findVisibleHeader(sheetId, "COL", range(col, this.getters.getNumberCols(sheetId))),
34976
- row: this.findVisibleHeader(sheetId, "ROW", range(row, this.getters.getNumberRows(sheetId))),
35141
+ col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
35142
+ row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
34977
35143
  };
34978
35144
  }
34979
- findVisibleHeader(sheetId, dimension, indexes) {
34980
- return indexes.find((index) => this.getters.doesHeaderExist(sheetId, dimension, index) &&
34981
- !this.isHeaderHidden(sheetId, dimension, index));
35145
+ /**
35146
+ * Find the first visible header in the range [`from` => `to`].
35147
+ *
35148
+ * Both `from` and `to` are inclusive.
35149
+ */
35150
+ findVisibleHeader(sheetId, dimension, from, to) {
35151
+ if (from <= to) {
35152
+ for (let i = from; i <= to; i++) {
35153
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
35154
+ !this.isHeaderHidden(sheetId, dimension, i)) {
35155
+ return i;
35156
+ }
35157
+ }
35158
+ }
35159
+ if (from > to) {
35160
+ for (let i = from; i >= to; i--) {
35161
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
35162
+ !this.isHeaderHidden(sheetId, dimension, i)) {
35163
+ return i;
35164
+ }
35165
+ }
35166
+ }
35167
+ return undefined;
34982
35168
  }
34983
35169
  findLastVisibleColRowIndex(sheetId, dimension, { last, first }) {
34984
35170
  const lastVisibleIndex = range(last, first, -1).find((index) => !this.isHeaderHidden(sheetId, dimension, index));
@@ -34986,7 +35172,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
34986
35172
  }
34987
35173
  findFirstVisibleColRowIndex(sheetId, dimension) {
34988
35174
  const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
34989
- for (let i = 0; i < numberOfHeaders - 1; i++) {
35175
+ for (let i = 0; i < numberOfHeaders; i++) {
34990
35176
  if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
34991
35177
  return i;
34992
35178
  }
@@ -39213,7 +39399,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39213
39399
  }
39214
39400
  openContextMenu(x, y, registry, menuId) {
39215
39401
  this.menuState.isOpen = true;
39216
- this.menuState.menuItems = registry.getAll().filter((x) => x.isVisible(this.env));
39402
+ this.menuState.menuItems = registry.getAll();
39217
39403
  this.menuState.position = { x, y };
39218
39404
  this.menuState.menuId = menuId;
39219
39405
  }
@@ -40020,7 +40206,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40020
40206
  const { left, top, height } = ev.target.getBoundingClientRect();
40021
40207
  this.state.menuState.isOpen = true;
40022
40208
  this.state.menuState.position = { x: left, y: top + height };
40023
- this.state.menuState.menuItems = getMenuChildren(menu, this.env).filter((item) => !item.isVisible || item.isVisible(this.env));
40209
+ this.state.menuState.menuItems = getMenuChildren(menu, this.env);
40024
40210
  this.state.menuState.parentMenu = menu;
40025
40211
  this.isSelectingMenu = true;
40026
40212
  this.openedEl = ev.target;
@@ -40063,9 +40249,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40063
40249
  this.style.align = this.style.align || cell.defaultAlign;
40064
40250
  this.fillColor = this.style.fillColor || "#ffffff";
40065
40251
  this.textColor = this.style.textColor || "#000000";
40066
- this.menus = topbarMenuRegistry
40067
- .getAll()
40068
- .filter((item) => !item.isVisible || item.isVisible(this.env));
40252
+ this.menus = topbarMenuRegistry.getAll();
40069
40253
  }
40070
40254
  getMenuName(menu) {
40071
40255
  return getMenuName(menu, this.env);
@@ -41779,8 +41963,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
41779
41963
  }
41780
41964
  const { left, right, top, bottom } = zone;
41781
41965
  const sheetId = this.getters.getActiveSheetId();
41782
- const refCol = this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1));
41783
- const refRow = this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1));
41966
+ const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
41967
+ const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
41784
41968
  if (refRow === undefined || refCol === undefined) {
41785
41969
  return 17 /* CommandResult.SelectionOutOfBound */;
41786
41970
  }
@@ -41855,10 +42039,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
41855
42039
  const { col: anchorCol, row: anchorRow } = anchor.cell;
41856
42040
  return {
41857
42041
  col: this.getters.isColHidden(sheetId, anchorCol)
41858
- ? this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1)) || anchorCol
42042
+ ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
41859
42043
  : anchorCol,
41860
42044
  row: this.getters.isRowHidden(sheetId, anchorRow)
41861
- ? this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1)) || anchorRow
42045
+ ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
41862
42046
  : anchorRow,
41863
42047
  };
41864
42048
  }
@@ -42432,12 +42616,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42432
42616
  else {
42433
42617
  // Shouldn't we always output the value then ?
42434
42618
  const value = cell.value;
42435
- // what if value = 0? Is this condition correct?
42436
- if (value) {
42437
- const type = getCellType(value);
42438
- attrs.push(["t", type]);
42439
- node = escapeXml /*xml*/ `<v>${value}</v>`;
42440
- }
42619
+ const type = getCellType(value);
42620
+ attrs.push(["t", type]);
42621
+ node = escapeXml /*xml*/ `<v>${value}</v>`;
42441
42622
  return { attrs, node };
42442
42623
  }
42443
42624
  }
@@ -43539,6 +43720,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43539
43720
  * Internal status of the model. Important for command handling coordination
43540
43721
  */
43541
43722
  this.status = 0 /* Status.Ready */;
43723
+ this.handlers = [];
43724
+ this.coreHandlers = [];
43542
43725
  /**
43543
43726
  * The dispatch method is the only entry point to manipulate data in the model.
43544
43727
  * This is through this method that commands are dispatched most of the time
@@ -43643,6 +43826,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43643
43826
  this.uuidGenerator.setIsFastStrategy(true);
43644
43827
  // Initiate stream processor
43645
43828
  this.selection = new SelectionStreamProcessor(this.getters);
43829
+ this.coreHandlers.push(this.range);
43830
+ this.handlers.push(this.range);
43646
43831
  this.corePluginConfig = this.setupCorePluginConfig();
43647
43832
  this.uiPluginConfig = this.setupUiPluginConfig();
43648
43833
  // registering plugins
@@ -43651,15 +43836,23 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43651
43836
  }
43652
43837
  Object.assign(this.getters, this.coreGetters);
43653
43838
  for (let Plugin of statefulUIPluginRegistry.getAll()) {
43654
- this.statefulUIPlugins.push(this.setupUiPlugin(Plugin));
43839
+ const plugin = this.setupUiPlugin(Plugin);
43840
+ this.statefulUIPlugins.push(plugin);
43841
+ this.handlers.push(plugin);
43655
43842
  }
43656
43843
  for (let Plugin of coreViewsPluginRegistry.getAll()) {
43657
- this.coreViewsPlugins.push(this.setupUiPlugin(Plugin));
43844
+ const plugin = this.setupUiPlugin(Plugin);
43845
+ this.coreViewsPlugins.push(plugin);
43846
+ this.handlers.push(plugin);
43847
+ this.coreHandlers.push(plugin);
43658
43848
  }
43659
43849
  for (let Plugin of featurePluginRegistry.getAll()) {
43660
- this.featurePlugins.push(this.setupUiPlugin(Plugin));
43850
+ const plugin = this.setupUiPlugin(Plugin);
43851
+ this.featurePlugins.push(plugin);
43852
+ this.handlers.push(plugin);
43661
43853
  }
43662
43854
  this.uuidGenerator.setIsFastStrategy(false);
43855
+ this.handlers.push(this.history);
43663
43856
  // starting plugins
43664
43857
  this.dispatch("START");
43665
43858
  // Model should be the last permanent subscriber in the list since he should render
@@ -43681,12 +43874,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43681
43874
  // by owl, since we do not rely on reactivity
43682
43875
  owl.markRaw(this);
43683
43876
  }
43684
- get handlers() {
43685
- return [this.range, ...this.corePlugins, ...this.allUIPlugins, this.history];
43686
- }
43687
- get allUIPlugins() {
43688
- return [...this.statefulUIPlugins, ...this.coreViewsPlugins, ...this.featurePlugins];
43689
- }
43690
43877
  joinSession() {
43691
43878
  this.session.join(this.config.client);
43692
43879
  }
@@ -43728,6 +43915,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43728
43915
  }
43729
43916
  plugin.import(data);
43730
43917
  this.corePlugins.push(plugin);
43918
+ this.coreHandlers.push(plugin);
43919
+ this.handlers.push(plugin);
43731
43920
  }
43732
43921
  onRemoteRevisionReceived({ commands }) {
43733
43922
  for (let command of commands) {
@@ -43870,7 +44059,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43870
44059
  }
43871
44060
  }
43872
44061
  data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
43873
- data = JSON.parse(JSON.stringify(data));
44062
+ data = deepCopy(data);
43874
44063
  return data;
43875
44064
  }
43876
44065
  updateMode(mode) {
@@ -43898,7 +44087,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43898
44087
  handler.exportForExcel(data);
43899
44088
  }
43900
44089
  }
43901
- data = JSON.parse(JSON.stringify(data));
44090
+ data = deepCopy(data);
43902
44091
  return getXLSX(data);
43903
44092
  }
43904
44093
  garbageCollectExternalResources() {
@@ -44041,9 +44230,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
44041
44230
  Object.defineProperty(exports, '__esModule', { value: true });
44042
44231
 
44043
44232
 
44044
- __info__.version = '16.1.8';
44045
- __info__.date = '2023-04-14T12:46:41.355Z';
44046
- __info__.hash = '4399770';
44233
+ __info__.version = '16.1.10';
44234
+ __info__.date = '2023-04-28T12:24:14.323Z';
44235
+ __info__.hash = '9632927';
44047
44236
 
44048
44237
 
44049
44238
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);