@odoo/o-spreadsheet 16.2.23 → 16.2.24

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.
@@ -1366,8 +1366,10 @@ function isSameColor(color1, color2) {
1366
1366
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
1367
1367
  // Same as above, but matches the exact string (nothing before or after)
1368
1368
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
1369
- /** Reference of a column header (eg. A, AB) */
1370
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
1369
+ /** Reference of a column header (eg. A, AB, $A) */
1370
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
1371
+ /** Reference of a row header (eg. 1, $1) */
1372
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
1371
1373
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
1372
1374
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
1373
1375
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -1397,6 +1399,9 @@ function isRowReference(xc) {
1397
1399
  function isColHeader(str) {
1398
1400
  return colHeader.test(str);
1399
1401
  }
1402
+ function isRowHeader(str) {
1403
+ return rowHeader.test(str);
1404
+ }
1400
1405
  /**
1401
1406
  * Return true if the given xc is the reference of a single cell,
1402
1407
  * without any specified sheet (e.g. A1)
@@ -2186,18 +2191,10 @@ class RangeImpl {
2186
2191
  if (isFullCol) {
2187
2192
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2188
2193
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2189
- if (zone.left === zone.right) {
2190
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2191
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2192
- }
2193
2194
  }
2194
2195
  if (isFullRow) {
2195
2196
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2196
2197
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2197
- if (zone.top === zone.bottom) {
2198
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2199
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2200
- }
2201
2198
  }
2202
2199
  return parts;
2203
2200
  }
@@ -5096,6 +5093,9 @@ function setElementScrollTop(el, scroll) {
5096
5093
  }
5097
5094
  function getOpenedMenus() {
5098
5095
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5096
+ }
5097
+ function isMacOS() {
5098
+ return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
5099
5099
  }
5100
5100
 
5101
5101
  /**
@@ -21139,6 +21139,7 @@ class AbstractResizer extends owl.Component {
21139
21139
  draggerShadowThickness: 0,
21140
21140
  delta: 0,
21141
21141
  base: 0,
21142
+ position: "before",
21142
21143
  });
21143
21144
  }
21144
21145
  _computeHandleDisplay(ev) {
@@ -21264,11 +21265,13 @@ class AbstractResizer extends owl.Component {
21264
21265
  this.state.draggerLinePosition = dimensions.start;
21265
21266
  this.state.draggerShadowPosition = dimensions.start;
21266
21267
  this.state.base = elementIndex;
21268
+ this.state.position = "before";
21267
21269
  }
21268
21270
  else if (this._getSelectedZoneEnd() < elementIndex) {
21269
21271
  this.state.draggerLinePosition = dimensions.end;
21270
21272
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
21271
- this.state.base = elementIndex + 1;
21273
+ this.state.base = elementIndex;
21274
+ this.state.position = "after";
21272
21275
  }
21273
21276
  else {
21274
21277
  this.state.draggerLinePosition = startDimensions.start;
@@ -21449,6 +21452,7 @@ class ColResizer extends AbstractResizer {
21449
21452
  dimension: "COL",
21450
21453
  base: this.state.base,
21451
21454
  elements,
21455
+ position: this.state.position,
21452
21456
  });
21453
21457
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21454
21458
  this.env.raiseError(MergeErrorMessage);
@@ -21621,6 +21625,7 @@ class RowResizer extends AbstractResizer {
21621
21625
  dimension: "ROW",
21622
21626
  base: this.state.base,
21623
21627
  elements,
21628
+ position: this.state.position,
21624
21629
  });
21625
21630
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21626
21631
  this.env.raiseError(MergeErrorMessage);
@@ -21729,8 +21734,8 @@ function useWheelHandler(handler) {
21729
21734
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
21730
21735
  }
21731
21736
  const onMouseWheel = (ev) => {
21732
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
21733
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
21737
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
21738
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
21734
21739
  handler(deltaX, deltaY);
21735
21740
  };
21736
21741
  return onMouseWheel;
@@ -24318,7 +24323,7 @@ const machine = {
24318
24323
  SPACE: goTo(State.RightRef),
24319
24324
  NUMBER: goTo(State.Found),
24320
24325
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24321
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
24326
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
24322
24327
  },
24323
24328
  [State.RightColumnRef]: {
24324
24329
  SPACE: goTo(State.RightColumnRef),
@@ -24329,6 +24334,7 @@ const machine = {
24329
24334
  SPACE: goTo(State.RightRowRef),
24330
24335
  NUMBER: goTo(State.Found),
24331
24336
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24337
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
24332
24338
  },
24333
24339
  [State.Found]: {},
24334
24340
  };
@@ -30931,7 +30937,7 @@ class SheetPlugin extends CorePlugin {
30931
30937
  const elements = cmd.dimension === "COL"
30932
30938
  ? this.getNumberCols(cmd.sheetId)
30933
30939
  : this.getNumberRows(cmd.sheetId);
30934
- if (cmd.base < 0 || cmd.base > elements) {
30940
+ if (cmd.base < 0 || cmd.base >= elements) {
30935
30941
  return 86 /* CommandResult.InvalidHeaderIndex */;
30936
30942
  }
30937
30943
  else if (cmd.quantity <= 0) {
@@ -34096,24 +34102,27 @@ class AutofillPlugin extends UIPlugin {
34096
34102
  * autofiller
34097
34103
  */
34098
34104
  autofillAuto() {
34105
+ var _a, _b;
34099
34106
  const zone = this.getters.getSelectedZone();
34100
34107
  const sheetId = this.getters.getActiveSheetId();
34101
34108
  let col = zone.left;
34102
34109
  let row = zone.bottom;
34103
34110
  if (col > 0) {
34104
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34105
- while (left.type !== CellValueType.empty) {
34111
+ let leftPosition = { sheetId, col: col - 1, row };
34112
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
34113
+ ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
34106
34114
  row += 1;
34107
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34115
+ leftPosition = { sheetId, col: col - 1, row };
34108
34116
  }
34109
34117
  }
34110
34118
  if (row === zone.bottom) {
34111
34119
  col = zone.right;
34112
34120
  if (col <= this.getters.getNumberCols(sheetId)) {
34113
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34114
- while (right.type !== CellValueType.empty) {
34121
+ let rightPosition = { sheetId, col: col + 1, row };
34122
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
34123
+ ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
34115
34124
  row += 1;
34116
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34125
+ rightPosition = { sheetId, col: col + 1, row };
34117
34126
  }
34118
34127
  }
34119
34128
  }
@@ -38431,6 +38440,10 @@ function setXcToReferenceType(xc, referenceType) {
38431
38440
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38432
38441
  case "colrow":
38433
38442
  indexOfNumber = xc.search(/[0-9]/);
38443
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
38444
+ // no row number (eg. A) or no column (eg. 1)
38445
+ return "$" + xc;
38446
+ }
38434
38447
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38435
38448
  return "$" + xc;
38436
38449
  case "none":
@@ -39572,7 +39585,7 @@ class GridSelectionPlugin extends UIPlugin {
39572
39585
  sheetId: cmd.sheetId,
39573
39586
  base: cmd.base,
39574
39587
  quantity: thickness,
39575
- position: "before",
39588
+ position: cmd.position,
39576
39589
  });
39577
39590
  const isCol = cmd.dimension === "COL";
39578
39591
  const start = cmd.elements[0];
@@ -39589,12 +39602,13 @@ class GridSelectionPlugin extends UIPlugin {
39589
39602
  },
39590
39603
  ];
39591
39604
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39605
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
39592
39606
  const pasteTarget = [
39593
39607
  {
39594
- left: isCol ? cmd.base : 0,
39595
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39596
- top: !isCol ? cmd.base : 0,
39597
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39608
+ left: isCol ? base : 0,
39609
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39610
+ top: !isCol ? base : 0,
39611
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39598
39612
  },
39599
39613
  ];
39600
39614
  state.paste(pasteTarget, { selectTarget: true });
@@ -39631,6 +39645,11 @@ class GridSelectionPlugin extends UIPlugin {
39631
39645
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
39632
39646
  return 2 /* CommandResult.WillRemoveExistingMerge */;
39633
39647
  }
39648
+ const headers = [cmd.base, ...cmd.elements];
39649
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
39650
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
39651
+ return 86 /* CommandResult.InvalidHeaderIndex */;
39652
+ }
39634
39653
  return 0 /* CommandResult.Success */;
39635
39654
  }
