@odoo/o-spreadsheet 18.1.14 → 18.1.16

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.1.14
6
- * @date 2025-04-04T08:42:40.149Z
7
- * @hash 63b2fb7
5
+ * @version 18.1.16
6
+ * @date 2025-04-18T16:24:16.854Z
7
+ * @hash 19f6de2
8
8
  */
9
9
 
10
10
  'use strict';
@@ -3564,6 +3564,7 @@ const coreTypes = new Set([
3564
3564
  "CLEAR_FORMATTING",
3565
3565
  "SET_BORDER",
3566
3566
  "SET_ZONE_BORDERS",
3567
+ "SET_BORDERS_ON_TARGET",
3567
3568
  /** CHART */
3568
3569
  "CREATE_CHART",
3569
3570
  "UPDATE_CHART",
@@ -6715,6 +6716,7 @@ class AbstractCellClipboardHandler extends ClipboardHandler {
6715
6716
  }
6716
6717
 
6717
6718
  class BorderClipboardHandler extends AbstractCellClipboardHandler {
6719
+ queuedBordersToAdd = {};
6718
6720
  copy(data) {
6719
6721
  const sheetId = data.sheetId;
6720
6722
  if (data.zones.length === 0) {
@@ -6745,6 +6747,7 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
6745
6747
  const { left, top } = zones[0];
6746
6748
  this.pasteZone(sheetId, left, top, content.borders);
6747
6749
  }
6750
+ this.executeQueuedChanges(sheetId);
6748
6751
  }
6749
6752
  pasteZone(sheetId, col, row, borders) {
6750
6753
  for (const [r, rowBorders] of borders.entries()) {
@@ -6763,7 +6766,20 @@ class BorderClipboardHandler extends AbstractCellClipboardHandler {
6763
6766
  ...targetBorders,
6764
6767
  ...originBorders,
6765
6768
  };
6766
- this.dispatch("SET_BORDER", { ...target, border });
6769
+ const borderKey = JSON.stringify(border);
6770
+ if (!this.queuedBordersToAdd[borderKey]) {
6771
+ this.queuedBordersToAdd[borderKey] = [];
6772
+ }
6773
+ this.queuedBordersToAdd[borderKey].push(positionToZone(target));
6774
+ }
6775
+ executeQueuedChanges(pasteSheetTarget) {
6776
+ for (const borderKey in this.queuedBordersToAdd) {
6777
+ const zones = this.queuedBordersToAdd[borderKey];
6778
+ const border = JSON.parse(borderKey);
6779
+ const target = recomputeZones(zones, []);
6780
+ this.dispatch("SET_BORDERS_ON_TARGET", { sheetId: pasteSheetTarget, target, border });
6781
+ }
6782
+ this.queuedBordersToAdd = {};
6767
6783
  }
6768
6784
  }
6769
6785
 
@@ -6875,6 +6891,12 @@ function tokenizeString(chars) {
6875
6891
  }
6876
6892
  return null;
6877
6893
  }
6894
+ /**
6895
+ - \p{L} is for any letter (from any language)
6896
+ - \p{N} is for any number
6897
+ - the u flag at the end is for unicode, which enables the `\p{...}` syntax
6898
+ */
6899
+ const unicodeSymbolCharRegexp = /\p{L}|\p{N}|_|\.|!|\$/u;
6878
6900
  const SYMBOL_CHARS = new Set("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.!$");
6879
6901
  /**
6880
6902
  * A "Symbol" is just basically any word-like element that can appear in a
@@ -6915,7 +6937,8 @@ function tokenizeSymbol(chars) {
6915
6937
  };
6916
6938
  }
6917
6939
  }
6918
- while (chars.current && SYMBOL_CHARS.has(chars.current)) {
6940
+ while (chars.current &&
6941
+ (SYMBOL_CHARS.has(chars.current) || chars.current.match(unicodeSymbolCharRegexp))) {
6919
6942
  result += chars.shift();
6920
6943
  }
6921
6944
  if (result.length) {
@@ -8702,12 +8725,13 @@ class ConditionalFormatClipboardHandler extends AbstractCellClipboardHandler {
8702
8725
  }
8703
8726
  pasteCf(origin, target, isCutOperation) {
8704
8727
  if (origin?.rules && origin.rules.length > 0) {
8728
+ const originZone = positionToZone(origin.position);
8705
8729
  const zone = positionToZone(target);
8706
8730
  for (const rule of origin.rules) {
8707
8731
  const toRemoveZones = [];
8708
8732
  if (isCutOperation) {
8709
8733
  //remove from current rule
8710
- toRemoveZones.push(positionToZone(origin.position));
8734
+ toRemoveZones.push(originZone);
8711
8735
  }
8712
8736
  if (origin.position.sheetId === target.sheetId) {
8713
8737
  this.adaptCFRules(origin.position.sheetId, rule, [zone], toRemoveZones);
@@ -8821,6 +8845,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
8821
8845
  pasteDataValidation(origin, target, isCutOperation) {
8822
8846
  if (origin) {
8823
8847
  const zone = positionToZone(target);
8848
+ const originZone = positionToZone(origin.position);
8824
8849
  const rule = origin.rule;
8825
8850
  if (!rule) {
8826
8851
  const targetRule = this.getters.getValidationRuleForCell(target);
@@ -8832,7 +8857,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
8832
8857
  }
8833
8858
  const toRemoveZone = [];
8834
8859
  if (isCutOperation) {
8835
- toRemoveZone.push(positionToZone(origin.position));
8860
+ toRemoveZone.push(originZone);
8836
8861
  }
8837
8862
  if (origin.position.sheetId === target.sheetId) {
8838
8863
  const copyToRule = this.getDataValidationRuleToCopyTo(target.sheetId, rule, false);
@@ -8892,7 +8917,7 @@ class DataValidationClipboardHandler extends AbstractCellClipboardHandler {
8892
8917
  continue;
8893
8918
  }
8894
8919
  this.dispatch("ADD_DATA_VALIDATION_RULE", {
8895
- rule: dv,
8920
+ rule: { id: dv.id, criterion: dv.criterion, isBlocking: dv.isBlocking },
8896
8921
  ranges: newDvZones.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
8897
8922
  sheetId,
8898
8923
  });
@@ -9219,7 +9244,7 @@ function transformZone(zone, executed) {
9219
9244
  if (executed.type === "ADD_COLUMNS_ROWS") {
9220
9245
  return expandZoneOnInsertion(zone, executed.dimension === "COL" ? "left" : "top", executed.base, executed.position, executed.quantity);
9221
9246
  }
9222
- return { ...zone };
9247
+ return zone;
9223
9248
  }
9224
9249
  function transformRangeData(range, executed) {
9225
9250
  const deletedSheet = executed.type === "DELETE_SHEET" && executed.sheetId;
@@ -50089,39 +50114,6 @@ function useCellHovered(env, gridRef, callback) {
50089
50114
  }
50090
50115
  return hoveredPosition;
50091
50116
  }
50092
- function useTouchMove(gridRef, handler, canMoveUp) {
50093
- let x = null;
50094
- let y = null;
50095
- function onTouchStart(ev) {
50096
- if (ev.touches.length !== 1)
50097
- return;
50098
- x = ev.touches[0].clientX;
50099
- y = ev.touches[0].clientY;
50100
- }
50101
- function onTouchEnd() {
50102
- x = null;
50103
- y = null;
50104
- }
50105
- function onTouchMove(ev) {
50106
- if (ev.touches.length !== 1)
50107
- return;
50108
- // On mobile browsers, swiping down is often associated with "pull to refresh".
50109
- // We only want this behavior if the grid is already at the top.
50110
- // Otherwise we only want to move the canvas up, without triggering any refresh.
50111
- if (canMoveUp()) {
50112
- ev.preventDefault();
50113
- ev.stopPropagation();
50114
- }
50115
- const currentX = ev.touches[0].clientX;
50116
- const currentY = ev.touches[0].clientY;
50117
- handler(x - currentX, y - currentY);
50118
- x = currentX;
50119
- y = currentY;
50120
- }
50121
- useRefListener(gridRef, "touchstart", onTouchStart);
50122
- useRefListener(gridRef, "touchend", onTouchEnd);
50123
- useRefListener(gridRef, "touchmove", onTouchMove);
50124
- }
50125
50117
  class GridOverlay extends owl.Component {
50126
50118
  static template = "o-spreadsheet-GridOverlay";
50127
50119
  static props = {
@@ -50169,10 +50161,6 @@ class GridOverlay extends owl.Component {
50169
50161
  owl.onWillUnmount(() => {
50170
50162
  resizeObserver.disconnect();
50171
50163
  });
50172
- useTouchMove(this.gridOverlay, this.props.onGridMoved, () => {
50173
- const { scrollY } = this.env.model.getters.getActiveSheetDOMScrollInfo();
50174
- return scrollY > 0;
50175
- });
50176
50164
  this.cellPopovers = useStore(CellPopoverStore);
50177
50165
  this.paintFormatStore = useStore(PaintFormatStore);
50178
50166
  }
@@ -51530,6 +51518,73 @@ function useGridDrawing(refName, model, canvasSize) {
51530
51518
  }
51531
51519
  }
51532
51520
 
51521
+ const friction = 0.95;
51522
+ const verticalScrollFactor = 1;
51523
+ const horizontalScrollFactor = 1;
51524
+ function useTouchScroll(ref, updateScroll, canMoveUp) {
51525
+ let lastX = 0;
51526
+ let lastY = 0;
51527
+ let velocityX = 0;
51528
+ let velocityY = 0;
51529
+ let isMouseDown = false;
51530
+ let lastTime = 0;
51531
+ useRefListener(ref, "touchstart", onTouchStart, { capture: false });
51532
+ useRefListener(ref, "touchmove", onTouchMove, { capture: false });
51533
+ useRefListener(ref, "touchend", onTouchEnd, { capture: false });
51534
+ function onTouchStart(event) {
51535
+ isMouseDown = true;
51536
+ ({ clientX: lastX, clientY: lastY } = event.touches[0]);
51537
+ velocityX = 0;
51538
+ velocityY = 0;
51539
+ }
51540
+ function onTouchMove(event) {
51541
+ if (!isMouseDown)
51542
+ return;
51543
+ const currentTime = Date.now();
51544
+ const { clientX, clientY } = event.touches[0];
51545
+ let deltaX = lastX - clientX;
51546
+ let deltaY = lastY - clientY;
51547
+ const elapsedTime = currentTime - lastTime;
51548
+ velocityX = deltaX / elapsedTime;
51549
+ velocityY = deltaY / elapsedTime;
51550
+ lastX = clientX;
51551
+ lastY = clientY;
51552
+ lastTime = currentTime;
51553
+ if (canMoveUp()) {
51554
+ if (event.cancelable) {
51555
+ event.preventDefault();
51556
+ }
51557
+ event.stopPropagation();
51558
+ }
51559
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
51560
+ }
51561
+ function onTouchEnd(ev) {
51562
+ isMouseDown = false;
51563
+ lastX = lastY = 0;
51564
+ requestAnimationFrame(scroll);
51565
+ }
51566
+ function scroll() {
51567
+ if (Math.abs(velocityX) < 0.05) {
51568
+ velocityX = 0;
51569
+ }
51570
+ if (Math.abs(velocityY) < 0.05) {
51571
+ velocityY = 0;
51572
+ }
51573
+ if (!velocityX && !velocityY) {
51574
+ return;
51575
+ }
51576
+ const currentTime = Date.now();
51577
+ const elapsedTime = Math.abs(currentTime - lastTime);
51578
+ const deltaX = velocityX * elapsedTime;
51579
+ const deltaY = velocityY * elapsedTime;
51580
+ updateScroll(deltaX * horizontalScrollFactor, deltaY * verticalScrollFactor);
51581
+ lastTime = currentTime;
51582
+ velocityX *= friction;
51583
+ velocityY *= friction;
51584
+ requestAnimationFrame(scroll);
51585
+ }
51586
+ }
51587
+
51533
51588
  function useWheelHandler(handler) {
51534
51589
  function normalize(val, deltaMode) {
51535
51590
  return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
@@ -52150,6 +52205,10 @@ class Grid extends owl.Component {
52150
52205
  this.DOMFocusableElementStore.focusableElement?.focus();
52151
52206
  }
52152
52207
  }, () => [this.sidePanel.isOpen]);
52208
+ useTouchScroll(this.gridRef, this.moveCanvas.bind(this), () => {
52209
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
52210
+ return scrollY > 0;
52211
+ });
52153
52212
  }
52154
52213
  onCellHovered({ col, row }) {
52155
52214
  this.hoveredCell.hover({ col, row });
@@ -52872,6 +52931,15 @@ class BordersPlugin extends CorePlugin {
52872
52931
  case "SET_BORDER":
52873
52932
  this.setBorder(cmd.sheetId, cmd.col, cmd.row, cmd.border);
52874
52933
  break;
52934
+ case "SET_BORDERS_ON_TARGET":
52935
+ for (const zone of cmd.target) {
52936
+ for (let row = zone.top; row <= zone.bottom; row++) {
52937
+ for (let col = zone.left; col <= zone.right; col++) {
52938
+ this.setBorder(cmd.sheetId, col, row, cmd.border);
52939
+ }
52940
+ }
52941
+ }
52942
+ break;
52875
52943
  case "SET_ZONE_BORDERS":
52876
52944
  if (cmd.border) {
52877
52945
  const target = cmd.target.map((zone) => this.getters.expandZone(cmd.sheetId, zone));
@@ -62598,25 +62666,6 @@ class AutofillPlugin extends UIPlugin {
62598
62666
  case "AUTOFILL_AUTO":
62599
62667
  this.autofillAuto();
62600
62668
  break;
62601
- case "AUTOFILL_CELL":
62602
- this.autoFillMerge(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
62603
- const sheetId = this.getters.getActiveSheetId();
62604
- this.dispatch("UPDATE_CELL", {
62605
- sheetId,
62606
- col: cmd.col,
62607
- row: cmd.row,
62608
- style: cmd.style || null,
62609
- content: cmd.content || "",
62610
- format: cmd.format || "",
62611
- });
62612
- this.dispatch("SET_BORDER", {
62613
- sheetId,
62614
- col: cmd.col,
62615
- row: cmd.row,
62616
- border: cmd.border,
62617
- });
62618
- this.autofillCF(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
62619
- this.autofillDV(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
62620
62669
  }
62621
62670
  }
62622
62671
  // ---------------------------------------------------------------------------
@@ -62640,6 +62689,7 @@ class AutofillPlugin extends UIPlugin {
62640
62689
  }
62641
62690
  const source = this.getters.getSelectedZone();
62642
62691
  const target = this.autofillZone;
62692
+ const autofillCellsData = [];
62643
62693
  switch (this.direction) {
62644
62694
  case "down" /* DIRECTION.DOWN */:
62645
62695
  for (let col = source.left; col <= source.right; col++) {
@@ -62649,7 +62699,7 @@ class AutofillPlugin extends UIPlugin {
62649
62699
  }
62650
62700
  const generator = this.createGenerator(xcs);
62651
62701
  for (let row = target.top; row <= target.bottom; row++) {
62652
- this.computeNewCell(generator, col, row, apply);
62702
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
62653
62703
  }
62654
62704
  }
62655
62705
  break;
@@ -62661,7 +62711,7 @@ class AutofillPlugin extends UIPlugin {
62661
62711
  }
62662
62712
  const generator = this.createGenerator(xcs);
62663
62713
  for (let row = target.bottom; row >= target.top; row--) {
62664
- this.computeNewCell(generator, col, row, apply);
62714
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
62665
62715
  }
62666
62716
  }
62667
62717
  break;
@@ -62673,7 +62723,7 @@ class AutofillPlugin extends UIPlugin {
62673
62723
  }
62674
62724
  const generator = this.createGenerator(xcs);
62675
62725
  for (let col = target.right; col >= target.left; col--) {
62676
- this.computeNewCell(generator, col, row, apply);
62726
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
62677
62727
  }
62678
62728
  }
