@odoo/o-spreadsheet 17.1.0-alpha.4 → 17.1.0-alpha.5

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 17.1.0-alpha.4
6
- * @date 2023-11-24T13:12:24.882Z
7
- * @hash 255821b
5
+ * @version 17.1.0-alpha.5
6
+ * @date 2023-12-05T09:51:40.034Z
7
+ * @hash c2823eb
8
8
  */
9
9
 
10
10
  'use strict';
@@ -3388,8 +3388,10 @@ function convertInternalFormatToFormat(internalFormat) {
3388
3388
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
3389
3389
  // Same as above, but matches the exact string (nothing before or after)
3390
3390
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
3391
- /** Reference of a column header (eg. A, AB) */
3392
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
3391
+ /** Reference of a column header (eg. A, AB, $A) */
3392
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
3393
+ /** Reference of a row header (eg. 1, $1) */
3394
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
3393
3395
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
3394
3396
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
3395
3397
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -3419,6 +3421,9 @@ function isRowReference(xc) {
3419
3421
  function isColHeader(str) {
3420
3422
  return colHeader.test(str);
3421
3423
  }
3424
+ function isRowHeader(str) {
3425
+ return rowHeader.test(str);
3426
+ }
3422
3427
  /**
3423
3428
  * Return true if the given xc is the reference of a single cell,
3424
3429
  * without any specified sheet (e.g. A1)
@@ -4109,18 +4114,10 @@ class RangeImpl {
4109
4114
  if (isFullCol) {
4110
4115
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4111
4116
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4112
- if (zone.left === zone.right) {
4113
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
4114
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
4115
- }
4116
4117
  }
4117
4118
  if (isFullRow) {
4118
4119
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
4119
4120
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
4120
- if (zone.top === zone.bottom) {
4121
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4122
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4123
- }
4124
4121
  }
4125
4122
  return parts;
4126
4123
  }
@@ -4362,7 +4359,7 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4362
4359
  function getDefaultCellHeight(ctx, cell, colSize) {
4363
4360
  if (!cell || !cell.content)
4364
4361
  return DEFAULT_CELL_HEIGHT;
4365
- const maxWidth = cell.style?.wrapping ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4362
+ const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4366
4363
  const numberOfLines = cell.isFormula
4367
4364
  ? 1
4368
4365
  : splitTextToWidth(ctx, cell.content, cell.style, maxWidth).length;
@@ -6259,10 +6256,6 @@ css /* scss */ `
6259
6256
 
6260
6257
  .o-error-tooltip-message {
6261
6258
  overflow: hidden;
6262
- display: -webkit-box; /* Limit to 3 lines */
6263
- -webkit-line-clamp: 3;
6264
- line-clamp: 3;
6265
- -webkit-box-orient: vertical;
6266
6259
  }
6267
6260
  }
6268
6261
  `;
@@ -6670,6 +6663,9 @@ function keyboardEventToShortcutString(ev, mode = "key") {
6670
6663
  keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
6671
6664
  return keyDownString;
6672
6665
  }
6666
+ function isMacOS() {
6667
+ return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
6668
+ }
6673
6669
 
6674
6670
  /**
6675
6671
  * Return the o-spreadsheet element position relative
@@ -17949,6 +17945,10 @@ function setXcToFixedReferenceType(xc, referenceType) {
17949
17945
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
17950
17946
  case "colrow":
17951
17947
  indexOfNumber = xc.search(/[0-9]/);
17948
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
17949
+ // no row number (eg. A) or no column (eg. 1)
17950
+ return "$" + xc;
17951
+ }
17952
17952
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
17953
17953
  return "$" + xc;
17954
17954
  case "none":
@@ -28519,6 +28519,7 @@ class AbstractResizer extends owl.Component {
28519
28519
  draggerShadowThickness: 0,
28520
28520
  delta: 0,
28521
28521
  base: 0,
28522
+ position: "before",
28522
28523
  });
28523
28524
  _computeHandleDisplay(ev) {
28524
28525
  const position = this._getEvOffset(ev);
@@ -28643,11 +28644,13 @@ class AbstractResizer extends owl.Component {
28643
28644
  this.state.draggerLinePosition = dimensions.start;
28644
28645
  this.state.draggerShadowPosition = dimensions.start;
28645
28646
  this.state.base = elementIndex;
28647
+ this.state.position = "before";
28646
28648
  }
28647
28649
  else if (this._getSelectedZoneEnd() < elementIndex) {
28648
28650
  this.state.draggerLinePosition = dimensions.end;
28649
28651
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
28650
- this.state.base = elementIndex + 1;
28652
+ this.state.base = elementIndex;
28653
+ this.state.position = "after";
28651
28654
  }
28652
28655
  else {
28653
28656
  this.state.draggerLinePosition = startDimensions.start;
@@ -28822,6 +28825,7 @@ class ColResizer extends AbstractResizer {
28822
28825
  dimension: "COL",
28823
28826
  base: this.state.base,
28824
28827
  elements,
28828
+ position: this.state.position,
28825
28829
  });
28826
28830
  if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
28827
28831
  this.env.raiseError(MergeErrorMessage);
@@ -28986,6 +28990,7 @@ class RowResizer extends AbstractResizer {
28986
28990
  dimension: "ROW",
28987
28991
  base: this.state.base,
28988
28992
  elements,
28993
+ position: this.state.position,
28989
28994
  });
28990
28995
  if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
28991
28996
  this.env.raiseError(MergeErrorMessage);
@@ -29093,8 +29098,8 @@ function useWheelHandler(handler) {
29093
29098
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
29094
29099
  }
29095
29100
  const onMouseWheel = (ev) => {
29096
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
29097
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
29101
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
29102
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
29098
29103
  handler(deltaX, deltaY);
29099
29104
  };
29100
29105
  return onMouseWheel;
@@ -33531,7 +33536,7 @@ const machine = {
33531
33536
  SPACE: goTo(State.RightRef),
33532
33537
  NUMBER: goTo(State.Found),
33533
33538
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
33534
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
33539
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
33535
33540
  },
33536
33541
  [State.RightColumnRef]: {
33537
33542
  SPACE: goTo(State.RightColumnRef),
@@ -33542,6 +33547,7 @@ const machine = {
33542
33547
  SPACE: goTo(State.RightRowRef),
33543
33548
  NUMBER: goTo(State.Found),
33544
33549
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
33550
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
33545
33551
  },
33546
33552
  [State.Found]: {},
33547
33553
  };
@@ -37521,7 +37527,16 @@ class HeaderVisibilityPlugin extends CorePlugin {
37521
37527
  return consecutiveIndexes;
37522
37528
  }
37523
37529
  getAllVisibleHeaders(sheetId, dimension) {
37524
- return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
37530
+ const headers = range(0, this.getters.getNumberHeaders(sheetId, dimension));
37531
+ const foldedHeaders = [];
37532
+ this.getters.getHeaderGroups(sheetId, dimension).forEach((group) => {
37533
+ if (group.isFolded) {
37534
+ foldedHeaders.push(...range(group.start, group.end + 1));
37535
+ }
37536
+ });
37537
+ return headers.filter((i) => {
37538
+ return !this.hiddenHeaders[sheetId][dimension][i] && !foldedHeaders.includes(i);
37539
+ });
37525
37540
  }
37526
37541
  import(data) {
37527
37542
  for (let sheet of data.sheets) {
@@ -39982,10 +39997,13 @@ class CompilationParametersBuilder {
39982
39997
  if (evaluatedCell === undefined) {
39983
39998
  return { value: null, format: this.getters.getCell(position)?.format };
39984
39999
  }
40000
+ if (evaluatedCell.type === CellValueType.error) {
40001
+ throw evaluatedCell.error;
40002
+ }
39985
40003
  return evaluatedCell;
39986
40004
  }
39987
40005
  getEvaluatedCellIfNotEmpty(position) {
39988
- const evaluatedCell = this.getEvaluatedCell(position);
40006
+ const evaluatedCell = this.computeCell(position);
39989
40007
  if (evaluatedCell.type === CellValueType.empty) {
39990
40008
  const cell = this.getters.getCell(position);
39991
40009
  if (!cell || (!cell.isFormula && cell.content === "")) {
@@ -39994,13 +40012,6 @@ class CompilationParametersBuilder {
39994
40012
  }
39995
40013
  return evaluatedCell;
39996
40014
  }
39997
- getEvaluatedCell(position) {
39998
- const evaluatedCell = this.computeCell(position);
39999
- if (evaluatedCell.type === CellValueType.error) {
40000
- throw evaluatedCell.error;
40001
- }
40002
- return evaluatedCell;
40003
- }
40004
40015
  /**
40005
40016
  * Return the values of the cell(s) used in reference, but always in the format of a range even
40006
40017
  * if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
@@ -40023,7 +40034,11 @@ class CompilationParametersBuilder {
40023
40034
  const { top, left, bottom, right } = zone;
40024
40035
  const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
40025
40036
  if (cacheKey in this.rangeCache) {
40026
- return this.rangeCache[cacheKey];
40037
+ const result = this.rangeCache[cacheKey];
40038
+ if (result instanceof EvaluationError) {
40039
+ throw result;
40040
+ }
40041
+ return result;
40027
40042
  }
40028
40043
  const height = _zone.bottom - _zone.top + 1;
40029
40044
  const width = _zone.right - _zone.left + 1;
@@ -40033,6 +40048,11 @@ class CompilationParametersBuilder {
40033
40048
  const colIndex = col - _zone.left;
40034
40049
  matrix[colIndex] = new Array(height);
40035
40050
  for (let row = _zone.top; row <= _zone.bottom; row++) {
40051
+ const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
40052
+ if (evaluatedCell?.type === CellValueType.error) {
40053
+ this.rangeCache[cacheKey] = evaluatedCell.error;
40054
+ throw evaluatedCell.error;
40055
+ }
40036
40056
  const rowIndex = row - _zone.top;
40037
40057
  matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
40038
40058
  }
@@ -41134,7 +41154,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
41134
41154
  // ---------------------------------------------------------------------------
41135
41155
  handle(cmd) {
41136
41156
  if (invalidateCFEvaluationCommands.has(cmd.type) ||
41137
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
41157
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
41138
41158
  this.isStale = true;
41139
41159
  }
41140
41160
  }
@@ -41460,7 +41480,7 @@ class EvaluationDataValidationPlugin extends UIPlugin {
41460
41480
  handle(cmd) {
41461
41481
  if (invalidateEvaluationCommands.has(cmd.type) ||
41462
41482
  cmd.type === "EVALUATE_CELLS" ||
41463
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
41483
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
41464
41484
  this.validationResults = {};
41465
41485
  return;
41466
41486
  }
@@ -41998,19 +42018,21 @@ class AutofillPlugin extends UIPlugin {
41998
42018
  let col = zone.left;
41999
42019
  let row = zone.bottom;
42000
42020
  if (col > 0) {
42001
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
42002
- while (left.type !== CellValueType.empty) {
42021
+ let leftPosition = { sheetId, col: col - 1, row };
42022
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
42023
+ this.getters.getCell(leftPosition)?.content) {
42003
42024
  row += 1;
42004
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
42025
+ leftPosition = { sheetId, col: col - 1, row };
42005
42026
  }
42006
42027
  }
42007
42028
  if (row === zone.bottom) {
42008
42029
  col = zone.right;
42009
42030
  if (col <= this.getters.getNumberCols(sheetId)) {
42010
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
42011
- while (right.type !== CellValueType.empty) {
42031
+ let rightPosition = { sheetId, col: col + 1, row };
42032
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
42033
+ this.getters.getCell(rightPosition)?.content) {
42012
42034
  row += 1;
42013
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
42035
+ rightPosition = { sheetId, col: col + 1, row };
42014
42036
  }
42015
42037
  }
42016
42038
  }
@@ -43002,6 +43024,7 @@ class Session extends EventBus {
43002
43024
  isReplayingInitialRevisions = false;
43003
43025
  processedRevisions = new Set();
43004
43026
  uuidGenerator = new UuidGenerator();
43027
+ lastLocalOperation;
43005
43028
  /**
43006
43029
  * Manages the collaboration between multiple users on the same spreadsheet.
43007
43030
  * It can forward local state changes to other users to ensure they all eventually
@@ -43034,6 +43057,11 @@ class Session extends EventBus {
43034
43057
  return;
43035
43058
  const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes, Date.now());
43036
43059
  this.revisions.append(revision.id, revision);
43060
+ // REQUEST_REDO just repeats the last operation, the
43061
+ // last operation is still the same and should not change.
43062
+ if (rootCommand.type !== "REQUEST_REDO") {
43063
+ this.lastLocalOperation = revision;
43064
+ }
43037
43065
  this.trigger("new-local-state-update", { id: revision.id });
43038
43066
  this.sendUpdateMessage({
43039
43067
  type: "REMOTE_REVISION",
@@ -43130,19 +43158,10 @@ class Session extends EventBus {
43130
43158
  return this.pendingMessages.length === 0;
43131
43159
  }
43132
43160
  /**
43133
- * Get the last local revision whose root command isn't in the given list of ignored commands
43161
+ * Get the last local revision
43134
43162
  * */
43135
- getLastLocalNonEmptyRevision(ignoredRootCommands) {
43136
- const revisions = this.revisions.getRevertedExecution();
43137
- for (const rev of revisions) {
43138
- if (rev.rootCommand === "SNAPSHOT")
43139
- return undefined;
43140
- if (!rev.rootCommand || rev.rootCommand === "REMOTE")
43141
- continue;
43142
- if (!ignoredRootCommands.includes(rev.rootCommand?.type) && rev.commands.length)
43143
- return rev;
43144
- }
43145
- return undefined;
43163
+ getLastLocalNonEmptyRevision() {
43164
+ return this.lastLocalOperation;
43146
43165
  }
43147
43166
  _move(position) {
43148
43167
  // this method is debounced and might be called after the client
@@ -43202,7 +43221,7 @@ class Session extends EventBus {
43202
43221
  break;
43203
43222
  case "REMOTE_REVISION":
43204
43223
  const { clientId, commands, timestamp } = message;
43205
- const revision = new Revision(message.nextRevisionId, clientId, commands, "REMOTE", undefined, timestamp);
43224
+ const revision = new Revision(message.nextRevisionId, clientId, commands, undefined, undefined, timestamp);
43206
43225
  if (revision.clientId !== this.clientId) {
43207
43226
  this.revisions.insert(revision.id, revision, message.serverRevisionId);
43208
43227
  const pendingCommands = this.pendingMessages
@@ -43215,10 +43234,11 @@ class Session extends EventBus {
43215
43234
  }
43216
43235
  break;
43217
43236
  case "SNAPSHOT_CREATED": {
43218
- const revision = new Revision(message.nextRevisionId, "server", [], "SNAPSHOT", undefined, Date.now());
43237
+ const revision = new Revision(message.nextRevisionId, "server", [], undefined, undefined, Date.now());
43219
43238
  this.revisions.insert(revision.id, revision, message.serverRevisionId);
43220
43239
  this.dropPendingHistoryMessages();
43221
43240
  this.trigger("snapshot");
43241
+ this.lastLocalOperation = undefined;
43222
43242
  break;
43223
43243
  }
43224
43244
  }
@@ -45863,6 +45883,9 @@ class SelectionInputsManagerPlugin extends UIPlugin {
45863
45883
  // Other
45864
45884
  // ---------------------------------------------------------------------------
45865
45885
  initInput(id, initialRanges, inputHasSingleRange = false) {
45886
+ if (this.inputs[id]) {
45887
+ this.unfocus();
45888
+ }
45866
45889
  this.inputs[id] = new SelectionInputPlugin(this.config, initialRanges, inputHasSingleRange);
45867
45890
  if (initialRanges.length === 0) {
45868
45891
  const input = this.inputs[id];
@@ -46571,7 +46594,7 @@ class HistoryPlugin extends UIPlugin {
46571
46594
  * Ignore standard undo/redo revisions (that are empty)
46572
46595
  */
46573
46596
  getPossibleRevisionToRepeat() {
46574
- return this.session.getLastLocalNonEmptyRevision(["REQUEST_REDO"]);
46597
+ return this.session.getLastLocalNonEmptyRevision();
46575
46598
  }
46576
46599
  }
46577
46600
 
@@ -48042,6 +48065,12 @@ class FilterEvaluationPlugin extends UIPlugin {
48042
48065
  break;
48043
48066
  case "HIDE_COLUMNS_ROWS":
48044
48067
  case "UNHIDE_COLUMNS_ROWS":
48068
+ case "GROUP_HEADERS":
48069
+ case "UNGROUP_HEADERS":
48070
+ case "FOLD_HEADER_GROUP":
48071
+ case "UNFOLD_HEADER_GROUP":
48072
+ case "FOLD_ALL_HEADER_GROUPS":
48073
+ case "UNFOLD_ALL_HEADER_GROUPS":
48045
48074
  this.updateHiddenRows();
48046
48075
  break;
48047
48076
  case "UPDATE_FILTER":
@@ -48743,7 +48772,7 @@ class GridSelectionPlugin extends UIPlugin {
48743
48772
  sheetId: cmd.sheetId,
48744
48773
  base: cmd.base,
48745
48774
  quantity: thickness,
48746
- position: "before",
48775
+ position: cmd.position,
48747
48776
  });
48748
48777
  const isCol = cmd.dimension === "COL";
48749
48778
  const start = cmd.elements[0];
@@ -48760,12 +48789,13 @@ class GridSelectionPlugin extends UIPlugin {
48760
48789
  },
48761
48790
  ];
48762
48791
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
48792
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
48763
48793
  const pasteTarget = [
48764
48794
  {
48765
- left: isCol ? cmd.base : 0,
48766
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
48767
- top: !isCol ? cmd.base : 0,
48768
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
48795
+ left: isCol ? base : 0,
48796
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
48797
+ top: !isCol ? base : 0,
48798
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
48769
48799
  },
48770
48800
  ];
48771
48801
  state.paste(pasteTarget, { selectTarget: true });
@@ -48800,6 +48830,11 @@ class GridSelectionPlugin extends UIPlugin {
48800
48830
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
48801
48831
  return "WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */;
48802
48832
  }
48833
+ const headers = [cmd.base, ...cmd.elements];
48834
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
48835
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
48836
+ return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
48837
+ }
48803
48838
  return "Success" /* CommandResult.Success */;
48804
48839
  }
48805
48840
  //-------------------------------------------
@@ -48977,9 +49012,6 @@ class InternalViewport {
48977
49012
  */
48978
49013
  adjustPosition(position) {
48979
49014
  const sheetId = this.sheetId;
48980
- if (!position) {
48981
- position = this.getters.getSheetPosition(sheetId);
48982
- }
48983
49015
  const mainCellPosition = this.getters.getMainCellPosition({ sheetId, ...position });
48984
49016
  const { col, row } = this.getters.getNextVisibleCellPosition(mainCellPosition);
48985
49017
  if (isInside(col, this.boundaries.top, this.boundaries)) {
@@ -48992,56 +49024,50 @@ class InternalViewport {
48992
49024
  adjustPositionX(targetCol) {
48993
49025
  const sheetId = this.sheetId;
48994
49026
  const { end } = this.getters.getColDimensions(sheetId, targetCol);
48995
- const maxCol = this.getters.getNumberCols(sheetId);
48996
49027
  if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
49028
+ const maxCol = this.getters.getNumberCols(sheetId);
48997
49029
  let finalTarget = targetCol;
48998
- while (this.getters.isColHidden(sheetId, finalTarget) && targetCol < maxCol) {
49030
+ while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget < maxCol) {
48999
49031
  finalTarget++;
49000
49032
  }
49001
49033
  const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
49002
49034
  const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left);
49003
- this.offsetX =
49035
+ this.offsetScrollbarX =
49004
49036
  this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
49005
- this.offsetScrollbarX = this.offsetX;
49006
- this.adjustViewportZoneX();
49007
49037
  }
49008
49038
  else if (this.left > targetCol) {
49009
49039
  let finalTarget = targetCol;
49010
- while (this.getters.isColHidden(sheetId, finalTarget) && targetCol > 0) {
49040
+ while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget > 0) {
49011
49041
  finalTarget--;
49012
49042
  }
49013
- this.offsetX =
49043
+ this.offsetScrollbarX =
49014
49044
  this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
49015
- this.offsetScrollbarX = this.offsetX;
49016
- this.adjustViewportZoneX();
49017
49045
  }
49046
+ this.adjustViewportZoneX();
49018
49047
  }
49019
49048
  adjustPositionY(targetRow) {
49020
49049
  const sheetId = this.sheetId;
49021
49050
  const { end } = this.getters.getRowDimensions(sheetId, targetRow);
49022
- const maxRow = this.getters.getNumberRows(sheetId);
49023
49051
  if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
49052
+ const maxRow = this.getters.getNumberRows(sheetId);
49024
49053
  let finalTarget = targetRow;
49025
- while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow < maxRow) {
49054
+ while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget < maxRow) {
49026
49055
  finalTarget++;
49027
49056
  }
49028
49057
  const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
49029
49058
  const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top);
49030
- this.offsetY =
49059
+ this.offsetScrollbarY =
49031
49060
  this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
49032
- this.offsetScrollbarY = this.offsetY;
49033
- this.adjustViewportZoneY();
49034
49061
  }
49035
49062
  else if (this.top > targetRow) {
49036
49063
  let finalTarget = targetRow;
49037
- while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow > 0) {
49064
+ while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget > 0) {
49038
49065
  finalTarget--;
49039
49066
  }
49040
- this.offsetY =
49067
+ this.offsetScrollbarY =
49041
49068
  this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
49042
- this.offsetScrollbarY = this.offsetY;
49043
- this.adjustViewportZoneY();
49044
49069
  }
49070
+ this.adjustViewportZoneY();
49045
49071
  }
49046
49072
  setViewportOffset(offsetX, offsetY) {
49047
49073
  this.setViewportOffsetX(offsetX);
@@ -49057,11 +49083,10 @@ class InternalViewport {
49057
49083
  * @returns Computes the absolute coordinate of a given zone inside the viewport
49058
49084
  */
49059
49085
  getRect(zone) {
49060
- const targetZone = intersection(zone, this.zone);
49086
+ const targetZone = intersection(zone, this);
49061
49087
  if (targetZone) {
49062
- const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
49063
- this.offsetCorrectionX;
49064
- const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
49088
+ const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) + this.offsetCorrectionX;
49089
+ const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) + this.offsetCorrectionY;
49065
49090
  const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
49066
49091
  const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
49067
49092
  return {
@@ -49071,9 +49096,7 @@ class InternalViewport {
49071
49096
  height,
49072
49097
  };
49073
49098
  }
49074
- else {
49075
- return undefined;
49076
- }
49099
+ return undefined;
49077
49100
  }
49078
49101
  isVisible(col, row) {
49079
49102
  const isInside = row <= this.bottom && row >= this.top && col >= this.left && col <= this.right;
@@ -49081,7 +49104,6 @@ class InternalViewport {
49081
49104
  !this.getters.isColHidden(this.sheetId, col) &&
49082
49105
  !this.getters.isRowHidden(this.sheetId, row));
49083
49106
  }
49084
- // PRIVATE
49085
49107
  searchHeaderIndex(dimension, position, startIndex = 0) {
49086
49108
  const sheetId = this.sheetId;
49087
49109
  const headers = this.getters.getNumberHeaders(sheetId, dimension);
@@ -49104,9 +49126,6 @@ class InternalViewport {
49104
49126
  }
49105
49127
  return -1;
49106
49128
  }
49107
- get zone() {
49108
- return { left: this.left, right: this.right, top: this.top, bottom: this.bottom };
49109
- }
49110
49129
  setViewportOffsetX(offsetX) {
49111
49130
  if (!this.canScrollHorizontally) {
49112
49131
  return;
@@ -49131,11 +49150,6 @@ class InternalViewport {
49131
49150
  this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
49132
49151
  }
49133
49152
  }
49134
- this.left = this.getColIndex(this.offsetScrollbarX);
49135
- this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth);
49136
- if (this.right === -1) {
49137
- this.right = this.boundaries.right;
49138
- }
49139
49153
  this.adjustViewportZoneX();
49140
49154
  }
49141
49155
  /** Corrects the viewport's vertical offset based on the current structure
@@ -49148,11 +49162,6 @@ class InternalViewport {
49148
49162
  this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
49149
49163
  }
49150
49164
  }
49151
- this.top = this.getRowIndex(this.offsetScrollbarY);
49152
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportHeight);
49153
- if (this.bottom === -1) {
49154
- this.bottom = this.boundaries.bottom;
49155
- }
49156
49165
  this.adjustViewportZoneY();
49157
49166
  }
49158
49167
  /** Updates the pane zone and snapped offset based on its horizontal
@@ -49530,7 +49539,7 @@ class SheetViewPlugin extends UIPlugin {
49530
49539
  isVisibleInViewport({ sheetId, col, row }) {
49531
49540
  return this.getSubViewports(sheetId).some((pane) => pane.isVisible(col, row));
49532
49541
  }
49533
- // => return s the new offset
49542
+ // => returns the new offset
49534
49543
  getEdgeScrollCol(x, previousX, startingX) {
49535
49544
  let canEdgeScroll = false;
49536
49545
  let direction = 0;
@@ -49845,10 +49854,13 @@ class HeaderPositionsUIPlugin extends UIPlugin {
49845
49854
  }
49846
49855
  break;
49847
49856
  case "UPDATE_CELL":
49848
- if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
49857
+ if ("content" in cmd || "format" in cmd) {
49849
49858
  this.headerPositions = {};
49850
49859
  this.isDirty = true;
49851
49860
  }
49861
+ else {
49862
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
49863
+ }
49852
49864
  break;
49853
49865
  case "UPDATE_FILTER":
49854
49866
  case "REMOVE_FILTER_TABLE":
@@ -52005,6 +52017,8 @@ css /* scss */ `
52005
52017
  *:before,
52006
52018
  *:after {
52007
52019
  box-sizing: content-box;
52020
+ /** rtl not supported ATM */
52021
+ direction: ltr;
52008
52022
  }
52009
52023
  .o-separator {
52010
52024
  border-bottom: ${MENU_SEPARATOR_BORDER_WIDTH}px solid ${SEPARATOR_COLOR};
@@ -56045,6 +56059,6 @@ exports.setTranslationMethod = setTranslationMethod;
56045
56059
  exports.tokenize = tokenize;
56046
56060
 
56047
56061
 
56048
- __info__.version = "17.1.0-alpha.4";
56049
- __info__.date = "2023-11-24T13:12:24.882Z";
56050
- __info__.hash = "255821b";
56062
+ __info__.version = "17.1.0-alpha.5";
56063
+ __info__.date = "2023-12-05T09:51:40.034Z";
56064
+ __info__.hash = "c2823eb";