@odoo/o-spreadsheet 16.0.7 → 16.0.8

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.
@@ -1024,6 +1024,10 @@
1024
1024
  }
1025
1025
  return true;
1026
1026
  }
1027
+ /** Check if the given array contains all the values of the other array. */
1028
+ function includesAll(arr, values) {
1029
+ return values.every((value) => arr.includes(value));
1030
+ }
1027
1031
  /**
1028
1032
  * Return an object with all the keys in the object that have a falsy value removed.
1029
1033
  */
@@ -1569,12 +1573,77 @@
1569
1573
  * - all digit stored in the decimal part of the number
1570
1574
  *
1571
1575
  * The 'maxDecimal' parameter allows to indicate the number of digits to not
1572
- * exceed in the decimal part, in which case digits are rounded
1576
+ * exceed in the decimal part, in which case digits are rounded.
1573
1577
  *
1574
- * Intl.Numberformat is used to properly handle all the roundings.
1575
- * e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
1576
1578
  **/
1577
1579
  function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
1580
+ const asString = value.toString();
1581
+ if (asString.includes("e"))
1582
+ return splitNumberIntl(value, maxDecimals);
1583
+ if (Number.isInteger(value)) {
1584
+ return { integerDigits: asString, decimalDigits: undefined };
1585
+ }
1586
+ const indexOfDot = asString.indexOf(".");
1587
+ let integerDigits = asString.substring(0, indexOfDot);
1588
+ let decimalDigits = asString.substring(indexOfDot + 1);
1589
+ if (maxDecimals === 0) {
1590
+ if (Number(decimalDigits[0]) >= 5) {
1591
+ integerDigits = (Number(integerDigits) + 1).toString();
1592
+ }
1593
+ return { integerDigits, decimalDigits: undefined };
1594
+ }
1595
+ if (decimalDigits.length > maxDecimals) {
1596
+ const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
1597
+ decimalDigits = roundedDecimalDigits;
1598
+ if (roundedIntegerDigits !== "0") {
1599
+ integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
1600
+ }
1601
+ }
1602
+ return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
1603
+ }
1604
+ /**
1605
+ * Return the given string minus the trailing "0" characters.
1606
+ *
1607
+ * @param numberString : a string of integers
1608
+ * @returns the numberString, minus the eventual zeroes at the end
1609
+ */
1610
+ function removeTrailingZeroes(numberString) {
1611
+ let i = numberString.length - 1;
1612
+ while (i >= 0 && numberString[i] === "0") {
1613
+ i--;
1614
+ }
1615
+ return numberString.slice(0, i + 1) || undefined;
1616
+ }
1617
+ /**
1618
+ * Limit the size of the decimal part of a number to the given number of digits.
1619
+ */
1620
+ function limitDecimalDigits(decimalDigits, maxDecimals) {
1621
+ let integerDigits = "0";
1622
+ let resultDecimalDigits = decimalDigits;
1623
+ // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1624
+ // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1625
+ let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1626
+ const i = maxDecimals;
1627
+ if (Number(Number(decimalDigits[i]) < 5)) {
1628
+ return { integerDigits, decimalDigits: slicedDecimalDigits };
1629
+ }
1630
+ // round up
1631
+ const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1632
+ if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1633
+ integerDigits = (Number(integerDigits) + 1).toString();
1634
+ resultDecimalDigits = undefined;
1635
+ }
1636
+ else {
1637
+ resultDecimalDigits = slicedRoundedUp;
1638
+ }
1639
+ return { integerDigits, decimalDigits: resultDecimalDigits };
1640
+ }
1641
+ /**
1642
+ * Split numbers into decimal/integer digits using Intl.NumberFormat.
1643
+ * Supports numbers with a lot of digits that are transformed to scientific notation by
1644
+ * number.toString(), but is slow.
1645
+ */
1646
+ function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
1578
1647
  let formatter = numberRepresentation[maxDecimals];
1579
1648
  if (!formatter) {
1580
1649
  formatter = new Intl.NumberFormat("en-US", {
@@ -3971,13 +4040,16 @@
3971
4040
  }
3972
4041
  });
3973
4042
  }
