@odoo/o-spreadsheet 17.0.32 → 17.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 17.0.32
6
- * @date 2024-07-24T10:26:05.203Z
7
- * @hash 679a547
5
+ * @version 17.0.34
6
+ * @date 2024-08-09T12:20:17.042Z
7
+ * @hash 1573912
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -593,7 +593,7 @@
593
593
  let timeout;
594
594
  return function () {
595
595
  const context = this;
596
- const args = arguments;
596
+ const args = Array.from(arguments);
597
597
  function later() {
598
598
  timeout = null;
599
599
  if (!immediate) {
@@ -796,7 +796,7 @@
796
796
  */
797
797
  function largeMax(array) {
798
798
  let len = array.length;
799
- if (len < 100000)
799
+ if (len < 100_000)
800
800
  return Math.max(...array);
801
801
  let max = -Infinity;
802
802
  while (len--) {
@@ -810,7 +810,7 @@
810
810
  */
811
811
  function largeMin(array) {
812
812
  let len = array.length;
813
- if (len < 100000)
813
+ if (len < 100_000)
814
814
  return Math.min(...array);
815
815
  let min = +Infinity;
816
816
  while (len--) {
@@ -2565,13 +2565,16 @@
2565
2565
  }
2566
2566
  return new RegExp("^" + exp + "$", "i");
2567
2567
  }
2568
- function evaluatePredicate(value = "", criterion) {
2568
+ function evaluatePredicate(value = "", criterion, locale) {
2569
2569
  const { operator, operand } = criterion;
2570
2570
  if (operand === undefined || value === null || operand === null) {
2571
2571
  return false;
2572
2572
  }
2573
2573
  if (typeof operand === "number" && operator === "=") {
2574
- return toString(value) === toString(operand);
2574
+ if (typeof value === "string" && (isNumber(value, locale) || isDateTime(value, locale))) {
2575
+ return toNumber(value, locale) === operand;
2576
+ }
2577
+ return value === operand;
2575
2578
  }
2576
2579
  if (operator === "<>" || operator === "=") {
2577
2580
  let result;
@@ -2650,7 +2653,7 @@
2650
2653
  for (let k = 0; k < countArg - 1; k += 2) {
2651
2654
  const criteriaValue = args[k][i][j];
2652
2655
  const criterion = predicates[k / 2];
2653
- validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
2656
+ validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion, locale);
2654
2657
  if (!validatedPredicates) {
2655
2658
  break;
2656
2659
  }
@@ -5899,7 +5902,7 @@
5899
5902
  function numberCell(value, localeFormat) {
5900
5903
  return {
5901
5904
  type: CellValueType.number,
5902
- value: value || 0,
5905
+ value: value || 0, // necessary to avoid "-0" and NaN values,
5903
5906
  format: localeFormat.format,
5904
5907
  isAutoSummable: true,
5905
5908
  defaultAlign: "right",
@@ -8432,8 +8435,8 @@
8432
8435
  function getDefaultChartJsRuntime(chart, labels, fontColor, { format, locale, truncateLabels = true }) {
8433
8436
  const options = {
8434
8437
  // https://www.chartjs.org/docs/latest/general/responsive.html
8435
- responsive: true,
8436
- maintainAspectRatio: false,
8438
+ responsive: true, // will resize when its container is resized
8439
+ maintainAspectRatio: false, // doesn't maintain the aspect ration (width/height =2 by default) so the user has the choice of the exact layout
8437
8440
  layout: {
8438
8441
  padding: { left: 20, right: 20, top: chart.title ? 10 : 25, bottom: 10 },
8439
8442
  },
@@ -8742,7 +8745,7 @@
8742
8745
  },
8743
8746
  y: {
8744
8747
  position: chart.verticalAxisPosition,
8745
- beginAtZero: true,
8748
+ beginAtZero: true, // the origin of the y axis is always zero
8746
8749
  ticks: {
8747
8750
  color: fontColor,
8748
8751
  callback: (value) => {
@@ -9396,7 +9399,7 @@
9396
9399
  },
9397
9400
  y: {
9398
9401
  position: chart.verticalAxisPosition,
9399
- beginAtZero: true,
9402
+ beginAtZero: true, // the origin of the y axis is always zero
9400
9403
  ticks: {
9401
9404
  color: fontColor,
9402
9405
  callback: (value) => {
@@ -9484,7 +9487,7 @@
9484
9487
  const dataset = {
9485
9488
  label,
9486
9489
  data,
9487
- tension: 0,
9490
+ tension: 0, // 0 -> render straight lines, which is much faster
9488
9491
  borderColor: color,
9489
9492
  backgroundColor,
9490
9493
  pointBackgroundColor: color,
@@ -9595,7 +9598,7 @@
9595
9598
  ...this.getDefinition(),
9596
9599
  backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
9597
9600
  fontColor: toXlsxHexColor(chartFontColor(this.background)),
9598
- verticalAxisPosition: "left",
9601
+ verticalAxisPosition: "left", //TODO ExcelChartDefinition should be adapted, but can be done later
9599
9602
  dataSets,
9600
9603
  labelRange,
9601
9604
  };
@@ -26699,7 +26702,9 @@
26699
26702
  argToFocus: 0,
26700
26703
  });
26701
26704
  compositionActive = false;
26705
+ spreadsheetRect = useSpreadsheetRect();
26702
26706
  get assistantStyle() {
26707
+ const composerRect = this.composerRef.el.getBoundingClientRect();
26703
26708
  const assistantStyle = {};
26704
26709
  assistantStyle["min-width"] = `${this.props.rect?.width || ASSISTANT_WIDTH}px`;
26705
26710
  if (this.autoCompleteState.type === "function") {
@@ -26722,6 +26727,10 @@
26722
26727
  assistantStyle.right = `0px`;
26723
26728
  }
26724
26729
  }
26730
+ if (this.props.focus === "contentFocus" &&
26731
+ composerRect.left + ASSISTANT_WIDTH > this.spreadsheetRect.width) {
26732
+ assistantStyle.right = "0px";
26733
+ }
26725
26734
  return cssPropertiesToCss(assistantStyle);
26726
26735
  }
26727
26736
  // we can't allow input events to be triggered while we remove and add back the content of the composer in processContent
@@ -29580,7 +29589,7 @@
29580
29589
  onScroll(offset) {
29581
29590
  const { scrollX } = this.env.model.getters.getActiveSheetDOMScrollInfo();
29582
29591
  this.env.model.dispatch("SET_VIEWPORT_OFFSET", {
29583
- offsetX: scrollX,
29592
+ offsetX: scrollX, // offsetX is the same
29584
29593
  offsetY: offset,
29585
29594
  });
29586
29595
  }
@@ -29791,8 +29800,8 @@
29791
29800
  "CTRL+SHIFT+L": () => this.setHorizontalAlign("left"),
29792
29801
  "CTRL+SHIFT+R": () => this.setHorizontalAlign("right"),
29793
29802
  "CTRL+SHIFT+V": () => PASTE_VALUE_ACTION(this.env),
29794
- "CTRL+SHIFT+<": () => this.clearFormatting(),
29795
- "CTRL+<": () => this.clearFormatting(),
29803
+ "CTRL+SHIFT+<": () => this.clearFormatting(), // for qwerty
29804
+ "CTRL+<": () => this.clearFormatting(), // for azerty
29796
29805
  "CTRL+SHIFT+ ": () => {
29797
29806
  this.env.model.selection.selectAll();
29798
29807
  },
@@ -30606,10 +30615,10 @@
30606
30615
  const CF_TYPE_CONVERSION_MAP = {
30607
30616
  aboveAverage: undefined,
30608
30617
  expression: undefined,
30609
- cellIs: undefined,
30610
- colorScale: undefined,
30618
+ cellIs: undefined, // exist but isn't an operator in o_spreadsheet
30619
+ colorScale: undefined, // exist but isn't an operator in o_spreadsheet
30611
30620
  dataBar: undefined,
30612
- iconSet: undefined,
30621
+ iconSet: undefined, // exist but isn't an operator in o_spreadsheet
30613
30622
  top10: undefined,
30614
30623
  uniqueValues: undefined,
30615
30624
  duplicateValues: undefined,
@@ -30844,7 +30853,7 @@
30844
30853
  61: "993366",
30845
30854
  62: "333399",
30846
30855
  63: "333333",
30847
- 64: "000000",
30856
+ 64: "000000", // system foreground
30848
30857
  65: "FFFFFF", // system background
30849
30858
  };
30850
30859
  const IMAGE_MIMETYPE_TO_EXTENSION_MAPPING = {
@@ -34485,12 +34494,13 @@
34485
34494
  this.clearBorders(cmd.sheetId, cmd.target);
34486
34495
  break;
34487
34496
  case "REMOVE_COLUMNS_ROWS":
34488
- for (let el of [...cmd.elements].sort((a, b) => b - a)) {
34497
+ const elements = [...cmd.elements].sort((a, b) => b - a);
34498
+ for (const group of groupConsecutive(elements)) {
34489
34499
  if (cmd.dimension === "COL") {
34490
- this.shiftBordersHorizontally(cmd.sheetId, el + 1, -1);
34500
+ this.shiftBordersHorizontally(cmd.sheetId, group[group.length - 1] + 1, -group.length);
34491
34501
  }
34492
34502
  else {
34493
- this.shiftBordersVertically(cmd.sheetId, el + 1, -1);
34503
+ this.shiftBordersVertically(cmd.sheetId, group[group.length - 1] + 1, -group.length);
34494
34504
  }
34495
34505
  }
34496
34506
  break;
@@ -38651,7 +38661,7 @@
38651
38661
  * @param sheetXC the string description of a range, in the form SheetName!XC:XC
38652
38662
  */
38653
38663
  getRangeFromSheetXC(defaultSheetId, sheetXC) {
38654
- if (!rangeReference.test(sheetXC)) {
38664
+ if (!rangeReference.test(sheetXC) || !this.getters.tryGetSheet(defaultSheetId)) {
38655
38665
  return new RangeImpl({
38656
38666
  sheetId: "",
38657
38667
  zone: { left: -1, top: -1, right: -1, bottom: -1 },
@@ -39551,12 +39561,7 @@
39551
39561
  });
39552
39562
  }
39553
39563
  if (colIndex > deletedColumn) {
39554
- this.dispatch("UPDATE_CELL_POSITION", {
39555
- sheetId: sheet.id,
39556
- cellId: cellId,
39557
- col: colIndex - 1,
39558
- row: rowIndex,
39559
- });
39564
+ this.setNewPosition(cellId, sheet.id, colIndex - 1, rowIndex);
39560
39565
  }
39561
39566
  }
39562
39567
  }
@@ -39566,7 +39571,7 @@
39566
39571
  * Move the cells after a column or rows insertion
39567
39572
  */
39568
39573
  moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
39569
- const commands = [];
39574
+ const updates = [];
39570
39575
  for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
39571
39576
  const row = sheet.rows[rowIndex];
39572
39577
  if (dimension !== "rows" || rowIndex >= addedElement) {
@@ -39575,20 +39580,20 @@
39575
39580
  const cellId = row.cells[i];
39576
39581
  if (cellId) {
39577
39582
  if (dimension === "rows" || colIndex >= addedElement) {
39578
- commands.push({
39579
- type: "UPDATE_CELL_POSITION",
39583
+ updates.push({
39580
39584
  sheetId: sheet.id,
39581
39585
  cellId: cellId,
39582
39586
  col: colIndex + (dimension === "columns" ? quantity : 0),
39583
39587
  row: rowIndex + (dimension === "rows" ? quantity : 0),
39588
+ type: "UPDATE_CELL_POSITION",
39584
39589
  });
39585
39590
  }
39586
39591
  }
39587
39592
  }
39588
39593
  }
39589
39594
  }
39590
- for (let cmd of commands.reverse()) {
39591
- this.dispatch(cmd.type, cmd);
39595
+ for (let update of updates.reverse()) {
39596
+ this.updateCellPosition(update);
39592
39597
  }
39593
39598
  }
39594
39599
  /**
@@ -39621,12 +39626,7 @@
39621
39626
  const colIndex = Number(i);
39622
39627
  const cellId = row.cells[i];
39623
39628
  if (cellId) {
39624
- this.dispatch("UPDATE_CELL_POSITION", {
39625
- sheetId: sheet.id,
39626
- cellId: cellId,
39627
- col: colIndex,
39628
- row: rowIndex - numberRows,
39629
- });
39629
+ this.setNewPosition(cellId, sheet.id, colIndex, rowIndex - numberRows);
39630
39630
  }
39631
39631
  }
39632
39632
  }
@@ -41603,15 +41603,16 @@
41603
41603
  this.evaluatedCells = new Map();
41604
41604
  this.evaluate(this.getAllCells());
41605
41605
  }
41606
- evaluateFormula(sheetId, formulaString) {
41607
- const compiledFormula = compile(formulaString);
41608
- const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
41609
- this.updateCompilationParameters();
41610
- const array = compiledFormula.execute(ranges, ...this.compilationParams);
41611
- if (isMatrix(array)) {
41612
- return matrixMap(array, (cell) => cell.value);
41606
+ evaluateFormulaResult(sheetId, formulaString) {
41607
+ try {
41608
+ const compiledFormula = compile(formulaString);
41609
+ const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
41610
+ this.updateCompilationParameters();
41611
+ return compiledFormula.execute(ranges, ...this.compilationParams);
41612
+ }
41613
+ catch (error) {
41614
+ return this.handleError(error);
41613
41615
  }
41614
- return array.value;
41615
41616
  }
41616
41617
  getAllCells() {
41617
41618
  const positionIds = new JetSet();
@@ -41687,7 +41688,7 @@
41687
41688
  : evaluateLiteral(cell.content, { format: cell.format, locale: this.getters.getLocale() });
41688
41689
  }
41689
41690
  catch (e) {
41690
- return this.handleError(e, cell);
41691
+ return this.handleError(e);
41691
41692
  }
41692
41693
  finally {
41693
41694
  this.cellsBeingComputed.delete(cellId);
@@ -41702,7 +41703,7 @@
41702
41703
  }
41703
41704
  return evaluatedCell;
41704
41705
  }
41705
- handleError(e, cell) {
41706
+ handleError(e) {
41706
41707
  if (!(e instanceof EvaluationError)) {
41707
41708
  e = new EvaluationError(CellErrorType.GenericError, e.message);
41708
41709
  }
@@ -42036,6 +42037,7 @@
42036
42037
  class EvaluationPlugin extends UIPlugin {
42037
42038
  static getters = [
42038
42039
  "evaluateFormula",
42040
+ "evaluateFormulaResult",
42039
42041
  "getCorrespondingFormulaCell",
42040
42042
  "getRangeFormattedValues",
42041
42043
  "getRangeValues",
@@ -42093,12 +42095,14 @@
42093
42095
  // Getters
42094
42096
  // ---------------------------------------------------------------------------
42095
42097
  evaluateFormula(sheetId, formulaString) {
42096
- try {
42097
- return this.evaluator.evaluateFormula(sheetId, formulaString);
42098
- }
42099
- catch (error) {
42100
- return error instanceof EvaluationError ? error.errorType : CellErrorType.GenericError;
42098
+ const result = this.evaluateFormulaResult(sheetId, formulaString);
42099
+ if (isMatrix(result)) {
42100
+ return matrixMap(result, (cell) => cell.value);
42101
42101
  }
42102
+ return result.value;
42103
+ }
42104
+ evaluateFormulaResult(sheetId, formulaString) {
42105
+ return this.evaluator.evaluateFormulaResult(sheetId, formulaString);
42102
42106
  }
42103
42107
  /**
42104
42108
  * Return the value of each cell in the range as they are displayed in the grid.
@@ -42239,17 +42243,17 @@
42239
42243
  */
42240
42244
  function sortWithClusters(colorsToSort) {
42241
42245
  const clusters = [
42242
- { leadColor: rgba(255, 0, 0), colors: [] },
42243
- { leadColor: rgba(255, 128, 0), colors: [] },
42244
- { leadColor: rgba(128, 128, 0), colors: [] },
42245
- { leadColor: rgba(128, 255, 0), colors: [] },
42246
- { leadColor: rgba(0, 255, 0), colors: [] },
42247
- { leadColor: rgba(0, 255, 128), colors: [] },
42248
- { leadColor: rgba(0, 255, 255), colors: [] },
42249
- { leadColor: rgba(0, 127, 255), colors: [] },
42250
- { leadColor: rgba(0, 0, 255), colors: [] },
42251
- { leadColor: rgba(127, 0, 255), colors: [] },
42252
- { leadColor: rgba(128, 0, 128), colors: [] },
42246
+ { leadColor: rgba(255, 0, 0), colors: [] }, // red
42247
+ { leadColor: rgba(255, 128, 0), colors: [] }, // orange
42248
+ { leadColor: rgba(128, 128, 0), colors: [] }, // yellow
42249
+ { leadColor: rgba(128, 255, 0), colors: [] }, // chartreuse
42250
+ { leadColor: rgba(0, 255, 0), colors: [] }, // green
42251
+ { leadColor: rgba(0, 255, 128), colors: [] }, // spring green
42252
+ { leadColor: rgba(0, 255, 255), colors: [] }, // cyan
42253
+ { leadColor: rgba(0, 127, 255), colors: [] }, // azure
42254
+ { leadColor: rgba(0, 0, 255), colors: [] }, // blue
42255
+ { leadColor: rgba(127, 0, 255), colors: [] }, // violet
42256
+ { leadColor: rgba(128, 0, 128), colors: [] }, // magenta
42253
42257
  { leadColor: rgba(255, 0, 128), colors: [] }, // rose
42254
42258
  ];
42255
42259
  for (const color of colorsToSort.map(colorToRGBA)) {
@@ -45898,6 +45902,7 @@
45898
45902
  * evaluated and updated with the number type.
45899
45903
  */
45900
45904
  setDecimal(sheetId, zones, step) {
45905
+ const positionsByFormat = {};
45901
45906
  // Find the each cell with a number value and get the format
45902
45907
  for (const zone of zones) {
45903
45908
  for (const position of positions(zone)) {
@@ -45907,15 +45912,20 @@
45907
45912
  // of the format
45908
45913
  this.getters.getLocale();
45909
45914
  const newFormat = changeDecimalPlaces(numberFormat, step);
45910
- // Apply the new format on the whole zone
45911
- this.dispatch("SET_FORMATTING", {
45912
- sheetId,
45913
- target: [positionToZone(position)],
45914
- format: newFormat,
45915
- });
45915
+ positionsByFormat[newFormat] = positionsByFormat[newFormat] || [];
45916
+ positionsByFormat[newFormat].push(position);
45916
45917
  }
45917
45918
  }
45918
45919
  }
45920
+ // consolidate all positions with the same format in bigger zones
45921
+ for (const newFormat in positionsByFormat) {
45922
+ const zones = futureRecomputeZones(positionsByFormat[newFormat].map((position) => positionToZone(position)));
45923
+ this.dispatch("SET_FORMATTING", {
45924
+ sheetId,
45925
+ format: newFormat,
45926
+ target: zones,
45927
+ });
45928
+ }
45919
45929
  }
45920
45930
  /**
45921
45931
  * Take a range of cells and return the format of the first cell containing a
@@ -52159,7 +52169,7 @@
52159
52169
  .map((sheetEl) => sheetEl.getBoundingClientRect())
52160
52170
  .map((rect) => ({
52161
52171
  x: rect.x,
52162
- width: rect.width - 1,
52172
+ width: rect.width - 1, // -1 to compensate negative margin
52163
52173
  y: rect.y,
52164
52174
  height: rect.height,
52165
52175
  }));
@@ -52384,7 +52394,7 @@
52384
52394
  }
52385
52395
  return cssPropertiesToCss({
52386
52396
  top: `${groupBox.headerRect.height / 2}px`,
52387
- left: `calc(50% - 1px)`,
52397
+ left: `calc(50% - 1px)`, // -1px: we want the border to be on the center
52388
52398
  width: `30%`,
52389
52399
  height: `calc(100% - ${groupBox.headerRect.height / 2}px)`,
52390
52400
  "border-left": `1px solid ${HEADER_GROUPING_BORDER_COLOR}`,
@@ -52436,7 +52446,7 @@
52436
52446
  return "";
52437
52447
  }
52438
52448
  return cssPropertiesToCss({
52439
- top: `calc(50% - 1px)`,
52449
+ top: `calc(50% - 1px)`, // -1px: we want the border to be on the center
52440
52450
  left: `${groupBox.headerRect.width / 2}px`,
52441
52451
  width: `calc(100% - ${groupBox.headerRect.width / 2}px)`,
52442
52452
  height: `30%`,
@@ -53837,7 +53847,7 @@
53837
53847
  const gridColSize = GROUP_LAYER_WIDTH * this.rowLayers.length;
53838
53848
  const gridRowSize = GROUP_LAYER_WIDTH * this.colLayers.length;
53839
53849
  return cssPropertiesToCss({
53840
- "grid-template-columns": `${gridColSize ? gridColSize + 2 : 0}px auto`,
53850
+ "grid-template-columns": `${gridColSize ? gridColSize + 2 : 0}px auto`, // +2: margins
53841
53851
  "grid-template-rows": `${gridRowSize ? gridRowSize + 2 : 0}px auto`,
53842
53852
  });
53843
53853
  }
@@ -55340,7 +55350,7 @@
55340
55350
  }
55341
55351
 
55342
55352
  class StateObserver {
55343
- changes = [];
55353
+ changes;
55344
55354
  commands = [];
55345
55355
  /**
55346
55356
  * Record the changes which could happen in the given callback, save them in a
@@ -55372,7 +55382,7 @@
55372
55382
  if (value[key] === val) {
55373
55383
  return;
55374
55384
  }
55375
- this.changes.push({
55385
+ this.changes?.push({
55376
55386
  path: args,
55377
55387
  before: value[key],
55378
55388
  after: val,
@@ -56503,7 +56513,7 @@
56503
56513
  const colHeaderXc = toXC(tableZone.left + i, tableZone.top);
56504
56514
  const colName = sheetData.cells[colHeaderXc]?.content || `col${i}`;
56505
56515
  const colAttributes = [
56506
- ["id", i + 1],
56516
+ ["id", i + 1], // id cannot be 0
56507
56517
  ["name", colName],
56508
56518
  ];
56509
56519
  columns.push(escapeXml /*xml*/ `<tableColumn ${formatAttributes(colAttributes)}/>`);
@@ -57585,9 +57595,9 @@
57585
57595
  exports.tokenize = tokenize;
57586
57596
 
57587
57597
 
57588
- __info__.version = "17.0.32";
57589
- __info__.date = "2024-07-24T10:26:05.203Z";
57590
- __info__.hash = "679a547";
57598
+ __info__.version = "17.0.34";
57599
+ __info__.date = "2024-08-09T12:20:17.042Z";
57600
+ __info__.hash = "1573912";
57591
57601
 
57592
57602
 
57593
57603
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);