@odoo/o-spreadsheet 19.0.10 → 19.0.11

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 19.0.10
6
- * @date 2025-11-12T14:15:51.076Z
7
- * @hash 18ac688
5
+ * @version 19.0.11
6
+ * @date 2025-11-24T07:46:47.685Z
7
+ * @hash f5bdbcc
8
8
  */
9
9
 
10
10
  'use strict';
@@ -864,7 +864,7 @@ const PIVOT_TABLE_CONFIG = {
864
864
  };
865
865
  const PIVOT_INDENT = 15;
866
866
  const PIVOT_COLLAPSE_ICON_SIZE = 12;
867
- const PIVOT_MAX_NUMBER_OF_CELLS = 1e5;
867
+ const PIVOT_MAX_NUMBER_OF_CELLS = 5e5;
868
868
  const DEFAULT_CURRENCY = {
869
869
  symbol: "$",
870
870
  position: "before",
@@ -13350,7 +13350,7 @@ const SUBTOTAL = {
13350
13350
  if (!acceptHiddenCells && this.getters.isRowHiddenByUser(sheetId, row))
13351
13351
  continue;
13352
13352
  for (let col = left; col <= right; col++) {
13353
- const cell = this.getters.getCell({ sheetId, col, row });
13353
+ const cell = this.getters.getCorrespondingFormulaCell({ sheetId, col, row });
13354
13354
  if (!cell || !isSubtotalCell(cell)) {
13355
13355
  evaluatedCellToKeep.push(this.getters.getEvaluatedCell({ sheetId, col, row }));
13356
13356
  }
@@ -19346,7 +19346,7 @@ function getTokenNextReferenceType(xc) {
19346
19346
  function setXcToFixedReferenceType(xc, referenceType) {
19347
19347
  let sheetName;
19348
19348
  ({ sheetName, xc } = splitReference(xc));
19349
- sheetName = sheetName ? sheetName + "!" : "";
19349
+ sheetName = sheetName ? getCanonicalSymbolName(sheetName) + "!" : "";
19350
19350
  xc = xc.replace(/\$/g, "");
19351
19351
  const splitIndex = xc.indexOf(":");
19352
19352
  if (splitIndex >= 0) {
@@ -34525,16 +34525,12 @@ class Composer extends owl.Component {
34525
34525
  processTabKey(ev, direction) {
34526
34526
  ev.preventDefault();
34527
34527
  ev.stopPropagation();
34528
- if (!this.assistant.forcedClosed) {
34529
- this.props.composerStore.autoCompleteOrStop(direction);
34530
- }
34528
+ this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
34531
34529
  }
34532
34530
  processEnterKey(ev, direction) {
34533
34531
  ev.preventDefault();
34534
34532
  ev.stopPropagation();
34535
- if (!this.assistant.forcedClosed) {
34536
- this.props.composerStore.autoCompleteOrStop(direction);
34537
- }
34533
+ this.props.composerStore.autoCompleteOrStop(direction, this.assistant.forcedClosed);
34538
34534
  }
34539
34535
  processNewLineEvent(ev) {
34540
34536
  ev.preventDefault();
@@ -34710,7 +34706,6 @@ class Composer extends owl.Component {
34710
34706
  return;
34711
34707
  }
34712
34708
  const newSelection = this.contentHelper.getCurrentSelection();
34713
- this.props.composerStore.stopComposerRangeSelection();
34714
34709
  const isCurrentlyInactive = this.props.composerStore.editionMode === "inactive";
34715
34710
  this.props.onComposerContentFocused(newSelection);
34716
34711
  if (!isCurrentlyInactive) {
@@ -35201,6 +35196,7 @@ class AbstractComposerStore extends SpreadsheetStore {
35201
35196
  }
35202
35197
  this.selectionStart = start;
35203
35198
  this.selectionEnd = end;
35199
+ this.editionMode = "editing";
35204
35200
  this.computeFormulaCursorContext();
35205
35201
  this.computeParenthesisRelatedToCursor();
35206
35202
  this.updateAutoCompleteProvider();
@@ -35871,10 +35867,13 @@ class AbstractComposerStore extends SpreadsheetStore {
35871
35867
  hideHelp() {
35872
35868
  this.autoComplete.hide();
35873
35869
  }
35874
- autoCompleteOrStop(direction) {
35870
+ autoCompleteOrStop(direction, assistantForcedClosed = false) {
35875
35871
  if (this.editionMode !== "inactive") {
35876
35872
  const autoComplete = this.autoComplete;
35877
- if (autoComplete.provider && autoComplete.selectedIndex !== undefined) {
35873
+ const suppressAutocomplete = assistantForcedClosed && this.canBeToggled;
35874
+ if (!suppressAutocomplete &&
35875
+ autoComplete.provider &&
35876
+ autoComplete.selectedIndex !== undefined) {
35878
35877
  const autoCompleteValue = autoComplete.provider.proposals[autoComplete.selectedIndex]?.text;
35879
35878
  if (autoCompleteValue) {
35880
35879
  this.autoComplete.provider?.selectProposal(autoCompleteValue);
@@ -51565,10 +51564,11 @@ class AbstractResizer extends owl.Component {
51565
51564
  this.state.waitingForMove = false;
51566
51565
  }
51567
51566
  onMouseMove(ev) {
51568
- if (this.env.isMobile()) {
51569
- return;
51570
- }
51571
- if (this.state.isResizing || this.state.isMoving || this.state.isSelecting) {
51567
+ if (this.env.isMobile() ||
51568
+ this.env.model.getters.isReadonly() ||
51569
+ this.state.isResizing ||
51570
+ this.state.isMoving ||
51571
+ this.state.isSelecting) {
51572
51572
  return;
51573
51573
  }
51574
51574
  this._computeHandleDisplay(ev);
@@ -51635,6 +51635,10 @@ class AbstractResizer extends owl.Component {
51635
51635
  if (index < 0) {
51636
51636
  return;
51637
51637
  }
51638
+ if (this.env.model.getters.isReadonly()) {
51639
+ this._selectElement(index, false);
51640
+ return;
51641
+ }
51638
51642
  if (this.state.waitingForMove) {
51639
51643
  if (!this.env.model.getters.isGridSelectionActive()) {
51640
51644
  this._selectElement(index, false);
@@ -52996,7 +53000,7 @@ const friction = 0.95;
52996
53000
  const verticalScrollFactor = 1;
52997
53001
  const horizontalScrollFactor = 1;
52998
53002
  const resetTimeoutDuration = 100;
52999
- function useTouchScroll(ref, updateScroll, canMoveUp) {
53003
+ function useTouchScroll(ref, updateScroll, canMoveUp, canMoveDown) {
53000
53004
  let lastX = 0;
53001
53005
  let lastY = 0;
53002
53006
  let velocityX = 0;
@@ -53033,7 +53037,7 @@ function useTouchScroll(ref, updateScroll, canMoveUp) {
53033
53037
  lastX = clientX;
53034
53038
  lastY = clientY;
53035
53039
  lastTime = currentTime;
53036
- if (canMoveUp()) {
53040
+ if ((deltaY < 0 && canMoveUp()) || (deltaY > 0 && canMoveDown())) {
53037
53041
  if (event.cancelable) {
53038
53042
  event.preventDefault();
53039
53043
  }
@@ -59271,7 +59275,6 @@ function insertTokenAfterArgSeparator(tokenAtCursor, value) {
59271
59275
  // replace the whole token
59272
59276
  start = tokenAtCursor.start;
59273
59277
  }
59274
- this.composer.stopComposerRangeSelection();
59275
59278
  this.composer.changeComposerCursorSelection(start, end);
59276
59279
  this.composer.replaceComposerCursorSelection(value);
59277
59280
  }
@@ -59289,7 +59292,6 @@ function insertTokenAfterLeftParenthesis(tokenAtCursor, value) {
59289
59292
  // replace the whole token
59290
59293
  start = tokenAtCursor.start;
59291
59294
  }
59292
- this.composer.stopComposerRangeSelection();
59293
59295
  this.composer.changeComposerCursorSelection(start, end);
59294
59296
  this.composer.replaceComposerCursorSelection(value);
59295
59297
  }
@@ -60750,6 +60752,7 @@ class SidePanelStore extends SpreadsheetStore {
60750
60752
  getPanelProps(panelInfo) {
60751
60753
  const state = this.computeState(panelInfo);
60752
60754
  if (state.isOpen) {
60755
+ panelInfo.currentPanelProps = state.props ?? panelInfo.currentPanelProps;
60753
60756
  return state.props ?? {};
60754
60757
  }
60755
60758
  return {};
@@ -60761,11 +60764,11 @@ class SidePanelStore extends SpreadsheetStore {
60761
60764
  }
60762
60765
  return undefined;
60763
60766
  }
60764
- open(componentTag, initialPanelProps = {}) {
60767
+ open(componentTag, currentPanelProps = {}) {
60765
60768
  if (this.screenWidthStore.isSmall) {
60766
60769
  return;
60767
60770
  }
60768
- const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60771
+ const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60769
60772
  const state = this.computeState(newPanelInfo);
60770
60773
  if (!state.isOpen) {
60771
60774
  return;
@@ -60789,8 +60792,8 @@ class SidePanelStore extends SpreadsheetStore {
60789
60792
  }
60790
60793
  this._openPanel("secondaryPanel", newPanelInfo, state);
60791
60794
  }
60792
- replace(componentTag, currentPanelKey, initialPanelProps = {}) {
60793
- const newPanelInfo = { initialPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60795
+ replace(componentTag, currentPanelKey, currentPanelProps = {}) {
60796
+ const newPanelInfo = { currentPanelProps, componentTag, size: DEFAULT_SIDE_PANEL_SIZE };
60794
60797
  const state = this.computeState(newPanelInfo);
60795
60798
  if (!state.isOpen) {
60796
60799
  return;
@@ -60820,10 +60823,10 @@ class SidePanelStore extends SpreadsheetStore {
60820
60823
  _openPanel(panel, newPanel, state) {
60821
60824
  const currentPanel = this[panel];
60822
60825
  if (currentPanel && newPanel.componentTag !== currentPanel.componentTag) {
60823
- currentPanel.initialPanelProps?.onCloseSidePanel?.();
60826
+ currentPanel.currentPanelProps?.onCloseSidePanel?.();
60824
60827
  }
60825
60828
  this[panel] = {
60826
- initialPanelProps: state.props ?? {},
60829
+ currentPanelProps: state.props ?? {},
60827
60830
  componentTag: newPanel.componentTag,
60828
60831
  size: currentPanel?.size || DEFAULT_SIDE_PANEL_SIZE,
60829
60832
  isCollapsed: currentPanel?.isCollapsed || false,
@@ -60845,16 +60848,16 @@ class SidePanelStore extends SpreadsheetStore {
60845
60848
  close() {
60846
60849
  if (this.mainPanel?.isPinned) {
60847
60850
  if (this.secondaryPanel) {
60848
- this.secondaryPanel.initialPanelProps.onCloseSidePanel?.();
60851
+ this.secondaryPanel.currentPanelProps.onCloseSidePanel?.();
60849
60852
  this.secondaryPanel = undefined;
60850
60853
  }
60851
60854
  return;
60852
60855
  }
60853
- this.mainPanel?.initialPanelProps.onCloseSidePanel?.();
60856
+ this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
60854
60857
  this.mainPanel = undefined;
60855
60858
  }
60856
60859
  closeMainPanel() {
60857
- this.mainPanel?.initialPanelProps.onCloseSidePanel?.();
60860
+ this.mainPanel?.currentPanelProps.onCloseSidePanel?.();
60858
60861
  this.mainPanel = this.secondaryPanel || undefined;
60859
60862
  this.secondaryPanel = undefined;
60860
60863
  }
@@ -60886,7 +60889,7 @@ class SidePanelStore extends SpreadsheetStore {
60886
60889
  }
60887
60890
  this.mainPanel.isPinned = !this.mainPanel.isPinned;
60888
60891
  if (!this.mainPanel.isPinned && this.secondaryPanel) {
60889
- this.secondaryPanel?.initialPanelProps.onCloseSidePanel?.();
60892
+ this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
60890
60893
  this.mainPanel = this.secondaryPanel;
60891
60894
  this.secondaryPanel = undefined;
60892
60895
  }
@@ -60905,7 +60908,7 @@ class SidePanelStore extends SpreadsheetStore {
60905
60908
  panelInfo.size = COLLAPSED_SIDE_PANEL_SIZE;
60906
60909
  }
60907
60910
  }
60908
- computeState({ componentTag, initialPanelProps }) {
60911
+ computeState({ componentTag, currentPanelProps: initialPanelProps, }) {
60909
60912
  const customComputeState = sidePanelRegistry.get(componentTag).computeState;
60910
60913
  const state = customComputeState
60911
60914
  ? customComputeState(this.getters, initialPanelProps)
@@ -60915,7 +60918,7 @@ class SidePanelStore extends SpreadsheetStore {
60915
60918
  changeSpreadsheetWidth(width) {
60916
60919
  this.availableWidth = width - MIN_SHEET_VIEW_WIDTH;
60917
60920
  if (this.secondaryPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
60918
- this.secondaryPanel?.initialPanelProps.onCloseSidePanel?.();
60921
+ this.secondaryPanel?.currentPanelProps.onCloseSidePanel?.();
60919
60922
  this.secondaryPanel = undefined;
60920
60923
  }
60921
60924
  if (this.mainPanel && width - this.totalPanelSize < MIN_SHEET_VIEW_WIDTH) {
@@ -61075,6 +61078,10 @@ class Grid extends owl.Component {
61075
61078
  useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
61076
61079
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
61077
61080
  return scrollY > 0;
61081
+ }, () => {
61082
+ const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
61083
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
61084
+ return scrollY < maxOffsetY;
61078
61085
  });
61079
61086
  }
61080
61087
  get highlights() {
@@ -62367,22 +62374,34 @@ class BordersPlugin extends CorePlugin {
62367
62374
  addBorder(sheetId, zone, newBorder, force = false) {
62368
62375
  const borders = [];
62369
62376
  const plannedBorder = newBorder ? { zone, style: newBorder } : undefined;
62370
- const sideToClear = {
62371
- left: force || !!newBorder?.left,
62372
- right: force || !!newBorder?.right,
62373
- top: force || !!newBorder?.top,
62374
- bottom: force || !!newBorder?.bottom,
62377
+ // For each side, decide if we must clear the border on the *adjacent*
62378
+ // existing cell when we draw on the opposite side of the new zone.
62379
+ //
62380
+ // Example:
62381
+ // - newBorder.right is set → we draw border on the RIGHT side of `zone`
62382
+ // - the cell on the right may already have a LEFT border on that edge
62383
+ // In that case we clear that LEFT border, so only the new RIGHT border
62384
+ // remains on the shared edge.
62385
+ //
62386
+ // existingBorderSideToClear[side] = true means we should clear the border on that
62387
+ // side of the existing adjacent zone before adding the new border.
62388
+ const existingBorderSideToClear = {
62389
+ left: force || !!newBorder?.right,
62390
+ right: force || !!newBorder?.left,
62391
+ top: force || !!newBorder?.bottom,
62392
+ bottom: force || !!newBorder?.top,
62375
62393
  };
62376
62394
  let editingZone = [zone];
62377
62395
  for (const existingBorder of this.borders[sheetId] ?? []) {
62378
62396
  const inter = intersection(existingBorder.zone, zone);
62379
62397
  if (!inter) {
62380
- // Clear adjacent borders on which you write
62398
+ // Check if the existing border is adjacent to the new zone
62381
62399
  const adjacentEdge = adjacent(existingBorder.zone, zone);
62382
- if (adjacentEdge && sideToClear[adjacentEdge.position]) {
62400
+ if (adjacentEdge && existingBorderSideToClear[adjacentEdge.position]) {
62383
62401
  for (const newZone of splitIfAdjacent(existingBorder.zone, zone)) {
62384
62402
  const border = this.computeBorderFromZone(newZone, existingBorder);
62385
62403
  const adjacentEdge = adjacent(newZone, zone);
62404
+ // Clear the existing border on the side that touches the new zone
62386
62405
  switch (adjacentEdge?.position) {
62387
62406
  case "left":
62388
62407
  border.style.left = undefined;
@@ -78676,6 +78695,7 @@ class SheetViewPlugin extends UIPlugin {
78676
78695
  "getFigureUI",
78677
78696
  "getPositionAnchorOffset",
78678
78697
  "getGridOffset",
78698
+ "getMaximumSheetOffset",
78679
78699
  ];
78680
78700
  viewports = {};
78681
78701
  /**
@@ -81987,6 +82007,10 @@ class SpreadsheetDashboard extends owl.Component {
81987
82007
  useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
81988
82008
  const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
81989
82009
  return scrollY > 0;
82010
+ }, () => {
82011
+ const { maxOffsetY } = this.env.model.getters.getMaximumSheetOffset();
82012
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
82013
+ return scrollY < maxOffsetY;
81990
82014
  });
81991
82015
  }
81992
82016
  get gridContainer() {
@@ -84031,7 +84055,7 @@ css /* scss */ `
84031
84055
  border-radius: 4px;
84032
84056
  font-weight: 500;
84033
84057
  font-size: 14px;
84034
- height: 32px;
84058
+ min-height: 32px;
84035
84059
  line-height: 16px;
84036
84060
  flex-grow: 1;
84037
84061
  background-color: ${BUTTON_BG};
@@ -88984,6 +89008,6 @@ exports.tokenColors = tokenColors;
88984
89008
  exports.tokenize = tokenize;
88985
89009
 
88986
89010
 
88987
- __info__.version = "19.0.10";
88988
- __info__.date = "2025-11-12T14:15:51.076Z";
88989
- __info__.hash = "18ac688";
89011
+ __info__.version = "19.0.11";
89012
+ __info__.date = "2025-11-24T07:46:47.685Z";
89013
+ __info__.hash = "f5bdbcc";
@@ -3873,7 +3873,7 @@ declare class InternalViewport {
3873
3873
  *
3874
3874
  */
3875
3875
  declare class SheetViewPlugin extends UIPlugin {
3876
- static getters: readonly ["getColIndex", "getRowIndex", "getActiveMainViewport", "getSheetViewDimension", "getSheetViewDimensionWithHeaders", "getMainViewportRect", "isVisibleInViewport", "getEdgeScrollCol", "getEdgeScrollRow", "getVisibleFigures", "getVisibleRect", "getVisibleRectWithoutHeaders", "getVisibleCellPositions", "getColRowOffsetInViewport", "getMainViewportCoordinates", "getActiveSheetScrollInfo", "getSheetViewVisibleCols", "getSheetViewVisibleRows", "getFrozenSheetViewRatio", "isPixelPositionVisible", "getColDimensionsInViewport", "getRowDimensionsInViewport", "getAllActiveViewportsZonesAndRect", "getRect", "getFigureUI", "getPositionAnchorOffset", "getGridOffset"];
3876
+ static getters: readonly ["getColIndex", "getRowIndex", "getActiveMainViewport", "getSheetViewDimension", "getSheetViewDimensionWithHeaders", "getMainViewportRect", "isVisibleInViewport", "getEdgeScrollCol", "getEdgeScrollRow", "getVisibleFigures", "getVisibleRect", "getVisibleRectWithoutHeaders", "getVisibleCellPositions", "getColRowOffsetInViewport", "getMainViewportCoordinates", "getActiveSheetScrollInfo", "getSheetViewVisibleCols", "getSheetViewVisibleRows", "getFrozenSheetViewRatio", "isPixelPositionVisible", "getColDimensionsInViewport", "getRowDimensionsInViewport", "getAllActiveViewportsZonesAndRect", "getRect", "getFigureUI", "getPositionAnchorOffset", "getGridOffset", "getMaximumSheetOffset"];
3877
3877
  private viewports;
3878
3878
  /**
3879
3879
  * The viewport dimensions are usually set by one of the components
@@ -3924,7 +3924,10 @@ declare class SheetViewPlugin extends UIPlugin {
3924
3924
  * Return the main viewport maximum size relative to the client size.
3925
3925
  */
3926
3926
  getMainViewportRect(): Rect;
3927
- private getMaximumSheetOffset;
3927
+ getMaximumSheetOffset(): {
3928
+ maxOffsetX: Pixel;
3929
+ maxOffsetY: Pixel;
3930
+ };
3928
3931
  getColRowOffsetInViewport(dimension: Dimension, referenceHeaderIndex: HeaderIndex, targetHeaderIndex: HeaderIndex): Pixel;
3929
3932
  /**
3930
3933
  * Check if a given position is visible in the viewport.
@@ -8785,7 +8788,7 @@ declare abstract class AbstractComposerStore extends SpreadsheetStore {
8785
8788
  private updateAutoCompleteProvider;
8786
8789
  private findAutocompleteProvider;
8787
8790
  hideHelp(): void;
8788
- autoCompleteOrStop(direction: Direction$1): void;
8791
+ autoCompleteOrStop(direction: Direction$1, assistantForcedClosed?: boolean): void;
8789
8792
  insertAutoCompleteValue(value: string): void;
8790
8793
  selectAutoCompleteIndex(index: number): void;
8791
8794
  moveAutoCompleteSelection(direction: "previous" | "next"): void;
@@ -9290,7 +9293,7 @@ interface ClosedSidePanel {
9290
9293
  }
9291
9294
  type SidePanelState = OpenSidePanel | ClosedSidePanel;
9292
9295
  interface PanelInfo {
9293
- initialPanelProps: SidePanelComponentProps;
9296
+ currentPanelProps: SidePanelComponentProps;
9294
9297
  componentTag: string;
9295
9298
  size: number;
9296
9299
  isCollapsed?: boolean;
@@ -9317,8 +9320,8 @@ declare class SidePanelStore extends SpreadsheetStore {
9317
9320
  get totalPanelSize(): number;
9318
9321
  private getPanelProps;
9319
9322
  private getPanelKey;
9320
- open(componentTag: string, initialPanelProps?: SidePanelComponentProps): void;
9321
- replace(componentTag: string, currentPanelKey: string, initialPanelProps?: SidePanelComponentProps): void;
9323
+ open(componentTag: string, currentPanelProps?: SidePanelComponentProps): void;
9324
+ replace(componentTag: string, currentPanelKey: string, currentPanelProps?: SidePanelComponentProps): void;
9322
9325
  private _openPanel;
9323
9326
  toggle(componentTag: string, panelProps: SidePanelComponentProps): void;
9324
9327
  close(): void;
@@ -10222,7 +10225,7 @@ declare abstract class AbstractResizer extends Component<ResizerProps, Spreadshe
10222
10225
  setup(): void;
10223
10226
  _computeHandleDisplay(ev: MouseEvent): void;
10224
10227
  _computeGrabDisplay(ev: MouseEvent): void;
10225
- onMouseMove(ev: PointerEvent): void;
10228
+ onMouseMove(ev: MouseEvent): void;
10226
10229
  onMouseLeave(): void;
10227
10230
  onDblClick(ev: MouseEvent): void;
10228
10231
  onMouseDown(ev: MouseEvent): void;