4043
+ get visibleMenuItems() {
4044
+ return this.props.menuItems.filter((x) => x.isVisible(this.env));
4045
+ }
3974
4046
  get subMenuPosition() {
3975
4047
  const position = Object.assign({}, this.subMenu.position);
3976
4048
  position.y -= this.subMenu.scrollOffset || 0;
3977
4049
  return position;
3978
4050
  }
3979
4051
  get menuHeight() {
3980
- return this.menuComponentHeight(this.props.menuItems);
4052
+ return this.menuComponentHeight(this.visibleMenuItems);
3981
4053
  }
3982
4054
  get subMenuHeight() {
3983
4055
  return this.menuComponentHeight(this.subMenu.menuItems);
@@ -4013,7 +4085,7 @@
4013
4085
  * and the menu item at a given index.
4014
4086
  */
4015
4087
  subMenuVerticalPosition(position) {
4016
- const menusAbove = this.props.menuItems.slice(0, position);
4088
+ const menusAbove = this.visibleMenuItems.slice(0, position);
4017
4089
  return this.menuComponentHeight(menusAbove) + this.position.y;
4018
4090
  }
4019
4091
  onExternalClick(ev) {
@@ -5546,6 +5618,11 @@
5546
5618
  name: REMOVE_COLUMNS_NAME,
5547
5619
  sequence: 90,
5548
5620
  action: REMOVE_COLUMNS_ACTION,
5621
+ isVisible: (env) => {
5622
+ const sheetId = env.model.getters.getActiveSheetId();
5623
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
5624
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
5625
+ },
5549
5626
  })
5550
5627
  .add("clear_column", {
5551
5628
  name: DELETE_CONTENT_COLUMNS_NAME,
@@ -5558,9 +5635,8 @@
5558
5635
  action: HIDE_COLUMNS_ACTION,
5559
5636
  isVisible: (env) => {
5560
5637
  const sheetId = env.model.getters.getActiveSheetId();
5561
- const hiddenCols = env.model.getters.getHiddenColsGroups(sheetId).flat();
5562
- return (env.model.getters.getNumberCols(sheetId) >
5563
- hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
5638
+ const selectedCols = env.model.getters.getElementsFromSelection("COL");
5639
+ return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
5564
5640
  },
5565
5641
  separator: true,
5566
5642
  })
@@ -5634,6 +5710,11 @@
5634
5710
  name: REMOVE_ROWS_NAME,
5635
5711
  sequence: 70,
5636
5712
  action: REMOVE_ROWS_ACTION,
5713
+ isVisible: (env) => {
5714
+ const sheetId = env.model.getters.getActiveSheetId();
5715
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
5716
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
5717
+ },
5637
5718
  })
