@odoo/o-spreadsheet 18.1.2 → 18.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 18.1.2
6
- * @date 2025-01-15T08:06:07.728Z
7
- * @hash 002aa4a
5
+ * @version 18.1.4
6
+ * @date 2025-01-29T06:27:32.901Z
7
+ * @hash a11ef27
8
8
  */
9
9
 
10
10
  import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
@@ -4378,15 +4378,18 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
4378
4378
  let currentIndex;
4379
4379
  let currentVal;
4380
4380
  let currentType;
4381
+ const getValue = sortOrder === "desc"
4382
+ ? (i) => normalizeValue(getValueInData(data, rangeLength - i - 1))
4383
+ : (i) => normalizeValue(getValueInData(data, i));
4381
4384
  while (indexRight - indexLeft >= 0) {
4382
4385
  indexMedian = Math.floor((indexLeft + indexRight) / 2);
4383
4386
  currentIndex = indexMedian;
4384
- currentVal = normalizeValue(getValueInData(data, currentIndex));
4387
+ currentVal = getValue(currentIndex);
4385
4388
  currentType = typeof currentVal;
4386
4389
  // 1 - linear search to find value with the same type
4387
4390
  while (indexLeft < currentIndex && targetType !== currentType) {
4388
4391
  currentIndex--;
4389
- currentVal = normalizeValue(getValueInData(data, currentIndex));
4392
+ currentVal = getValue(currentIndex);
4390
4393
  currentType = typeof currentVal;
4391
4394
  }
4392
4395
  if (currentType !== targetType || currentVal === undefined || currentVal === null) {
@@ -4402,8 +4405,7 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
4402
4405
  if (matchVal === undefined ||
4403
4406
  matchVal === null ||
4404
4407
  matchVal < currentVal ||
4405
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
4406
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
4408
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
4407
4409
  matchVal = currentVal;
4408
4410
  matchValIndex = currentIndex;
4409
4411
  }
@@ -4411,15 +4413,13 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
4411
4413
  else if (mode === "nextGreater" && currentVal >= _target) {
4412
4414
  if (matchVal === undefined ||
4413
4415
  matchVal > currentVal ||
4414
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
4415
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
4416
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
4416
4417
  matchVal = currentVal;
4417
4418
  matchValIndex = currentIndex;
4418
4419
  }
4419
4420
  }
4420
4421
  // 3 - give new indexes for the Binary search
4421
- if ((sortOrder === "asc" && currentVal > _target) ||
4422
- (sortOrder === "desc" && currentVal <= _target)) {
4422
+ if (currentVal > _target || (mode === "strict" && currentVal === _target)) {
4423
4423
  indexRight = currentIndex - 1;
4424
4424
  }
4425
4425
  else {
@@ -4427,7 +4427,10 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
4427
4427
  }
4428
4428
  }
4429
4429
  // note that valMinIndex could be 0
4430
- return matchValIndex !== undefined ? matchValIndex : -1;
4430
+ if (matchValIndex === undefined) {
4431
+ return -1;
4432
+ }
4433
+ return sortOrder === "desc" ? rangeLength - matchValIndex - 1 : matchValIndex;
4431
4434
  }
4432
4435
  /**
4433
4436
  * Perform a linear search and return the index of the match.
@@ -9653,13 +9656,13 @@ function toExcelDataset(getters, ds) {
9653
9656
  else if (ds.labelCell) {
9654
9657
  label = {
9655
9658
  reference: getters.getRangeString(ds.labelCell, "forceSheetReference", {
9656
- useFixedReference: true,
9659
+ useBoundedReference: true,
9657
9660
  }),
9658
9661
  };
9659
9662
  }
9660
9663
  return {
9661
9664
  label,
9662
- range: getters.getRangeString(dataRange, "forceSheetReference", { useFixedReference: true }),
9665
+ range: getters.getRangeString(dataRange, "forceSheetReference", { useBoundedReference: true }),
9663
9666
  backgroundColor: ds.backgroundColor,
9664
9667
  rightYAxis: ds.rightYAxis,
9665
9668
  };
@@ -9674,7 +9677,7 @@ function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
9674
9677
  zone.top = zone.top + 1;
9675
9678
  }
9676
9679
  const range = labelRange.clone({ zone });
9677
- return getters.getRangeString(range, "forceSheetReference", { useFixedReference: true });
9680
+ return getters.getRangeString(range, "forceSheetReference", { useBoundedReference: true });
9678
9681
  }
9679
9682
  /**
9680
9683
  * Transform a chart definition which supports dataSets (dataSets and LabelRange)
@@ -32201,6 +32204,10 @@ class Popover extends Component {
32201
32204
  this.currentDisplayValue = newDisplay;
32202
32205
  if (!anchor)
32203
32206
  return;
32207
+ el.style.top = "";
32208
+ el.style.left = "";
32209
+ el.style["max-height"] = "";
32210
+ el.style["max-width"] = "";
32204
32211
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
32205
32212
  let elDims = {
32206
32213
  width: el.getBoundingClientRect().width,
@@ -48636,7 +48643,7 @@ class GridComposer extends Component {
48636
48643
  return;
48637
48644
  }
48638
48645
  const sheetId = this.env.model.getters.getActiveSheetId();
48639
- const zone = this.env.model.getters.getSelectedZone();
48646
+ const zone = positionToZone(this.env.model.getters.getSelection().anchor.cell);
48640
48647
  const rect = this.env.model.getters.getVisibleRect(zone);
48641
48648
  if (!deepEquals(rect, this.rect) || sheetId !== this.composerStore.currentEditedCell.sheetId) {
48642
48649
  this.isCellReferenceVisible = true;
@@ -50472,13 +50479,23 @@ class GridRenderer {
50472
50479
  drawLayer(renderingContext, layer) {
50473
50480
  switch (layer) {
50474
50481
  case "Background":
50475
- const boxes = this.getGridBoxes();
50476
- this.drawBackground(renderingContext, boxes);
50477
- this.drawOverflowingCellBackground(renderingContext, boxes);
50478
- this.drawCellBackground(renderingContext, boxes);
50479
- this.drawBorders(renderingContext, boxes);
50480
- this.drawTexts(renderingContext, boxes);
50481
- this.drawIcon(renderingContext, boxes);
50482
+ this.drawGlobalBackground(renderingContext);
50483
+ for (const zone of this.getters.getAllActiveViewportsZones()) {
50484
+ const { ctx } = renderingContext;
50485
+ ctx.save();
50486
+ ctx.beginPath();
50487
+ const rect = this.getters.getVisibleRect(zone);
50488
+ ctx.rect(rect.x, rect.y, rect.width, rect.height);
50489
+ ctx.clip();
50490
+ const boxes = this.getGridBoxes(zone);
50491
+ this.drawBackground(renderingContext, boxes);
50492
+ this.drawOverflowingCellBackground(renderingContext, boxes);
50493
+ this.drawCellBackground(renderingContext, boxes);
50494
+ this.drawBorders(renderingContext, boxes);
50495
+ this.drawTexts(renderingContext, boxes);
50496
+ this.drawIcon(renderingContext, boxes);
50497
+ ctx.restore();
50498
+ }
50482
50499
  this.drawFrozenPanes(renderingContext);
50483
50500
  break;
50484
50501
  case "Headers":
@@ -50489,12 +50506,15 @@ class GridRenderer {
50489
50506
  break;
50490
50507
  }
50491
50508
  }
50492
- drawBackground(renderingContext, boxes) {
50493
- const { ctx, thinLineWidth } = renderingContext;
50509
+ drawGlobalBackground(renderingContext) {
50510
+ const { ctx } = renderingContext;
50494
50511
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
50495
50512
  // white background
50496
50513
  ctx.fillStyle = "#ffffff";
50497
50514
  ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
50515
+ }
50516
+ drawBackground(renderingContext, boxes) {
50517
+ const { ctx, thinLineWidth } = renderingContext;
50498
50518
  const areGridLinesVisible = !this.getters.isDashboard() &&
50499
50519
  this.getters.getGridLinesVisibility(this.getters.getActiveSheetId());
50500
50520
  const inset = areGridLinesVisible ? 0.1 * thinLineWidth : 0;
@@ -50925,7 +50945,7 @@ class GridRenderer {
50925
50945
  const position = { sheetId, col, row };
50926
50946
  const cell = this.getters.getEvaluatedCell(position);
50927
50947
  const showFormula = this.getters.shouldShowFormulas();
50928
- const { x, y, width, height } = this.getters.getVisibleRect(zone);
50948
+ const { x, y, width, height } = this.getters.getRect(zone);
50929
50949
  const { verticalAlign } = this.getters.getCellStyle(position);
50930
50950
  let style = this.getters.getCellComputedStyle(position);
50931
50951
  if (this.fingerprints.isEnabled) {
@@ -51050,12 +51070,16 @@ class GridRenderer {
51050
51070
  }
51051
51071
  return box;
51052
51072
  }
51053
- getGridBoxes() {
51073
+ getGridBoxes(zone) {
51054
51074
  const boxes = [];
51055
- const visibleCols = this.getters.getSheetViewVisibleCols();
51075
+ const visibleCols = this.getters
51076
+ .getSheetViewVisibleCols()
51077
+ .filter((col) => col >= zone.left && col <= zone.right);
51056
51078
  const left = visibleCols[0];
51057
51079
  const right = visibleCols[visibleCols.length - 1];
51058
- const visibleRows = this.getters.getSheetViewVisibleRows();
51080
+ const visibleRows = this.getters
51081
+ .getSheetViewVisibleRows()
51082
+ .filter((row) => row >= zone.top && row <= zone.bottom);
51059
51083
  const top = visibleRows[0];
51060
51084
  const bottom = visibleRows[visibleRows.length - 1];
51061
51085
  const viewport = { left, right, top, bottom };
@@ -53287,7 +53311,7 @@ class CellPlugin extends CorePlugin {
53287
53311
  /*
53288
53312
  * Reconstructs the original formula string based on new dependencies
53289
53313
  */
53290
- getFormulaString(sheetId, tokens, dependencies, useFixedReference = false) {
53314
+ getFormulaString(sheetId, tokens, dependencies, useBoundedReference = false) {
53291
53315
  if (!dependencies.length) {
53292
53316
  return concat(tokens.map((token) => token.value));
53293
53317
  }
@@ -53295,7 +53319,7 @@ class CellPlugin extends CorePlugin {
53295
53319
  return concat(tokens.map((token) => {
53296
53320
  if (token.type === "REFERENCE") {
53297
53321
  const range = dependencies[rangeIndex++];
53298
- return this.getters.getRangeString(range, sheetId, { useFixedReference });
53322
+ return this.getters.getRangeString(range, sheetId, { useBoundedReference });
53299
53323
  }
53300
53324
  return token.value;
53301
53325
  }));
@@ -53575,7 +53599,7 @@ class FormulaCellWithDependencies {
53575
53599
  if (token.type === "REFERENCE") {
53576
53600
  const index = rangeIndex++;
53577
53601
  return this.getRangeString(this.compiledFormula.dependencies[index], this.sheetId, {
53578
- useFixedReference: true,
53602
+ useBoundedReference: true,
53579
53603
  });
53580
53604
  }
53581
53605
  return token.value;
@@ -53912,7 +53936,7 @@ class ConditionalFormatPlugin extends CorePlugin {
53912
53936
  if (data.sheets) {
53913
53937
  for (let sheet of data.sheets) {
53914
53938
  if (this.cfRules[sheet.id]) {
53915
- sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
53939
+ sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useBoundedReference: true }));
53916
53940
  }
53917
53941
  }
53918
53942
  }
@@ -53981,9 +54005,9 @@ class ConditionalFormatPlugin extends CorePlugin {
53981
54005
  // ---------------------------------------------------------------------------
53982
54006
  // Private
53983
54007
  // ---------------------------------------------------------------------------
53984
- mapToConditionalFormat(sheetId, cf, { useFixedReference } = { useFixedReference: false }) {
54008
+ mapToConditionalFormat(sheetId, cf, { useBoundedReference } = { useBoundedReference: false }) {
53985
54009
  const ranges = cf.ranges.map((range) => {
53986
- return this.getters.getRangeString(range, sheetId, { useFixedReference });
54010
+ return this.getters.getRangeString(range, sheetId, { useBoundedReference });
53987
54011
  });
53988
54012
  if (cf.rule.type !== "DataBarRule") {
53989
54013
  return {
@@ -53998,7 +54022,7 @@ class ConditionalFormatPlugin extends CorePlugin {
53998
54022
  ...cf.rule,
53999
54023
  rangeValues: cf.rule.rangeValues &&
54000
54024
  this.getters.getRangeString(cf.rule.rangeValues, sheetId, {
54001
- useFixedReference,
54025
+ useBoundedReference,
54002
54026
  }),
54003
54027
  },
54004
54028
  ranges,
@@ -54439,10 +54463,20 @@ class DataValidationPlugin extends CorePlugin {
54439
54463
  for (const sheet of data.sheets) {
54440
54464
  sheet.dataValidationRules = [];
54441
54465
  for (const rule of this.rules[sheet.id]) {
54442
- sheet.dataValidationRules.push({
54443
- ...rule,
54444
- ranges: rule.ranges.map((range) => this.getters.getRangeString(range, sheet.id, { useFixedReference: true })),
54445
- });
54466
+ const excelRule = {
54467
+ ...deepCopy(rule),
54468
+ ranges: rule.ranges.map((range) => this.getters.getRangeString(range, sheet.id, { useBoundedReference: true })),
54469
+ };
54470
+ if (rule.criterion.type === "isValueInRange") {
54471
+ excelRule.criterion.values = rule.criterion.values.map((value) => {
54472
+ const range = this.getters.getRangeFromSheetXC(sheet.id, value);
54473
+ return this.getters.getRangeString(range, sheet.id, {
54474
+ useBoundedReference: true,
54475
+ useFixedReference: true,
54476
+ });
54477
+ });
54478
+ }
54479
+ sheet.dataValidationRules.push(excelRule);
54446
54480
  }
54447
54481
  }
54448
54482
  }
@@ -55863,9 +55897,10 @@ class RangeAdapter {
55863
55897
  * @param range the range (received from getRangeFromXC or getRangeFromZone)
55864
55898
  * @param forSheetId the id of the sheet where the range string is supposed to be used.
55865
55899
  * @param options
55900
+ * @param options.useBoundedReference if true, the range will be returned with bounded row and column
55866
55901
  * @param options.useFixedReference if true, the range will be returned with fixed row and column
55867
55902
  */
55868
- getRangeString(range, forSheetId, options = { useFixedReference: false }) {
55903
+ getRangeString(range, forSheetId, options = { useBoundedReference: false, useFixedReference: false }) {
55869
55904
  if (!range) {
55870
55905
  return CellErrorType.InvalidReference;
55871
55906
  }
@@ -55968,13 +56003,13 @@ class RangeAdapter {
55968
56003
  /**
55969
56004
  * Get a Xc string that represent a part of a range
55970
56005
  */
55971
- getRangePartString(range, part, options = { useFixedReference: false }) {
55972
- const colFixed = range.parts && range.parts[part]?.colFixed ? "$" : "";
56006
+ getRangePartString(range, part, options = { useBoundedReference: false, useFixedReference: false }) {
56007
+ const colFixed = range.parts[part]?.colFixed || options.useFixedReference ? "$" : "";
55973
56008
  const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
55974
- const rowFixed = range.parts && range.parts[part]?.rowFixed ? "$" : "";
56009
+ const rowFixed = range.parts[part]?.rowFixed || options.useFixedReference ? "$" : "";
55975
56010
  const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
55976
56011
  let str = "";
55977
- if (range.isFullCol && !options.useFixedReference) {
56012
+ if (range.isFullCol && !options.useBoundedReference) {
55978
56013
  if (part === 0 && range.unboundedZone.hasHeader) {
55979
56014
  str = colFixed + col + rowFixed + row;
55980
56015
  }
@@ -55982,7 +56017,7 @@ class RangeAdapter {
55982
56017
  str = colFixed + col;
55983
56018
  }
55984
56019
  }
55985
- else if (range.isFullRow && !options.useFixedReference) {
56020
+ else if (range.isFullRow && !options.useBoundedReference) {
55986
56021
  if (part === 0 && range.unboundedZone.hasHeader) {
55987
56022
  str = colFixed + col + rowFixed + row;
55988
56023
  }
@@ -63161,6 +63196,7 @@ class Session extends EventBus {
63161
63196
  waitingUndoRedoAck = false;
63162
63197
  isReplayingInitialRevisions = false;
63163
63198
  processedRevisions = new Set();
63199
+ lastRevisionMessage = undefined;
63164
63200
  uuidGenerator = new UuidGenerator();
63165
63201
  lastLocalOperation;
63166
63202
  /**
@@ -63261,7 +63297,10 @@ class Session extends EventBus {
63261
63297
  * Notify the server that the user client left the collaborative session
63262
63298
  */
63263
63299
  async leave(data) {
63264
- if (data && Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
63300
+ if (data &&
63301
+ Object.keys(this.clients).length === 1 &&
63302
+ this.lastRevisionMessage &&
63303
+ this.lastRevisionMessage?.type !== "SNAPSHOT_CREATED") {
63265
63304
  await this.snapshot(data());
63266
63305
  }
63267
63306
  delete this.clients[this.clientId];
@@ -63482,6 +63521,7 @@ class Session extends EventBus {
63482
63521
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
63483
63522
  this.serverRevisionId = message.nextRevisionId;
63484
63523
  this.processedRevisions.add(message.nextRevisionId);
63524
+ this.lastRevisionMessage = message;
63485
63525
  this.sendPendingMessage();
63486
63526
  break;
63487
63527
  }
@@ -66721,8 +66761,12 @@ class GridSelectionPlugin extends UIPlugin {
66721
66761
  },
66722
66762
  ];
66723
66763
  handler.paste({ zones: pasteTarget, sheetId }, data, { isCutOperation: true });
66764
+ const selection = pasteTarget[0];
66765
+ const col = selection.left;
66766
+ const row = selection.top;
66767
+ this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
66724
66768
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
66725
- let currentIndex = cmd.base;
66769
+ let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
66726
66770
  const resizingGroups = {};
66727
66771
  for (const element of toRemove) {
66728
66772
  const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
@@ -67013,22 +67057,33 @@ class InternalViewport {
67013
67057
  }
67014
67058
  /**
67015
67059
  *
67016
- * @param zone
67017
- * @returns Computes the absolute coordinate of a given zone inside the viewport
67060
+ * Computes the visible coordinates & dimensions of a given zone inside the viewport
67061
+ *
67018
67062
  */
67019
- getRect(zone) {
67063
+ getVisibleRect(zone) {
67020
67064
  const targetZone = intersection(zone, this);
67021
67065
  if (targetZone) {
67022
67066
  const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) + this.offsetCorrectionX;
67023
67067
  const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) + this.offsetCorrectionY;
67024
67068
  const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
67025
67069
  const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
67026
- return {
67027
- x,
67028
- y,
67029
- width,
67030
- height,
67031
- };
67070
+ return { x, y, width, height };
67071
+ }
67072
+ return undefined;
67073
+ }
67074
+ /**
67075
+ *
67076
+ * @returns Computes the absolute coordinates & dimensions of a given zone inside the viewport
67077
+ *
67078
+ */
67079
+ getFullRect(zone) {
67080
+ const targetZone = intersection(zone, this);
67081
+ if (targetZone) {
67082
+ const x = this.getters.getColRowOffset("COL", this.left, zone.left) + this.offsetCorrectionX;
67083
+ const y = this.getters.getColRowOffset("ROW", this.top, zone.top) + this.offsetCorrectionY;
67084
+ const width = this.getters.getColRowOffset("COL", zone.left, zone.right + 1);
67085
+ const height = this.getters.getColRowOffset("ROW", zone.top, zone.bottom + 1);
67086
+ return { x, y, width, height };
67032
67087
  }
67033
67088
  return undefined;
67034
67089
  }
@@ -67198,6 +67253,8 @@ class SheetViewPlugin extends UIPlugin {
67198
67253
  "isPositionVisible",
67199
67254
  "getColDimensionsInViewport",
67200
67255
  "getRowDimensionsInViewport",
67256
+ "getAllActiveViewportsZones",
67257
+ "getRect",
67201
67258
  ];
67202
67259
  viewports = {};
67203
67260
  /**
@@ -67581,16 +67638,27 @@ class SheetViewPlugin extends UIPlugin {
67581
67638
  getVisibleRectWithoutHeaders(zone) {
67582
67639
  const sheetId = this.getters.getActiveSheetId();
67583
67640
  const viewportRects = this.getSubViewports(sheetId)
67584
- .map((viewport) => viewport.getRect(zone))
67641
+ .map((viewport) => viewport.getVisibleRect(zone))
67585
67642
  .filter(isDefined);
67586
67643
  if (viewportRects.length === 0) {
67587
67644
  return { x: 0, y: 0, width: 0, height: 0 };
67588
67645
  }
67589
- const x = Math.min(...viewportRects.map((rect) => rect.x));
67590
- const y = Math.min(...viewportRects.map((rect) => rect.y));
67591
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
67592
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
67593
- return { x, y, width, height };
67646
+ return this.recomposeRect(viewportRects);
67647
+ }
67648
+ /**
67649
+ * Computes the actual size and position (:Rect) of the zone on the canvas
67650
+ * regardless of the viewport dimensions.
67651
+ */
67652
+ getRect(zone) {
67653
+ const sheetId = this.getters.getActiveSheetId();
67654
+ const viewportRects = this.getSubViewports(sheetId)
67655
+ .map((viewport) => viewport.getFullRect(zone))
67656
+ .filter(isDefined);
67657
+ if (viewportRects.length === 0) {
67658
+ return { x: 0, y: 0, width: 0, height: 0 };
67659
+ }
67660
+ const rect = this.recomposeRect(viewportRects);
67661
+ return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
67594
67662
  }
67595
67663
  /**
67596
67664
  * Returns the position of the MainViewport relatively to the start of the grid (without headers)
@@ -67634,6 +67702,10 @@ class SheetViewPlugin extends UIPlugin {
67634
67702
  end: start + (isRowHidden ? 0 : size),
67635
67703
  };
67636
67704
  }
67705
+ getAllActiveViewportsZones() {
67706
+ const sheetId = this.getters.getActiveSheetId();
67707
+ return this.getSubViewports(sheetId);
67708
+ }
67637
67709
  // ---------------------------------------------------------------------------
67638
67710
  // Private
67639
67711
  // ---------------------------------------------------------------------------
@@ -67824,6 +67896,13 @@ class SheetViewPlugin extends UIPlugin {
67824
67896
  const height = this.sheetViewHeight + this.gridOffsetY;
67825
67897
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
67826
67898
  }
67899
+ recomposeRect(viewportRects) {
67900
+ const x = Math.min(...viewportRects.map((rect) => rect.x));
67901
+ const y = Math.min(...viewportRects.map((rect) => rect.y));
67902
+ const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
67903
+ const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
67904
+ return { x, y, width, height };
67905
+ }
67827
67906
  }
67828
67907
 
67829
67908
  class HeaderPositionsUIPlugin extends UIPlugin {
@@ -74908,6 +74987,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
74908
74987
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
74909
74988
 
74910
74989
 
74911
- __info__.version = "18.1.2";
74912
- __info__.date = "2025-01-15T08:06:07.728Z";
74913
- __info__.hash = "002aa4a";
74990
+ __info__.version = "18.1.4";
74991
+ __info__.date = "2025-01-29T06:27:32.901Z";
74992
+ __info__.hash = "a11ef27";