@odoo/o-spreadsheet 17.4.18 → 17.4.20

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.4.18
6
- * @date 2025-01-15T08:05:34.182Z
7
- * @hash 9e0f399
5
+ * @version 17.4.20
6
+ * @date 2025-01-31T08:00:07.103Z
7
+ * @hash 54a344a
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -1953,11 +1953,11 @@
1953
1953
  * number from the point of view of the isNumber function.
1954
1954
  */
1955
1955
  function parseNumber(str, locale) {
1956
+ // remove invaluable characters
1957
+ str = str.replace(getInvaluableSymbolsRegexp(locale), "");
1956
1958
  if (locale.decimalSeparator !== ".") {
1957
1959
  str = str.replace(locale.decimalSeparator, ".");
1958
1960
  }
1959
- // remove invaluable characters
1960
- str = str.replace(getInvaluableSymbolsRegexp(locale), "");
1961
1961
  let n = Number(str);
1962
1962
  if (isNaN(n) && str.includes("%")) {
1963
1963
  n = Number(str.split("%")[0]);
@@ -3014,15 +3014,18 @@
3014
3014
  let currentIndex;
3015
3015
  let currentVal;
3016
3016
  let currentType;
3017
+ const getValue = sortOrder === "desc"
3018
+ ? (i) => normalizeValue(getValueInData(data, rangeLength - i - 1))
3019
+ : (i) => normalizeValue(getValueInData(data, i));
3017
3020
  while (indexRight - indexLeft >= 0) {
3018
3021
  indexMedian = Math.floor((indexLeft + indexRight) / 2);
3019
3022
  currentIndex = indexMedian;
3020
- currentVal = normalizeValue(getValueInData(data, currentIndex));
3023
+ currentVal = getValue(currentIndex);
3021
3024
  currentType = typeof currentVal;
3022
3025
  // 1 - linear search to find value with the same type
3023
3026
  while (indexLeft < currentIndex && targetType !== currentType) {
3024
3027
  currentIndex--;
3025
- currentVal = normalizeValue(getValueInData(data, currentIndex));
3028
+ currentVal = getValue(currentIndex);
3026
3029
  currentType = typeof currentVal;
3027
3030
  }
3028
3031
  if (currentType !== targetType || currentVal === undefined || currentVal === null) {
@@ -3038,8 +3041,7 @@
3038
3041
  if (matchVal === undefined ||
3039
3042
  matchVal === null ||
3040
3043
  matchVal < currentVal ||
3041
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
3042
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
3044
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
3043
3045
  matchVal = currentVal;
3044
3046
  matchValIndex = currentIndex;
3045
3047
  }
@@ -3047,15 +3049,13 @@
3047
3049
  else if (mode === "nextGreater" && currentVal >= _target) {
3048
3050
  if (matchVal === undefined ||
3049
3051
  matchVal > currentVal ||
3050
- (matchVal === currentVal && sortOrder === "asc" && matchValIndex < currentIndex) ||
3051
- (matchVal === currentVal && sortOrder === "desc" && matchValIndex > currentIndex)) {
3052
+ (matchVal === currentVal && matchValIndex < currentIndex)) {
3052
3053
  matchVal = currentVal;
3053
3054
  matchValIndex = currentIndex;
3054
3055
  }
3055
3056
  }
3056
3057
  // 3 - give new indexes for the Binary search
3057
- if ((sortOrder === "asc" && currentVal > _target) ||
3058
- (sortOrder === "desc" && currentVal <= _target)) {
3058
+ if (currentVal > _target || (mode === "strict" && currentVal === _target)) {
3059
3059
  indexRight = currentIndex - 1;
3060
3060
  }
3061
3061
  else {
@@ -3063,7 +3063,10 @@
3063
3063
  }
3064
3064
  }
3065
3065
  // note that valMinIndex could be 0
3066
- return matchValIndex !== undefined ? matchValIndex : -1;
3066
+ if (matchValIndex === undefined) {
3067
+ return -1;
3068
+ }
3069
+ return sortOrder === "desc" ? rangeLength - matchValIndex - 1 : matchValIndex;
3067
3070
  }
3068
3071
  /**
3069
3072
  * Perform a linear search and return the index of the match.
@@ -21612,6 +21615,12 @@ stores.inject(MyMetaStore, storeInstance);
21612
21615
  }
21613
21616
  this.contentHelper.updateEl(el);
21614
21617
  });
21618
+ this.env.model.selection.observe(this, {
21619
+ handleEvent: () => this.autoCompleteState.hide(),
21620
+ });
21621
+ owl.onWillUnmount(() => {
21622
+ this.env.model.selection.detachObserver(this);
21623
+ });
21615
21624
  owl.useEffect(() => {
21616
21625
  this.processContent();
21617
21626
  });
@@ -26458,6 +26467,10 @@ stores.inject(MyMetaStore, storeInstance);
26458
26467
  this.currentDisplayValue = newDisplay;
26459
26468
  if (!anchor)
26460
26469
  return;
26470
+ el.style.top = "";
26471
+ el.style.left = "";
26472
+ el.style["max-height"] = "";
26473
+ el.style["max-width"] = "";
26461
26474
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
26462
26475
  let elDims = {
26463
26476
  width: el.getBoundingClientRect().width,
@@ -39450,7 +39463,7 @@ stores.inject(MyMetaStore, storeInstance);
39450
39463
  return;
39451
39464
  }
39452
39465
  const sheetId = this.env.model.getters.getActiveSheetId();
39453
- const zone = this.env.model.getters.getSelectedZone();
39466
+ const zone = positionToZone(this.env.model.getters.getSelection().anchor.cell);
39454
39467
  const rect = this.env.model.getters.getVisibleRect(zone);
39455
39468
  if (!deepEquals(rect, this.rect) || sheetId !== this.composerStore.currentEditedCell.sheetId) {
39456
39469
  this.isCellReferenceVisible = true;
@@ -41205,13 +41218,23 @@ stores.inject(MyMetaStore, storeInstance);
41205
41218
  drawLayer(renderingContext, layer) {
41206
41219
  switch (layer) {
41207
41220
  case "Background":
41208
- const boxes = this.getGridBoxes();
41209
- this.drawBackground(renderingContext, boxes);
41210
- this.drawOverflowingCellBackground(renderingContext, boxes);
41211
- this.drawCellBackground(renderingContext, boxes);
41212
- this.drawBorders(renderingContext, boxes);
41213
- this.drawTexts(renderingContext, boxes);
41214
- this.drawIcon(renderingContext, boxes);
41221
+ this.drawGlobalBackground(renderingContext);
41222
+ for (const zone of this.getters.getAllActiveViewportsZones()) {
41223
+ const { ctx } = renderingContext;
41224
+ ctx.save();
41225
+ ctx.beginPath();
41226
+ const rect = this.getters.getVisibleRect(zone);
41227
+ ctx.rect(rect.x, rect.y, rect.width, rect.height);
41228
+ ctx.clip();
41229
+ const boxes = this.getGridBoxes(zone);
41230
+ this.drawBackground(renderingContext, boxes);
41231
+ this.drawOverflowingCellBackground(renderingContext, boxes);
41232
+ this.drawCellBackground(renderingContext, boxes);
41233
+ this.drawBorders(renderingContext, boxes);
41234
+ this.drawTexts(renderingContext, boxes);
41235
+ this.drawIcon(renderingContext, boxes);
41236
+ ctx.restore();
41237
+ }
41215
41238
  this.drawFrozenPanes(renderingContext);
41216
41239
  break;
41217
41240
  case "Headers":
@@ -41222,12 +41245,15 @@ stores.inject(MyMetaStore, storeInstance);
41222
41245
  break;
41223
41246
  }
41224
41247
  }
41225
- drawBackground(renderingContext, boxes) {
41226
- const { ctx, thinLineWidth } = renderingContext;
41248
+ drawGlobalBackground(renderingContext) {
41249
+ const { ctx } = renderingContext;
41227
41250
  const { width, height } = this.getters.getSheetViewDimensionWithHeaders();
41228
41251
  // white background
41229
41252
  ctx.fillStyle = "#ffffff";
41230
41253
  ctx.fillRect(0, 0, width + CANVAS_SHIFT, height + CANVAS_SHIFT);
41254
+ }
41255
+ drawBackground(renderingContext, boxes) {
41256
+ const { ctx, thinLineWidth } = renderingContext;
41231
41257
  const areGridLinesVisible = !this.getters.isDashboard() &&
41232
41258
  this.getters.getGridLinesVisibility(this.getters.getActiveSheetId());
41233
41259
  const inset = areGridLinesVisible ? 0.1 * thinLineWidth : 0;
@@ -41652,7 +41678,7 @@ stores.inject(MyMetaStore, storeInstance);
41652
41678
  const position = { sheetId, col, row };
41653
41679
  const cell = this.getters.getEvaluatedCell(position);
41654
41680
  const showFormula = this.getters.shouldShowFormulas();
41655
- const { x, y, width, height } = this.getters.getVisibleRect(zone);
41681
+ const { x, y, width, height } = this.getters.getRect(zone);
41656
41682
  const { verticalAlign } = this.getters.getCellStyle(position);
41657
41683
  const box = {
41658
41684
  x,
@@ -41768,12 +41794,16 @@ stores.inject(MyMetaStore, storeInstance);
41768
41794
  }
41769
41795
  return box;
41770
41796
  }
41771
- getGridBoxes() {
41797
+ getGridBoxes(zone) {
41772
41798
  const boxes = [];
41773
- const visibleCols = this.getters.getSheetViewVisibleCols();
41799
+ const visibleCols = this.getters
41800
+ .getSheetViewVisibleCols()
41801
+ .filter((col) => col >= zone.left && col <= zone.right);
41774
41802
  const left = visibleCols[0];
41775
41803
  const right = visibleCols[visibleCols.length - 1];
41776
- const visibleRows = this.getters.getSheetViewVisibleRows();
41804
+ const visibleRows = this.getters
41805
+ .getSheetViewVisibleRows()
41806
+ .filter((row) => row >= zone.top && row <= zone.bottom);
41777
41807
  const top = visibleRows[0];
41778
41808
  const bottom = visibleRows[visibleRows.length - 1];
41779
41809
  const viewport = { left, right, top, bottom };
@@ -58510,14 +58540,12 @@ stores.inject(MyMetaStore, storeInstance);
58510
58540
  }
58511
58541
  break;
58512
58542
  case "AUTORESIZE_ROWS":
58513
- for (let row of cmd.rows) {
58514
- this.dispatch("RESIZE_COLUMNS_ROWS", {
58515
- elements: [row],
58516
- dimension: "ROW",
58517
- size: null,
58518
- sheetId: cmd.sheetId,
58519
- });
58520
- }
58543
+ this.dispatch("RESIZE_COLUMNS_ROWS", {
58544
+ elements: cmd.rows,
58545
+ dimension: "ROW",
58546
+ size: null,
58547
+ sheetId: cmd.sheetId,
58548
+ });
58521
58549
  break;
58522
58550
  }
58523
58551
  }
@@ -60776,8 +60804,12 @@ stores.inject(MyMetaStore, storeInstance);
60776
60804
  },
60777
60805
  ];
60778
60806
  handler.paste({ zones: pasteTarget, sheetId }, data, { isCutOperation: true });
60807
+ const selection = pasteTarget[0];
60808
+ const col = selection.left;
60809
+ const row = selection.top;
60810
+ this.setSelectionMixin({ zone: selection, cell: { col, row } }, [selection]);
60779
60811
  const toRemove = isBasedBefore ? cmd.elements.map((el) => el + thickness) : cmd.elements;
60780
- let currentIndex = cmd.base;
60812
+ let currentIndex = isBasedBefore ? cmd.base : cmd.base + 1;
60781
60813
  for (const element of toRemove) {
60782
60814
  const size = this.getters.getHeaderSize(cmd.sheetId, cmd.dimension, element);
60783
60815
  this.dispatch("RESIZE_COLUMNS_ROWS", {
@@ -61060,22 +61092,33 @@ stores.inject(MyMetaStore, storeInstance);
61060
61092
  }
61061
61093
  /**
61062
61094
  *
61063
- * @param zone
61064
- * @returns Computes the absolute coordinate of a given zone inside the viewport
61095
+ * Computes the visible coordinates & dimensions of a given zone inside the viewport
61096
+ *
61065
61097
  */
61066
- getRect(zone) {
61098
+ getVisibleRect(zone) {
61067
61099
  const targetZone = intersection(zone, this);
61068
61100
  if (targetZone) {
61069
61101
  const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) + this.offsetCorrectionX;
61070
61102
  const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) + this.offsetCorrectionY;
61071
61103
  const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
61072
61104
  const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
61073
- return {
61074
- x,
61075
- y,
61076
- width,
61077
- height,
61078
- };
61105
+ return { x, y, width, height };
61106
+ }
61107
+ return undefined;
61108
+ }
61109
+ /**
61110
+ *
61111
+ * @returns Computes the absolute coordinates & dimensions of a given zone inside the viewport
61112
+ *
61113
+ */
61114
+ getFullRect(zone) {
61115
+ const targetZone = intersection(zone, this);
61116
+ if (targetZone) {
61117
+ const x = this.getters.getColRowOffset("COL", this.left, zone.left) + this.offsetCorrectionX;
61118
+ const y = this.getters.getColRowOffset("ROW", this.top, zone.top) + this.offsetCorrectionY;
61119
+ const width = this.getters.getColRowOffset("COL", zone.left, zone.right + 1);
61120
+ const height = this.getters.getColRowOffset("ROW", zone.top, zone.bottom + 1);
61121
+ return { x, y, width, height };
61079
61122
  }
61080
61123
  return undefined;
61081
61124
  }
@@ -61245,6 +61288,8 @@ stores.inject(MyMetaStore, storeInstance);
61245
61288
  "isPositionVisible",
61246
61289
  "getColDimensionsInViewport",
61247
61290
  "getRowDimensionsInViewport",
61291
+ "getAllActiveViewportsZones",
61292
+ "getRect",
61248
61293
  ];
61249
61294
  viewports = {};
61250
61295
  /**
@@ -61631,16 +61676,27 @@ stores.inject(MyMetaStore, storeInstance);
61631
61676
  getVisibleRectWithoutHeaders(zone) {
61632
61677
  const sheetId = this.getters.getActiveSheetId();
61633
61678
  const viewportRects = this.getSubViewports(sheetId)
61634
- .map((viewport) => viewport.getRect(zone))
61679
+ .map((viewport) => viewport.getVisibleRect(zone))
61635
61680
  .filter(isDefined);
61636
61681
  if (viewportRects.length === 0) {
61637
61682
  return { x: 0, y: 0, width: 0, height: 0 };
61638
61683
  }
61639
- const x = Math.min(...viewportRects.map((rect) => rect.x));
61640
- const y = Math.min(...viewportRects.map((rect) => rect.y));
61641
- const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
61642
- const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
61643
- return { x, y, width, height };
61684
+ return this.recomposeRect(viewportRects);
61685
+ }
61686
+ /**
61687
+ * Computes the actual size and position (:Rect) of the zone on the canvas
61688
+ * regardless of the viewport dimensions.
61689
+ */
61690
+ getRect(zone) {
61691
+ const sheetId = this.getters.getActiveSheetId();
61692
+ const viewportRects = this.getSubViewports(sheetId)
61693
+ .map((viewport) => viewport.getFullRect(zone))
61694
+ .filter(isDefined);
61695
+ if (viewportRects.length === 0) {
61696
+ return { x: 0, y: 0, width: 0, height: 0 };
61697
+ }
61698
+ const rect = this.recomposeRect(viewportRects);
61699
+ return { ...rect, x: rect.x + this.gridOffsetX, y: rect.y + this.gridOffsetY };
61644
61700
  }
61645
61701
  /**
61646
61702
  * Returns the position of the MainViewport relatively to the start of the grid (without headers)
@@ -61684,6 +61740,10 @@ stores.inject(MyMetaStore, storeInstance);
61684
61740
  end: start + (isRowHidden ? 0 : size),
61685
61741
  };
61686
61742
  }
61743
+ getAllActiveViewportsZones() {
61744
+ const sheetId = this.getters.getActiveSheetId();
61745
+ return this.getSubViewports(sheetId);
61746
+ }
61687
61747
  // ---------------------------------------------------------------------------
61688
61748
  // Private
61689
61749
  // ---------------------------------------------------------------------------
@@ -61874,6 +61934,13 @@ stores.inject(MyMetaStore, storeInstance);
61874
61934
  const height = this.sheetViewHeight + this.gridOffsetY;
61875
61935
  return { xRatio: offsetCorrectionX / width, yRatio: offsetCorrectionY / height };
61876
61936
  }
61937
+ recomposeRect(viewportRects) {
61938
+ const x = Math.min(...viewportRects.map((rect) => rect.x));
61939
+ const y = Math.min(...viewportRects.map((rect) => rect.y));
61940
+ const width = Math.max(...viewportRects.map((rect) => rect.x + rect.width)) - x;
61941
+ const height = Math.max(...viewportRects.map((rect) => rect.y + rect.height)) - y;
61942
+ return { x, y, width, height };
61943
+ }
61877
61944
  }
61878
61945
 
61879
61946
  class HeaderPositionsUIPlugin extends UIPlugin {
@@ -65488,6 +65555,9 @@ stores.inject(MyMetaStore, storeInstance);
65488
65555
  observe(owner, callbacks) {
65489
65556
  this.observers.set(owner, { owner, callbacks });
65490
65557
  }
65558
+ detachObserver(owner) {
65559
+ this.observers.delete(owner);
65560
+ }
65491
65561
  /**
65492
65562
  * Capture the stream for yourself
65493
65563
  */
@@ -65580,6 +65650,9 @@ stores.inject(MyMetaStore, storeInstance);
65580
65650
  observe(owner, callbacks) {
65581
65651
  this.stream.observe(owner, callbacks);
65582
65652
  }
65653
+ detachObserver(owner) {
65654
+ this.stream.detachObserver(owner);
65655
+ }
65583
65656
  release(owner) {
65584
65657
  if (this.stream.isListening(owner)) {
65585
65658
  this.stream.release(owner);
@@ -68799,9 +68872,9 @@ stores.inject(MyMetaStore, storeInstance);
68799
68872
  exports.tokenize = tokenize;
68800
68873
 
68801
68874
 
68802
- __info__.version = "17.4.18";
68803
- __info__.date = "2025-01-15T08:05:34.182Z";
68804
- __info__.hash = "9e0f399";
68875
+ __info__.version = "17.4.20";
68876
+ __info__.date = "2025-01-31T08:00:07.103Z";
68877
+ __info__.hash = "54a344a";
68805
68878
 
68806
68879
 
68807
68880
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);