@odoo/o-spreadsheet 18.0.32 → 18.0.34

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.0.32
6
- * @date 2025-06-06T09:29:16.581Z
7
- * @hash bef1e2b
5
+ * @version 18.0.34
6
+ * @date 2025-06-19T18:26:11.726Z
7
+ * @hash 5526881
8
8
  */
9
9
 
10
10
  'use strict';
@@ -5678,7 +5678,9 @@ function isTextFormat(format) {
5678
5678
  }
5679
5679
 
5680
5680
  function evaluateLiteral(literalCell, localeFormat) {
5681
- const value = isTextFormat(localeFormat.format) ? literalCell.content : literalCell.parsedValue;
5681
+ const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
5682
+ ? literalCell.content
5683
+ : literalCell.parsedValue;
5682
5684
  const functionResult = { value, format: localeFormat.format };
5683
5685
  return createEvaluatedCell(functionResult, localeFormat.locale);
5684
5686
  }
@@ -5727,6 +5729,9 @@ function _createEvaluatedCell(functionResult, locale, cell) {
5727
5729
  if (isEvaluationError(value)) {
5728
5730
  return errorCell(value, message);
5729
5731
  }
5732
+ if (value === null) {
5733
+ return emptyCell(format);
5734
+ }
5730
5735
  if (isTextFormat(format)) {
5731
5736
  // TO DO:
5732
5737
  // with the next line, the value of the cell is transformed depending on the format.
@@ -5734,9 +5739,6 @@ function _createEvaluatedCell(functionResult, locale, cell) {
5734
5739
  // to interpret the value as a number.
5735
5740
  return textCell(toString(value), format, formattedValue);
5736
5741
  }
5737
- if (value === null) {
5738
- return emptyCell(format);
5739
- }
5740
5742
  if (typeof value === "number") {
5741
5743
  if (isDateTimeFormat(format || "")) {
5742
5744
  return dateTimeCell(value, format, formattedValue);
@@ -10172,10 +10174,22 @@ function drawPieChartValues(chart, options, ctx) {
10172
10174
  const midAngle = (startAngle + endAngle) / 2;
10173
10175
  const midRadius = (innerRadius + outerRadius) / 2;
10174
10176
  const x = bar.x + midRadius * Math.cos(midAngle);
10175
- const y = bar.y + midRadius * Math.sin(midAngle) + 7;
10177
+ const y = bar.y + midRadius * Math.sin(midAngle);
10178
+ const displayValue = options.callback(value, dataset, i);
10179
+ const textHeight = 12; // ChartJS default
10180
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: textHeight }, "px");
10181
+ const radius = outerRadius - innerRadius;
10182
+ // Check if the text fits in the slice. Not perfect, but good enough heuristic.
10183
+ if (textWidth >= radius || radius < textHeight) {
10184
+ continue;
10185
+ }
10186
+ const sliceAngle = endAngle - startAngle;
10187
+ const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
10188
+ if (sliceAngle < Math.PI / 2 && (textWidth >= midWidth || midWidth < textHeight)) {
10189
+ continue;
10190
+ }
10176
10191
  ctx.fillStyle = chartFontColor(options.background);
10177
10192
  ctx.strokeStyle = options.background || "#ffffff";
10178
- const displayValue = options.callback(value, dataset, i);
10179
10193
  drawTextWithBackground(displayValue, x, y, ctx);
10180
10194
  }
10181
10195
  }
@@ -13392,7 +13406,7 @@ class XlsxBaseExtractor {
13392
13406
  */
13393
13407
  handleMissingValue(parentElement, missingElementName, optionalArgs) {
13394
13408
  if (optionalArgs?.required) {
13395
- if (optionalArgs?.default) {
13409
+ if (optionalArgs?.default !== undefined) {
13396
13410
  this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
13397
13411
  }
13398
13412
  else {
@@ -32518,19 +32532,26 @@ class FilterMenu extends owl.Component {
32518
32532
  .filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
32519
32533
  .map(({ col, row }) => this.env.model.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
32520
32534
  const filterValues = this.env.model.getters.getFilterHiddenValues({ sheetId, ...position });
32521
- const strValues = [...cellValues, ...filterValues];
32522
- const normalizedFilteredValues = filterValues.map(toLowerCase);
32523
- // Set with lowercase values to avoid duplicates
32524
- const normalizedValues = [...new Set(strValues.map(toLowerCase))];
32525
- const sortedValues = normalizedValues.sort((val1, val2) => val1.localeCompare(val2, undefined, { numeric: true, sensitivity: "base" }));
32526
- return sortedValues.map((normalizedValue) => {
32527
- const checked = normalizedFilteredValues.findIndex((filteredValue) => filteredValue === normalizedValue) ===
32528
- -1;
32529
- return {
32530
- checked,
32531
- string: strValues.find((val) => toLowerCase(val) === normalizedValue) || "",
32532
- };
32533
- });
32535
+ const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
32536
+ const set = new Set();
32537
+ const values = [];
32538
+ const addValue = (value) => {
32539
+ const normalizedValue = toLowerCase(value);
32540
+ if (!set.has(normalizedValue)) {
32541
+ values.push({
32542
+ string: value || "",
32543
+ checked: !normalizedFilteredValues.has(normalizedValue),
32544
+ normalizedValue,
32545
+ });
32546
+ set.add(normalizedValue);
32547
+ }
32548
+ };
32549
+ cellValues.forEach(addValue);
32550
+ filterValues.forEach(addValue);
32551
+ return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
32552
+ numeric: true,
32553
+ sensitivity: "base",
32554
+ }));
32534
32555
  }
32535
32556
  checkValue(value) {
32536
32557
  this.state.selectedValue = value.string;
@@ -33649,6 +33670,10 @@ const REMOVE_ROWS_ACTION = (env) => {
33649
33670
  });
33650
33671
  };
33651
33672
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
33673
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
33674
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
33675
+ return false;
33676
+ }
33652
33677
  const sheetId = env.model.getters.getActiveSheetId();
33653
33678
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
33654
33679
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -36369,11 +36394,11 @@ class OTRegistry extends Registry {
36369
36394
  * transformation function given
36370
36395
  */
36371
36396
  addTransformation(executed, toTransforms, fn) {
36372
- for (let toTransform of toTransforms) {
36373
- if (!this.content[toTransform]) {
36374
- this.content[toTransform] = new Map();
36375
- }
36376
- this.content[toTransform].set(executed, fn);
36397
+ if (!this.content[executed]) {
36398
+ this.content[executed] = new Map();
36399
+ }
36400
+ for (const toTransform of toTransforms) {
36401
+ this.content[executed].set(toTransform, fn);
36377
36402
  }
36378
36403
  return this;
36379
36404
  }
@@ -36382,7 +36407,7 @@ class OTRegistry extends Registry {
36382
36407
  * that the executed command happened.
36383
36408
  */
36384
36409
  getTransformation(toTransform, executed) {
36385
- return this.content[toTransform] && this.content[toTransform].get(executed);
36410
+ return this.content[executed] && this.content[executed].get(toTransform);
36386
36411
  }
36387
36412
  }
36388
36413
  const otRegistry = new OTRegistry();
@@ -56029,7 +56054,9 @@ class TablePlugin extends CorePlugin {
56029
56054
  const ranges = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData));
56030
56055
  const union = this.getters.getRangesUnion(ranges);
56031
56056
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
56032
- this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
56057
+ if (mergesInTarget.length) {
56058
+ this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
56059
+ }
56033
56060
  const id = this.uuidGenerator.smallUuid();
56034
56061
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
56035
56062
  const newTable = cmd.tableType === "dynamic"
@@ -56140,14 +56167,16 @@ class TablePlugin extends CorePlugin {
56140
56167
  const zoneToCheckIfEmpty = direction === "down"
56141
56168
  ? { ...zone, bottom: zone.bottom + 1, top: zone.bottom + 1 }
56142
56169
  : { ...zone, right: zone.right + 1, left: zone.right + 1 };
56143
- for (const position of positions(zoneToCheckIfEmpty)) {
56144
- const cellPosition = { sheetId, ...position };
56145
- // Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
56146
- const cellContent = this.getters.getCell(cellPosition)?.content;
56147
- if (cellContent ||
56148
- this.getters.isInMerge(cellPosition) ||
56149
- this.getTablesOverlappingZones(sheetId, [positionToZone(position)]).length) {
56150
- return "none";
56170
+ for (let row = zoneToCheckIfEmpty.top; row <= zoneToCheckIfEmpty.bottom; row++) {
56171
+ for (let col = zoneToCheckIfEmpty.left; col <= zoneToCheckIfEmpty.right; col++) {
56172
+ const cellPosition = { sheetId, col, row };
56173
+ // Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
56174
+ const cellContent = this.getters.getCell(cellPosition)?.content;
56175
+ if (cellContent ||
56176
+ this.getters.isInMerge(cellPosition) ||
56177
+ this.getTablesOverlappingZones(sheetId, [positionToZone(cellPosition)]).length) {
56178
+ return "none";
56179
+ }
56151
56180
  }
56152
56181
  }
56153
56182
  return direction;
@@ -62177,10 +62206,20 @@ function transform(toTransform, executed) {
62177
62206
  */
62178
62207
  function transformAll(toTransform, executed) {
62179
62208
  let transformedCommands = [...toTransform];
62209
+ const possibleTransformations = new Set(otRegistry.getKeys());
62180
62210
  for (const executedCommand of executed) {
62181
- transformedCommands = transformedCommands
62182
- .map((cmd) => transform(cmd, executedCommand))
62183
- .filter(isDefined);
62211
+ // If the executed command is not in the registry, we skip it
62212
+ // because we know there won't be any transformation impacting the
62213
+ // commands to transform.
62214
+ if (possibleTransformations.has(executedCommand.type)) {
62215
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
62216
+ const transformed = transform(cmd, executedCommand);
62217
+ if (transformed) {
62218
+ acc.push(transformed);
62219
+ }
62220
+ return acc;
62221
+ }, []);
62222
+ }
62184
62223
  }
62185
62224
  return transformedCommands;
62186
62225
  }
@@ -62666,7 +62705,6 @@ class Session extends EventBus {
62666
62705
  if (this.waitingAck) {
62667
62706
  return;
62668
62707
  }
62669
- this.waitingAck = true;
62670
62708
  this.sendPendingMessage();
62671
62709
  }
62672
62710
  /**
@@ -62696,6 +62734,7 @@ class Session extends EventBus {
62696
62734
  throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
62697
62735
  ${JSON.stringify(message)}`);
62698
62736
  }
62737
+ this.waitingAck = true;
62699
62738
  this.transportService.sendMessage({
62700
62739
  ...message,
62701
62740
  serverRevisionId: this.serverRevisionId,
@@ -63836,7 +63875,7 @@ class SheetUIPlugin extends UIPlugin {
63836
63875
  }
63837
63876
  const position = this.getters.getCellPosition(cell.id);
63838
63877
  const colSize = this.getters.getColSize(sheetId, position.col);
63839
- if (cell.isFormula) {
63878
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
63840
63879
  const content = this.getters.getEvaluatedCell(position).formattedValue;
63841
63880
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
63842
63881
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -65472,9 +65511,10 @@ class FilterEvaluationPlugin extends UIPlugin {
65472
65511
  const filteredZone = filter.filteredRange?.zone;
65473
65512
  if (!filteredValues || !filteredZone)
65474
65513
  continue;
65514
+ const filteredValuesSet = new Set(filteredValues);
65475
65515
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
65476
65516
  const value = this.getCellValueAsString(sheetId, filter.col, row);
65477
- if (filteredValues.includes(value)) {
65517
+ if (filteredValuesSet.has(value)) {
65478
65518
  hiddenRows.add(row);
65479
65519
  }
65480
65520
  }
@@ -74421,6 +74461,6 @@ exports.tokenColors = tokenColors;
74421
74461
  exports.tokenize = tokenize;
74422
74462
 
74423
74463
 
74424
- __info__.version = "18.0.32";
74425
- __info__.date = "2025-06-06T09:29:16.581Z";
74426
- __info__.hash = "bef1e2b";
74464
+ __info__.version = "18.0.34";
74465
+ __info__.date = "2025-06-19T18:26:11.726Z";
74466
+ __info__.hash = "5526881";
@@ -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.0.32
6
- * @date 2025-06-06T09:29:16.581Z
7
- * @hash bef1e2b
5
+ * @version 18.0.34
6
+ * @date 2025-06-19T18:26:11.726Z
7
+ * @hash 5526881
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';
@@ -5676,7 +5676,9 @@ function isTextFormat(format) {
5676
5676
  }
5677
5677
 
5678
5678
  function evaluateLiteral(literalCell, localeFormat) {
5679
- const value = isTextFormat(localeFormat.format) ? literalCell.content : literalCell.parsedValue;
5679
+ const value = isTextFormat(localeFormat.format) && literalCell.parsedValue !== null
5680
+ ? literalCell.content
5681
+ : literalCell.parsedValue;
5680
5682
  const functionResult = { value, format: localeFormat.format };
5681
5683
  return createEvaluatedCell(functionResult, localeFormat.locale);
5682
5684
  }
@@ -5725,6 +5727,9 @@ function _createEvaluatedCell(functionResult, locale, cell) {
5725
5727
  if (isEvaluationError(value)) {
5726
5728
  return errorCell(value, message);
5727
5729
  }
5730
+ if (value === null) {
5731
+ return emptyCell(format);
5732
+ }
5728
5733
  if (isTextFormat(format)) {
5729
5734
  // TO DO:
5730
5735
  // with the next line, the value of the cell is transformed depending on the format.
@@ -5732,9 +5737,6 @@ function _createEvaluatedCell(functionResult, locale, cell) {
5732
5737
  // to interpret the value as a number.
5733
5738
  return textCell(toString(value), format, formattedValue);
5734
5739
  }
5735
- if (value === null) {
5736
- return emptyCell(format);
5737
- }
5738
5740
  if (typeof value === "number") {
5739
5741
  if (isDateTimeFormat(format || "")) {
5740
5742
  return dateTimeCell(value, format, formattedValue);
@@ -10170,10 +10172,22 @@ function drawPieChartValues(chart, options, ctx) {
10170
10172
  const midAngle = (startAngle + endAngle) / 2;
10171
10173
  const midRadius = (innerRadius + outerRadius) / 2;
10172
10174
  const x = bar.x + midRadius * Math.cos(midAngle);
10173
- const y = bar.y + midRadius * Math.sin(midAngle) + 7;
10175
+ const y = bar.y + midRadius * Math.sin(midAngle);
10176
+ const displayValue = options.callback(value, dataset, i);
10177
+ const textHeight = 12; // ChartJS default
10178
+ const textWidth = computeTextWidth(ctx, displayValue, { fontSize: textHeight }, "px");
10179
+ const radius = outerRadius - innerRadius;
10180
+ // Check if the text fits in the slice. Not perfect, but good enough heuristic.
10181
+ if (textWidth >= radius || radius < textHeight) {
10182
+ continue;
10183
+ }
10184
+ const sliceAngle = endAngle - startAngle;
10185
+ const midWidth = 2 * midRadius * Math.tan(sliceAngle / 2);
10186
+ if (sliceAngle < Math.PI / 2 && (textWidth >= midWidth || midWidth < textHeight)) {
10187
+ continue;
10188
+ }
10174
10189
  ctx.fillStyle = chartFontColor(options.background);
10175
10190
  ctx.strokeStyle = options.background || "#ffffff";
10176
- const displayValue = options.callback(value, dataset, i);
10177
10191
  drawTextWithBackground(displayValue, x, y, ctx);
10178
10192
  }
10179
10193
  }
@@ -13390,7 +13404,7 @@ class XlsxBaseExtractor {
13390
13404
  */
13391
13405
  handleMissingValue(parentElement, missingElementName, optionalArgs) {
13392
13406
  if (optionalArgs?.required) {
13393
- if (optionalArgs?.default) {
13407
+ if (optionalArgs?.default !== undefined) {
13394
13408
  this.warningManager.addParsingWarning(`Missing required ${missingElementName} in element <${parentElement.tagName}> of ${this.currentFile}, replacing it by the default value ${optionalArgs.default}`);
13395
13409
  }
13396
13410
  else {
@@ -32516,19 +32530,26 @@ class FilterMenu extends Component {
32516
32530
  .filter(({ row }) => !this.env.model.getters.isRowHidden(sheetId, row))
32517
32531
  .map(({ col, row }) => this.env.model.getters.getEvaluatedCell({ sheetId, col, row }).formattedValue);
32518
32532
  const filterValues = this.env.model.getters.getFilterHiddenValues({ sheetId, ...position });
32519
- const strValues = [...cellValues, ...filterValues];
32520
- const normalizedFilteredValues = filterValues.map(toLowerCase);
32521
- // Set with lowercase values to avoid duplicates
32522
- const normalizedValues = [...new Set(strValues.map(toLowerCase))];
32523
- const sortedValues = normalizedValues.sort((val1, val2) => val1.localeCompare(val2, undefined, { numeric: true, sensitivity: "base" }));
32524
- return sortedValues.map((normalizedValue) => {
32525
- const checked = normalizedFilteredValues.findIndex((filteredValue) => filteredValue === normalizedValue) ===
32526
- -1;
32527
- return {
32528
- checked,
32529
- string: strValues.find((val) => toLowerCase(val) === normalizedValue) || "",
32530
- };
32531
- });
32533
+ const normalizedFilteredValues = new Set(filterValues.map(toLowerCase));
32534
+ const set = new Set();
32535
+ const values = [];
32536
+ const addValue = (value) => {
32537
+ const normalizedValue = toLowerCase(value);
32538
+ if (!set.has(normalizedValue)) {
32539
+ values.push({
32540
+ string: value || "",
32541
+ checked: !normalizedFilteredValues.has(normalizedValue),
32542
+ normalizedValue,
32543
+ });
32544
+ set.add(normalizedValue);
32545
+ }
32546
+ };
32547
+ cellValues.forEach(addValue);
32548
+ filterValues.forEach(addValue);
32549
+ return values.sort((val1, val2) => val1.normalizedValue.localeCompare(val2.normalizedValue, undefined, {
32550
+ numeric: true,
32551
+ sensitivity: "base",
32552
+ }));
32532
32553
  }
32533
32554
  checkValue(value) {
32534
32555
  this.state.selectedValue = value.string;
@@ -33647,6 +33668,10 @@ const REMOVE_ROWS_ACTION = (env) => {
33647
33668
  });
33648
33669
  };
33649
33670
  const CAN_REMOVE_COLUMNS_ROWS = (dimension, env) => {
33671
+ if ((dimension === "COL" && env.model.getters.getActiveRows().size > 0) ||
33672
+ (dimension === "ROW" && env.model.getters.getActiveCols().size > 0)) {
33673
+ return false;
33674
+ }
33650
33675
  const sheetId = env.model.getters.getActiveSheetId();
33651
33676
  const selectedElements = env.model.getters.getElementsFromSelection(dimension);
33652
33677
  const includesAllVisibleHeaders = env.model.getters.checkElementsIncludeAllVisibleHeaders(sheetId, dimension, selectedElements);
@@ -36367,11 +36392,11 @@ class OTRegistry extends Registry {
36367
36392
  * transformation function given
36368
36393
  */
36369
36394
  addTransformation(executed, toTransforms, fn) {
36370
- for (let toTransform of toTransforms) {
36371
- if (!this.content[toTransform]) {
36372
- this.content[toTransform] = new Map();
36373
- }
36374
- this.content[toTransform].set(executed, fn);
36395
+ if (!this.content[executed]) {
36396
+ this.content[executed] = new Map();
36397
+ }
36398
+ for (const toTransform of toTransforms) {
36399
+ this.content[executed].set(toTransform, fn);
36375
36400
  }
36376
36401
  return this;
36377
36402
  }
@@ -36380,7 +36405,7 @@ class OTRegistry extends Registry {
36380
36405
  * that the executed command happened.
36381
36406
  */
36382
36407
  getTransformation(toTransform, executed) {
36383
- return this.content[toTransform] && this.content[toTransform].get(executed);
36408
+ return this.content[executed] && this.content[executed].get(toTransform);
36384
36409
  }
36385
36410
  }
36386
36411
  const otRegistry = new OTRegistry();
@@ -56027,7 +56052,9 @@ class TablePlugin extends CorePlugin {
56027
56052
  const ranges = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData));
56028
56053
  const union = this.getters.getRangesUnion(ranges);
56029
56054
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
56030
- this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
56055
+ if (mergesInTarget.length) {
56056
+ this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
56057
+ }
56031
56058
  const id = this.uuidGenerator.smallUuid();
56032
56059
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
56033
56060
  const newTable = cmd.tableType === "dynamic"
@@ -56138,14 +56165,16 @@ class TablePlugin extends CorePlugin {
56138
56165
  const zoneToCheckIfEmpty = direction === "down"
56139
56166
  ? { ...zone, bottom: zone.bottom + 1, top: zone.bottom + 1 }
56140
56167
  : { ...zone, right: zone.right + 1, left: zone.right + 1 };
56141
- for (const position of positions(zoneToCheckIfEmpty)) {
56142
- const cellPosition = { sheetId, ...position };
56143
- // Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
56144
- const cellContent = this.getters.getCell(cellPosition)?.content;
56145
- if (cellContent ||
56146
- this.getters.isInMerge(cellPosition) ||
56147
- this.getTablesOverlappingZones(sheetId, [positionToZone(position)]).length) {
56148
- return "none";
56168
+ for (let row = zoneToCheckIfEmpty.top; row <= zoneToCheckIfEmpty.bottom; row++) {
56169
+ for (let col = zoneToCheckIfEmpty.left; col <= zoneToCheckIfEmpty.right; col++) {
56170
+ const cellPosition = { sheetId, col, row };
56171
+ // Since this plugin is loaded before CellPlugin, the getters still give us the old cell content
56172
+ const cellContent = this.getters.getCell(cellPosition)?.content;
56173
+ if (cellContent ||
56174
+ this.getters.isInMerge(cellPosition) ||
56175
+ this.getTablesOverlappingZones(sheetId, [positionToZone(cellPosition)]).length) {
56176
+ return "none";
56177
+ }
56149
56178
  }
56150
56179
  }
56151
56180
  return direction;
@@ -62175,10 +62204,20 @@ function transform(toTransform, executed) {
62175
62204
  */
62176
62205
  function transformAll(toTransform, executed) {
62177
62206
  let transformedCommands = [...toTransform];
62207
+ const possibleTransformations = new Set(otRegistry.getKeys());
62178
62208
  for (const executedCommand of executed) {
62179
- transformedCommands = transformedCommands
62180
- .map((cmd) => transform(cmd, executedCommand))
62181
- .filter(isDefined);
62209
+ // If the executed command is not in the registry, we skip it
62210
+ // because we know there won't be any transformation impacting the
62211
+ // commands to transform.
62212
+ if (possibleTransformations.has(executedCommand.type)) {
62213
+ transformedCommands = transformedCommands.reduce((acc, cmd) => {
62214
+ const transformed = transform(cmd, executedCommand);
62215
+ if (transformed) {
62216
+ acc.push(transformed);
62217
+ }
62218
+ return acc;
62219
+ }, []);
62220
+ }
62182
62221
  }
62183
62222
  return transformedCommands;
62184
62223
  }
@@ -62664,7 +62703,6 @@ class Session extends EventBus {
62664
62703
  if (this.waitingAck) {
62665
62704
  return;
62666
62705
  }
62667
- this.waitingAck = true;
62668
62706
  this.sendPendingMessage();
62669
62707
  }
62670
62708
  /**
@@ -62694,6 +62732,7 @@ class Session extends EventBus {
62694
62732
  throw new Error(`Trying to send a new revision while replaying initial revision. This can lead to endless dispatches every time the spreadsheet is open.
62695
62733
  ${JSON.stringify(message)}`);
62696
62734
  }
62735
+ this.waitingAck = true;
62697
62736
  this.transportService.sendMessage({
62698
62737
  ...message,
62699
62738
  serverRevisionId: this.serverRevisionId,
@@ -63834,7 +63873,7 @@ class SheetUIPlugin extends UIPlugin {
63834
63873
  }
63835
63874
  const position = this.getters.getCellPosition(cell.id);
63836
63875
  const colSize = this.getters.getColSize(sheetId, position.col);
63837
- if (cell.isFormula) {
63876
+ if (cell.isFormula || this.getters.getArrayFormulaSpreadingOn(position)) {
63838
63877
  const content = this.getters.getEvaluatedCell(position).formattedValue;
63839
63878
  const evaluatedSize = getCellContentHeight(this.ctx, content, cell?.style, colSize);
63840
63879
  if (evaluatedSize > evaluatedRowSize && evaluatedSize > DEFAULT_CELL_HEIGHT) {
@@ -65470,9 +65509,10 @@ class FilterEvaluationPlugin extends UIPlugin {
65470
65509
  const filteredZone = filter.filteredRange?.zone;
65471
65510
  if (!filteredValues || !filteredZone)
65472
65511
  continue;
65512
+ const filteredValuesSet = new Set(filteredValues);
65473
65513
  for (let row = filteredZone.top; row <= filteredZone.bottom; row++) {
65474
65514
  const value = this.getCellValueAsString(sheetId, filter.col, row);
65475
- if (filteredValues.includes(value)) {
65515
+ if (filteredValuesSet.has(value)) {
65476
65516
  hiddenRows.add(row);
65477
65517
  }
65478
65518
  }
@@ -74376,6 +74416,6 @@ const constants = {
74376
74416
  export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
74377
74417
 
74378
74418
 
74379
- __info__.version = "18.0.32";
74380
- __info__.date = "2025-06-06T09:29:16.581Z";
74381
- __info__.hash = "bef1e2b";
74419
+ __info__.version = "18.0.34";
74420
+ __info__.date = "2025-06-19T18:26:11.726Z";
74421
+ __info__.hash = "5526881";