@odoo/o-spreadsheet 19.4.5 → 19.4.7

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 19.4.5
6
- * @date 2026-07-30T06:55:39.923Z
7
- * @hash 9308e17
5
+ * @version 19.4.7
6
+ * @date 2026-08-12T09:16:40.949Z
7
+ * @hash 65642fe
8
8
  */
9
9
 
10
10
  (function(exports, _odoo_owl) {
@@ -5959,6 +5959,9 @@ set(value) {
5959
5959
  }
5960
5960
  };
5961
5961
  const functionRegistry = new FunctionRegistry();
5962
+ /** Formulas using one of these functions are never squished: they are always exported
5963
+ * as a full formula string, and they don't become the base formula of the next cells. */
5964
+ const NonSquishableFunctionRegistry = new Registry();
5962
5965
 
5963
5966
  //#endregion
5964
5967
  //#region src/helpers/references.ts
@@ -8917,6 +8920,25 @@ set(value) {
8917
8920
  };
8918
8921
  };
8919
8922
 
8923
+ //#endregion
8924
+ //#region src/components/figures/chart/chartJs/chartjs_geo_projection_plugin.ts
8925
+ /**
8926
+ * ChartJS plugin to apply custom changes to a d3 projection.
8927
+ *
8928
+ * We pass the projection as a string instead of a customized d3 object so
8929
+ * Chart.js creates a fresh projection instance. Custom changes (e.g. rotation)
8930
+ * are then applied in `beforeUpdate`.
8931
+ *
8932
+ * This is important because Chart.js mutates the projection instance at runtime,
8933
+ * and a customize d3 projection object would not be copied during deepCopy.
8934
+ */
8935
+ const geoProjectionPlugin = {
8936
+ id: "geoProjection",
8937
+ beforeUpdate(chart) {
8938
+ if (chart.options?.scales?.projection?.projection === "conicConformal") chart.scales?.projection?.projection?.rotate([100, 0]);
8939
+ }
8940
+ };
8941
+
8920
8942
  //#endregion
8921
8943
  //#region src/components/figures/chart/chartJs/chartjs_minor_grid_plugin.ts