39636
39655
  //-------------------------------------------
@@ -45572,6 +45591,6 @@ exports.setTranslationMethod = setTranslationMethod;
45572
45591
  exports.tokenize = tokenize;
45573
45592
 
45574
45593
 
45575
- __info__.version = '16.2.23';
45576
- __info__.date = '2023-11-24T13:11:02.651Z';
45577
- __info__.hash = '3c723d3';
45594
+ __info__.version = '16.2.24';
45595
+ __info__.date = '2023-12-05T09:37:14.992Z';
45596
+ __info__.hash = '7b1a35c';
@@ -1507,6 +1507,7 @@ interface MoveColumnsRowsCommand extends GridDependentCommand {
1507
1507
  type: "MOVE_COLUMNS_ROWS";
1508
1508
  base: HeaderIndex;
1509
1509
  elements: HeaderIndex[];
1510
+ position: "before" | "after";
1510
1511
  }
1511
1512
  interface ResizeColumnsRowsCommand extends GridDependentCommand {
1512
1513
  type: "RESIZE_COLUMNS_ROWS";
@@ -6345,6 +6346,7 @@ interface ResizerState {
6345
6346
  draggerShadowThickness: number;
6346
6347
  delta: number;
6347
6348
  base: number;
6349
+ position: "before" | "after";
6348
6350
  }
6349
6351
  interface ResizerProps {
6350
6352
  onOpenContextMenu: (type: ContextMenuType, x: Pixel, y: Pixel) => void;
@@ -1362,8 +1362,10 @@ function isSameColor(color1, color2) {
1362
1362
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
1363
1363
  // Same as above, but matches the exact string (nothing before or after)
1364
1364
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
1365
- /** Reference of a column header (eg. A, AB) */
1366
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
1365
+ /** Reference of a column header (eg. A, AB, $A) */
1366
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
1367
+ /** Reference of a row header (eg. 1, $1) */
1368
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
1367
1369
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
1368
1370
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
1369
1371
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -1393,6 +1395,9 @@ function isRowReference(xc) {
1393
1395
  function isColHeader(str) {
1394
1396
  return colHeader.test(str);
1395
1397
  }
1398
+ function isRowHeader(str) {
1399
+ return rowHeader.test(str);
1400
+ }
1396
1401
  /**
1397
1402
  * Return true if the given xc is the reference of a single cell,
1398
1403
  * without any specified sheet (e.g. A1)
@@ -2182,18 +2187,10 @@ class RangeImpl {
2182
2187
  if (isFullCol) {
2183
2188
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2184
2189
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2185
- if (zone.left === zone.right) {
2186
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2187
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2188
- }
2189
2190
  }
2190
2191
  if (isFullRow) {
2191
2192
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2192
2193
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2193
- if (zone.top === zone.bottom) {
2194
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2195
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2196
- }
2197
2194
  }
2198
2195
  return parts;
2199
2196
  }
@@ -5092,6 +5089,9 @@ function setElementScrollTop(el, scroll) {
5092
5089
  }
5093
5090
  function getOpenedMenus() {
5094
5091
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5092
+ }
5093
+ function isMacOS() {
5094
+ return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
5095
5095
  }
5096
5096
 
5097
5097
  /**
@@ -21135,6 +21135,7 @@ class AbstractResizer extends Component {
21135
21135
  draggerShadowThickness: 0,
21136
21136
  delta: 0,
21137
21137
  base: 0,
21138
+ position: "before",
21138
21139
  });
21139
21140
  }
21140
21141
  _computeHandleDisplay(ev) {
@@ -21260,11 +21261,13 @@ class AbstractResizer extends Component {
21260
21261
  this.state.draggerLinePosition = dimensions.start;
21261
21262
  this.state.draggerShadowPosition = dimensions.start;
21262
21263
  this.state.base = elementIndex;
21264
+ this.state.position = "before";
21263
21265
  }
21264
21266
  else if (this._getSelectedZoneEnd() < elementIndex) {
21265
21267
  this.state.draggerLinePosition = dimensions.end;
21266
21268
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
21267
- this.state.base = elementIndex + 1;
21269
+ this.state.base = elementIndex;
21270
+ this.state.position = "after";
21268
21271
  }
21269
21272
  else {
21270
21273
  this.state.draggerLinePosition = startDimensions.start;
@@ -21445,6 +21448,7 @@ class ColResizer extends AbstractResizer {
21445
21448
  dimension: "COL",
21446
21449
  base: this.state.base,
21447
21450
  elements,
21451
+ position: this.state.position,
21448
21452
  });
21449
21453
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21450
21454
  this.env.raiseError(MergeErrorMessage);
@@ -21617,6 +21621,7 @@ class RowResizer extends AbstractResizer {
21617
21621
  dimension: "ROW",
21618
21622
  base: this.state.base,
21619
21623
  elements,
21624
+ position: this.state.position,
21620
21625
  });
21621
21626
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21622
21627
  this.env.raiseError(MergeErrorMessage);
@@ -21725,8 +21730,8 @@ function useWheelHandler(handler) {
21725
21730
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
21726
21731
  }
21727
21732
  const onMouseWheel = (ev) => {
21728
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
21729
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
21733
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
21734
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
21730
21735
  handler(deltaX, deltaY);
21731
21736
  };
21732
21737
  return onMouseWheel;
@@ -24314,7 +24319,7 @@ const machine = {
24314
24319
  SPACE: goTo(State.RightRef),
24315
24320
  NUMBER: goTo(State.Found),
24316
24321
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24317
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
24322
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
24318
24323
  },
24319
24324
  [State.RightColumnRef]: {
24320
24325
  SPACE: goTo(State.RightColumnRef),
@@ -24325,6 +24330,7 @@ const machine = {
24325
24330
  SPACE: goTo(State.RightRowRef),
24326
24331
  NUMBER: goTo(State.Found),
24327
24332
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24333
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
24328
24334
  },
24329
24335
  [State.Found]: {},
24330
24336
  };
@@ -30927,7 +30933,7 @@ class SheetPlugin extends CorePlugin {
30927
30933
  const elements = cmd.dimension === "COL"
30928
30934
  ? this.getNumberCols(cmd.sheetId)
30929
30935
  : this.getNumberRows(cmd.sheetId);
30930
- if (cmd.base < 0 || cmd.base > elements) {
30936
+ if (cmd.base < 0 || cmd.base >= elements) {
30931
30937
  return 86 /* CommandResult.InvalidHeaderIndex */;
30932
30938
  }
30933
30939
  else if (cmd.quantity <= 0) {
@@ -34092,24 +34098,27 @@ class AutofillPlugin extends UIPlugin {
34092
34098
  * autofiller
34093
34099
  */
34094
34100
  autofillAuto() {
34101
+ var _a, _b;
34095
34102
  const zone = this.getters.getSelectedZone();
34096
34103
  const sheetId = this.getters.getActiveSheetId();
34097
34104
  let col = zone.left;
34098
34105
  let row = zone.bottom;
34099
34106
  if (col > 0) {
34100
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34101
- while (left.type !== CellValueType.empty) {
34107
+ let leftPosition = { sheetId, col: col - 1, row };
34108
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
34109
+ ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
34102
34110
  row += 1;
34103
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34111
+ leftPosition = { sheetId, col: col - 1, row };
34104
34112
  }
34105
34113
  }
34106
34114
  if (row === zone.bottom) {
34107
34115
  col = zone.right;
34108
34116
  if (col <= this.getters.getNumberCols(sheetId)) {
34109
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34110
- while (right.type !== CellValueType.empty) {
34117
+ let rightPosition = { sheetId, col: col + 1, row };
34118
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
34119
+ ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
34111
34120
  row += 1;
34112
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34121
+ rightPosition = { sheetId, col: col + 1, row };
34113
34122
  }
34114
34123
  }
34115
34124
  }
@@ -38427,6 +38436,10 @@ function setXcToReferenceType(xc, referenceType) {
38427
38436
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38428
38437
  case "colrow":
38429
38438
  indexOfNumber = xc.search(/[0-9]/);
38439
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
38440
+ // no row number (eg. A) or no column (eg. 1)
38441
+ return "$" + xc;
38442
+ }
38430
38443
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38431
38444
  return "$" + xc;
38432
38445
  case "none":
@@ -39568,7 +39581,7 @@ class GridSelectionPlugin extends UIPlugin {
39568
39581
  sheetId: cmd.sheetId,
39569
39582
  base: cmd.base,
39570
39583
  quantity: thickness,
39571
- position: "before",
39584
+ position: cmd.position,
39572
39585
  });
39573
39586
  const isCol = cmd.dimension === "COL";
39574
39587
  const start = cmd.elements[0];
@@ -39585,12 +39598,13 @@ class GridSelectionPlugin extends UIPlugin {
39585
39598
  },
39586
39599
  ];
39587
39600
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39601
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
39588
39602
  const pasteTarget = [
39589
39603
  {
39590
- left: isCol ? cmd.base : 0,
39591
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39592
- top: !isCol ? cmd.base : 0,
39593
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39604
+ left: isCol ? base : 0,
39605
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39606
+ top: !isCol ? base : 0,
39607
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39594
39608
  },
39595
39609
  ];
39596
39610
  state.paste(pasteTarget, { selectTarget: true });
@@ -39627,6 +39641,11 @@ class GridSelectionPlugin extends UIPlugin {
39627
39641
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
39628
39642
  return 2 /* CommandResult.WillRemoveExistingMerge */;
39629
39643
  }
39644
+ const headers = [cmd.base, ...cmd.elements];
39645
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
39646
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
39647
+ return 86 /* CommandResult.InvalidHeaderIndex */;
39648
+ }
39630
39649
  return 0 /* CommandResult.Success */;
39631
39650
  }
39632
39651
  //-------------------------------------------
@@ -45540,6 +45559,6 @@ function addFunction(functionName, functionDescription) {
45540
45559
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
45541
45560
 
45542
45561
 
45543
- __info__.version = '16.2.23';
45544
- __info__.date = '2023-11-24T13:11:02.651Z';
45545
- __info__.hash = '3c723d3';
45562
+ __info__.version = '16.2.24';
45563
+ __info__.date = '2023-12-05T09:37:14.992Z';
45564
+ __info__.hash = '7b1a35c';
@@ -1363,8 +1363,10 @@
1363
1363
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
1364
1364
  // Same as above, but matches the exact string (nothing before or after)
1365
1365
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
1366
- /** Reference of a column header (eg. A, AB) */
1367
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
1366
+ /** Reference of a column header (eg. A, AB, $A) */
1367
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
1368
+ /** Reference of a row header (eg. 1, $1) */
1369
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
1368
1370
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
1369
1371
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
1370
1372
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -1394,6 +1396,9 @@
1394
1396
  function isColHeader(str) {
1395
1397
  return colHeader.test(str);
1396
1398
  }
1399
+ function isRowHeader(str) {
1400
+ return rowHeader.test(str);
1401
+ }
1397
1402
  /**
1398
1403
  * Return true if the given xc is the reference of a single cell,
1399
1404
  * without any specified sheet (e.g. A1)
@@ -2183,18 +2188,10 @@
2183
2188
  if (isFullCol) {
2184
2189
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2185
2190
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2186
- if (zone.left === zone.right) {
2187
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2188
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2189
- }
2190
2191
  }
2191
2192
  if (isFullRow) {
2192
2193
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
2193
2194
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
2194
- if (zone.top === zone.bottom) {
2195
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2196
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
2197
- }
2198
2195
  }
2199
2196
  return parts;
2200
2197
  }
@@ -5093,6 +5090,9 @@
5093
5090
  }
5094
5091
  function getOpenedMenus() {
5095
5092
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5093
+ }
5094
+ function isMacOS() {
5095
+ return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
5096
5096
  }
5097
5097
 
5098
5098
  /**
@@ -21136,6 +21136,7 @@
21136
21136
  draggerShadowThickness: 0,
21137
21137
  delta: 0,
21138
21138
  base: 0,
21139
+ position: "before",
21139
21140
  });
21140
21141
  }
21141
21142
  _computeHandleDisplay(ev) {
@@ -21261,11 +21262,13 @@
21261
21262
  this.state.draggerLinePosition = dimensions.start;
21262
21263
  this.state.draggerShadowPosition = dimensions.start;
21263
21264
  this.state.base = elementIndex;
21265
+ this.state.position = "before";
21264
21266
  }
21265
21267
  else if (this._getSelectedZoneEnd() < elementIndex) {
21266
21268
  this.state.draggerLinePosition = dimensions.end;
21267
21269
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
21268
- this.state.base = elementIndex + 1;
21270
+ this.state.base = elementIndex;
21271
+ this.state.position = "after";
21269
21272
  }
21270
21273
  else {
21271
21274
  this.state.draggerLinePosition = startDimensions.start;
@@ -21446,6 +21449,7 @@
21446
21449
  dimension: "COL",
21447
21450
  base: this.state.base,
21448
21451
  elements,
21452
+ position: this.state.position,
21449
21453
  });
21450
21454
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21451
21455
  this.env.raiseError(MergeErrorMessage);
@@ -21618,6 +21622,7 @@
21618
21622
  dimension: "ROW",
21619
21623
  base: this.state.base,
21620
21624
  elements,
21625
+ position: this.state.position,
21621
21626
  });
21622
21627
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21623
21628
  this.env.raiseError(MergeErrorMessage);
@@ -21726,8 +21731,8 @@
21726
21731
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
21727
21732
  }
21728
21733
  const onMouseWheel = (ev) => {
21729
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
21730
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
21734
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
21735
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
21731
21736
  handler(deltaX, deltaY);
21732
21737
  };
21733
21738
  return onMouseWheel;
@@ -24315,7 +24320,7 @@
24315
24320
  SPACE: goTo(State.RightRef),
24316
24321
  NUMBER: goTo(State.Found),
24317
24322
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24318
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
24323
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
24319
24324
  },
24320
24325
  [State.RightColumnRef]: {
24321
24326
  SPACE: goTo(State.RightColumnRef),
@@ -24326,6 +24331,7 @@
24326
24331
  SPACE: goTo(State.RightRowRef),
24327
24332
  NUMBER: goTo(State.Found),
24328
24333
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24334
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
24329
24335
  },
24330
24336
  [State.Found]: {},
24331
24337
  };
@@ -30928,7 +30934,7 @@
30928
30934
  const elements = cmd.dimension === "COL"
30929
30935
  ? this.getNumberCols(cmd.sheetId)
30930
30936
  : this.getNumberRows(cmd.sheetId);
30931
- if (cmd.base < 0 || cmd.base > elements) {
30937
+ if (cmd.base < 0 || cmd.base >= elements) {
30932
30938
  return 86 /* CommandResult.InvalidHeaderIndex */;
30933
30939
  }
30934
30940
  else if (cmd.quantity <= 0) {
@@ -34093,24 +34099,27 @@
34093
34099
  * autofiller
34094
34100
  */
34095
34101
  autofillAuto() {
34102
+ var _a, _b;
34096
34103
  const zone = this.getters.getSelectedZone();
34097
34104
  const sheetId = this.getters.getActiveSheetId();
34098
34105
  let col = zone.left;
34099
34106
  let row = zone.bottom;
34100
34107
  if (col > 0) {
34101
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34102
- while (left.type !== CellValueType.empty) {
34108
+ let leftPosition = { sheetId, col: col - 1, row };
34109
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
34110
+ ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
34103
34111
  row += 1;
34104
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34112
+ leftPosition = { sheetId, col: col - 1, row };
34105
34113
  }
34106
34114
  }
34107
34115
  if (row === zone.bottom) {
34108
34116
  col = zone.right;
34109
34117
  if (col <= this.getters.getNumberCols(sheetId)) {
34110
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34111
- while (right.type !== CellValueType.empty) {
34118
+ let rightPosition = { sheetId, col: col + 1, row };
34119
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
34120
+ ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
34112
34121
  row += 1;
34113
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34122
+ rightPosition = { sheetId, col: col + 1, row };
34114
34123
  }
34115
34124
  }
34116
34125
  }
@@ -38428,6 +38437,10 @@
38428
38437
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38429
38438
  case "colrow":
38430
38439
  indexOfNumber = xc.search(/[0-9]/);
38440
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
38441
+ // no row number (eg. A) or no column (eg. 1)
38442
+ return "$" + xc;
38443
+ }
38431
38444
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38432
38445
  return "$" + xc;
38433
38446
  case "none":
@@ -39569,7 +39582,7 @@
39569
39582
  sheetId: cmd.sheetId,
39570
39583
  base: cmd.base,
39571
39584
  quantity: thickness,
39572
- position: "before",
39585
+ position: cmd.position,
39573
39586
  });
39574
39587
  const isCol = cmd.dimension === "COL";
39575
39588
  const start = cmd.elements[0];
@@ -39586,12 +39599,13 @@
39586
39599
  },
