@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
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
@@ -3386,8 +3386,10 @@ function convertInternalFormatToFormat(internalFormat) {
3386
3386
  const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
3387
3387
  // Same as above, but matches the exact string (nothing before or after)
3388
3388
  const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
3389
- /** Reference of a column header (eg. A, AB) */
3390
- const colHeader = new RegExp(/^([A-Z]{1,3})+$/, "i");
3389
+ /** Reference of a column header (eg. A, AB, $A) */
3390
+ const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
3391
+ /** Reference of a row header (eg. 1, $1) */
3392
+ const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
3391
3393
  /** Reference of a column (eg. A, $CA, Sheet1!B) */
3392
3394
  const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
3393
3395
  /** Reference of a row (eg. 1, 59, Sheet1!9) */
@@ -3417,6 +3419,9 @@ function isRowReference(xc) {
3417
3419
  function isColHeader(str) {
3418
3420
  return colHeader.test(str);
3419
3421
  }
3422
+ function isRowHeader(str) {
3423
+ return rowHeader.test(str);
3424
+ }
3420
3425
  /**
3421
3426
  * Return true if the given xc is the reference of a single cell,
3422
3427
  * without any specified sheet (e.g. A1)
@@ -4107,18 +4112,10 @@ class RangeImpl {
4107
4112
  if (isFullCol) {
4108
4113
  parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4109
4114
  parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4110
- if (zone.left === zone.right) {
4111
- parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
4112
- parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
4113
- }
4114
4115
  }
4115
4116
  if (isFullRow) {
4116
4117
  parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
4117
4118
  parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
4118
- if (zone.top === zone.bottom) {
4119
- parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4120
- parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
4121
- }
4122
4119
  }
4123
4120
  return parts;
4124
4121
  }
@@ -4360,7 +4357,7 @@ function computeTextLinesHeight(textLineHeight, numberOfLines = 1) {
4360
4357
  function getDefaultCellHeight(ctx, cell, colSize) {
4361
4358
  if (!cell || !cell.content)
4362
4359
  return DEFAULT_CELL_HEIGHT;
4363
- const maxWidth = cell.style?.wrapping ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4360
+ const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
4364
4361
  const numberOfLines = cell.isFormula
4365
4362
  ? 1
4366
4363
  : splitTextToWidth(ctx, cell.content, cell.style, maxWidth).length;
@@ -6257,10 +6254,6 @@ css /* scss */ `
6257
6254
 
6258
6255
  .o-error-tooltip-message {
6259
6256
  overflow: hidden;
6260
- display: -webkit-box; /* Limit to 3 lines */
6261
- -webkit-line-clamp: 3;
6262
- line-clamp: 3;
6263
- -webkit-box-orient: vertical;
6264
6257
  }
6265
6258
  }
6266
6259
  `;
@@ -6668,6 +6661,9 @@ function keyboardEventToShortcutString(ev, mode = "key") {
6668
6661
  keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
6669
6662
  return keyDownString;
6670
6663
  }
6664
+ function isMacOS() {
6665
+ return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
6666
+ }
6671
6667
 
6672
6668
  /**
6673
6669
  * Return the o-spreadsheet element position relative
@@ -17947,6 +17943,10 @@ function setXcToFixedReferenceType(xc, referenceType) {
17947
17943
  return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
17948
17944
  case "colrow":
17949
17945
  indexOfNumber = xc.search(/[0-9]/);
17946
+ if (indexOfNumber === -1 || indexOfNumber === 0) {
17947
+ // no row number (eg. A) or no column (eg. 1)
17948
+ return "$" + xc;
17949
+ }
17950
17950
  xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
17951
17951
  return "$" + xc;
17952
17952
  case "none":
@@ -28517,6 +28517,7 @@ class AbstractResizer extends Component {
28517
28517
  draggerShadowThickness: 0,
28518
28518
  delta: 0,
28519
28519
  base: 0,
28520
+ position: "before",
28520
28521
  });
28521
28522
  _computeHandleDisplay(ev) {
28522
28523
  const position = this._getEvOffset(ev);
@@ -28641,11 +28642,13 @@ class AbstractResizer extends Component {
28641
28642
  this.state.draggerLinePosition = dimensions.start;
28642
28643
  this.state.draggerShadowPosition = dimensions.start;
28643
28644
  this.state.base = elementIndex;
28645
+ this.state.position = "before";
28644
28646
  }
28645
28647
  else if (this._getSelectedZoneEnd() < elementIndex) {
28646
28648
  this.state.draggerLinePosition = dimensions.end;
28647
28649
  this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
28648
- this.state.base = elementIndex + 1;
28650
+ this.state.base = elementIndex;
28651
+ this.state.position = "after";
28649
28652
  }
28650
28653
  else {
28651
28654
  this.state.draggerLinePosition = startDimensions.start;
@@ -28820,6 +28823,7 @@ class ColResizer extends AbstractResizer {
28820
28823
  dimension: "COL",
28821
28824
  base: this.state.base,
28822
28825
  elements,
28826
+ position: this.state.position,
28823
28827
  });
28824
28828
  if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
28825
28829
  this.env.raiseError(MergeErrorMessage);
@@ -28984,6 +28988,7 @@ class RowResizer extends AbstractResizer {
28984
28988
  dimension: "ROW",
28985
28989
  base: this.state.base,
28986
28990
  elements,
28991
+ position: this.state.position,
28987
28992
  });
28988
28993
  if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
28989
28994
  this.env.raiseError(MergeErrorMessage);
@@ -29091,8 +29096,8 @@ function useWheelHandler(handler) {
29091
29096
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
29092
29097
  }
29093
29098
  const onMouseWheel = (ev) => {
29094
- const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
29095
- const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
29099
+ const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
29100
+ const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
29096
29101
  handler(deltaX, deltaY);
29097
29102
  };
29098
29103
  return onMouseWheel;
@@ -33529,7 +33534,7 @@ const machine = {
33529
33534
  SPACE: goTo(State.RightRef),
33530
33535
  NUMBER: goTo(State.Found),
33531
33536
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
33532
- SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
33537
+ SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
33533
33538
  },
33534
33539
  [State.RightColumnRef]: {
33535
33540
  SPACE: goTo(State.RightColumnRef),
@@ -33540,6 +33545,7 @@ const machine = {
33540
33545
  SPACE: goTo(State.RightRowRef),
33541
33546
  NUMBER: goTo(State.Found),
33542
33547
  REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
33548
+ SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
33543
33549
  },
33544
33550
  [State.Found]: {},
33545
33551
  };
@@ -37519,7 +37525,16 @@ class HeaderVisibilityPlugin extends CorePlugin {
37519
37525
  return consecutiveIndexes;
37520
37526
  }
37521
37527
  getAllVisibleHeaders(sheetId, dimension) {
37522
- return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
37528
+ const headers = range(0, this.getters.getNumberHeaders(sheetId, dimension));
37529
+ const foldedHeaders = [];
37530
+ this.getters.getHeaderGroups(sheetId, dimension).forEach((group) => {
37531
+ if (group.isFolded) {
37532
+ foldedHeaders.push(...range(group.start, group.end + 1));
37533
+ }
37534
+ });
37535
+ return headers.filter((i) => {
37536
+ return !this.hiddenHeaders[sheetId][dimension][i] && !foldedHeaders.includes(i);
37537
+ });
37523
37538
  }
37524
37539
  import(data) {
37525
37540
  for (let sheet of data.sheets) {
@@ -39980,10 +39995,13 @@ class CompilationParametersBuilder {
39980
39995
  if (evaluatedCell === undefined) {
39981
39996
  return { value: null, format: this.getters.getCell(position)?.format };
39982
39997
  }
39998
+ if (evaluatedCell.type === CellValueType.error) {
39999
+ throw evaluatedCell.error;
40000
+ }
39983
40001
  return evaluatedCell;
39984
40002
  }
39985
40003
  getEvaluatedCellIfNotEmpty(position) {
39986
- const evaluatedCell = this.getEvaluatedCell(position);
40004
+ const evaluatedCell = this.computeCell(position);
39987
40005
  if (evaluatedCell.type === CellValueType.empty) {
39988
40006
  const cell = this.getters.getCell(position);
39989
40007
  if (!cell || (!cell.isFormula && cell.content === "")) {
@@ -39992,13 +40010,6 @@ class CompilationParametersBuilder {
39992
40010
  }
39993
40011
  return evaluatedCell;
39994
40012
  }
39995
- getEvaluatedCell(position) {
39996
- const evaluatedCell = this.computeCell(position);
39997
- if (evaluatedCell.type === CellValueType.error) {
39998
- throw evaluatedCell.error;
39999
- }
40000
- return evaluatedCell;
40001
- }
40002
40013
  /**
40003
40014
  * Return the values of the cell(s) used in reference, but always in the format of a range even
40004
40015
  * if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
@@ -40021,7 +40032,11 @@ class CompilationParametersBuilder {
40021
40032
  const { top, left, bottom, right } = zone;
40022
40033
  const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
40023
40034
  if (cacheKey in this.rangeCache) {
40024
- return this.rangeCache[cacheKey];
40035
+ const result = this.rangeCache[cacheKey];
40036
+ if (result instanceof EvaluationError) {
40037
+ throw result;
40038
+ }
40039
+ return result;
40025
40040
  }
40026
40041
  const height = _zone.bottom - _zone.top + 1;
40027
40042
  const width = _zone.right - _zone.left + 1;
@@ -40031,6 +40046,11 @@ class CompilationParametersBuilder {
40031
40046
  const colIndex = col - _zone.left;
40032
40047
  matrix[colIndex] = new Array(height);
40033
40048
  for (let row = _zone.top; row <= _zone.bottom; row++) {
40049
+ const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
40050
+ if (evaluatedCell?.type === CellValueType.error) {
40051
+ this.rangeCache[cacheKey] = evaluatedCell.error;
40052
+ throw evaluatedCell.error;
40053
+ }
40034
40054
  const rowIndex = row - _zone.top;
40035
40055
  matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
40036
40056
  }
@@ -41132,7 +41152,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
41132
41152
  // ---------------------------------------------------------------------------
41133
41153
  handle(cmd) {
41134
41154
  if (invalidateCFEvaluationCommands.has(cmd.type) ||
41135
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
41155
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
41136
41156
  this.isStale = true;
41137
41157
  }
41138
41158
  }
@@ -41458,7 +41478,7 @@ class EvaluationDataValidationPlugin extends UIPlugin {
41458
41478
  handle(cmd) {
41459
41479
  if (invalidateEvaluationCommands.has(cmd.type) ||
41460
41480
  cmd.type === "EVALUATE_CELLS" ||
41461
- (cmd.type === "UPDATE_CELL" && "content" in cmd)) {
41481
+ (cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
41462
41482
  this.validationResults = {};
41463
41483
  return;
41464
41484
  }
@@ -41996,19 +42016,21 @@ class AutofillPlugin extends UIPlugin {
41996
42016
  let col = zone.left;
41997
42017
  let row = zone.bottom;
41998
42018
  if (col > 0) {
41999
- let left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
42000
- while (left.type !== CellValueType.empty) {
42019
+ let leftPosition = { sheetId, col: col - 1, row };
42020
+ while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
42021
+ this.getters.getCell(leftPosition)?.content) {
42001
42022
  row += 1;
42002
- left = this.getters.getEvaluatedCell({ sheetId, col: col - 1, row });
42023
+ leftPosition = { sheetId, col: col - 1, row };
42003
42024
  }
42004
42025
  }
42005
42026
  if (row === zone.bottom) {
42006
42027
  col = zone.right;
42007
42028
  if (col <= this.getters.getNumberCols(sheetId)) {
42008
- let right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
42009
- while (right.type !== CellValueType.empty) {
42029
+ let rightPosition = { sheetId, col: col + 1, row };
42030
+ while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
42031
+ this.getters.getCell(rightPosition)?.content) {
42010
42032
  row += 1;
42011
- right = this.getters.getEvaluatedCell({ sheetId, col: col + 1, row });
42033
+ rightPosition = { sheetId, col: col + 1, row };
42012
42034
  }
42013
42035
  }
42014
42036
  }
@@ -43000,6 +43022,7 @@ class Session extends EventBus {
43000
43022
  isReplayingInitialRevisions = false;
43001
43023
  processedRevisions = new Set();
43002
43024
  uuidGenerator = new UuidGenerator();
43025
+ lastLocalOperation;
43003
43026
  /**
43004
43027
  * Manages the collaboration between multiple users on the same spreadsheet.
43005
43028
  * It can forward local state changes to other users to ensure they all eventually
@@ -43032,6 +43055,11 @@ class Session extends EventBus {
43032
43055
  return;
43033
43056
  const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes, Date.now());
43034
43057
  this.revisions.append(revision.id, revision);
43058
+ // REQUEST_REDO just repeats the last operation, the
43059
+ // last operation is still the same and should not change.
43060
+ if (rootCommand.type !== "REQUEST_REDO") {
43061
+ this.lastLocalOperation = revision;
43062
+ }
43035
43063
  this.trigger("new-local-state-update", { id: revision.id });
43036
43064
  this.sendUpdateMessage({
43037
43065
  type: "REMOTE_REVISION",
@@ -43128,19 +43156,10 @@ class Session extends EventBus {
43128
43156
  return this.pendingMessages.length === 0;
43129
43157
  }
43130
43158
  /**
43131
- * Get the last local revision whose root command isn't in the given list of ignored commands
43159
+ * Get the last local revision
43132
43160
  * */
43133
- getLastLocalNonEmptyRevision(ignoredRootCommands) {
43134
- const revisions = this.revisions.getRevertedExecution();
43135
- for (const rev of revisions) {
43136
- if (rev.rootCommand === "SNAPSHOT")
43137
- return undefined;
43138
- if (!rev.rootCommand || rev.rootCommand === "REMOTE")
43139
- continue;
43140
- if (!ignoredRootCommands.includes(rev.rootCommand?.type) && rev.commands.length)
43141
- return rev;
43142
- }
43143
- return undefined;
43161
+ getLastLocalNonEmptyRevision() {
43162
+ return this.lastLocalOperation;
43144
43163
  }
43145
43164
  _move(position) {
43146
43165
  // this method is debounced and might be called after the client
@@ -43200,7 +43219,7 @@ class Session extends EventBus {
43200
43219
  break;
43201
43220
  case "REMOTE_REVISION":
43202
43221
  const { clientId, commands, timestamp } = message;
43203
- const revision = new Revision(message.nextRevisionId, clientId, commands, "REMOTE", undefined, timestamp);
43222
+ const revision = new Revision(message.nextRevisionId, clientId, commands, undefined, undefined, timestamp);
43204
43223
  if (revision.clientId !== this.clientId) {
43205
43224
  this.revisions.insert(revision.id, revision, message.serverRevisionId);
43206
43225
  const pendingCommands = this.pendingMessages
@@ -43213,10 +43232,11 @@ class Session extends EventBus {
43213
43232
  }
43214
43233
  break;
43215
43234
  case "SNAPSHOT_CREATED": {
43216
- const revision = new Revision(message.nextRevisionId, "server", [], "SNAPSHOT", undefined, Date.now());
43235
+ const revision = new Revision(message.nextRevisionId, "server", [], undefined, undefined, Date.now());
43217
43236
  this.revisions.insert(revision.id, revision, message.serverRevisionId);
43218
43237
  this.dropPendingHistoryMessages();
43219
43238
  this.trigger("snapshot");
43239
+ this.lastLocalOperation = undefined;
43220
43240
  break;
43221
43241
  }
43222
43242
  }
@@ -45861,6 +45881,9 @@ class SelectionInputsManagerPlugin extends UIPlugin {
45861
45881
  // Other
45862
45882
  // ---------------------------------------------------------------------------
45863
45883
  initInput(id, initialRanges, inputHasSingleRange = false) {
45884
+ if (this.inputs[id]) {
45885
+ this.unfocus();
45886
+ }
45864
45887
  this.inputs[id] = new SelectionInputPlugin(this.config, initialRanges, inputHasSingleRange);
45865
45888
  if (initialRanges.length === 0) {
45866
45889
  const input = this.inputs[id];
@@ -46569,7 +46592,7 @@ class HistoryPlugin extends UIPlugin {
46569
46592
  * Ignore standard undo/redo revisions (that are empty)
46570
46593
  */
46571
46594
  getPossibleRevisionToRepeat() {
46572
- return this.session.getLastLocalNonEmptyRevision(["REQUEST_REDO"]);
46595
+ return this.session.getLastLocalNonEmptyRevision();
46573
46596
  }
46574
46597
  }
46575
46598
 
@@ -48040,6 +48063,12 @@ class FilterEvaluationPlugin extends UIPlugin {
48040
48063
  break;
48041
48064
  case "HIDE_COLUMNS_ROWS":
48042
48065
  case "UNHIDE_COLUMNS_ROWS":
48066
+ case "GROUP_HEADERS":
48067
+ case "UNGROUP_HEADERS":
48068
+ case "FOLD_HEADER_GROUP":
48069
+ case "UNFOLD_HEADER_GROUP":
48070
+ case "FOLD_ALL_HEADER_GROUPS":
48071
+ case "UNFOLD_ALL_HEADER_GROUPS":
48043
48072
  this.updateHiddenRows();
48044
48073
  break;
48045
48074
  case "UPDATE_FILTER":
@@ -48741,7 +48770,7 @@ class GridSelectionPlugin extends UIPlugin {
48741
48770
  sheetId: cmd.sheetId,
48742
48771
  base: cmd.base,
48743
48772
  quantity: thickness,
48744
- position: "before",
48773
+ position: cmd.position,
48745
48774
  });
48746
48775
  const isCol = cmd.dimension === "COL";
48747
48776
  const start = cmd.elements[0];
@@ -48758,12 +48787,13 @@ class GridSelectionPlugin extends UIPlugin {
48758
48787
  },
48759
48788
  ];
48760
48789
  const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
48790
+ const base = isBasedBefore ? cmd.base : cmd.base + 1;
48761
48791
  const pasteTarget = [
48762
48792
  {
48763
- left: isCol ? cmd.base : 0,
48764
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
48765
- top: !isCol ? cmd.base : 0,
48766
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
48793
+ left: isCol ? base : 0,
48794
+ right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
48795
+ top: !isCol ? base : 0,
48796
+ bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
48767
48797
  },
48768
48798
  ];
48769
48799
  state.paste(pasteTarget, { selectTarget: true });
@@ -48798,6 +48828,11 @@ class GridSelectionPlugin extends UIPlugin {
48798
48828
  doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
48799
48829
  return "WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */;
48800
48830
  }
48831
+ const headers = [cmd.base, ...cmd.elements];
48832
+ const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
48833
+ if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
48834
+ return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
48835
+ }
48801
48836
  return "Success" /* CommandResult.Success */;
48802
48837
  }
48803
48838
  //-------------------------------------------
@@ -48975,9 +49010,6 @@ class InternalViewport {
48975
49010
  */
48976
49011
  adjustPosition(position) {
48977
49012
  const sheetId = this.sheetId;
48978
- if (!position) {
48979
- position = this.getters.getSheetPosition(sheetId);
48980
- }
48981
49013
  const mainCellPosition = this.getters.getMainCellPosition({ sheetId, ...position });
48982
49014
  const { col, row } = this.getters.getNextVisibleCellPosition(mainCellPosition);
48983
49015
  if (isInside(col, this.boundaries.top, this.boundaries)) {
@@ -48990,56 +49022,50 @@ class InternalViewport {
48990
49022
  adjustPositionX(targetCol) {
48991
49023
  const sheetId = this.sheetId;
48992
49024
  const { end } = this.getters.getColDimensions(sheetId, targetCol);
48993
- const maxCol = this.getters.getNumberCols(sheetId);
48994
49025
  if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
49026
+ const maxCol = this.getters.getNumberCols(sheetId);
48995
49027
  let finalTarget = targetCol;
48996
- while (this.getters.isColHidden(sheetId, finalTarget) && targetCol < maxCol) {
49028
+ while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget < maxCol) {
48997
49029
  finalTarget++;
48998
49030
  }
48999
49031
  const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
49000
49032
  const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left);
49001
- this.offsetX =
49033
+ this.offsetScrollbarX =
49002
49034
  this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
49003
- this.offsetScrollbarX = this.offsetX;
49004
- this.adjustViewportZoneX();
49005
49035
  }
49006
49036
  else if (this.left > targetCol) {
49007
49037
  let finalTarget = targetCol;
49008
- while (this.getters.isColHidden(sheetId, finalTarget) && targetCol > 0) {
49038
+ while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget > 0) {
49009
49039
  finalTarget--;
49010
49040
  }
49011
- this.offsetX =
49041
+ this.offsetScrollbarX =
49012
49042
  this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
49013
- this.offsetScrollbarX = this.offsetX;
49014
- this.adjustViewportZoneX();
49015
49043
  }
49044
+ this.adjustViewportZoneX();
49016
49045
  }
49017
49046
  adjustPositionY(targetRow) {
49018
49047
  const sheetId = this.sheetId;
49019
49048
  const { end } = this.getters.getRowDimensions(sheetId, targetRow);
49020
- const maxRow = this.getters.getNumberRows(sheetId);
49021
49049
  if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
49050
+ const maxRow = this.getters.getNumberRows(sheetId);
49022
49051
  let finalTarget = targetRow;
49023
- while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow < maxRow) {
49052
+ while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget < maxRow) {
49024
49053
  finalTarget++;
49025
49054
  }
49026
49055
  const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
49027
49056
  const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top);
49028
- this.offsetY =
49057
+ this.offsetScrollbarY =
49029
49058
  this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
49030
- this.offsetScrollbarY = this.offsetY;
49031
- this.adjustViewportZoneY();
49032
49059
  }
49033
49060
  else if (this.top > targetRow) {
49034
49061
  let finalTarget = targetRow;
49035
- while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow > 0) {
49062
+ while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget > 0) {
49036
49063
  finalTarget--;
49037
49064
  }
49038
- this.offsetY =
49065
+ this.offsetScrollbarY =
49039
49066
  this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
49040
- this.offsetScrollbarY = this.offsetY;
49041
- this.adjustViewportZoneY();
49042
49067
  }
49068
+ this.adjustViewportZoneY();
49043
49069
  }
49044
49070
  setViewportOffset(offsetX, offsetY) {
49045
49071
  this.setViewportOffsetX(offsetX);
@@ -49055,11 +49081,10 @@ class InternalViewport {
49055
49081
  * @returns Computes the absolute coordinate of a given zone inside the viewport
49056
49082
  */
49057
49083
  getRect(zone) {
49058
- const targetZone = intersection(zone, this.zone);
49084
+ const targetZone = intersection(zone, this);
49059
49085
  if (targetZone) {
49060
- const x = this.getters.getColRowOffset("COL", this.zone.left, targetZone.left) +
49061
- this.offsetCorrectionX;
49062
- const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
49086
+ const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) + this.offsetCorrectionX;
49087
+ const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) + this.offsetCorrectionY;
49063
49088
  const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
49064
49089
  const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
49065
49090
  return {
@@ -49069,9 +49094,7 @@ class InternalViewport {
49069
49094
  height,
49070
49095
  };
49071
49096
  }
49072
- else {
49073
- return undefined;
49074
- }
49097
+ return undefined;
49075
49098
  }
49076
49099
  isVisible(col, row) {
49077
49100
  const isInside = row <= this.bottom && row >= this.top && col >= this.left && col <= this.right;
@@ -49079,7 +49102,6 @@ class InternalViewport {
49079
49102
  !this.getters.isColHidden(this.sheetId, col) &&
49080
49103
  !this.getters.isRowHidden(this.sheetId, row));
49081
49104
  }
49082
- // PRIVATE
49083
49105
  searchHeaderIndex(dimension, position, startIndex = 0) {
49084
49106
  const sheetId = this.sheetId;
49085
49107
  const headers = this.getters.getNumberHeaders(sheetId, dimension);
@@ -49102,9 +49124,6 @@ class InternalViewport {
49102
49124
  }
49103
49125
  return -1;
49104
49126
  }
49105
- get zone() {
49106
- return { left: this.left, right: this.right, top: this.top, bottom: this.bottom };
49107
- }
49108
49127
  setViewportOffsetX(offsetX) {
49109
49128
  if (!this.canScrollHorizontally) {
49110
49129
  return;
@@ -49129,11 +49148,6 @@ class InternalViewport {
49129
49148
  this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
49130
49149
  }
49131
49150
  }
49132
- this.left = this.getColIndex(this.offsetScrollbarX);
49133
- this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth);
49134
- if (this.right === -1) {
49135
- this.right = this.boundaries.right;
49136
- }
49137
49151
  this.adjustViewportZoneX();
49138
49152
  }
49139
49153
  /** Corrects the viewport's vertical offset based on the current structure
@@ -49146,11 +49160,6 @@ class InternalViewport {
49146
49160
  this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
49147
49161
  }
49148
49162
  }
49149
- this.top = this.getRowIndex(this.offsetScrollbarY);
49150
- this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportHeight);
49151
- if (this.bottom === -1) {
49152
- this.bottom = this.boundaries.bottom;
49153
- }
49154
49163
  this.adjustViewportZoneY();
49155
49164
  }
49156
49165
  /** Updates the pane zone and snapped offset based on its horizontal
@@ -49528,7 +49537,7 @@ class SheetViewPlugin extends UIPlugin {
49528
49537
  isVisibleInViewport({ sheetId, col, row }) {
49529
49538
  return this.getSubViewports(sheetId).some((pane) => pane.isVisible(col, row));
49530
49539
  }
49531
- // => return s the new offset
49540
+ // => returns the new offset
49532
49541
  getEdgeScrollCol(x, previousX, startingX) {
49533
49542
  let canEdgeScroll = false;
49534
49543
  let direction = 0;
@@ -49843,10 +49852,13 @@ class HeaderPositionsUIPlugin extends UIPlugin {
49843
49852
  }
49844
49853
  break;
49845
49854
  case "UPDATE_CELL":
49846
- if ("content" in cmd || "format" in cmd || cmd.style?.fontSize !== undefined) {
49855
+ if ("content" in cmd || "format" in cmd) {
49847
49856
  this.headerPositions = {};
49848
49857
  this.isDirty = true;
49849
49858
  }
49859
+ else {
49860
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
49861
+ }
49850
49862
  break;
49851
49863
  case "UPDATE_FILTER":
49852
49864
  case "REMOVE_FILTER_TABLE":
@@ -52003,6 +52015,8 @@ css /* scss */ `
52003
52015
  *:before,
52004
52016
  *:after {
52005
52017
  box-sizing: content-box;
52018
+ /** rtl not supported ATM */
52019
+ direction: ltr;
52006
52020
  }
52007
52021
  .o-separator {
52008
52022
  border-bottom: ${MENU_SEPARATOR_BORDER_WIDTH}px solid ${SEPARATOR_COLOR};
@@ -56008,6 +56022,6 @@ const constants = {
56008
56022
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
56009
56023
 
56010
56024
 
56011
- __info__.version = "17.1.0-alpha.4";
56012
- __info__.date = "2023-11-24T13:12:24.882Z";
56013
- __info__.hash = "255821b";
56025
+ __info__.version = "17.1.0-alpha.5";
56026
+ __info__.date = "2023-12-05T09:51:40.034Z";
56027
+ __info__.hash = "c2823eb";