8922
8944
  const chartMinorGridPlugin = {
@@ -10720,7 +10742,7 @@ set(value) {
10720
10742
  const format = axisFormats?.y || axisFormats?.y1;
10721
10743
  return {
10722
10744
  projection: {
10723
- projection: getGeoChartProjection(region?.defaultProjection || "mercator"),
10745
+ projection: region?.defaultProjection || "mercator",
10724
10746
  axis: "x"
10725
10747
  },
10726
10748
  color: {
@@ -10772,10 +10794,6 @@ set(value) {
10772
10794
  }
10773
10795
  };
10774
10796
  }
10775
- function getGeoChartProjection(projection) {
10776
- if (globalThis.ChartGeo && projection === "conicConformal") return globalThis.ChartGeo.geoConicConformal().rotate([100, 0]);
10777
- return projection;
10778
- }
10779
10797
  function getChartAxisTitleRuntime(design) {
10780
10798
  if (design?.title?.text) {
10781
10799
  const { text, color, align, italic, bold } = design.title;
@@ -11736,6 +11754,10 @@ set(value) {
11736
11754
  register: (Chart) => Chart.register(chartBackgroundPlugin),
11737
11755
  unregister: (Chart) => Chart.unregister(chartBackgroundPlugin)
11738
11756
  });
11757
+ chartJsExtensionRegistry.add("geoProjectionPlugin", {
11758
+ register: (Chart) => Chart.register(geoProjectionPlugin),
11759
+ unregister: (Chart) => Chart.unregister(geoProjectionPlugin)
11760
+ });
11739
11761
  var ChartJsComponent = class extends Component {
11740
11762
  static template = "o-spreadsheet-ChartJsComponent";
11741
11763
  props = (0, _odoo_owl.useProps)({
@@ -15585,7 +15607,7 @@ set(value) {
15585
15607
  figures.push({
15586
15608
  sheetId,
15587
15609
  figureId,
15588
- ...this.postionInBoundary(this.env.model.getters.getFigureUI(sheetId, figure), ev.key, ev.shiftKey)
15610
+ ...this.positionInBoundary(sheetId, this.env.model.getters.getFigureUI(sheetId, figure), ev.key, ev.shiftKey)
15589
15611
  });
15590
15612
  }
15591
15613
  this.env.model.dispatch("MOVE_FIGURES", { figures });
@@ -15605,21 +15627,23 @@ set(value) {
15605
15627
  break;
15606
15628
  }
15607
15629
  }
15608
- postionInBoundary(position, key, shift) {
15609
- const sheetId = this.env.model.getters.getActiveSheetId();
15630
+ positionInBoundary(sheetId, figure, key, shift) {
15610
15631
  const shiftAmount = shift ? 1 : 5;
15611
- let { col, row, offset } = position;
15632
+ let { col, row, offset } = figure;
15612
15633
  offset = { ...offset };
15634
+ const maxAnchor = this.env.model.getters.getMaxAnchorOffset(sheetId, figure.height, figure.width);
15613
15635
  switch (key) {
15614
15636
  case "ArrowUp":
15615
15637
  if (offset.y < shiftAmount) {
15616
15638
  row--;
15639
+ while (row > 0 && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row--;
15617
15640
  offset.y = this.env.model.getters.getRowSize(sheetId, row) - shiftAmount + offset.y;
15618
15641
  } else offset.y -= shiftAmount;
15619
15642
  break;
15620
15643
  case "ArrowLeft":
15621
15644
  if (offset.x < shiftAmount) {
15622
15645
  col--;
15646
+ while (col > 0 && this.env.model.getters.isColHiddenByUser(sheetId, col)) col--;
15623
15647
  offset.x = this.env.model.getters.getColSize(sheetId, col) - shiftAmount + offset.x;
15624
15648
  } else offset.x -= shiftAmount;
15625
15649
  break;
@@ -15627,6 +15651,7 @@ set(value) {
15627
15651
  const rowSize = this.env.model.getters.getRowSize(sheetId, row);
15628
15652
  if (offset.y + shiftAmount >= rowSize) {
15629
15653
  row++;
15654
+ while (row <= maxAnchor.row && this.env.model.getters.isRowHiddenByUser(sheetId, row)) row++;
15630
15655
  offset.y = offset.y + shiftAmount - rowSize;
15631
15656
  } else offset.y += shiftAmount;
15632
15657
  break;
@@ -15634,9 +15659,24 @@ set(value) {
15634
15659
  const colSize = this.env.model.getters.getColSize(sheetId, col);
15635
15660
  if (offset.x + shiftAmount >= colSize) {
15636
15661
  col++;
15662
+ while (col <= maxAnchor.col && this.env.model.getters.isColHiddenByUser(sheetId, col)) col++;
15637
15663
  offset.x = offset.x + shiftAmount - colSize;
15638
15664
  } else offset.x += shiftAmount;
15639
15665
  }
15666
+ if (col < 0) {
15667
+ col = 0;
15668
+ offset.x = 0;
15669
+ } else if (col > maxAnchor.col || col === maxAnchor.col && offset.x > maxAnchor.offset.x) {
15670
+ col = maxAnchor.col;
15671
+ offset.x = maxAnchor.offset.x;
15672
+ }
15673
+ if (row < 0) {
15674
+ row = 0;
15675
+ offset.y = 0;
15676
+ } else if (row > maxAnchor.row || row === maxAnchor.row && offset.y > maxAnchor.offset.y) {
15677
+ row = maxAnchor.row;
15678
+ offset.y = maxAnchor.offset.y;
15679
+ }
15640
15680
  return {
15641
15681
  col,
15642
15682
  row,
@@ -46022,7 +46062,13 @@ set(value) {
46022
46062
  const cell = this.getters.getEvaluatedCell(position);
46023
46063
  if (cell.link && !isFormula(content)) content = markdownLink(content, cell.link.url);
46024
46064
  const currentFormat = this.getters.getCell(position)?.format;
46025
- const afterFormat = currentFormat === "@" || currentFormat && isDateTimeFormat(currentFormat) ? void 0 : detectDateFormat(content, this.getters.getLocale());
46065
+ const isCurrentFormatDate = currentFormat && isDateTimeFormat(currentFormat);
46066
+ const contentDateFormat = detectDateFormat(content, this.getters.getLocale());
46067
+ let afterFormat;
46068
+ if (currentFormat !== "@") {
46069
+ if (contentDateFormat && !isCurrentFormatDate) afterFormat = contentDateFormat;
46070
+ else if (isCurrentFormatDate && isNumber(content, this.getters.getLocale())) afterFormat = "";
46071
+ }
46026
46072
  this.addHeadersForSpreadingFormula(content);
46027
46073
  result = this.model.dispatch("UPDATE_CELL", {
46028
46074
  ...this.currentEditedCell,
@@ -51108,7 +51154,8 @@ set(value) {
51108
51154
  * The result of this method is:
51109
51155
  * - if the cell is not a formula, returns the content as is and resets the base formula
51110
51156
  * - if the cell is a formula:
51111
- * - if there is no previous formula, or the normalized formula is different from the previous one, resets the base formula to this one and returns the full formula string
51157
+ * - if there is no previous formula, or the normalized formula is different from the previous one or it contains blacklisted functions (see NonSquishableFunctionRegistry),
51158
+ * resets the base formula to this one and returns the full formula string
51112
51159
  * - else, compares the literal values and range dependencies to the previous formula, and for each parameter:
51113
51160
  * - for numbers: returns a relative change (+N or -N) if possible, else the full number or "=" if unchanged
51114
51161
  * - for strings: returns the full string if changed, else "="
@@ -51116,6 +51163,10 @@ set(value) {
51116
51163
  * */
51117
51164
  squish(cell, forSheetId) {
51118
51165
  if (cell.isFormula) {
51166
+ if (NonSquishableFunctionRegistry.getAll().some((functionName) => cell.compiledFormula.usesSymbol(functionName))) {
51167
+ this.resetBaseFormula();
51168
+ return cell.compiledFormula.toFormulaString(this.getters, this.rangeToStringOptions);
51169
+ }
51119
51170
  let numbers = [];
51120
51171
  let strings = [];
51121
51172
  let references = [];
@@ -62376,7 +62427,7 @@ set(value) {
62376
62427
  }
62377
62428
  message = {
62378
62429
  ...message,
62379
- commands: this.commandSquisher.squish(revision.commands)
62430
+ commands: revision.commands
62380
62431
  };
62381
62432
  }
62382
62433
  if (this.isReplayingInitialRevisions) 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.
@@ -67693,6 +67744,10 @@ set(value) {
67693
67744
  }
67694
67745
  function inverseCreateChart(cmd) {
67695
67746
  return [{
67747
+ type: "DELETE_CHART",
67748
+ chartId: cmd.chartId,
67749
+ sheetId: cmd.sheetId
67750
+ }, {
67696
67751
  type: "DELETE_FIGURE",
67697
67752
  figureId: cmd.figureId,
67698
67753
  sheetId: cmd.sheetId
@@ -87382,7 +87437,8 @@ set(value) {
87382
87437
  migrationStepRegistry,
87383
87438
  chartJsExtensionRegistry,
87384
87439
  onIterationEndEvaluationRegistry,
87385
- specificRangeTransformRegistry
87440
+ specificRangeTransformRegistry,
87441
+ NonSquishableFunctionRegistry
87386
87442
  };
87387
87443
  const helpers = {
87388
87444
  arg,
@@ -87529,7 +87585,8 @@ set(value) {
87529
87585
  FullScreenFigure,
87530
87586
  NumberInput,
87531
87587
  TopBar,
87532
- Composer
87588
+ Composer,
87589
+ CarouselFigure
87533
87590
  };
87534
87591
  const hooks = {
87535
87592
  useDragAndDropListItems,
@@ -87683,8 +87740,8 @@ exports.stores = stores;
87683
87740
  exports.tokenColors = tokenColors;
87684
87741
  exports.tokenize = tokenize;
87685
87742
 
87686
- __info__.version = "19.4.5";
87687
- __info__.date = "2026-07-30T06:55:39.923Z";
87688
- __info__.hash = "9308e17";
87743
+ __info__.version = "19.4.7";
87744
+ __info__.date = "2026-08-12T09:16:40.949Z";
87745
+ __info__.hash = "65642fe";
87689
87746
 
87690
87747
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);