62679
62729
  break;
@@ -62685,12 +62735,26 @@ class AutofillPlugin extends UIPlugin {
62685
62735
  }
62686
62736
  const generator = this.createGenerator(xcs);
62687
62737
  for (let col = target.left; col <= target.right; col++) {
62688
- this.computeNewCell(generator, col, row, apply);
62738
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
62689
62739
  }
62690
62740
  }
62691
62741
  break;
62692
62742
  }
62693
62743
  if (apply) {
62744
+ const bordersZones = {};
62745
+ const cfNewRanges = {};
62746
+ const dvNewZones = {};
62747
+ const sheetId = this.getters.getActiveSheetId();
62748
+ for (const data of autofillCellsData) {
62749
+ this.collectBordersData(data, bordersZones);
62750
+ this.autofillMerge(sheetId, data);
62751
+ this.autofillCell(sheetId, data);
62752
+ this.collectConditionalFormatsData(sheetId, data, cfNewRanges);
62753
+ this.collectDataValidationsData(sheetId, data, dvNewZones);
62754
+ }
62755
+ this.autofillBorders(sheetId, bordersZones);
62756
+ this.autofillConditionalFormats(sheetId, cfNewRanges);
62757
+ this.autofillDataValidations(sheetId, dvNewZones);
62694
62758
  this.autofillZone = undefined;
62695
62759
  this.selection.resizeAnchorZone(this.direction, this.steps);
62696
62760
  this.lastCellSelected = {};
@@ -62699,6 +62763,95 @@ class AutofillPlugin extends UIPlugin {
62699
62763
  this.tooltip = undefined;
62700
62764
  }
62701
62765
  }
