@odoo/o-spreadsheet 16.4.6 → 16.4.8

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.
@@ -611,13 +611,17 @@
611
611
  return position === "after" ? base + 1 : base;
612
612
  }
613
613
  /**
614
- * Compare two objects.
614
+ * Compares two objects.
615
615
  */
616
616
  function deepEquals(o1, o2) {
617
617
  if (o1 === o2)
618
618
  return true;
619
619
  if ((o1 && !o2) || (o2 && !o1))
620
620
  return false;
621
+ if (typeof o1 !== typeof o2)
622
+ return false;
623
+ if (typeof o1 !== "object")
624
+ return o1 === o2;
621
625
  // Objects can have different keys if the values are undefined
622
626
  const keys = new Set();
623
627
  Object.keys(o1).forEach((key) => keys.add(key));
@@ -5262,6 +5266,7 @@
5262
5266
  padding: 10px;
5263
5267
  width: ${ERROR_TOOLTIP_WIDTH}px;
5264
5268
  box-sizing: border-box !important;
5269
+ overflow-wrap: break-word;
5265
5270
  }
5266
5271
  `;
5267
5272
  class ErrorToolTip extends owl.Component {
@@ -5441,6 +5446,9 @@
5441
5446
  });
5442
5447
  this.state.values = this.getFilterValues(this.props.filterPosition);
5443
5448
  }
5449
+ get isReadonly() {
5450
+ return this.env.model.getters.isReadonly();
5451
+ }
5444
5452
  getFilterValues(position) {
5445
5453
  const sheetId = this.env.model.getters.getActiveSheetId();
5446
5454
  const filter = this.env.model.getters.getFilter({ sheetId, ...position });
@@ -15117,13 +15125,42 @@
15117
15125
  }
15118
15126
  return true;
15119
15127
  }
15120
- /** Change a content string to its canonical form (en_US locale) */
15128
+ /**
15129
+ * Change a content string from the given locale to its canonical form (en_US locale). Don't convert date string.
15130
+ *
15131
+ * @example
15132
+ * canonicalizeNumberContent("=SUM(1,5; 02/12/2012)", FR_LOCALE) // "=SUM(1.5, 02/12/2012)"
15133
+ * canonicalizeNumberContent("125,9", FR_LOCALE) // "125.9"
15134
+ * canonicalizeNumberContent("02/12/2012", FR_LOCALE) // "02/12/2012"
15135
+ */
15136
+ function canonicalizeNumberContent(content, locale) {
15137
+ return content.startsWith("=")
15138
+ ? canonicalizeFormula$1(content, locale)
15139
+ : canonicalizeNumberLiteral(content, locale);
15140
+ }
15141
+ /**
15142
+ * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
15143
+ * This is destructive and won't preserve the original format.
15144
+ *
15145
+ * @example
15146
+ * canonicalizeContent("=SUM(1,5; 5)", FR_LOCALE) // "=SUM(1.5, 5)"
15147
+ * canonicalizeContent("125,9", FR_LOCALE) // "125.9"
15148
+ * canonicalizeContent("02/12/2012", FR_LOCALE) // "12/02/2012"
15149
+ * canonicalizeContent("02-12-2012", FR_LOCALE) // "12/02/2012"
15150
+ */
15121
15151
  function canonicalizeContent(content, locale) {
15122
15152
  return content.startsWith("=")
15123
15153
  ? canonicalizeFormula$1(content, locale)
15124
- : toCanonicalNumberString(content, locale);
15154
+ : canonicalizeLiteral(content, locale);
15125
15155
  }
15126
- /** Change the content of a cell to its canonical form (en_US locale) */
15156
+ /**
15157
+ * Change a content string from its canonical form (en_US locale) to the given locale. Also convert date string.
15158
+ *
15159
+ * @example
15160
+ * localizeContent("=SUM(1.5, 5)", FR_LOCALE) // "=SUM(1,5; 5)"
15161
+ * localizeContent("125.9", FR_LOCALE) // "125,9"
15162
+ * localizeContent("12/02/2012", FR_LOCALE) // "02/12/2012"
15163
+ */
15127
15164
  function localizeContent(content, locale) {
15128
15165
  return content.startsWith("=")
15129
15166
  ? localizeFormula(content, locale)
@@ -15158,24 +15195,75 @@
15158
15195
  return localizedFormula;
15159
15196
  }
15160
15197
  /**
15161
- * Replace localized number with localized decimal separator by a number with "." as decimal separator
15198
+ * Change a literal string from the given locale to its canonical form (en_US locale). Don't convert date string.
15199
+ *
15200
+ * @example
15201
+ * canonicalizeNumberLiteral("125,9", FR_LOCALE) // "125.9"
15202
+ * canonicalizeNumberLiteral("02/12/2012", FR_LOCALE) // "02/12/2012"
15162
15203
  */
15163
- function toCanonicalNumberString(content, locale) {
15204
+ function canonicalizeNumberLiteral(content, locale) {
15164
15205
  if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
15165
15206
  return content;
15166
15207
  }
15167
15208
  return content.replace(locale.decimalSeparator, ".");
15168
15209
  }
15169
- function localizeLiteral(content, locale) {
15170
- if (locale.decimalSeparator === "." || !isNumber(content, DEFAULT_LOCALE)) {
15171
- return content;
15210
+ /**
15211
+ * Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
15212
+ * This is destructive and won't preserve the original format.
15213
+ *
15214
+ * @example
15215
+ * canonicalizeLiteral("125,9", FR_LOCALE) // "125.9"
15216
+ * canonicalizeLiteral("02/12/2012", FR_LOCALE) // "12/02/2012"
15217
+ * canonicalizeLiteral("02-12-2012", FR_LOCALE) // "12/02/2012"
15218
+ */
15219
+ function canonicalizeLiteral(content, locale) {
15220
+ if (isDateTime(content, locale)) {
15221
+ const dateNumber = toNumber(content, locale);
15222
+ let format = DEFAULT_LOCALE.dateFormat;
15223
+ if (!Number.isInteger(dateNumber)) {
15224
+ format += " " + DEFAULT_LOCALE.timeFormat;
15225
+ }
15226
+ return formatValue(dateNumber, { locale: DEFAULT_LOCALE, format });
15227
+ }
15228
+ return canonicalizeNumberLiteral(content, locale);
15229
+ }
15230
+ /**
15231
+ * Change a literal string from its canonical form (en_US locale) to the given locale. Don't convert date string.
15232
+ * This is destructive and won't preserve the original format.
15233
+ *
15234
+ * @example
15235
+ * localizeNumberLiteral("125.9", FR_LOCALE) // "125,9"
15236
+ * localizeNumberLiteral("12/02/2012", FR_LOCALE) // "12/02/2012"
15237
+ * localizeNumberLiteral("12-02-2012", FR_LOCALE) // "12/02/2012"
15238
+ */
15239
+ function localizeNumberLiteral(literal, locale) {
15240
+ if (locale.decimalSeparator === "." || !isNumber(literal, DEFAULT_LOCALE)) {
15241
+ return literal;
15172
15242
  }
15173
15243
  const decimalNumberRegex = getDecimalNumberRegex(DEFAULT_LOCALE);
15174
- const localized = content.replace(decimalNumberRegex, (match) => {
15244
+ const localized = literal.replace(decimalNumberRegex, (match) => {
15175
15245
  return match.replace(".", locale.decimalSeparator);
15176
15246
  });
15177
15247
  return localized;
15178
15248
  }
15249
+ /**
15250
+ * Change a literal string from its canonical form (en_US locale) to the given locale. Also convert date string.
15251
+ *
15252
+ * @example
15253
+ * localizeLiteral("125.9", FR_LOCALE) // "125,9"
15254
+ * localizeLiteral("12/02/2012", FR_LOCALE) // "02/12/2012"
15255
+ */
15256
+ function localizeLiteral(literal, locale) {
15257
+ if (isDateTime(literal, DEFAULT_LOCALE)) {
15258
+ const dateNumber = toNumber(literal, DEFAULT_LOCALE);
15259
+ let format = locale.dateFormat;
15260
+ if (!Number.isInteger(dateNumber)) {
15261
+ format += " " + locale.timeFormat;
15262
+ }
15263
+ return formatValue(dateNumber, { locale, format });
15264
+ }
15265
+ return localizeNumberLiteral(literal, locale);
15266
+ }
15179
15267
  function canonicalizeCFRule(cf, locale) {
15180
15268
  return changeCFRuleLocale(cf, (content) => canonicalizeContent(content, locale));
15181
15269
  }
@@ -15532,7 +15620,9 @@
15532
15620
  save() {
15533
15621
  const { col, row } = this.props.cellPosition;
15534
15622
  const locale = this.env.model.getters.getLocale();
15535
- const label = this.link.label ? canonicalizeContent(this.link.label, locale) : this.link.url;
15623
+ const label = this.link.label
15624
+ ? canonicalizeNumberContent(this.link.label, locale)
15625
+ : this.link.url;
15536
15626
  this.env.model.dispatch("UPDATE_CELL", {
15537
15627
  col: col,
15538
15628
  row: row,
@@ -22708,7 +22798,6 @@
22708
22798
  state = owl.useState(this.initialState());
22709
22799
  debounceTimeoutId;
22710
22800
  showFormulaState = false;
22711
- debouncedUpdateSearch;
22712
22801
  findAndReplaceRef = owl.useRef("findAndReplace");
22713
22802
  get hasSearchResult() {
22714
22803
  return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
@@ -22718,9 +22807,9 @@
22718
22807
  }
22719
22808
  setup() {
22720
22809
  this.showFormulaState = this.env.model.getters.shouldShowFormulas();
22721
- this.debouncedUpdateSearch = debounce(this.updateSearch.bind(this), 200);
22722
22810
  owl.onMounted(() => this.focusInput());
22723
22811
  owl.onWillUnmount(() => {
22812
+ clearTimeout(this.debounceTimeoutId);
22724
22813
  this.env.model.dispatch("CLEAR_SEARCH");
22725
22814
  this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.showFormulaState });
22726
22815
  });
@@ -22765,6 +22854,13 @@
22765
22854
  searchOptions: this.state.searchOptions,
22766
22855
  });
22767
22856
  }
22857
+ debouncedUpdateSearch() {
22858
+ clearTimeout(this.debounceTimeoutId);
22859
+ this.debounceTimeoutId = setTimeout(() => {
22860
+ this.updateSearch();
22861
+ this.debounceTimeoutId = undefined;
22862
+ }, 200);
22863
+ }
22768
22864
  replace() {
22769
22865
  this.env.model.dispatch("REPLACE_SEARCH", {
22770
22866
  replaceWith: this.state.replaceWith,
@@ -25302,9 +25398,11 @@
25302
25398
  }
25303
25399
  }
25304
25400
  function updateMousePosition(e) {
25305
- x = e.offsetX;
25306
- y = e.offsetY;
25307
- lastMoved = Date.now();
25401
+ if (gridRef.el === e.target) {
25402
+ x = e.offsetX;
25403
+ y = e.offsetY;
25404
+ lastMoved = Date.now();
25405
+ }
25308
25406
  }
25309
25407
  function recompute() {
25310
25408
  const { col, row } = getPosition();
@@ -36677,8 +36775,7 @@
36677
36775
  if (cell.type === CellValueType.error) {
36678
36776
  return false;
36679
36777
  }
36680
- const locale = this.getters.getLocale();
36681
- const values = rule.values.map((val) => parseLiteral(val, locale));
36778
+ const values = rule.values.map((val) => parseLiteral(val, DEFAULT_LOCALE));
36682
36779
  switch (rule.operator) {
36683
36780
  case "IsEmpty":
36684
36781
  return cell.value.toString().trim() === "";
@@ -38603,14 +38700,10 @@
38603
38700
  case "REPLACE_ALL_SEARCH":
38604
38701
  this.replaceAll(cmd.replaceWith);
38605
38702
  break;
38606
- case "EVALUATE_CELLS":
38607
- case "UPDATE_CELL":
38608
- case "REMOVE_FILTER_TABLE":
38609
- case "UPDATE_FILTER":
38610
- this.isSearchDirty = true;
38611
- break;
38612
38703
  case "UNDO":
38613
38704
  case "REDO":
38705
+ case "REMOVE_FILTER_TABLE":
38706
+ case "UPDATE_FILTER":
38614
38707
  case "REMOVE_COLUMNS_ROWS":
38615
38708
  case "HIDE_COLUMNS_ROWS":
38616
38709
  case "UNHIDE_COLUMNS_ROWS":
@@ -38762,7 +38855,7 @@
38762
38855
  const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
38763
38856
  const toReplace = this.getSearchableString({ sheetId, col, row });
38764
38857
  const content = toReplace.replace(replaceRegex, replaceWith);
38765
- const canonicalContent = canonicalizeContent(content, this.getters.getLocale());
38858
+ const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
38766
38859
  this.dispatch("UPDATE_CELL", { sheetId, col, row, content: canonicalContent });
38767
38860
  }
38768
38861
  /**
@@ -40936,7 +41029,7 @@
40936
41029
  sheetId,
40937
41030
  col: col + index,
40938
41031
  row,
40939
- content: canonicalizeContent(content, this.getters.getLocale()),
41032
+ content: canonicalizeNumberContent(content, this.getters.getLocale()),
40940
41033
  format: "",
40941
41034
  style: mainCell?.style || null,
40942
41035
  });
@@ -41122,6 +41215,7 @@
41122
41215
  cells;
41123
41216
  copiedTables;
41124
41217
  zones;
41218
+ uuidGenerator = new UuidGenerator();
41125
41219
  constructor(zones, operation, getters, dispatch, selection) {
41126
41220
  super(operation, getters, dispatch, selection);
41127
41221
  if (!zones.length) {
@@ -41270,7 +41364,7 @@
41270
41364
  });
41271
41365
  for (const filterTable of this.copiedTables) {
41272
41366
  this.dispatch("REMOVE_FILTER_TABLE", {
41273
- sheetId: this.getters.getActiveSheetId(),
41367
+ sheetId: this.sheetId,
41274
41368
  target: [filterTable.zone],
41275
41369
  });
41276
41370
  }
@@ -41583,8 +41677,9 @@
41583
41677
  this.adaptCFRules(origin.sheetId, cf, [xc], toRemoveRange);
41584
41678
  }
41585
41679
  else {
41586
- this.adaptCFRules(target.sheetId, cf, [xc], []);
41587
41680
  this.adaptCFRules(origin.sheetId, cf, [], toRemoveRange);
41681
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
41682
+ this.adaptCFRules(target.sheetId, cfToCopyTo, [xc], []);
41588
41683
  }
41589
41684
  }
41590
41685
  }
@@ -41608,6 +41703,12 @@
41608
41703
  sheetId,
41609
41704
  });
41610
41705
  }
41706
+ getCFToCopyTo(targetSheetId, originCF) {
41707
+ const cfInTarget = this.getters
41708
+ .getConditionalFormats(targetSheetId)
41709
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
41710
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
41711
+ }
41611
41712
  }
41612
41713
 
41613
41714
  /** State of the clipboard when copying/cutting figures */
@@ -41739,7 +41840,7 @@
41739
41840
  function canonicalizeNumberValue(content, locale) {
41740
41841
  return content.startsWith("=")
41741
41842
  ? canonicalizeFormula(content, locale)
41742
- : toCanonicalNumberString(content, locale);
41843
+ : canonicalizeNumberLiteral(content, locale);
41743
41844
  }
41744
41845
  /** Change a formula to its canonical form (en_US locale) */
41745
41846
  function canonicalizeFormula(formula, locale) {
@@ -41856,7 +41957,7 @@
41856
41957
  allowDispatch(cmd) {
41857
41958
  switch (cmd.type) {
41858
41959
  case "CUT":
41859
- const zones = cmd.cutTarget || this.getters.getSelectedZones();
41960
+ const zones = this.getters.getSelectedZones();
41860
41961
  const state = this.getClipboardState(zones, cmd.type);
41861
41962
  return state.isCutAllowed(zones);
41862
41963
  case "PASTE":
@@ -41891,7 +41992,7 @@
41891
41992
  switch (cmd.type) {
41892
41993
  case "COPY":
41893
41994
  case "CUT":
41894
- const zones = ("cutTarget" in cmd && cmd.cutTarget) || this.getters.getSelectedZones();
41995
+ const zones = this.getters.getSelectedZones();
41895
41996
  this.state = this.getClipboardState(zones, cmd.type);
41896
41997
  this.status = "visible";
41897
41998
  this.originSheetId = this.getters.getActiveSheetId();
@@ -42541,7 +42642,7 @@
42541
42642
  if (content) {
42542
42643
  const sheetId = this.getters.getActiveSheetId();
42543
42644
  const cell = this.getters.getEvaluatedCell({ sheetId, col: this.col, row: this.row });
42544
- content = canonicalizeContent(content, this.getters.getLocale());
42645
+ content = canonicalizeNumberContent(content, this.getters.getLocale());
42545
42646
  if (content.startsWith("=")) {
42546
42647
  const left = this.currentTokens.filter((t) => t.type === "LEFT_PAREN").length;
42547
42648
  const right = this.currentTokens.filter((t) => t.type === "RIGHT_PAREN").length;
@@ -43562,26 +43663,24 @@
43562
43663
  const isBasedBefore = cmd.base < start;
43563
43664
  const deltaCol = isBasedBefore && isCol ? thickness : 0;
43564
43665
  const deltaRow = isBasedBefore && !isCol ? thickness : 0;
43565
- this.dispatch("CUT", {
43566
- cutTarget: [
43567
- {
43568
- left: isCol ? start + deltaCol : 0,
43569
- right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
43570
- top: !isCol ? start + deltaRow : 0,
43571
- bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
43572
- },
43573
- ],
43574
- });
43575
- this.dispatch("PASTE", {
43576
- target: [
43577
- {
43578
- left: isCol ? cmd.base : 0,
43579
- right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
43580
- top: !isCol ? cmd.base : 0,
43581
- bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
43582
- },
43583
- ],
43584
- });
43666
+ const target = [
43667
+ {
43668
+ left: isCol ? start + deltaCol : 0,
43669
+ right: isCol ? end + deltaCol : this.getters.getNumberCols(cmd.sheetId) - 1,
43670
+ top: !isCol ? start + deltaRow : 0,
43671
+ bottom: !isCol ? end + deltaRow : this.getters.getNumberRows(cmd.sheetId) - 1,
43672
+ },
43673
+ ];
43674
+ const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
43675
+ const pasteTarget = [
43676
+ {
43677
+ left: isCol ? cmd.base : 0,
43678
+ right: isCol ? cmd.base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
43679
+ top: !isCol ? cmd.base : 0,
43680
+ bottom: !isCol ? cmd.base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
43681
+ },
43682
+ ];
43683
+ state.paste(pasteTarget, { selectTarget: true });
43585
43684
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
43586
43685
  let currentIndex = cmd.base;
43587
43686
  for (const element of toRemove) {
@@ -43806,30 +43905,26 @@
43806
43905
  const { end } = this.getters.getColDimensions(sheetId, targetCol);
43807
43906
  const maxCol = this.getters.getNumberCols(sheetId);
43808
43907
  if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
43809
- for (let col = this.left; this.offsetX + this.offsetCorrectionX + this.viewportWidth < end; col++) {
43810
- if (col > maxCol) {
43811
- break;
43812
- }
43813
- if (this.getters.isColHidden(sheetId, col)) {
43814
- continue;
43815
- }
43816
- this.offsetX = this.getters.getColDimensions(sheetId, col).end - this.offsetCorrectionX;
43817
- this.offsetScrollbarX = this.offsetX;
43818
- this.adjustViewportZoneX();
43908
+ let finalTarget = targetCol;
43909
+ while (this.getters.isColHidden(sheetId, finalTarget) && targetCol < maxCol) {
43910
+ finalTarget++;
43819
43911
  }
43912
+ const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
43913
+ const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left, true);
43914
+ this.offsetX =
43915
+ this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
43916
+ this.offsetScrollbarX = this.offsetX;
43917
+ this.adjustViewportZoneX();
43820
43918
  }
43821
43919
  else if (this.left > targetCol) {
43822
- for (let col = this.left; col >= targetCol; col--) {
43823
- if (col < 0) {
43824
- break;
43825
- }
43826
- if (this.getters.isColHidden(sheetId, col)) {
43827
- continue;
43828
- }
43829
- this.offsetX = this.getters.getColDimensions(sheetId, col).start - this.offsetCorrectionX;
43830
- this.offsetScrollbarX = this.offsetX;
43831
- this.adjustViewportZoneX();
43920
+ let finalTarget = targetCol;
43921
+ while (this.getters.isColHidden(sheetId, finalTarget) && targetCol > 0) {
43922
+ finalTarget--;
43832
43923
  }
43924
+ this.offsetX =
43925
+ this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
43926
+ this.offsetScrollbarX = this.offsetX;
43927
+ this.adjustViewportZoneX();
43833
43928
  }
43834
43929
  }
43835
43930
  adjustPositionY(targetRow) {
@@ -43837,30 +43932,26 @@
43837
43932
  const { end } = this.getters.getRowDimensions(sheetId, targetRow);
43838
43933
  const maxRow = this.getters.getNumberRows(sheetId);
43839
43934
  if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
43840
- for (let row = this.top; this.offsetY + this.viewportHeight + this.offsetCorrectionY < end; row++) {
43841
- if (row > maxRow) {
43842
- break;
43843
- }
43844
- if (this.getters.isRowHidden(sheetId, row)) {
43845
- continue;
43846
- }
43847
- this.offsetY = this.getters.getRowDimensions(sheetId, row).end - this.offsetCorrectionY;
43848
- this.offsetScrollbarY = this.offsetY;
43849
- this.adjustViewportZoneY();
43935
+ let finalTarget = targetRow;
43936
+ while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow < maxRow) {
43937
+ finalTarget++;
43850
43938
  }
43939
+ const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
43940
+ const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top, true);
43941
+ this.offsetY =
43942
+ this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
43943
+ this.offsetScrollbarY = this.offsetY;
43944
+ this.adjustViewportZoneY();
43851
43945
  }
43852
43946
  else if (this.top > targetRow) {
43853
- for (let row = this.top; row >= targetRow; row--) {
43854
- if (row < 0) {
43855
- break;
43856
- }
43857
- if (this.getters.isRowHidden(sheetId, row)) {
43858
- continue;
43859
- }
43860
- this.offsetY = this.getters.getRowDimensions(sheetId, row).start - this.offsetCorrectionY;
43861
- this.offsetScrollbarY = this.offsetY;
43862
- this.adjustViewportZoneY();
43947
+ let finalTarget = targetRow;
43948
+ while (this.getters.isRowHidden(sheetId, finalTarget) && targetRow > 0) {
43949
+ finalTarget--;
43863
43950
  }
43951
+ this.offsetY =
43952
+ this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
43953
+ this.offsetScrollbarY = this.offsetY;
43954
+ this.adjustViewportZoneY();
43864
43955
  }
43865
43956
  }
43866
43957
  setViewportOffset(offsetX, offsetY) {
@@ -50601,9 +50692,9 @@
50601
50692
  Object.defineProperty(exports, '__esModule', { value: true });
50602
50693
 
50603
50694
 
50604
- __info__.version = '16.4.6';
50605
- __info__.date = '2023-09-12T11:43:54.243Z';
50606
- __info__.hash = '5746355';
50695
+ __info__.version = '16.4.8';
50696
+ __info__.date = '2023-10-03T12:45:33.807Z';
50697
+ __info__.hash = 'c614d64';
50607
50698
 
50608
50699
 
50609
50700
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);