39587
39600
  ];
39588
39601
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39602
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
39589
39603
  const pasteTarget = [
39590
39604
  {
39591
- left: isCol ? cmd.base : 0,
39592
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39593
- top: !isCol ? cmd.base : 0,
39594
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39605
+ left: isCol ? base : 0,
39606
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39607
+ top: !isCol ? base : 0,
39608
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39595
39609
  },
39596
39610
  ];
39597
39611
  state.paste(pasteTarget, { selectTarget: true });
@@ -39628,6 +39642,11 @@
39628
39642
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
39629
39643
  return 2 /* CommandResult.WillRemoveExistingMerge */;
39630
39644
  }
39645
+ const headers = [cmd.base, ...cmd.elements];
39646
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
39647
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
39648
+ return 86 /* CommandResult.InvalidHeaderIndex */;
39649
+ }
39631
39650
  return 0 /* CommandResult.Success */;
39632
39651
  }
39633
39652
  //-------------------------------------------
@@ -45571,9 +45590,9 @@
45571
45590
  Object.defineProperty(exports, '__esModule', { value: true });
45572
45591
 
45573
45592
 
45574
- __info__.version = '16.2.23';
45575
- __info__.date = '2023-11-24T13:11:02.651Z';
45576
- __info__.hash = '3c723d3';
45593
+ __info__.version = '16.2.24';
45594
+ __info__.date = '2023-12-05T09:37:14.992Z';
45595
+ __info__.hash = '7b1a35c';
45577
45596
 
45578
45597
 
45579
45598
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);