62766
+ collectBordersData(data, bordersPositions) {
62767
+ const key = JSON.stringify(data.border);
62768
+ if (!(key in bordersPositions)) {
62769
+ bordersPositions[key] = [];
62770
+ }
62771
+ bordersPositions[key].push(positionToZone({ col: data.col, row: data.row }));
62772
+ }
62773
+ collectConditionalFormatsData(sheetId, data, cfNewRanges) {
62774
+ const { originCol, originRow, col, row } = data;
62775
+ const cfsAtOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
62776
+ const xc = toXC(col, row);
62777
+ for (const cf of cfsAtOrigin) {
62778
+ if (!(cf.id in cfNewRanges)) {
62779
+ cfNewRanges[cf.id] = [];
62780
+ }
62781
+ cfNewRanges[cf.id].push(xc);
62782
+ }
62783
+ }
62784
+ collectDataValidationsData(sheetId, data, dvNewZones) {
62785
+ const { originCol, originRow, col, row } = data;
62786
+ const cellPosition = { sheetId, col: originCol, row: originRow };
62787
+ const dvsAtOrigin = this.getters.getValidationRuleForCell(cellPosition);
62788
+ if (!dvsAtOrigin) {
62789
+ return;
62790
+ }
62791
+ if (!(dvsAtOrigin.id in dvNewZones)) {
62792
+ dvNewZones[dvsAtOrigin.id] = [];
62793
+ }
62794
+ dvNewZones[dvsAtOrigin.id].push(positionToZone({ col, row }));
62795
+ }
62796
+ autofillCell(sheetId, data) {
62797
+ this.dispatch("UPDATE_CELL", {
62798
+ sheetId,
62799
+ col: data.col,
62800
+ row: data.row,
62801
+ content: data.content || "",
62802
+ style: data.style || null,
62803
+ format: data.format || "",
62804
+ });
62805
+ // Still usefull in odoo ATM to autofill field sync
62806
+ this.dispatch("AUTOFILL_CELL", data);
62807
+ }
62808
+ autofillBorders(sheetId, bordersPositions) {
62809
+ for (const stringifiedBorder in bordersPositions) {
62810
+ const border = stringifiedBorder === "undefined" ? undefined : JSON.parse(stringifiedBorder);
62811
+ this.dispatch("SET_BORDERS_ON_TARGET", {
62812
+ sheetId,
62813
+ border,
62814
+ target: recomputeZones(bordersPositions[stringifiedBorder]),
62815
+ });
62816
+ }
62817
+ }
62818
+ autofillConditionalFormats(sheetId, cfNewRanges) {
62819
+ for (const cfId in cfNewRanges) {
62820
+ const changes = cfNewRanges[cfId];
62821
+ const cf = this.getters.getConditionalFormats(sheetId).find((cf) => cf.id === cfId);
62822
+ if (!cf) {
62823
+ continue;
62824
+ }
62825
+ const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, changes.map(toZone), []);
62826
+ if (newCfRanges) {
62827
+ this.dispatch("ADD_CONDITIONAL_FORMAT", {
62828
+ cf: {
62829
+ id: cf.id,
62830
+ rule: cf.rule,
62831
+ stopIfTrue: cf.stopIfTrue,
62832
+ },
62833
+ ranges: newCfRanges,
62834
+ sheetId,
62835
+ });
62836
+ }
62837
+ }
62838
+ }
62839
+ autofillDataValidations(sheetId, dvNewZones) {
62840
+ for (const dvId in dvNewZones) {
62841
+ const changes = dvNewZones[dvId];
62842
+ const dvOrigin = this.getters.getDataValidationRule(sheetId, dvId);
62843
+ if (!dvOrigin) {
62844
+ continue;
62845
+ }
62846
+ const dvRangesXcs = dvOrigin.ranges.map((range) => range.zone);
62847
+ const newDvRanges = recomputeZones(dvRangesXcs.concat(changes), []);
62848
+ this.dispatch("ADD_DATA_VALIDATION_RULE", {
62849
+ rule: dvOrigin,
62850
+ ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
62851
+ sheetId,
62852
+ });
62853
+ }
62854
+ }
62702
62855
  /**
62703
62856
  * Select a cell which becomes the last cell of the autofillZone
62704
62857
  */
