@odoo/o-spreadsheet 16.2.23 → 16.2.26

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.
@@ -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
  }
@@ -5048,6 +5045,7 @@
5048
5045
  },
5049
5046
  };
5050
5047
 
5048
+ const macRegex = /Mac/i;
5051
5049
  /**
5052
5050
  * Return true if the event was triggered from
5053
5051
  * a child element.
@@ -5093,6 +5091,17 @@
5093
5091
  }
5094
5092
  function getOpenedMenus() {
5095
5093
  return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
5094
+ }
5095
+ function isMacOS() {
5096
+ return Boolean(macRegex.test(navigator.userAgent));
5097
+ }
5098
+ /**
5099
+ * @param {KeyboardEvent | MouseEvent} ev
5100
+ * @returns Returns true if the event was triggered with the "ctrl" modifier pressed.
5101
+ * On Mac, this is the "meta" or "command" key.
5102
+ */
5103
+ function isCtrlKey(ev) {
5104
+ return isMacOS() ? ev.metaKey : ev.ctrlKey;
5096
5105
  }
5097
5106
 
5098
5107
  /**
@@ -16710,10 +16719,10 @@
16710
16719
  function updateSelectionWithArrowKeys(ev, selection) {
16711
16720
  const direction = arrowMap[ev.key];
16712
16721
  if (ev.shiftKey) {
16713
- selection.resizeAnchorZone(direction, ev.ctrlKey ? "end" : 1);
16722
+ selection.resizeAnchorZone(direction, isCtrlKey(ev) ? "end" : 1);
16714
16723
  }
16715
16724
  else {
16716
- selection.moveAnchorCell(direction, ev.ctrlKey ? "end" : 1);
16725
+ selection.moveAnchorCell(direction, isCtrlKey(ev) ? "end" : 1);
16717
16726
  }
16718
16727
  }
16719
16728
 
@@ -21048,7 +21057,10 @@
21048
21057
  return;
21049
21058
  }
21050
21059
  const [col, row] = this.getCartesianCoordinates(ev);
21051
- this.props.onCellClicked(col, row, { shiftKey: ev.shiftKey, ctrlKey: ev.ctrlKey });
21060
+ this.props.onCellClicked(col, row, {
21061
+ expandZone: ev.shiftKey,
21062
+ addZone: isCtrlKey(ev),
21063
+ });
21052
21064
  }
21053
21065
  onDoubleClick(ev) {
21054
21066
  const [col, row] = this.getCartesianCoordinates(ev);
@@ -21136,6 +21148,7 @@
21136
21148
  draggerShadowThickness: 0,
21137
21149
  delta: 0,
21138
21150
  base: 0,
21151
+ position: "before",
21139
21152
  });
21140
21153
  }
21141
21154
  _computeHandleDisplay(ev) {
@@ -21261,11 +21274,13 @@
21261
21274
  this.state.draggerLinePosition = dimensions.start;
21262
21275
  this.state.draggerShadowPosition = dimensions.start;
21263
21276
  this.state.base = elementIndex;
21277
+ this.state.position = "before";
21264
21278
  }
21265
21279
  else if (this._getSelectedZoneEnd() < elementIndex) {
21266
21280
  this.state.draggerLinePosition = dimensions.end;
21267
21281
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
21268
- this.state.base = elementIndex + 1;
21282
+ this.state.base = elementIndex;
21283
+ this.state.position = "after";
21269
21284
  }
21270
21285
  else {
21271
21286
  this.state.draggerLinePosition = startDimensions.start;
@@ -21289,7 +21304,7 @@
21289
21304
  this._increaseSelection(index);
21290
21305
  }
21291
21306
  else {
21292
- this._selectElement(index, ev.ctrlKey);
21307
+ this._selectElement(index, isCtrlKey(ev));
21293
21308
  }
21294
21309
  this.lastSelectedElementIndex = index;
21295
21310
  const mouseMoveSelect = (col, row) => {
@@ -21302,7 +21317,7 @@
21302
21317
  const mouseUpSelect = () => {
21303
21318
  this.state.isSelecting = false;
21304
21319
  this.lastSelectedElementIndex = null;
21305
- this.env.model.dispatch(ev.ctrlKey ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
21320
+ this.env.model.dispatch(isCtrlKey(ev) ? "PREPARE_SELECTION_INPUT_EXPANSION" : "STOP_SELECTION_INPUT");
21306
21321
  this._computeGrabDisplay(ev);
21307
21322
  };
21308
21323
  dragAndDropBeyondTheViewport(this.env, mouseMoveSelect, mouseUpSelect);
@@ -21446,13 +21461,14 @@
21446
21461
  dimension: "COL",
21447
21462
  base: this.state.base,
21448
21463
  elements,
21464
+ position: this.state.position,
21449
21465
  });
21450
21466
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21451
21467
  this.env.raiseError(MergeErrorMessage);
21452
21468
  }
21453
21469
  }
21454
- _selectElement(index, ctrlKey) {
21455
- this.env.model.selection.selectColumn(index, ctrlKey ? "newAnchor" : "overrideSelection");
21470
+ _selectElement(index, addDistinctHeader) {
21471
+ this.env.model.selection.selectColumn(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
21456
21472
  }
21457
21473
  _increaseSelection(index) {
21458
21474
  this.env.model.selection.selectColumn(index, "updateAnchor");
@@ -21618,13 +21634,14 @@
21618
21634
  dimension: "ROW",
21619
21635
  base: this.state.base,
21620
21636
  elements,
21637
+ position: this.state.position,
21621
21638
  });
21622
21639
  if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
21623
21640
  this.env.raiseError(MergeErrorMessage);
21624
21641
  }
21625
21642
  }
21626
- _selectElement(index, ctrlKey) {
21627
- this.env.model.selection.selectRow(index, ctrlKey ? "newAnchor" : "overrideSelection");
21643
+ _selectElement(index, addDistinctHeader) {
21644
+ this.env.model.selection.selectRow(index, addDistinctHeader ? "newAnchor" : "overrideSelection");
21628
21645
  }
21629
21646
  _increaseSelection(index) {
21630
21647
  this.env.model.selection.selectRow(index, "updateAnchor");
@@ -21726,8 +21743,8 @@
21726
21743
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
21727
21744
  }
21728
21745
  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);
21746
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
21747
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
21731
21748
  handler(deltaX, deltaY);
21732
21749
  };
21733
21750
  return onMouseWheel;
@@ -22371,8 +22388,8 @@
22371
22388
  // ---------------------------------------------------------------------------
22372
22389
  // Zone selection with mouse
22373
22390
  // ---------------------------------------------------------------------------
22374
- onCellClicked(col, row, { ctrlKey, shiftKey }) {
22375
- if (ctrlKey) {
22391
+ onCellClicked(col, row, { addZone, expandZone }) {
22392
+ if (addZone) {
22376
22393
  this.env.model.dispatch("PREPARE_SELECTION_INPUT_EXPANSION");
22377
22394
  }
22378
22395
  if (this.env.model.getters.hasOpenedPopover()) {
@@ -22381,10 +22398,10 @@
22381
22398
  if (this.env.model.getters.getEditionMode() === "editing") {
22382
22399
  this.env.model.dispatch("STOP_EDITION");
22383
22400
  }
22384
- if (shiftKey) {
22401
+ if (expandZone) {
22385
22402
  this.env.model.selection.setAnchorCorner(col, row);
22386
22403
  }
22387
- else if (ctrlKey) {
22404
+ else if (addZone) {
22388
22405
  this.env.model.selection.addCellToSelection(col, row);
22389
22406
  }
22390
22407
  else {
@@ -22446,9 +22463,7 @@
22446
22463
  return;
22447
22464
  }
22448
22465
  let keyDownString = "";
22449
- if (ev.ctrlKey)
22450
- keyDownString += "CTRL+";
22451
- if (ev.metaKey)
22466
+ if (isCtrlKey(ev))
22452
22467
  keyDownString += "CTRL+";
22453
22468
  if (ev.altKey)
22454
22469
  keyDownString += "ALT+";
@@ -24315,7 +24330,7 @@
24315
24330
  SPACE: goTo(State.RightRef),
24316
24331
  NUMBER: goTo(State.Found),
24317
24332
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24318
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
24333
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
24319
24334
  },
24320
24335
  [State.RightColumnRef]: {
24321
24336
  SPACE: goTo(State.RightColumnRef),
@@ -24326,6 +24341,7 @@
24326
24341
  SPACE: goTo(State.RightRowRef),
24327
24342
  NUMBER: goTo(State.Found),
24328
24343
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
24344
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
24329
24345
  },
24330
24346
  [State.Found]: {},
24331
24347
  };
@@ -30928,7 +30944,7 @@
30928
30944
  const elements = cmd.dimension === "COL"
30929
30945
  ? this.getNumberCols(cmd.sheetId)
30930
30946
  : this.getNumberRows(cmd.sheetId);
30931
- if (cmd.base < 0 || cmd.base > elements) {
30947
+ if (cmd.base < 0 || cmd.base >= elements) {
30932
30948
  return 86 /* CommandResult.InvalidHeaderIndex */;
