@odoo/o-spreadsheet 18.2.7 → 18.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.2.7
6
- * @date 2025-04-14T17:19:31.011Z
7
- * @hash e187958
5
+ * @version 18.2.9
6
+ * @date 2025-04-25T08:06:52.677Z
7
+ * @hash 3e88645
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -3842,11 +3842,13 @@
3842
3842
  NullError: "#NULL!",
3843
3843
  };
3844
3844
  const errorTypes = new Set(Object.values(CellErrorType));
3845
- class EvaluationError extends Error {
3845
+ class EvaluationError {
3846
+ message;
3846
3847
  value;
3847
3848
  constructor(message = _t("Error"), value = CellErrorType.GenericError) {
3848
- super(message);
3849
+ this.message = message;
3849
3850
  this.value = value;
3851
+ this.message = message.toString();
3850
3852
  }
3851
3853
  }
3852
3854
  class BadExpressionError extends EvaluationError {
@@ -6899,6 +6901,12 @@
6899
6901
  }
6900
6902
  return null;
6901
6903
  }
6904
+ /**
6905
+ - \p{L} is for any letter (from any language)
6906
+ - \p{N} is for any number
6907
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6908
+ */
6909
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6902
6910
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6903
6911
  /**
6904
6912
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6939,7 +6947,8 @@
6939
6947
  };
6940
6948
  }
6941
6949
  }
6942
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6950
+ while (chars.current &&
6951
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6943
6952
  result += chars.shift();
6944
6953
  }
6945
6954
  if (result.length) {
@@ -9246,7 +9255,7 @@
9246
9255
  if (executed.type === "ADD_COLUMNS_ROWS") {
9247
9256
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9248
9257
  }
9249
- return { ...zone };
9258
+ return zone;
9250
9259
  }
9251
9260
  function transformRangeData(range, executed) {
9252
9261
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -13744,7 +13753,7 @@ stores.inject(MyMetaStore, storeInstance);
13744
13753
  }
13745
13754
  }
13746
13755
  if (!found) {
13747
- throw new NotAvailableError(_t("Value not found in the given data."));
13756
+ return new NotAvailableError(_t("Value not found in the given data."));
13748
13757
  }
13749
13758
  return rank;
13750
13759
  },
@@ -15484,7 +15493,7 @@ stores.inject(MyMetaStore, storeInstance);
15484
15493
  result.push(row.data);
15485
15494
  }
15486
15495
  if (!result.length)
15487
- throw new EvaluationError(_t("No unique values found"));
15496
+ return new EvaluationError(_t("No unique values found"));
15488
15497
  return _byColumn ? result : transposeMatrix(result);
15489
15498
  },
15490
15499
  isExported: true,
@@ -19263,7 +19272,7 @@ stores.inject(MyMetaStore, storeInstance);
19263
19272
  }
19264
19273
  const _cellReference = cellReference?.value;
19265
19274
  if (!_cellReference) {
19266
- throw new Error("In this context, the function OFFSET needs to have a cell or range in parameter.");
19275
+ return new EvaluationError("In this context, the function OFFSET needs to have a cell or range in parameter.");
19267
19276
  }
19268
19277
  const zone = toZone(_cellReference);
19269
19278
  let offsetHeight = zone.bottom - zone.top + 1;
@@ -33637,6 +33646,12 @@ stores.inject(MyMetaStore, storeInstance);
33637
33646
  function isCtrlKey(ev) {
33638
33647
  return isMacOS() ? ev.metaKey : ev.ctrlKey;
33639
33648
  }
33649
+ /**
33650
+ * Detects if the current browser is Firefox
33651
+ */
33652
+ function isBrowserFirefox() {
33653
+ return /Firefox/i.test(navigator.userAgent);
33654
+ }
33640
33655
 