@@ -62777,22 +62930,20 @@ class AutofillPlugin extends UIPlugin {
62777
62930
  /**
62778
62931
  * Generate the next cell
62779
62932
  */
62780
- computeNewCell(generator, col, row, apply) {
62933
+ computeNewCell(generator, col, row) {
62781
62934
  const { cellData, tooltip, origin } = generator.next();
62782
62935
  const { content, style, border, format } = cellData;
62783
62936
  this.tooltip = tooltip;
62784
- if (apply) {
62785
- this.dispatch("AUTOFILL_CELL", {
62786
- originCol: origin.col,
62787
- originRow: origin.row,
62788
- col,
62789
- row,
62790
- content,
62791
- style,
62792
- border,
62793
- format,
62794
- });
62795
- }
62937
+ return {
62938
+ originCol: origin.col,
62939
+ originRow: origin.row,
62940
+ col,
62941
+ row,
62942
+ content,
62943
+ style,
62944
+ border,
62945
+ format,
62946
+ };
62796
62947
  }
62797
62948
  /**
62798
62949
  * Get the rule associated to the current cell
@@ -62860,8 +63011,8 @@ class AutofillPlugin extends UIPlugin {
62860
63011
  ? position[first].value
62861
63012
  : position[second].value;
62862
63013
  }
62863
- autoFillMerge(originCol, originRow, col, row) {
62864
- const sheetId = this.getters.getActiveSheetId();
63014
+ autofillMerge(sheetId, data) {
63015
+ const { originCol, originRow, col, row } = data;
62865
63016
  const position = { sheetId, col, row };
62866
63017
  const originPosition = { sheetId, col: originCol, row: originRow };
62867
63018
  if (this.getters.isInMerge(position) && !this.getters.isInMerge(originPosition)) {
@@ -62888,35 +63039,6 @@ class AutofillPlugin extends UIPlugin {
62888
63039
  });
62889
63040
  }
62890
63041
  }
62891
- autofillCF(originCol, originRow, col, row) {
62892
- const sheetId = this.getters.getActiveSheetId();
62893
- const cfOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
62894
- for (const cf of cfOrigin) {
62895
- const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, [positionToZone({ col, row })], []);
62896
- if (newCfRanges) {
62897
- this.dispatch("ADD_CONDITIONAL_FORMAT", {
62898
- cf: deepCopy(cf),
62899
- ranges: newCfRanges,
62900
- sheetId,
62901
- });
62902
- }
62903
- }
62904
- }
62905
- autofillDV(originCol, originRow, col, row) {
62906
- const sheetId = this.getters.getActiveSheetId();
62907
- const cellPosition = { sheetId, col: originCol, row: originRow };
62908
- const dvOrigin = this.getters.getValidationRuleForCell(cellPosition);
62909
- if (!dvOrigin) {
62910
- return;
62911
- }
62912
- const dvRangesZones = dvOrigin.ranges.map((range) => range.zone);
62913
- const newDvRanges = recomputeZones(dvRangesZones.concat(positionToZone({ col, row })), []);
62914
- this.dispatch("ADD_DATA_VALIDATION_RULE", {
62915
- rule: dvOrigin,
62916
- ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
62917
- sheetId,
62918
- });
62919
- }
62920
63042
  // ---------------------------------------------------------------------------
62921
63043
  // Grid rendering
62922
63044
  // ---------------------------------------------------------------------------
@@ -63296,10 +63418,8 @@ function mergeTransformation(toTransform, executed) {
63296
63418
  }
63297
63419
  const target = [];
63298
63420
  for (const zone1 of toTransform.target) {
63299
- for (const zone2 of executed.target) {
63300
- if (!overlap(zone1, zone2)) {
63301
- target.push({ ...zone1 });
63302
- }
63421
+ if (executed.target.every((zone2) => !overlap(zone1, zone2))) {
63422
+ target.push(zone1);
63303
63423
  }
63304
63424
  }
63305
63425
  if (target.length) {
@@ -69571,6 +69691,10 @@ class SpreadsheetDashboard extends owl.Component {
69571
69691
  this.hoveredCell.clear();
69572
69692
  });
69573
69693
  this.cellPopovers = useStore(CellPopoverStore);
69694
+ useTouchScroll(gridRef, this.moveCanvas.bind(this), () => {
69695
+ const { scrollY } = this.env.model.getters.getActiveSheetScrollInfo();
69696
+ return scrollY > 0;
69697
+ });
69574
69698
  }
69575
69699
  onCellHovered({ col, row }) {
69576
69700
  this.hoveredCell.hover({ col, row });
@@ -75645,6 +75769,6 @@ exports.tokenColors = tokenColors;
75645
75769
  exports.tokenize = tokenize;
75646
75770
 
75647
75771
 
75648
- __info__.version = "18.1.14";
75649
- __info__.date = "2025-04-04T08:42:40.149Z";
75650
- __info__.hash = "63b2fb7";
75772
+ __info__.version = "18.1.16";
75773
+ __info__.date = "2025-04-18T16:24:16.854Z";
75774
+ __info__.hash = "19f6de2";