30933
30949
  }
30934
30950
  else if (cmd.quantity <= 0) {
@@ -31965,13 +31981,18 @@
31965
31981
  // Getters
31966
31982
  // ---------------------------------------------------------------------------
31967
31983
  evaluateFormula(formulaString, sheetId = this.getters.getActiveSheetId()) {
31968
- const compiledFormula = compile(formulaString);
31969
- const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
31970
- const ranges = [];
31971
- for (let xc of compiledFormula.dependencies) {
31972
- ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
31984
+ try {
31985
+ const compiledFormula = compile(formulaString);
31986
+ const params = this.getCompilationParameters((cell) => this.getEvaluatedCell(this.getters.getCellPosition(cell.id)));
31987
+ const ranges = [];
31988
+ for (let xc of compiledFormula.dependencies) {
31989
+ ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
31990
+ }
31991
+ return compiledFormula.execute(ranges, ...params).value;
31992
+ }
31993
+ catch (error) {
31994
+ return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
31973
31995
  }
31974
- return compiledFormula.execute(ranges, ...params).value;
31975
31996
  }
31976
31997
  /**
31977
31998
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -32473,39 +32494,34 @@
32473
32494
  this.computedIcons[sheetId] = {};
32474
32495
  const computedStyle = this.computedStyles[sheetId];
32475
32496
  for (let cf of this.getters.getConditionalFormats(sheetId).reverse()) {
32476
- try {
32477
- switch (cf.rule.type) {
32478
- case "ColorScaleRule":
32479
- for (let range of cf.ranges) {
32480
- this.applyColorScale(range, cf.rule);
32481
- }
32482
- break;
32483
- case "IconSetRule":
32484
- for (let range of cf.ranges) {
32485
- this.applyIcon(range, cf.rule);
32486
- }
32487
- break;
32488
- default:
32489
- for (let ref of cf.ranges) {
32490
- const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
32491
- for (let row = zone.top; row <= zone.bottom; row++) {
32492
- for (let col = zone.left; col <= zone.right; col++) {
32493
- const pr = this.rulePredicate[cf.rule.type];
32494
- let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
32495
- if (pr && pr(cell, cf.rule)) {
32496
- if (!computedStyle[col])
32497
- computedStyle[col] = [];
32498
- // we must combine all the properties of all the CF rules applied to the given cell
32499
- computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
32500
- }
32497
+ switch (cf.rule.type) {
32498
+ case "ColorScaleRule":
32499
+ for (let range of cf.ranges) {
32500
+ this.applyColorScale(range, cf.rule);
32501
+ }
32502
+ break;
32503
+ case "IconSetRule":
32504
+ for (let range of cf.ranges) {
32505
+ this.applyIcon(range, cf.rule);
32506
+ }
32507
+ break;
32508
+ default:
32509
+ for (let ref of cf.ranges) {
32510
+ const zone = this.getters.getRangeFromSheetXC(sheetId, ref).zone;
32511
+ for (let row = zone.top; row <= zone.bottom; row++) {
32512
+ for (let col = zone.left; col <= zone.right; col++) {
32513
+ const pr = this.rulePredicate[cf.rule.type];
32514
+ let cell = this.getters.getEvaluatedCell({ sheetId, col, row });
32515
+ if (pr && pr(cell, cf.rule)) {
32516
+ if (!computedStyle[col])
32517
+ computedStyle[col] = [];
32518
+ // we must combine all the properties of all the CF rules applied to the given cell
32519
+ computedStyle[col][row] = Object.assign(((_a = computedStyle[col]) === null || _a === void 0 ? void 0 : _a[row]) || {}, cf.rule.style);
32501
32520
  }
32502
32521
  }
32503
32522
  }
32504
- break;
32505
- }
32506
- }
32507
- catch (_) {
32508
- // we don't care about the errors within the evaluation of a rule
32523
+ }
32524
+ break;
32509
32525
  }
32510
32526
  }
32511
32527
  }
@@ -32530,7 +32546,7 @@
32530
32546
  return percentile(rangeValues, Number(threshold.value) / 100, true);
32531
32547
  case "formula":
32532
32548
  const value = threshold.value && this.getters.evaluateFormula(threshold.value);
32533
- return !(value instanceof Promise) ? value : null;
32549
+ return typeof value === "number" ? value : null;
32534
32550
  default:
32535
32551
  return null;
32536
32552
  }
@@ -34093,24 +34109,27 @@
34093
34109
  * autofiller
34094
34110
  */
34095
34111
  autofillAuto() {
34112
+ var _a, _b;
34096
34113
  const zone = this.getters.getSelectedZone();
34097
34114
  const sheetId = this.getters.getActiveSheetId();
34098
34115
  let col = zone.left;
34099
34116
  let row = zone.bottom;
34100
34117
  if (col > 0) {
34101
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34102
- while (left.type !== CellValueType.empty) {
34118
+ let leftPosition = { sheetId, col: col - 1, row };
34119
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
34120
+ ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
34103
34121
  row += 1;
34104
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
34122
+ leftPosition = { sheetId, col: col - 1, row };
34105
34123
  }
34106
34124
  }
34107
34125
  if (row === zone.bottom) {
34108
34126
  col = zone.right;
34109
34127
  if (col <= this.getters.getNumberCols(sheetId)) {
34110
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34111
- while (right.type !== CellValueType.empty) {
34128
+ let rightPosition = { sheetId, col: col + 1, row };
34129
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
34130
+ ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
34112
34131
  row += 1;
34113
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
34132
+ rightPosition = { sheetId, col: col + 1, row };
34114
34133
  }
34115
34134
  }
34116
34135
  }
@@ -38428,6 +38447,10 @@
38428
38447
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38429
38448
  case "colrow":
38430
38449
  indexOfNumber = xc.search(/[0-9]/);
38450
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
38451
+ // no row number (eg. A) or no column (eg. 1)
38452
+ return "$" + xc;
38453
+ }
38431
38454
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
38432
38455
  return "$" + xc;
38433
38456
  case "none":
@@ -39569,7 +39592,7 @@
39569
39592
  sheetId: cmd.sheetId,
39570
39593
  base: cmd.base,
39571
39594
  quantity: thickness,
39572
- position: "before",
39595
+ position: cmd.position,
39573
39596
  });