5638
5719
  .add("clear_row", {
5639
5720
  name: DELETE_CONTENT_ROWS_NAME,
@@ -5646,9 +5727,8 @@
5646
5727
  action: HIDE_ROWS_ACTION,
5647
5728
  isVisible: (env) => {
5648
5729
  const sheetId = env.model.getters.getActiveSheetId();
5649
- const hiddenRows = env.model.getters.getHiddenRowsGroups(sheetId).flat();
5650
- return (env.model.getters.getNumberRows(sheetId) >
5651
- hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
5730
+ const selectedRows = env.model.getters.getElementsFromSelection("ROW");
5731
+ return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
5652
5732
  },
5653
5733
  separator: true,
5654
5734
  })
@@ -10310,7 +10390,7 @@
10310
10390
  openContextMenu(position) {
10311
10391
  const registry = this.getMenuItemRegistry();
10312
10392
  this.menuState.isOpen = true;
10313
- this.menuState.menuItems = registry.getAll().filter((x) => x.isVisible(this.env));
10393
+ this.menuState.menuItems = registry.getAll();
10314
10394
  this.menuState.position = position;
10315
10395
  }
10316
10396
  get chartComponent() {
@@ -19830,14 +19910,31 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19830
19910
  * */
19831
19911
  getCurrentSelection() {
19832
19912
  let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
19833
- let startSizeBefore = this.findSizeBeforeElement(startElement);
19834
- let endSizeBefore = this.findSizeBeforeElement(endElement);
19913
+ let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
19914
+ let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
19835
19915
  return {
19836
- start: startSizeBefore + startSelectionOffset,
19837
- end: endSizeBefore + endSelectionOffset,
19916
+ start: startSizeBefore,
19917
+ end: endSizeBefore,
19838
19918
  };
19839
19919
  }
19840
- findSizeBeforeElement(nodeToFind) {
19920
+ /**
19921
+ * Computes the text 'index' inside this.el based on the currently selected node and its offset.
19922
+ * The selected node is either a Text node or an Element node.
19923
+ *
19924
+ * case 1 -Text node:
19925
+ * the offset is the number of characters from the start of the node. We have to add this offset to the
19926
+ * content length of all previous nodes.
19927
+ *
19928
+ * case 2 - Element node:
19929
+ * the offset is the number of child nodes before the selected node. We have to add the content length of
19930
+ * all the bnodes prior to the selected node as well as the content of the child node before the offset.
19931
+ *
19932
+ * See the MDN documentation for more details.
19933
+ * https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
19934
+ * https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
19935
+ *
19936
+ */
19937
+ findSelectionIndex(nodeToFind, nodeOffset) {
19841
19938
  let it = this.iterateChildren(this.el);
19842
19939
  let usedCharacters = 0;
19843
19940
  let current = it.next();
@@ -19849,6 +19946,19 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19849
19946
  }
19850
19947
  current = it.next();
19851
19948
  }
19949
+ if (current.value === nodeToFind) {
19950
+ if (!current.value.hasChildNodes()) {
19951
+ usedCharacters += nodeOffset;
19952
+ }
19953
+ else {
19954
+ const children = [...current.value.childNodes].slice(0, nodeOffset);
19955
+ for (const child of children) {
19956
+ if (!child.textContent)
19957
+ continue;
19958
+ usedCharacters += child.textContent.length;
19959
+ }
19960
+ }
19961
+ }
19852
19962
  return usedCharacters;
19853
19963
  }
19854
19964
  getStartAndEndSelection() {
@@ -22334,8 +22444,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22334
22444
  },
22335
22445
  "CTRL+END": () => {
22336
22446
  const sheetId = this.env.model.getters.getActiveSheetId();
22337
- const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", range(0, this.env.model.getters.getNumberCols(sheetId)).reverse());
22338
- const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", range(0, this.env.model.getters.getNumberRows(sheetId)).reverse());
22447
+ const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
22448
+ const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
22339
22449
  this.env.model.selection.selectCell(col, row);
22340
22450
  },
22341
22451
  "SHIFT+ ": () => {
@@ -22411,9 +22521,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22411
22521
  this.focus();
22412
22522
  }
22413
22523
  focus() {
22524
+ var _a;
22414
22525
  if (!this.env.model.getters.getSelectedFigureId() &&
22415
22526
  this.env.model.getters.getEditionMode() === "inactive") {
22416
- this.hiddenInput.el.focus();
22527
+ (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
22417
22528
  }
22418
22529
  }
22419
22530
  get gridEl() {
@@ -22617,9 +22728,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22617
22728
  this.closeOpenedPopover();
22618
22729
  this.menuState.isOpen = true;
22619
22730
  this.menuState.position = { x, y };
22620
- this.menuState.menuItems = registries$1[type]
22621
- .getAll()
22622
- .filter((item) => !item.isVisible || item.isVisible(this.env));
22731
+ this.menuState.menuItems = registries$1[type].getAll();
22623
22732
  }
22624
22733
  copy(cut, ev) {
22625
22734
  if (!this.gridEl.contains(document.activeElement)) {
@@ -26357,7 +26466,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
26357
26466
  }
26358
26467
  }
26359
26468
  }
26360
- data = JSON.parse(JSON.stringify(data));
26469
+ data = deepCopy(data);
26361
26470
  // apply migrations, if needed
26362
26471
  if ("version" in data) {
26363
26472
  if (data.version < CURRENT_VERSION) {
@@ -28942,7 +29051,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
28942
29051
  allowDispatch(cmd) {
28943
29052
  switch (cmd.type) {
28944
29053
  case "HIDE_COLUMNS_ROWS": {
28945
- if (!this.hiddenHeaders[cmd.sheetId]) {
29054
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
28946
29055
  return 27 /* CommandResult.InvalidSheetId */;
28947
29056
  }
28948
29057
  const hiddenGroup = cmd.dimension === "COL"
@@ -28955,6 +29064,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
28955
29064
  ? 0 /* CommandResult.Success */
28956
29065
  : 65 /* CommandResult.TooManyHiddenElements */;
28957
29066
  }
29067
+ case "REMOVE_COLUMNS_ROWS":
29068
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
29069
+ return 27 /* CommandResult.InvalidSheetId */;
29070
+ }
29071
+ if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
29072
+ return 8 /* CommandResult.NotEnoughElements */;
29073
+ }
29074
+ return 0 /* CommandResult.Success */;
28958
29075
  }
28959
29076
  return 0 /* CommandResult.Success */;
28960
29077
  }
@@ -29001,6 +29118,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29001
29118
  }
