@odoo/o-spreadsheet 18.2.0-alpha.8 → 18.3.0-alpha.0

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.2.0-alpha.8
6
- * @date 2025-02-14T08:40:13.286Z
7
- * @hash 19d45d9
5
+ * @version 18.3.0-alpha.0
6
+ * @date 2025-02-18T09:02:28.625Z
7
+ * @hash 9b88da0
8
8
  */
9
9
 
10
10
  'use strict';
@@ -2231,17 +2231,7 @@ function toZoneWithoutBoundaryChanges(xc) {
2231
2231
  */
2232
2232
  function toUnboundedZone(xc) {
2233
2233
  const zone = toZoneWithoutBoundaryChanges(xc);
2234
- if (zone.right !== undefined && zone.right < zone.left) {
2235
- const tmp = zone.left;
2236
- zone.left = zone.right;
2237
- zone.right = tmp;
2238
- }
2239
- if (zone.bottom !== undefined && zone.bottom < zone.top) {
2240
- const tmp = zone.top;
2241
- zone.top = zone.bottom;
2242
- zone.bottom = tmp;
2243
- }
2244
- return zone;
2234
+ return reorderZone(zone);
2245
2235
  }
2246
2236
  /**
2247
2237
  * Convert from a cartesian reference to a Zone.
@@ -2515,11 +2505,11 @@ function positions(zone) {
2515
2505
  return positions;
2516
2506
  }
2517
2507
  function reorderZone(zone) {
2518
- if (zone.left > zone.right) {
2519
- zone = { left: zone.right, right: zone.left, top: zone.top, bottom: zone.bottom };
2508
+ if (zone.right !== undefined && zone.left > zone.right) {
2509
+ zone = { ...zone, left: zone.right, right: zone.left };
2520
2510
  }
2521
- if (zone.top > zone.bottom) {
2522
- zone = { left: zone.left, right: zone.right, top: zone.bottom, bottom: zone.top };
2511
+ if (zone.bottom !== undefined && zone.top > zone.bottom) {
2512
+ zone = { ...zone, top: zone.bottom, bottom: zone.top };
2523
2513
  }
2524
2514
  return zone;
2525
2515
  }
@@ -3424,12 +3414,12 @@ function isTargetDependent(cmd) {
3424
3414
  function isRangeDependant(cmd) {
3425
3415
  return "ranges" in cmd;
3426
3416
  }
3427
- function isZoneDependent(cmd) {
3428
- return "zone" in cmd;
3429
- }
3430
3417
  function isPositionDependent(cmd) {
3431
3418
  return "col" in cmd && "row" in cmd && "sheetId" in cmd;
3432
3419
  }
3420
+ function isZoneDependent(cmd) {
3421
+ return "sheetId" in cmd && "zone" in cmd;
3422
+ }
3433
3423
  const invalidateEvaluationCommands = new Set([
3434
3424
  "RENAME_SHEET",
3435
3425
  "DELETE_SHEET",
@@ -3441,6 +3431,7 @@ const invalidateEvaluationCommands = new Set([
3441
3431
  "REDO",
3442
3432
  "ADD_MERGE",
3443
3433
  "REMOVE_MERGE",
3434
+ "DUPLICATE_SHEET",
3444
3435
  "UPDATE_LOCALE",
3445
3436
  "ADD_PIVOT",
3446
3437
  "UPDATE_PIVOT",
@@ -3470,7 +3461,6 @@ const invalidateChartEvaluationCommands = new Set([
3470
3461
  ]);
3471
3462
  const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
3472
3463
  const invalidateCFEvaluationCommands = new Set([
3473
- "DUPLICATE_SHEET",
3474
3464
  "EVALUATE_CELLS",
3475
3465
  "ADD_CONDITIONAL_FORMAT",
3476
3466
  "REMOVE_CONDITIONAL_FORMAT",
@@ -3640,6 +3630,7 @@ exports.CommandResult = void 0;
3640
3630
  CommandResult["InvalidRange"] = "InvalidRange";
3641
3631
  CommandResult["InvalidZones"] = "InvalidZones";
3642
3632
  CommandResult["InvalidSheetId"] = "InvalidSheetId";
3633
+ CommandResult["InvalidCellId"] = "InvalidCellId";
3643
3634
  CommandResult["InvalidFigureId"] = "InvalidFigureId";
3644
3635
  CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
3645
3636
  CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
@@ -12238,6 +12229,25 @@ const LN = {
12238
12229
  isExported: true,
12239
12230
  };
12240
12231
  // -----------------------------------------------------------------------------
12232
+ // LOG
12233
+ // -----------------------------------------------------------------------------
12234
+ const LOG = {
12235
+ description: _t("The logarithm of a number, for a given base."),
12236
+ args: [
12237
+ arg("value (number)", _t("The value for which to calculate the logarithm.")),
12238
+ arg("base (number, default=10)", _t("The base of the logarithm.")),
12239
+ ],
12240
+ compute: function (value, base = { value: 10 }) {
12241
+ const _value = toNumber(value, this.locale);
12242
+ const _base = toNumber(base, this.locale);
12243
+ assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
12244
+ assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
12245
+ assert(() => _base !== 1, _t("The base must be different from 1."));
12246
+ return Math.log10(_value) / Math.log10(_base);
12247
+ },
12248
+ isExported: true,
12249
+ };
12250
+ // -----------------------------------------------------------------------------
12241
12251
  // MOD
12242
12252
  // -----------------------------------------------------------------------------
12243
12253
  function mod(dividend, divisor) {
@@ -12777,6 +12787,7 @@ var math = /*#__PURE__*/Object.freeze({
12777
12787
  ISODD: ISODD,
12778
12788
  ISO_CEILING: ISO_CEILING,
12779
12789
  LN: LN,
12790
+ LOG: LOG,
12780
12791
  MOD: MOD,
12781
12792
  MUNIT: MUNIT,
12782
12793
  ODD: ODD,
@@ -28932,7 +28943,7 @@ function getPieChartDatasets(definition, args) {
28932
28943
  const dataset = {
28933
28944
  label,
28934
28945
  data,
28935
- borderColor: BACKGROUND_CHART_COLOR,
28946
+ borderColor: definition.background || "#FFFFFF",
28936
28947
  backgroundColor,
28937
28948
  hoverOffset: 30,
28938
28949
  };
@@ -38920,7 +38931,7 @@ css /* scss */ `
38920
38931
  .o-font-size-editor {
38921
38932
  height: calc(100% - 4px);
38922
38933
  input.o-font-size {
38923
- outline-color: ${SELECTION_BORDER_COLOR};
38934
+ outline: none;
38924
38935
  height: 20px;
38925
38936
  width: 23px;
38926
38937
  }
@@ -53466,6 +53477,10 @@ class CellPlugin extends CorePlugin {
53466
53477
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
53467
53478
  case "CLEAR_CELL":
53468
53479
  return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
53480
+ case "UPDATE_CELL_POSITION":
53481
+ return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
53482
+ ? "Success" /* CommandResult.Success */
53483
+ : "InvalidCellId" /* CommandResult.InvalidCellId */;
53469
53484
  default:
53470
53485
  return "Success" /* CommandResult.Success */;
53471
53486
  }
@@ -53510,6 +53525,9 @@ class CellPlugin extends CorePlugin {
53510
53525
  case "DELETE_CONTENT":
53511
53526
  this.clearZones(cmd.sheetId, cmd.target);
53512
53527
  break;
53528
+ case "DELETE_SHEET": {
53529
+ this.history.update("cells", cmd.sheetId, undefined);
53530
+ }
53513
53531
  }
53514
53532
  }
53515
53533
  clearZones(sheetId, zones) {
@@ -54300,6 +54318,9 @@ class ConditionalFormatPlugin extends CorePlugin {
54300
54318
  allowDispatch(cmd) {
54301
54319
  switch (cmd.type) {
54302
54320
  case "ADD_CONDITIONAL_FORMAT":
54321
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54322
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54323
+ }
54303
54324
  return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
54304
54325
  case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
54305
54326
  return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
@@ -54716,8 +54737,17 @@ class DataValidationPlugin extends CorePlugin {
54716
54737
  allowDispatch(cmd) {
54717
54738
  switch (cmd.type) {
54718
54739
  case "ADD_DATA_VALIDATION_RULE":
54740
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54741
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54742
+ }
54743
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
54744
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54745
+ }
54719
54746
  return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
54720
54747
  case "REMOVE_DATA_VALIDATION_RULE":
54748
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
54749
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
54750
+ }
54721
54751
  if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
54722
54752
  return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
54723
54753
  }
@@ -54944,6 +54974,7 @@ class DataValidationPlugin extends CorePlugin {
54944
54974
  class FigurePlugin extends CorePlugin {
54945
54975
  static getters = ["getFigures", "getFigure", "getFigureSheetId"];
54946
54976
  figures = {};
54977
+ insertionOrders = []; // TODO use a list in master
54947
54978
  // ---------------------------------------------------------------------------
54948
54979
  // Command Handling
54949
54980
  // ---------------------------------------------------------------------------
@@ -55046,11 +55077,14 @@ class FigurePlugin extends CorePlugin {
55046
55077
  }
55047
55078
  addFigure(figure, sheetId) {
55048
55079
  this.history.update("figures", sheetId, figure.id, figure);
55080
+ this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
55049
55081
  }
55050
55082
  deleteSheet(sheetId) {
55083
+ this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
55051
55084
  this.history.update("figures", sheetId, undefined);
55052
55085
  }
55053
55086
  removeFigure(id, sheetId) {
55087
+ this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
55054
55088
  this.history.update("figures", sheetId, id, undefined);
55055
55089
  }
55056
55090
  checkFigureExists(sheetId, figureId) {
@@ -55069,7 +55103,14 @@ class FigurePlugin extends CorePlugin {
55069
55103
  // Getters
55070
55104
  // ---------------------------------------------------------------------------
55071
55105
  getFigures(sheetId) {
55072
- return Object.values(this.figures[sheetId] || {}).filter(isDefined);
55106
+ const figures = [];
55107
+ for (const figureId of this.insertionOrders) {
55108
+ const figure = this.figures[sheetId]?.[figureId];
55109
+ if (figure) {
55110
+ figures.push(figure);
55111
+ }
55112
+ }
55113
+ return figures;
55073
55114
  }
55074
55115
  getFigure(sheetId, figureId) {
55075
55116
  return this.figures[sheetId]?.[figureId];
@@ -55082,11 +55123,9 @@ class FigurePlugin extends CorePlugin {
55082
55123
  // ---------------------------------------------------------------------------
55083
55124
  import(data) {
55084
55125
  for (let sheet of data.sheets) {
55085
- const figures = {};
55086
- sheet.figures.forEach((figure) => {
55087
- figures[figure.id] = figure;
55088
- });
55089
- this.figures[sheet.id] = figures;
55126
+ for (const figure of sheet.figures) {
55127
+ this.addFigure(figure, sheet.id);
55128
+ }
55090
55129
  }
55091
55130
  }
55092
55131
  export(data) {
@@ -56546,6 +56585,9 @@ class SheetPlugin extends CorePlugin {
56546
56585
  case "CREATE_SHEET": {
56547
56586
  return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
56548
56587
  }
56588
+ case "DUPLICATE_SHEET": {
56589
+ return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
56590
+ }
56549
56591
  case "MOVE_SHEET":
56550
56592
  try {
56551
56593
  const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
@@ -57348,14 +57390,18 @@ class SheetPlugin extends CorePlugin {
57348
57390
  checkZonesAreInSheet(cmd) {
57349
57391
  if (!("sheetId" in cmd))
57350
57392
  return "Success" /* CommandResult.Success */;
57393
+ if ("ranges" in cmd &&
57394
+ cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
57395
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57396
+ }
57351
57397
  return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
57352
57398
  }
57353
57399
  }
57354
57400
 
57355
- let nextTableId = 1;
57356
57401
  class TablePlugin extends CorePlugin {
57357
57402
  static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
57358
57403
  tables = {};
57404
+ nextTableId = 1;
57359
57405
  adaptRanges(applyChange, sheetId) {
57360
57406
  const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
57361
57407
  for (const sheetId of sheetIds) {
@@ -57367,6 +57413,9 @@ class TablePlugin extends CorePlugin {
57367
57413
  allowDispatch(cmd) {
57368
57414
  switch (cmd.type) {
57369
57415
  case "CREATE_TABLE":
57416
+ if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
57417
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57418
+ }
57370
57419
  const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
57371
57420
  if (!areZonesContinuous(zones)) {
57372
57421
  return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
@@ -57420,7 +57469,7 @@ class TablePlugin extends CorePlugin {
57420
57469
  const union = this.getters.getRangesUnion(ranges);
57421
57470
  const mergesInTarget = this.getters.getMergesInZone(cmd.sheetId, union.zone);
57422
57471
  this.dispatch("REMOVE_MERGE", { sheetId: cmd.sheetId, target: mergesInTarget });
57423
- const id = `${nextTableId++}`;
57472
+ const id = this.consumeNextId();
57424
57473
  const config = cmd.config || DEFAULT_TABLE_CONFIG;
57425
57474
  const newTable = cmd.tableType === "dynamic"
57426
57475
  ? this.createDynamicTable(id, union, config)
@@ -57573,7 +57622,7 @@ class TablePlugin extends CorePlugin {
57573
57622
  filters = [];
57574
57623
  for (const i of range(zone.left, zone.right + 1)) {
57575
57624
  const filterZone = { ...zone, left: i, right: i };
57576
- const uid = `${nextTableId++}`;
57625
+ const uid = this.consumeNextId();
57577
57626
  filters.push(this.createFilterFromZone(uid, tableRange.sheetId, filterZone, config));
57578
57627
  }
57579
57628
  }
@@ -57638,7 +57687,7 @@ class TablePlugin extends CorePlugin {
57638
57687
  ? table.filters.find((f) => f.col === i)
57639
57688
  : undefined;
57640
57689
  const filterZone = { ...tableZone, left: i, right: i };
57641
- const filterId = oldFilter?.id || `${nextTableId++}`;
57690
+ const filterId = oldFilter?.id || this.consumeNextId();
57642
57691
  filters.push(this.createFilterFromZone(filterId, tableRange.sheetId, filterZone, config));
57643
57692
  }
57644
57693
  }
@@ -57739,7 +57788,7 @@ class TablePlugin extends CorePlugin {
57739
57788
  if (filters.length < zoneToDimension(tableZone).numberOfCols) {
57740
57789
  for (let col = tableZone.left; col <= tableZone.right; col++) {
57741
57790
  if (!filters.find((filter) => filter.col === col)) {
57742
- const uid = `${nextTableId++}`;
57791
+ const uid = this.consumeNextId();
57743
57792
  const filterZone = { ...tableZone, left: col, right: col };
57744
57793
  filters.push(this.createFilterFromZone(uid, sheetId, filterZone, table.config));
57745
57794
  }
@@ -57749,13 +57798,18 @@ class TablePlugin extends CorePlugin {
57749
57798
  const newTable = this.createStaticTable(table.id, table.type, newTableRange, table.config, filters);
57750
57799
  this.history.update("tables", sheetId, table.id, newTable);
57751
57800
  }
57801
+ consumeNextId() {
57802
+ const id = `${this.nextTableId}`;
57803
+ this.history.update("nextTableId", this.nextTableId + 1);
57804
+ return id;
57805
+ }
57752
57806
  // ---------------------------------------------------------------------------
57753
57807
  // Import/Export
57754
57808
  // ---------------------------------------------------------------------------
57755
57809
  import(data) {
57756
57810
  for (const sheet of data.sheets) {
57757
57811
  for (const tableData of sheet.tables || []) {
57758
- const uuid = `${nextTableId++}`;
57812
+ const uuid = this.consumeNextId();
57759
57813
  const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
57760
57814
  const range = this.getters.getRangeFromSheetXC(sheet.id, tableData.range);
57761
57815
  const tableType = tableData.type || "static";
@@ -57803,7 +57857,10 @@ class HeaderGroupingPlugin extends CorePlugin {
57803
57857
  allowDispatch(cmd) {
57804
57858
  switch (cmd.type) {
57805
57859
  case "GROUP_HEADERS": {
57806
- const { start, end } = cmd;
57860
+ const { start, end, sheetId } = cmd;
57861
+ if (!this.getters.tryGetSheet(sheetId)) {
57862
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57863
+ }
57807
57864
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57808
57865
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57809
57866
  }
@@ -57816,7 +57873,10 @@ class HeaderGroupingPlugin extends CorePlugin {
57816
57873
  break;
57817
57874
  }
57818
57875
  case "UNGROUP_HEADERS": {
57819
- const { start, end } = cmd;
57876
+ const { start, end, sheetId } = cmd;
57877
+ if (!this.getters.tryGetSheet(sheetId)) {
57878
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57879
+ }
57820
57880
  if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
57821
57881
  return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
57822
57882
  }
@@ -57827,6 +57887,9 @@ class HeaderGroupingPlugin extends CorePlugin {
57827
57887
  }
57828
57888
  case "UNFOLD_HEADER_GROUP":
57829
57889
  case "FOLD_HEADER_GROUP":
57890
+ if (!this.getters.tryGetSheet(cmd.sheetId)) {
57891
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
57892
+ }
57830
57893
  const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
57831
57894
  if (!group) {
57832
57895
  return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
@@ -58227,6 +58290,9 @@ class PivotCorePlugin extends CorePlugin {
58227
58290
  return this.checkDuplicatedMeasureIds(cmd.pivot);
58228
58291
  }
58229
58292
  case "UPDATE_PIVOT": {
58293
+ if (!(cmd.pivotId in this.pivots)) {
58294
+ return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
58295
+ }
58230
58296
  if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
58231
58297
  return "NoChanges" /* CommandResult.NoChanges */;
58232
58298
  }
@@ -58243,6 +58309,8 @@ class PivotCorePlugin extends CorePlugin {
58243
58309
  return "EmptyName" /* CommandResult.EmptyName */;
58244
58310
  }
58245
58311
  break;
58312
+ case "REMOVE_PIVOT":
58313
+ case "DUPLICATE_PIVOT":
58246
58314
  case "INSERT_PIVOT": {
58247
58315
  if (!(cmd.pivotId in this.pivots)) {
58248
58316
  return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
@@ -58292,7 +58360,7 @@ class PivotCorePlugin extends CorePlugin {
58292
58360
  break;
58293
58361
  }
58294
58362
  case "UPDATE_PIVOT": {
58295
- this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
58363
+ this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
58296
58364
  this.compileCalculatedMeasures(cmd.pivot.measures);
58297
58365
  break;
58298
58366
  }
@@ -58363,7 +58431,7 @@ class PivotCorePlugin extends CorePlugin {
58363
58431
  // Private
58364
58432
  // -------------------------------------------------------------------------
58365
58433
  addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
58366
- this.history.update("pivots", pivotId, { definition: pivot, formulaId });
58434
+ this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
58367
58435
  this.compileCalculatedMeasures(pivot.measures);
58368
58436
  this.history.update("formulaIds", formulaId, pivotId);
58369
58437
  this.history.update("nextFormulaId", this.nextFormulaId + 1);
@@ -63281,6 +63349,9 @@ function updateChartRangesTransformation(toTransform, executed) {
63281
63349
  };
63282
63350
  }
63283
63351
  function createSheetTransformation(toTransform, executed) {
63352
+ if (toTransform.sheetId === executed.sheetId) {
63353
+ toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
63354
+ }
63284
63355
  if (toTransform.name === executed.name) {
63285
63356
  return {
63286
63357
  ...toTransform,
@@ -63924,15 +63995,6 @@ class Session extends EventBus {
63924
63995
  }
63925
63996
  this.sendPendingMessage();
63926
63997
  }
63927
- dropPendingRevision(revisionId) {
63928
- this.revisions.drop(revisionId);
63929
- const revisionIds = this.pendingMessages
63930
- .filter((message) => message.type === "REMOTE_REVISION")
63931
- .map((message) => message.nextRevisionId);
63932
- this.trigger("pending-revisions-dropped", { revisionIds });
63933
- this.waitingAck = false;
63934
- this.waitingUndoRedoAck = false;
63935
- }
63936
63998
  /**
63937
63999
  * Send the next pending message
63938
64000
  */
@@ -63941,15 +64003,14 @@ class Session extends EventBus {
63941
64003
  if (!message)
63942
64004
  return;
63943
64005
  if (message.type === "REMOTE_REVISION") {
63944
- const revision = this.revisions.get(message.nextRevisionId);
64006
+ let revision = this.revisions.get(message.nextRevisionId);
63945
64007
  if (revision.commands.length === 0) {
63946
64008
  /**
63947
- * The command is empty, we have to drop all the next local revisions
64009
+ * The command is empty, we have to rebase all the next local revisions
63948
64010
  * to avoid issues with undo/redo
63949
64011
  */
63950
- this.dropPendingRevision(revision.id);
63951
- this.pendingMessages = [];
63952
- return;
64012
+ this.revisions.rebase(revision.id);
64013
+ revision = this.revisions.get(message.nextRevisionId);
63953
64014
  }
63954
64015
  message = {
63955
64016
  ...message,
@@ -63985,18 +64046,16 @@ class Session extends EventBus {
63985
64046
  case "REVISION_UNDONE": {
63986
64047
  this.waitingAck = false;
63987
64048
  this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
63988
- const pendingRemoteRevisions = this.pendingMessages.filter((message) => message.type === "REMOTE_REVISION");
63989
- const firstTransformedRevisionIndex = pendingRemoteRevisions.findIndex((message) => !deepEquals(message.commands, this.revisions.get(message.nextRevisionId).commands));
63990
- if (firstTransformedRevisionIndex !== -1) {
64049
+ const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
64050
+ if (firstPendingRevisionId !== -1) {
63991
64051
  /**
63992
64052
  * Some revisions undergo transformations that may cause issues with
63993
64053
  * undo/redo if the transformation is destructive (we don't get back
63994
64054
  * the original command by transforming it with the inverse).
63995
- * To prevent these problems, we must discard all subsequent local
64055
+ * To prevent these problems, we must rebase all subsequent local
63996
64056
  * revisions.
63997
64057
  */
63998
- this.dropPendingRevision(this.pendingMessages[firstTransformedRevisionIndex].nextRevisionId);
63999
- this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
64058
+ this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
64000
64059
  }
64001
64060
  this.serverRevisionId = message.nextRevisionId;
64002
64061
  this.processedRevisions.add(message.nextRevisionId);
@@ -65118,6 +65177,10 @@ class SheetUIPlugin extends UIPlugin {
65118
65177
  */
65119
65178
  checkZonesAreInSheet(cmd) {
65120
65179
  const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
65180
+ if ("ranges" in cmd &&
65181
+ cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
65182
+ return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
65183
+ }
65121
65184
  const zones = this.getters.getCommandZones(cmd);
65122
65185
  if (!sheetId && zones.length > 0) {
65123
65186
  return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
@@ -65672,7 +65735,6 @@ class HistoryPlugin extends UIPlugin {
65672
65735
  super(config);
65673
65736
  this.session = config.session;
65674
65737
  this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
65675
- this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
65676
65738
  this.session.on("snapshot", this, () => {
65677
65739
  this.undoStack = [];
65678
65740
  this.redoStack = [];
@@ -65742,10 +65804,6 @@ class HistoryPlugin extends UIPlugin {
65742
65804
  const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
65743
65805
  return canRepeatRevision(lastNonRedoRevision);
65744
65806
  }
65745
- drop(revisionIds) {
65746
- this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
65747
- this.redoStack = [];
65748
- }
65749
65807
  onNewLocalStateUpdate({ id }) {
65750
65808
  this.undoStack.push(id);
65751
65809
  this.redoStack = [];
@@ -68420,7 +68478,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
68420
68478
  case "UNGROUP_HEADERS":
68421
68479
  case "GROUP_HEADERS":
68422
68480
  case "CREATE_SHEET":
68423
- this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68481
+ if (this.getters.tryGetSheet(cmd.sheetId)) {
68482
+ this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
68483
+ }
68424
68484
  break;
68425
68485
  case "DUPLICATE_SHEET":
68426
68486
  this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
@@ -68428,12 +68488,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
68428
68488
  }
68429
68489
  }
68430
68490
  finalize() {
68431
- if (this.isDirty) {
68432
- for (const sheetId of this.getters.getSheetIds()) {
68491
+ for (const sheetId of this.getters.getSheetIds()) {
68492
+ // sheets can be created without this plugin being aware of it
68493
+ // in concurrent situations.
68494
+ if (this.isDirty || !this.headerPositions[sheetId]) {
68433
68495
  this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
68434
68496
  }
68435
- this.isDirty = false;
68436
68497
  }
68498
+ this.isDirty = false;
68437
68499
  }
68438
68500
  /**
68439
68501
  * Returns the size, start and end coordinates of a column on an unfolded sheet
@@ -70274,6 +70336,10 @@ const FX_SVG = /*xml*/ `
70274
70336
  </svg>
70275
70337
  `;
70276
70338
  css /* scss */ `
70339
+ .o-topbar-composer-container {
70340
+ height: ${TOPBAR_TOOLBAR_HEIGHT}px;
70341
+ }
70342
+
70277
70343
  .o-topbar-composer {
70278
70344
  height: fit-content;
70279
70345
  margin-top: -1px;
@@ -71837,9 +71903,16 @@ class SelectiveHistory {
71837
71903
  this.fastForward();
71838
71904
  this.insert(redoId, this.buildEmpty(redoId), insertAfter);
71839
71905
  }
71840
- drop(operationId) {
71906
+ rebase(operationId) {
71907
+ const operation = this.get(operationId);
71908
+ const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
71841
71909
  this.revertBefore(operationId);
71910
+ const baseId = this.HEAD_OPERATION.id;
71842
71911
  this.tree.drop(operationId);
71912
+ this.insert(operationId, operation, baseId);
71913
+ for (const { operation } of execution) {
71914
+ this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
71915
+ }
71843
71916
  }
71844
71917
  /**
71845
71918
  * Revert the state as it was *before* the given operation was executed.
@@ -74967,6 +75040,11 @@ class Model extends EventBus {
74967
75040
  dispatch: (command) => {
74968
75041
  const result = this.checkDispatchAllowed(command);
74969
75042
  if (!result.isSuccessful) {
75043
+ // core views plugins need to be invalidated
75044
+ this.dispatchToHandlers(this.coreHandlers, {
75045
+ type: "UNDO",
75046
+ commands: [command],
75047
+ });
74970
75048
  return;
74971
75049
  }
74972
75050
  this.isReplayingCommand = true;
@@ -75533,6 +75611,6 @@ exports.tokenColors = tokenColors;
75533
75611
  exports.tokenize = tokenize;
75534
75612
 
75535
75613
 
75536
- __info__.version = "18.2.0-alpha.8";
75537
- __info__.date = "2025-02-14T08:40:13.286Z";
75538
- __info__.hash = "19d45d9";
75614
+ __info__.version = "18.3.0-alpha.0";
75615
+ __info__.date = "2025-02-18T09:02:28.625Z";
75616
+ __info__.hash = "9b88da0";