39574
39597
  const isCol = cmd.dimension === "COL";
39575
39598
  const start = cmd.elements[0];
@@ -39586,12 +39609,13 @@
39586
39609
  },
39587
39610
  ];
39588
39611
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
39612
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
39589
39613
  const pasteTarget = [
39590
39614
  {
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,
39615
+ left: isCol ? base : 0,
39616
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
39617
+ top: !isCol ? base : 0,
39618
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
39595
39619
  },
39596
39620
  ];
39597
39621
  state.paste(pasteTarget, { selectTarget: true });
@@ -39628,6 +39652,11 @@
39628
39652
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
39629
39653
  return 2 /* CommandResult.WillRemoveExistingMerge */;
39630
39654
  }
39655
+ const headers = [cmd.base, ...cmd.elements];
39656
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
39657
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
39658
+ return 86 /* CommandResult.InvalidHeaderIndex */;
39659
+ }
39631
39660
  return 0 /* CommandResult.Success */;
39632
39661
  }
39633
39662
  //-------------------------------------------
@@ -41865,7 +41894,7 @@
41865
41894
  }
41866
41895
  onKeydown(ev) {
41867
41896
  let keyDownString = "";
41868
- if (ev.ctrlKey || ev.metaKey) {
41897
+ if (isCtrlKey(ev)) {
41869
41898
  keyDownString += "CTRL+";
41870
41899
  }
41871
41900
  keyDownString += ev.key.toUpperCase();
@@ -45571,9 +45600,9 @@
45571
45600
  Object.defineProperty(exports, '__esModule', { value: true });
45572
45601
 
45573
45602
 
45574
- __info__.version = '16.2.23';
45575
- __info__.date = '2023-11-24T13:11:02.651Z';
45576
- __info__.hash = '3c723d3';
45603
+ __info__.version = '16.2.26';
45604
+ __info__.date = '2024-01-04T16:19:52.806Z';
45605
+ __info__.hash = 'ef51232';
45577
45606
 
45578
45607
 
45579
45608
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);