33641
33656
  /**
33642
33657
  * Repeatedly calls a callback function with a time delay between calls.
@@ -39103,7 +39118,7 @@ stores.inject(MyMetaStore, storeInstance);
39103
39118
  }
39104
39119
  setHexColor(ev) {
39105
39120
  // only support HEX code input
39106
- const val = ev.target.value.slice(0, 7);
39121
+ const val = ev.target.value.replace("##", "#").slice(0, 7);
39107
39122
  this.state.customHexColor = val;
39108
39123
  if (!isColorValid(val)) ;
39109
39124
  else {
@@ -50432,39 +50447,6 @@ stores.inject(MyMetaStore, storeInstance);
50432
50447
  }
50433
50448
  return hoveredPosition;
50434
50449
  }
50435
- function useTouchMove(gridRef, handler, canMoveUp) {
50436
- let x = null;
50437
- let y = null;
50438
- function onTouchStart(ev) {
50439
- if (ev.touches.length !== 1)
50440
- return;
50441
- x = ev.touches[0].clientX;
50442
- y = ev.touches[0].clientY;
50443
- }
50444
- function onTouchEnd() {
50445
- x = null;
50446
- y = null;
50447
- }
50448
- function onTouchMove(ev) {
50449
- if (ev.touches.length !== 1)
50450
- return;
50451
- // On mobile browsers, swiping down is often associated with "pull to refresh".
50452
- // We only want this behavior if the grid is already at the top.
50453
- // Otherwise we only want to move the canvas up, without triggering any refresh.
50454
- if (canMoveUp()) {
50455
- ev.preventDefault();
50456
- ev.stopPropagation();
50457
- }
50458
- const currentX = ev.touches[0].clientX;
50459
- const currentY = ev.touches[0].clientY;
50460
- handler(x - currentX, y - currentY);
50461
- x = currentX;
50462
- y = currentY;
50463
- }
50464
- useRefListener(gridRef, "touchstart", onTouchStart);
50465
- useRefListener(gridRef, "touchend", onTouchEnd);
50466
- useRefListener(gridRef, "touchmove", onTouchMove);
50467
- }
50468
50450
  class GridOverlay extends owl.Component {
50469
50451
  static template = "o-spreadsheet-GridOverlay";
50470
50452
  static props = {
@@ -50512,10 +50494,6 @@ stores.inject(MyMetaStore, storeInstance);
50512
50494
  owl.onWillUnmount(() => {
50513
50495
  resizeObserver.disconnect();
50514
50496
  });
50515
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
50516
- const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
50517
- return scrollY > 0;
50518
- });
50519
50497
  this.cellPopovers = useStore(CellPopoverStore);
50520
50498
  this.paintFormatStore = useStore(PaintFormatStore);
50521
50499
  }
@@ -51987,6 +51965,73 @@ stores.inject(MyMetaStore, storeInstance);
51987
51965
  }
51988
51966
  }
51989
51967
 
51968
+ const friction = 0.95;
51969
+ const verticalScrollFactor = 1;
51970
+ const horizontalScrollFactor = 1;
51971
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
51972
+ let lastX = 0;
51973
+ let lastY = 0;
51974
+ let velocityX = 0;
51975
+ let velocityY = 0;
51976
+ let isMouseDown = false;
51977
+ let lastTime = 0;
51978
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
51979
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
51980
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
51981
+ function onTouchStart(event) {
51982
+ isMouseDown = true;
51983
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
51984
+ velocityX = 0;
51985
+ velocityY = 0;
51986
+ }
51987
+ function onTouchMove(event) {
51988
+ if (!isMouseDown)
51989
+ return;
51990
+ const currentTime = Date.now();
51991
+ const { clientX, clientY } = event.touches[0];
51992
+ let deltaX = lastX - clientX;
51993
+ let deltaY = lastY - clientY;
51994
+ const elapsedTime = currentTime - lastTime;
51995
+ velocityX = deltaX / elapsedTime;
51996
+ velocityY = deltaY / elapsedTime;
51997
+ lastX = clientX;
51998
+ lastY = clientY;
51999
+ lastTime = currentTime;
52000
+ if (canMoveUp()) {
52001
+ if (event.cancelable) {
52002
+ event.preventDefault();
52003
+ }
52004
+ event.stopPropagation();
52005
+ }
52006
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52007
+ }
52008
+ function onTouchEnd(ev) {
52009
+ isMouseDown = false;
52010
+ lastX = lastY = 0;
52011
+ requestAnimationFrame(scroll);
52012
+ }
52013
+ function scroll() {
52014
+ if (Math.abs(velocityX) < 0.05) {
52015
+ velocityX = 0;
52016
+ }
52017
+ if (Math.abs(velocityY) < 0.05) {
52018
+ velocityY = 0;
52019
+ }
52020
+ if (!velocityX && !velocityY) {
52021
+ return;
52022
+ }
52023
+ const currentTime = Date.now();
52024
+ const elapsedTime = Math.abs(currentTime - lastTime);
52025
+ const deltaX = velocityX * elapsedTime;
52026
+ const deltaY = velocityY * elapsedTime;
52027
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
52028
+ lastTime = currentTime;
52029
+ velocityX *= friction;
52030
+ velocityY *= friction;
52031
+ requestAnimationFrame(scroll);
52032
+ }
52033
+ }
52034
+
51990
52035
  function useWheelHandler(handler) {
51991
52036
  function normalize(val, deltaMode) {
51992
52037
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -52327,7 +52372,7 @@ stores.inject(MyMetaStore, storeInstance);
52327
52372
  left: `${this.props.leftOffset + x}px`,
52328
52373
  bottom: "0px",
52329
52374
  height: `${SCROLLBAR_WIDTH}px`,
52330
- right: `0px`,
52375
+ right: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52331
52376
  };
52332
52377
  }
52333
52378
  onScroll(offset) {
@@ -52372,7 +52417,7 @@ stores.inject(MyMetaStore, storeInstance);
52372
52417
  top: `${this.props.topOffset + y}px`,
52373
52418
  right: "0px",
52374
52419
  width: `${SCROLLBAR_WIDTH}px`,
52375
- bottom: `0px`,
52420
+ bottom: isBrowserFirefox() ? `${SCROLLBAR_WIDTH}px` : "0",
52376
52421
  };
52377
52422
  }
52378
52423
  onScroll(offset) {
@@ -52608,6 +52653,10 @@ stores.inject(MyMetaStore, storeInstance);
52608
52653
  this.DOMFocusableElementStore.focusableElement?.focus();
52609
52654
  }
52610
52655
  }, () => [this.sidePanel.isOpen]);
52656
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
52657
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
52658
+ return scrollY > 0;
52659
+ });
52611
52660
  }
52612
52661
  onCellHovered({ col, row }) {
52613
52662
  this.hoveredCell.hover({ col, row });
@@ -62287,6 +62336,16 @@ stores.inject(MyMetaStore, storeInstance);
62287
62336
  }
62288
62337
  return values;
62289
62338
  }
62339
+ else if (rowDomain.length === this.definition.rows.length &&
62340
+ colDomain.length &&
62341
+ colDomain.length < this.definition.columns.length) {
62342
+ const colSubTree = this.getSubTreeMatchingDomain(table.getColTree(), colDomain);
62343
+ const domains = this.treeToLeafDomains(colSubTree, colDomain);
62344
+ for (const domain of domains) {
62345
+ values.push(this._getPivotCellValueAndFormat(measure.id, rowDomain.concat(domain)));
62346
+ }
62347
+ return values;
62348
+ }
62290
62349
  else {
62291
62350
  const tree = table.getRowTree();
62292
62351
  const subTree = this.getSubTreeMatchingDomain(tree, rowDomain);
@@ -63853,10 +63912,8 @@ stores.inject(MyMetaStore, storeInstance);
63853
63912
  }
63854
63913
  const target = [];
63855
63914
  for (const zone1 of toTransform.target) {
63856
- for (const zone2 of executed.target) {
63857
- if (!overlap(zone1, zone2)) {
63858
- target.push({ ...zone1 });
63859
- }
63915
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
63916
+ target.push(zone1);
63860
63917
  }
63861
63918
  }
63862
63919
  if (target.length) {
@@ -67988,24 +68045,14 @@ stores.inject(MyMetaStore, storeInstance);
67988
68045
  first: this.boundaries.top,
67989
68046
  last: this.boundaries.bottom,
67990
68047
  });
67991
- const { end: lastColEnd, size: lastColSize } = this.getters.getColDimensions(this.sheetId, lastCol);
67992
- const { end: lastRowEnd, size: lastRowSize } = this.getters.getRowDimensions(this.sheetId, lastRow);
67993
- const leftColIndex = this.searchHeaderIndex("COL", lastColEnd - this.viewportWidth, 0);
67994
- const leftColSize = this.getters.getColSize(this.sheetId, leftColIndex);
67995
- const leftRowIndex = this.searchHeaderIndex("ROW", lastRowEnd - this.viewportHeight, 0);
67996
- const topRowSize = this.getters.getRowSize(this.sheetId, leftRowIndex);
68048
+ const { end: lastColEnd } = this.getters.getColDimensions(this.sheetId, lastCol);
68049
+ const { end: lastRowEnd } = this.getters.getRowDimensions(this.sheetId, lastRow);
67997
68050
  let width = lastColEnd - this.offsetCorrectionX;
67998
68051
  if (this.canScrollHorizontally) {
67999
- width += Math.max(DEFAULT_CELL_WIDTH, // leave some minimal space to let the user know they scrolled all the way
68000
- Math.min(leftColSize, this.viewportWidth - lastColSize) // Add pixels that allows the snapping at maximum horizontal scroll
68001
- );
68002
68052
  width = Math.max(width, this.viewportWidth); // if the viewport grid size is smaller than its client width, return client width
68003
68053
  }
68004
68054
  let height = lastRowEnd - this.offsetCorrectionY;
68005
68055
  if (this.canScrollVertically) {
68006
- height += Math.max(DEFAULT_CELL_HEIGHT + 5, // leave some space to let the user know they scrolled all the way
68007
- Math.min(topRowSize, this.viewportHeight - lastRowSize) // Add pixels that allows the snapping at maximum vertical scroll
68008
- );
68009
68056
  height = Math.max(height, this.viewportHeight); // if the viewport grid size is smaller than its client height, return client height
68010
68057
  if (lastRowEnd + FOOTER_HEIGHT > height && !this.getters.isReadonly()) {
68011
68058
  height += FOOTER_HEIGHT;
@@ -68570,8 +68617,8 @@ stores.inject(MyMetaStore, storeInstance);
68570
68617
  const { width, height } = this.getMainViewportRect();
68571
68618
  const viewport = this.getMainInternalViewport(sheetId);
68572
68619
  return {
68573
- maxOffsetX: Math.max(0, width - viewport.viewportWidth + 1),
68574
- maxOffsetY: Math.max(0, height - viewport.viewportHeight + 1),
68620
+ maxOffsetX: Math.max(0, width - viewport.viewportWidth),
68621
+ maxOffsetY: Math.max(0, height - viewport.viewportHeight),
68575
68622
  };
68576
68623
  }
68577
68624
  getColRowOffsetInViewport(dimension, referenceHeaderIndex, targetHeaderIndex) {
@@ -70093,6 +70140,10 @@ stores.inject(MyMetaStore, storeInstance);
70093
70140
  this.hoveredCell.clear();
70094
70141
  });
70095
70142
  this.cellPopovers = useStore(CellPopoverStore);
70143
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
70144
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
70145
+ return scrollY > 0;
70146
+ });
70096
70147
  }
70097
70148
  onCellHovered({ col, row }) {
70098
70149
  this.hoveredCell.hover({ col, row });
@@ -71483,6 +71534,7 @@ stores.inject(MyMetaStore, storeInstance);
71483
71534
  > canvas {
71484
71535
  box-sizing: content-box;
71485
71536
  border-bottom: 1px solid #e2e3e3;
71537
+ border-right: 1px solid #e2e3e3;
71486
71538
  }
71487
71539
 
71488
71540
  .o-grid-overlay {
@@ -76189,9 +76241,9 @@ stores.inject(MyMetaStore, storeInstance);
76189
76241
  exports.tokenize = tokenize;
76190
76242
 
76191
76243
 
76192
- __info__.version = "18.2.7";
76193
- __info__.date = "2025-04-14T17:19:31.011Z";
76194
- __info__.hash = "e187958";
76244
+ __info__.version = "18.2.9";
76245
+ __info__.date = "2025-04-25T08:06:52.677Z";
76246
+ __info__.hash = "3e88645";
76195
76247
 
76196
76248
 
76197
76249
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);