29002
29119
  return;
29003
29120
  }
29121
+ canRemoveHeaders(sheetId, dimension, elements) {
29122
+ const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
29123
+ return !includesAll(elements, visibleHeaders);
29124
+ }
29004
29125
  isRowHiddenByUser(sheetId, index) {
29005
29126
  return this.hiddenHeaders[sheetId].ROW[index];
29006
29127
  }
@@ -29045,6 +29166,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29045
29166
  }
29046
29167
  return consecutiveIndexes;
29047
29168
  }
29169
+ getAllVisibleHeaders(sheetId, dimension) {
29170
+ return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
29171
+ }
29048
29172
  import(data) {
29049
29173
  var _a, _b;
29050
29174
  for (let sheet of data.sheets) {
@@ -29092,6 +29216,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29092
29216
  }
29093
29217
  }
29094
29218
  HeaderVisibilityPlugin.getters = [
29219
+ "canRemoveHeaders",
29095
29220
  "getHiddenColsGroups",
29096
29221
  "getHiddenRowsGroups",
29097
29222
  "isRowHiddenByUser",
@@ -29592,14 +29717,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
29592
29717
  return this.orderedSheetIds.length > 1
29593
29718
  ? 0 /* CommandResult.Success */
29594
29719
  : 9 /* CommandResult.NotEnoughSheets */;
29595
- case "REMOVE_COLUMNS_ROWS": {
29596
- const length = cmd.dimension === "COL"
29597
- ? this.getNumberCols(cmd.sheetId)
29598
- : this.getNumberRows(cmd.sheetId);
29599
- return length > cmd.elements.length
29600
- ? 0 /* CommandResult.Success */
29601
- : 8 /* CommandResult.NotEnoughElements */;
29602
- }
29603
29720
  case "FREEZE_ROWS": {
29604
29721
  return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
29605
29722
  }
@@ -30083,7 +30200,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30083
30200
  duplicateSheet(fromId, toId) {
30084
30201
  const sheet = this.getSheet(fromId);
30085
30202
  const toName = this.getDuplicateSheetName(sheet.name);
30086
- const newSheet = JSON.parse(JSON.stringify(sheet));
30203
+ const newSheet = deepCopy(sheet);
30087
30204
  newSheet.id = toId;
30088
30205
  newSheet.name = toName;
30089
30206
  for (let col = 0; col <= newSheet.numberOfCols; col++) {
@@ -30210,10 +30327,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30210
30327
  }
30211
30328
  }
30212
30329
  moveCellOnColumnsDeletion(sheet, deletedColumn) {
30213
- for (let [index, row] of Object.entries(sheet.rows)) {
30214
- const rowIndex = parseInt(index, 10);
30330
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
30331
+ const row = sheet.rows[rowIndex];
30215
30332
  for (let i in row.cells) {
30216
- const colIndex = parseInt(i, 10);
30333
+ const colIndex = Number(i);
30217
30334
  const cellId = row.cells[i];
30218
30335
  if (cellId) {
30219
30336
  if (colIndex === deletedColumn) {
@@ -30240,11 +30357,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30240
30357
  */
30241
30358
  moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
30242
30359
  const commands = [];
30243
- for (const [index, row] of Object.entries(sheet.rows)) {
30244
- const rowIndex = parseInt(index, 10);
30360
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
30361
+ const row = sheet.rows[rowIndex];
30245
30362
  if (dimension !== "rows" || rowIndex >= addedElement) {
30246
30363
  for (let i in row.cells) {
30247
- const colIndex = parseInt(i, 10);
30364
+ const colIndex = Number(i);
30248
30365
  const cellId = row.cells[i];
30249
30366
  if (cellId) {
30250
30367
  if (dimension === "rows" || colIndex >= addedElement) {
@@ -30274,11 +30391,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30274
30391
  */
30275
30392
  moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
30276
30393
  const numberRows = deleteToRow - deleteFromRow + 1;
30277
- for (let [index, row] of Object.entries(sheet.rows)) {
30278
- const rowIndex = parseInt(index, 10);
30394
+ for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
30395
+ const row = sheet.rows[rowIndex];
30279
30396
  if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
30280
30397
  for (let i in row.cells) {
30281
- const colIndex = parseInt(i, 10);
30398
+ const colIndex = Number(i);
30282
30399
  const cellId = row.cells[i];
30283
30400
  if (cellId) {
30284
30401
  this.dispatch("CLEAR_CELL", {
@@ -30291,7 +30408,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30291
30408
  }
30292
30409
  if (rowIndex > deleteToRow) {
30293
30410
  for (let i in row.cells) {
30294
- const colIndex = parseInt(i, 10);
30411
+ const colIndex = Number(i);
30295
30412
  const cellId = row.cells[i];
30296
30413
  if (cellId) {
30297
30414
  this.dispatch("UPDATE_CELL_POSITION", {
@@ -30309,7 +30426,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
30309
30426
  const rows = [];
30310
30427
  const cellsQueue = sheet.rows.map((row) => row.cells);
30311
30428
  for (let i in sheet.rows) {
30312
- if (parseInt(i, 10) === index) {
30429
+ if (Number(i) === index) {
30313
30430
  continue;
30314
30431
  }
30315
30432
  rows.push({
@@ -32945,13 +33062,11 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
32945
33062
  return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
32946
33063
  }
32947
33064
  intersectZoneWithViewport(sheetId, zone) {
32948
- const colsRange = range(zone.left, zone.right + 1);
32949
- const rowsRange = range(zone.top, zone.bottom + 1);
32950
33065
  return {
32951
- left: this.getters.findVisibleHeader(sheetId, "COL", colsRange),
32952
- right: this.getters.findVisibleHeader(sheetId, "COL", colsRange.reverse()),
32953
- top: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange),
32954
- bottom: this.getters.findVisibleHeader(sheetId, "ROW", rowsRange.reverse()),
33066
+ left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
33067
+ right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
33068
+ top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
33069
+ bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
32955
33070
  };
32956
33071
  }
32957
33072
  updateFilter({ col, row, values, sheetId }) {
@@ -33393,13 +33508,33 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33393
33508
  }
33394
33509
  getNextVisibleCellPosition(sheetId, col, row) {
33395
33510
  return {
33396
- col: this.findVisibleHeader(sheetId, "COL", range(col, this.getters.getNumberCols(sheetId))),
33397
- row: this.findVisibleHeader(sheetId, "ROW", range(row, this.getters.getNumberRows(sheetId))),
33511
+ col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
33512
+ row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
33398
33513
  };
33399
33514
  }
33400
- findVisibleHeader(sheetId, dimension, indexes) {
33401
- return indexes.find((index) => this.getters.doesHeaderExist(sheetId, dimension, index) &&
33402
- !this.isHeaderHidden(sheetId, dimension, index));
33515
+ /**
33516
+ * Find the first visible header in the range [`from` => `to`].
33517
+ *
33518
+ * Both `from` and `to` are inclusive.
33519
+ */
33520
+ findVisibleHeader(sheetId, dimension, from, to) {
33521
+ if (from <= to) {
33522
+ for (let i = from; i <= to; i++) {
33523
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
33524
+ !this.isHeaderHidden(sheetId, dimension, i)) {
33525
+ return i;
33526
+ }
33527
+ }
33528
+ }
33529
+ if (from > to) {
33530
+ for (let i = from; i >= to; i--) {
33531
+ if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
33532
+ !this.isHeaderHidden(sheetId, dimension, i)) {
33533
+ return i;
33534
+ }
33535
+ }
33536
+ }
33537
+ return undefined;
33403
33538
  }
33404
33539
  findLastVisibleColRowIndex(sheetId, dimension, indexes) {
33405
33540
  let lastIndex;
@@ -33412,7 +33547,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33412
33547
  }
33413
33548
  findFirstVisibleColRowIndex(sheetId, dimension) {
33414
33549
  const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
33415
- for (let i = 0; i < numberOfHeaders - 1; i++) {
33550
+ for (let i = 0; i < numberOfHeaders; i++) {
33416
33551
  if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
33417
33552
  return i;
33418
33553
  }
@@ -37539,7 +37674,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
37539
37674
  }
37540
37675
  openContextMenu(x, y, registry, menuId) {
37541
37676
  this.menuState.isOpen = true;
37542
- this.menuState.menuItems = registry.getAll().filter((x) => x.isVisible(this.env));
37677
+ this.menuState.menuItems = registry.getAll();
37543
37678
  this.menuState.position = { x, y };
37544
37679
  this.menuState.menuId = menuId;
37545
37680
  }
@@ -38300,7 +38435,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
38300
38435
  const { left, top, height } = ev.target.getBoundingClientRect();
38301
38436
  this.state.menuState.isOpen = true;
38302
38437
  this.state.menuState.position = { x: left, y: top + height };
38303
- this.state.menuState.menuItems = getMenuChildren(menu, this.env).filter((item) => !item.isVisible || item.isVisible(this.env));
38438
+ this.state.menuState.menuItems = getMenuChildren(menu, this.env);
38304
38439
  this.state.menuState.parentMenu = menu;
38305
38440
  this.isSelectingMenu = true;
38306
38441
  this.openedEl = ev.target;
@@ -38349,9 +38484,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
38349
38484
  this.style.align = this.style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign);
38350
38485
  this.fillColor = this.style.fillColor || "#ffffff";
38351
38486
  this.textColor = this.style.textColor || "#000000";
38352
- this.menus = topbarMenuRegistry
38353
- .getAll()
38354
- .filter((item) => !item.isVisible || item.isVisible(this.env));
38487
+ this.menus = topbarMenuRegistry.getAll();
38355
38488
  }
38356
38489
  getMenuName(menu) {
38357
38490
  return getMenuName(menu, this.env);
@@ -40417,8 +40550,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40417
40550
  }
40418
40551
  const { left, right, top, bottom } = zone;
40419
40552
  const sheetId = this.getters.getActiveSheetId();
40420
- const refCol = this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1));
40421
- const refRow = this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1));
40553
+ const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
40554
+ const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
40422
40555
  if (refRow === undefined || refCol === undefined) {
40423
40556
  return 17 /* CommandResult.SelectionOutOfBound */;
40424
40557
  }
@@ -40493,10 +40626,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40493
40626
  const { col: anchorCol, row: anchorRow } = anchor.cell;
40494
40627
  return {
40495
40628
  col: this.getters.isColHidden(sheetId, anchorCol)
40496
- ? this.getters.findVisibleHeader(sheetId, "COL", range(left, right + 1)) || anchorCol
40629
+ ? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
40497
40630
  : anchorCol,
40498
40631
  row: this.getters.isRowHidden(sheetId, anchorRow)
40499
- ? this.getters.findVisibleHeader(sheetId, "ROW", range(top, bottom + 1)) || anchorRow
40632
+ ? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
40500
40633
  : anchorRow,
40501
40634
  };
40502
40635
  }
@@ -42136,6 +42269,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42136
42269
  * Internal status of the model. Important for command handling coordination
42137
42270
  */
42138
42271
  this.status = 0 /* Status.Ready */;
42272
+ this.handlers = [];
42273
+ this.coreHandlers = [];
42139
42274
  /**
42140
42275
  * The dispatch method is the only entry point to manipulate data in the model.
42141
42276
  * This is through this method that commands are dispatched most of the time
@@ -42208,7 +42343,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42208
42343
  const command = { type, ...payload };
42209
42344
  const previousStatus = this.status;
42210
42345
  this.status = 2 /* Status.RunningCore */;
42211
- const handlers = this.isReplayingCommand ? [this.range, ...this.corePlugins] : this.handlers;
42346
+ const handlers = this.isReplayingCommand ? this.coreHandlers : this.handlers;
42212
42347
  this.dispatchToHandlers(handlers, command);
42213
42348
  this.status = previousStatus;
42214
42349
  return DispatchResult.Success;
@@ -42242,6 +42377,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42242
42377
  this.uuidGenerator.setIsFastStrategy(true);
42243
42378
  // Initiate stream processor
42244
42379
  this.selection = new SelectionStreamProcessor(this.getters);
42380
+ this.coreHandlers.push(this.range);
42381
+ this.handlers.push(this.range);
42245
42382
  // registering plugins
42246
42383
  for (let Plugin of corePluginRegistry.getAll()) {
42247
42384
  this.setupCorePlugin(Plugin, workbookData);
@@ -42251,6 +42388,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42251
42388
  this.setupUiPlugin(Plugin);
42252
42389
  }
42253
42390
  this.uuidGenerator.setIsFastStrategy(false);
42391
+ this.handlers.push(this.history);
42254
42392
  // starting plugins
42255
42393
  this.dispatch("START");
42256
42394
  // Model should be the last permanent subscriber in the list since he should render
@@ -42271,9 +42409,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42271
42409
  // by owl, since we do not rely on reactivity
42272
42410
  owl.markRaw(this);
42273
42411
  }
42274
- get handlers() {
42275
- return [this.range, ...this.corePlugins, ...this.uiPlugins, this.history];
42276
- }
42277
42412
  joinSession() {
42278
42413
  this.session.join(this.config.client);
42279
42414
  }
@@ -42292,6 +42427,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42292
42427
  this.getters[name] = plugin[name].bind(plugin);
42293
42428
  }
42294
42429
  this.uiPlugins.push(plugin);
42430
+ this.handlers.push(plugin);
42295
42431
  const layers = Plugin.layers.map((l) => [plugin, l]);
42296
42432
  this.renderers.push(...layers);
42297
42433
  this.renderers.sort((p1, p2) => p1[1] - p2[1]);
@@ -42315,6 +42451,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42315
42451
  }
42316
42452
  plugin.import(data);
42317
42453
  this.corePlugins.push(plugin);
42454
+ this.coreHandlers.push(plugin);
42455
+ this.handlers.push(plugin);
42318
42456
  }
42319
42457
  onRemoteRevisionReceived({ commands }) {
42320
42458
  for (let command of commands) {
@@ -42332,7 +42470,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42332
42470
  return;
42333
42471
  }
42334
42472
  this.isReplayingCommand = true;
42335
- this.dispatchToHandlers([this.range, ...this.corePlugins], command);
42473
+ this.dispatchToHandlers(this.coreHandlers, command);
42336
42474
  this.isReplayingCommand = false;
42337
42475
  }), this.config.transportService, revisionId);
42338
42476
  return session;
@@ -42432,7 +42570,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42432
42570
  }
42433
42571
  }
42434
42572
  data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
42435
- data = JSON.parse(JSON.stringify(data));
42573
+ data = deepCopy(data);
42436
42574
  return data;
42437
42575
  }
42438
42576
  updateMode(mode) {
@@ -42459,7 +42597,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42459
42597
  handler.exportForExcel(data);
42460
42598
  }
42461
42599
  }
42462
- data = JSON.parse(JSON.stringify(data));
42600
+ data = deepCopy(data);
42463
42601
  return getXLSX(data);
42464
42602
  }
42465
42603
  }
@@ -42593,9 +42731,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42593
42731
  Object.defineProperty(exports, '__esModule', { value: true });
42594
42732
 
42595
42733
 
42596
- __info__.version = '16.0.7';
42597
- __info__.date = '2023-04-14T12:46:24.076Z';
42598
- __info__.hash = '2b4831d';
42734
+ __info__.version = '16.0.8';
42735
+ __info__.date = '2023-04-21T07:29:33.894Z';
42736
+ __info__.hash = 'dbd7aa4';
42599
42737
 
42600
42738
 
42601
42739
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);