@odoo/o-spreadsheet 18.0.21 → 18.0.23

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.0.21
6
- * @date 2025-03-26T12:49:46.872Z
7
- * @hash c687e1c
5
+ * @version 18.0.23
6
+ * @date 2025-04-14T17:16:35.374Z
7
+ * @hash f560133
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -801,8 +801,7 @@
801
801
  *
802
802
  * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
803
803
  */
804
- const whiteSpaceSpecialCharacters = [
805
- " ",
804
+ const specialWhiteSpaceSpecialCharacters = [
806
805
  "\t",
807
806
  "\f",
808
807
  "\v",
@@ -817,7 +816,7 @@
817
816
  String.fromCharCode(parseInt("3000", 16)),
818
817
  String.fromCharCode(parseInt("feff", 16)),
819
818
  ];
820
- const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|"), "g");
819
+ const specialWhiteSpaceRegexp = new RegExp(specialWhiteSpaceSpecialCharacters.join("|"), "g");
821
820
  const newLineRegexp = /(\r\n|\r)/g;
822
821
  /**
823
822
  * Replace all different newlines characters by \n
@@ -3397,6 +3396,7 @@
3397
3396
  "CLEAR_FORMATTING",
3398
3397
  "SET_BORDER",
3399
3398
  "SET_ZONE_BORDERS",
3399
+ "SET_BORDERS_ON_TARGET",
3400
3400
  /** CHART */
3401
3401
  "CREATE_CHART",
3402
3402
  "UPDATE_CHART",
@@ -6560,6 +6560,7 @@
6560
6560
  }
6561
6561
 
6562
6562
  class BorderClipboardHandler extends AbstractCellClipboardHandler {
6563
+ queuedBordersToAdd = {};
6563
6564
  copy(data) {
6564
6565
  const sheetId = data.sheetId;
6565
6566
  if (data.zones.length === 0) {
@@ -6590,6 +6591,7 @@
6590
6591
  const { left, top } = zones[0];
6591
6592
  this.pasteZone(sheetId, left, top, content.borders);
6592
6593
  }
6594
+ this.executeQueuedChanges(sheetId);
6593
6595
  }
6594
6596
  pasteZone(sheetId, col, row, borders) {
6595
6597
  for (const [r, rowBorders] of borders.entries()) {
@@ -6608,7 +6610,20 @@
6608
6610
  ...targetBorders,
6609
6611
  ...originBorders,
6610
6612
  };
6611
- this.dispatch("SET_BORDER", { ...target, border });
6613
+ const borderKey = JSON.stringify(border);
6614
+ if (!this.queuedBordersToAdd[borderKey]) {
6615
+ this.queuedBordersToAdd[borderKey] = [];
6616
+ }
6617
+ this.queuedBordersToAdd[borderKey].push(positionToZone(target));
6618
+ }
6619
+ executeQueuedChanges(pasteSheetTarget) {
6620
+ for (const borderKey in this.queuedBordersToAdd) {
6621
+ const zones = this.queuedBordersToAdd[borderKey];
6622
+ const border = JSON.parse(borderKey);
6623
+ const target = recomputeZones(zones, []);
6624
+ this.dispatch("SET_BORDERS_ON_TARGET", { sheetId: pasteSheetTarget, target, border });
6625
+ }
6626
+ this.queuedBordersToAdd = {};
6612
6627
  }
6613
6628
  }
6614
6629
 
@@ -6634,8 +6649,12 @@
6634
6649
  str = replaceNewLines(str);
6635
6650
  const chars = new TokenizingChars(str);
6636
6651
  const result = [];
6652
+ const tokenizeSpace = specialWhiteSpaceRegexp.test(str)
6653
+ ? tokenizeSpecialCharacterSpace
6654
+ : tokenizeSimpleSpace;
6637
6655
  while (!chars.isOver()) {
6638
- let token = tokenizeSpace(chars) ||
6656
+ let token = tokenizeNewLine(chars) ||
6657
+ tokenizeSpace(chars) ||
6639
6658
  tokenizeArgsSeparator(chars, locale) ||
6640
6659
  tokenizeParenthesis(chars) ||
6641
6660
  tokenizeOperator(chars) ||
@@ -6769,17 +6788,19 @@
6769
6788
  }
6770
6789
  return null;
6771
6790
  }
6772
- function tokenizeSpace(chars) {
6773
- let length = 0;
6774
- while (chars.current === NEWLINE) {
6775
- length++;
6776
- chars.shift();
6791
+ function tokenizeSpecialCharacterSpace(chars) {
6792
+ let spaces = "";
6793
+ while (chars.current === " " || (chars.current && chars.current.match(specialWhiteSpaceRegexp))) {
6794
+ spaces += chars.shift();
6777
6795
  }
6778
- if (length) {
6779
- return { type: "SPACE", value: NEWLINE.repeat(length) };
6796
+ if (spaces) {
6797
+ return { type: "SPACE", value: spaces };
6780
6798
  }
6799
+ return null;
6800
+ }
6801
+ function tokenizeSimpleSpace(chars) {
6781
6802
  let spaces = "";
6782
- while (chars.current && chars.current.match(whiteSpaceRegexp)) {
6803
+ while (chars.current === " ") {
6783
6804
  spaces += chars.shift();
6784
6805
  }
6785
6806
  if (spaces) {
@@ -6787,6 +6808,17 @@
6787
6808
  }
6788
6809
  return null;
6789
6810
  }
6811
+ function tokenizeNewLine(chars) {
6812
+ let length = 0;
6813
+ while (chars.current === NEWLINE) {
6814
+ length++;
6815
+ chars.shift();
6816
+ }
6817
+ if (length) {
6818
+ return { type: "SPACE", value: NEWLINE.repeat(length) };
6819
+ }
6820
+ return null;
6821
+ }
6790
6822
  function tokenizeInvalidRange(chars) {
6791
6823
  if (chars.currentStartsWith(CellErrorType.InvalidReference)) {
6792
6824
  chars.advanceBy(CellErrorType.InvalidReference.length);
@@ -8483,12 +8515,13 @@
8483
8515
  }
8484
8516
  pasteCf(origin, target, isCutOperation) {
8485
8517
  if (origin?.rules && origin.rules.length > 0) {
8518
+ const originZone = positionToZone(origin.position);
8486
8519
  const zone = positionToZone(target);
8487
8520
  for (const rule of origin.rules) {
8488
8521
  const toRemoveZones = [];
8489
8522
  if (isCutOperation) {
8490
8523
  //remove from current rule
8491
- toRemoveZones.push(positionToZone(origin.position));
8524
+ toRemoveZones.push(originZone);
8492
8525
  }
8493
8526
  if (origin.position.sheetId === target.sheetId) {
8494
8527
  this.adaptCFRules(origin.position.sheetId, rule, [zone], toRemoveZones);
@@ -8602,6 +8635,7 @@
8602
8635
  pasteDataValidation(origin, target, isCutOperation) {
8603
8636
  if (origin) {
8604
8637
  const zone = positionToZone(target);
8638
+ const originZone = positionToZone(origin.position);
8605
8639
  const rule = origin.rule;
8606
8640
  if (!rule) {
8607
8641
  const targetRule = this.getters.getValidationRuleForCell(target);
@@ -8613,7 +8647,7 @@
8613
8647
  }
8614
8648
  const toRemoveZone = [];
8615
8649
  if (isCutOperation) {
8616
- toRemoveZone.push(positionToZone(origin.position));
8650
+ toRemoveZone.push(originZone);
8617
8651
  }
8618
8652
  if (origin.position.sheetId === target.sheetId) {
8619
8653
  const copyToRule = this.getDataValidationRuleToCopyTo(target.sheetId, rule, false);
@@ -8673,7 +8707,7 @@
8673
8707
  continue;
8674
8708
  }
8675
8709
  this.dispatch("ADD_DATA_VALIDATION_RULE", {
8676
- rule: dv,
8710
+ rule: { id: dv.id, criterion: dv.criterion, isBlocking: dv.isBlocking },
8677
8711
  ranges: newDvZones.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
8678
8712
  sheetId,
8679
8713
  });
@@ -42786,7 +42820,8 @@ stores.inject(MyMetaStore, storeInstance);
42786
42820
  &.pivot-dimension-invalid {
42787
42821
  background-color: #ffdddd;
42788
42822
  border-color: red !important;
42789
- select {
42823
+ select,
42824
+ input {
42790
42825
  background-color: #ffdddd;
42791
42826
  }
42792
42827
  }
@@ -44533,7 +44568,7 @@ stores.inject(MyMetaStore, storeInstance);
44533
44568
  this.notification.notifyUser({
44534
44569
  type: "info",
44535
44570
  text: _t("Pivot updates only work with dynamic pivot tables. Use %s or re-insert the static pivot from the Data menu.", pivotExample),
44536
- sticky: false,
44571
+ sticky: true,
44537
44572
  });
44538
44573
  }
44539
44574
  }
@@ -50773,6 +50808,15 @@ stores.inject(MyMetaStore, storeInstance);
50773
50808
  case "SET_BORDER":
50774
50809
  this.setBorder(cmd.sheetId, cmd.col, cmd.row, cmd.border);
50775
50810
  break;
50811
+ case "SET_BORDERS_ON_TARGET":
50812
+ for (const zone of cmd.target) {
50813
+ for (let row = zone.top; row <= zone.bottom; row++) {
50814
+ for (let col = zone.left; col <= zone.right; col++) {
50815
+ this.setBorder(cmd.sheetId, col, row, cmd.border);
50816
+ }
50817
+ }
50818
+ }
50819
+ break;
50776
50820
  case "SET_ZONE_BORDERS":
50777
50821
  if (cmd.border) {
50778
50822
  const target = cmd.target.map((zone) => this.getters.expandZone(cmd.sheetId, zone));
@@ -60591,25 +60635,6 @@ stores.inject(MyMetaStore, storeInstance);
60591
60635
  case "AUTOFILL_AUTO":
60592
60636
  this.autofillAuto();
60593
60637
  break;
60594
- case "AUTOFILL_CELL":
60595
- this.autoFillMerge(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
60596
- const sheetId = this.getters.getActiveSheetId();
60597
- this.dispatch("UPDATE_CELL", {
60598
- sheetId,
60599
- col: cmd.col,
60600
- row: cmd.row,
60601
- style: cmd.style || null,
60602
- content: cmd.content || "",
60603
- format: cmd.format || "",
60604
- });
60605
- this.dispatch("SET_BORDER", {
60606
- sheetId,
60607
- col: cmd.col,
60608
- row: cmd.row,
60609
- border: cmd.border,
60610
- });
60611
- this.autofillCF(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
60612
- this.autofillDV(cmd.originCol, cmd.originRow, cmd.col, cmd.row);
60613
60638
  }
60614
60639
  }
60615
60640
  // ---------------------------------------------------------------------------
@@ -60633,6 +60658,7 @@ stores.inject(MyMetaStore, storeInstance);
60633
60658
  }
60634
60659
  const source = this.getters.getSelectedZone();
60635
60660
  const target = this.autofillZone;
60661
+ const autofillCellsData = [];
60636
60662
  switch (this.direction) {
60637
60663
  case "down" /* DIRECTION.DOWN */:
60638
60664
  for (let col = source.left; col <= source.right; col++) {
@@ -60642,7 +60668,7 @@ stores.inject(MyMetaStore, storeInstance);
60642
60668
  }
60643
60669
  const generator = this.createGenerator(xcs);
60644
60670
  for (let row = target.top; row <= target.bottom; row++) {
60645
- this.computeNewCell(generator, col, row, apply);
60671
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
60646
60672
  }
60647
60673
  }
60648
60674
  break;
@@ -60654,7 +60680,7 @@ stores.inject(MyMetaStore, storeInstance);
60654
60680
  }
60655
60681
  const generator = this.createGenerator(xcs);
60656
60682
  for (let row = target.bottom; row >= target.top; row--) {
60657
- this.computeNewCell(generator, col, row, apply);
60683
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
60658
60684
  }
60659
60685
  }
60660
60686
  break;
@@ -60666,7 +60692,7 @@ stores.inject(MyMetaStore, storeInstance);
60666
60692
  }
60667
60693
  const generator = this.createGenerator(xcs);
60668
60694
  for (let col = target.right; col >= target.left; col--) {
60669
- this.computeNewCell(generator, col, row, apply);
60695
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
60670
60696
  }
60671
60697
  }
60672
60698
  break;
@@ -60678,12 +60704,26 @@ stores.inject(MyMetaStore, storeInstance);
60678
60704
  }
60679
60705
  const generator = this.createGenerator(xcs);
60680
60706
  for (let col = target.left; col <= target.right; col++) {
60681
- this.computeNewCell(generator, col, row, apply);
60707
+ autofillCellsData.push(this.computeNewCell(generator, col, row));
60682
60708
  }
60683
60709
  }
60684
60710
  break;
60685
60711
  }
60686
60712
  if (apply) {
60713
+ const bordersZones = {};
60714
+ const cfNewRanges = {};
60715
+ const dvNewZones = {};
60716
+ const sheetId = this.getters.getActiveSheetId();
60717
+ for (const data of autofillCellsData) {
60718
+ this.collectBordersData(data, bordersZones);
60719
+ this.autofillMerge(sheetId, data);
60720
+ this.autofillCell(sheetId, data);
60721
+ this.collectConditionalFormatsData(sheetId, data, cfNewRanges);
60722
+ this.collectDataValidationsData(sheetId, data, dvNewZones);
60723
+ }
60724
+ this.autofillBorders(sheetId, bordersZones);
60725
+ this.autofillConditionalFormats(sheetId, cfNewRanges);
60726
+ this.autofillDataValidations(sheetId, dvNewZones);
60687
60727
  this.autofillZone = undefined;
60688
60728
  this.selection.resizeAnchorZone(this.direction, this.steps);
60689
60729
  this.lastCellSelected = {};
@@ -60692,6 +60732,95 @@ stores.inject(MyMetaStore, storeInstance);
60692
60732
  this.tooltip = undefined;
60693
60733
  }
60694
60734
  }
60735
+ collectBordersData(data, bordersPositions) {
60736
+ const key = JSON.stringify(data.border);
60737
+ if (!(key in bordersPositions)) {
60738
+ bordersPositions[key] = [];
60739
+ }
60740
+ bordersPositions[key].push(positionToZone({ col: data.col, row: data.row }));
60741
+ }
60742
+ collectConditionalFormatsData(sheetId, data, cfNewRanges) {
60743
+ const { originCol, originRow, col, row } = data;
60744
+ const cfsAtOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
60745
+ const xc = toXC(col, row);
60746
+ for (const cf of cfsAtOrigin) {
60747
+ if (!(cf.id in cfNewRanges)) {
60748
+ cfNewRanges[cf.id] = [];
60749
+ }
60750
+ cfNewRanges[cf.id].push(xc);
60751
+ }
60752
+ }
60753
+ collectDataValidationsData(sheetId, data, dvNewZones) {
60754
+ const { originCol, originRow, col, row } = data;
60755
+ const cellPosition = { sheetId, col: originCol, row: originRow };
60756
+ const dvsAtOrigin = this.getters.getValidationRuleForCell(cellPosition);
60757
+ if (!dvsAtOrigin) {
60758
+ return;
60759
+ }
60760
+ if (!(dvsAtOrigin.id in dvNewZones)) {
60761
+ dvNewZones[dvsAtOrigin.id] = [];
60762
+ }
60763
+ dvNewZones[dvsAtOrigin.id].push(positionToZone({ col, row }));
60764
+ }
60765
+ autofillCell(sheetId, data) {
60766
+ this.dispatch("UPDATE_CELL", {
60767
+ sheetId,
60768
+ col: data.col,
60769
+ row: data.row,
60770
+ content: data.content || "",
60771
+ style: data.style || null,
60772
+ format: data.format || "",
60773
+ });
60774
+ // Still usefull in odoo ATM to autofill field sync
60775
+ this.dispatch("AUTOFILL_CELL", data);
60776
+ }
60777
+ autofillBorders(sheetId, bordersPositions) {
60778
+ for (const stringifiedBorder in bordersPositions) {
60779
+ const border = stringifiedBorder === "undefined" ? undefined : JSON.parse(stringifiedBorder);
60780
+ this.dispatch("SET_BORDERS_ON_TARGET", {
60781
+ sheetId,
60782
+ border,
60783
+ target: recomputeZones(bordersPositions[stringifiedBorder]),
60784
+ });
60785
+ }
60786
+ }
60787
+ autofillConditionalFormats(sheetId, cfNewRanges) {
60788
+ for (const cfId in cfNewRanges) {
60789
+ const changes = cfNewRanges[cfId];
60790
+ const cf = this.getters.getConditionalFormats(sheetId).find((cf) => cf.id === cfId);
60791
+ if (!cf) {
60792
+ continue;
60793
+ }
60794
+ const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, changes.map(toZone), []);
60795
+ if (newCfRanges) {
60796
+ this.dispatch("ADD_CONDITIONAL_FORMAT", {
60797
+ cf: {
60798
+ id: cf.id,
60799
+ rule: cf.rule,
60800
+ stopIfTrue: cf.stopIfTrue,
60801
+ },
60802
+ ranges: newCfRanges,
60803
+ sheetId,
60804
+ });
60805
+ }
60806
+ }
60807
+ }
60808
+ autofillDataValidations(sheetId, dvNewZones) {
60809
+ for (const dvId in dvNewZones) {
60810
+ const changes = dvNewZones[dvId];
60811
+ const dvOrigin = this.getters.getDataValidationRule(sheetId, dvId);
60812
+ if (!dvOrigin) {
60813
+ continue;
60814
+ }
60815
+ const dvRangesXcs = dvOrigin.ranges.map((range) => range.zone);
60816
+ const newDvRanges = recomputeZones(dvRangesXcs.concat(changes), []);
60817
+ this.dispatch("ADD_DATA_VALIDATION_RULE", {
60818
+ rule: dvOrigin,
60819
+ ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
60820
+ sheetId,
60821
+ });
60822
+ }
60823
+ }
60695
60824
  /**
60696
60825
  * Select a cell which becomes the last cell of the autofillZone
60697
60826
  */
@@ -60770,22 +60899,20 @@ stores.inject(MyMetaStore, storeInstance);
60770
60899
  /**
60771
60900
  * Generate the next cell
60772
60901
  */
60773
- computeNewCell(generator, col, row, apply) {
60902
+ computeNewCell(generator, col, row) {
60774
60903
  const { cellData, tooltip, origin } = generator.next();
60775
60904
  const { content, style, border, format } = cellData;
60776
60905
  this.tooltip = tooltip;
60777
- if (apply) {
60778
- this.dispatch("AUTOFILL_CELL", {
60779
- originCol: origin.col,
60780
- originRow: origin.row,
60781
- col,
60782
- row,
60783
- content,
60784
- style,
60785
- border,
60786
- format,
60787
- });
60788
- }
60906
+ return {
60907
+ originCol: origin.col,
60908
+ originRow: origin.row,
60909
+ col,
60910
+ row,
60911
+ content,
60912
+ style,
60913
+ border,
60914
+ format,
60915
+ };
60789
60916
  }
60790
60917
  /**
60791
60918
  * Get the rule associated to the current cell
@@ -60853,8 +60980,8 @@ stores.inject(MyMetaStore, storeInstance);
60853
60980
  ? position[first].value
60854
60981
  : position[second].value;
60855
60982
  }
60856
- autoFillMerge(originCol, originRow, col, row) {
60857
- const sheetId = this.getters.getActiveSheetId();
60983
+ autofillMerge(sheetId, data) {
60984
+ const { originCol, originRow, col, row } = data;
60858
60985
  const position = { sheetId, col, row };
60859
60986
  const originPosition = { sheetId, col: originCol, row: originRow };
60860
60987
  if (this.getters.isInMerge(position) && !this.getters.isInMerge(originPosition)) {
@@ -60881,35 +61008,6 @@ stores.inject(MyMetaStore, storeInstance);
60881
61008
  });
60882
61009
  }
60883
61010
  }
60884
- autofillCF(originCol, originRow, col, row) {
60885
- const sheetId = this.getters.getActiveSheetId();
60886
- const cfOrigin = this.getters.getRulesByCell(sheetId, originCol, originRow);
60887
- for (const cf of cfOrigin) {
60888
- const newCfRanges = this.getters.getAdaptedCfRanges(sheetId, cf, [positionToZone({ col, row })], []);
60889
- if (newCfRanges) {
60890
- this.dispatch("ADD_CONDITIONAL_FORMAT", {
60891
- cf: deepCopy(cf),
60892
- ranges: newCfRanges,
60893
- sheetId,
60894
- });
60895
- }
60896
- }
60897
- }
60898
- autofillDV(originCol, originRow, col, row) {
60899
- const sheetId = this.getters.getActiveSheetId();
60900
- const cellPosition = { sheetId, col: originCol, row: originRow };
60901
- const dvOrigin = this.getters.getValidationRuleForCell(cellPosition);
60902
- if (!dvOrigin) {
60903
- return;
60904
- }
60905
- const dvRangesZones = dvOrigin.ranges.map((range) => range.zone);
60906
- const newDvRanges = recomputeZones(dvRangesZones.concat(positionToZone({ col, row })), []);
60907
- this.dispatch("ADD_DATA_VALIDATION_RULE", {
60908
- rule: dvOrigin,
60909
- ranges: newDvRanges.map((zone) => this.getters.getRangeDataFromZone(sheetId, zone)),
60910
- sheetId,
60911
- });
60912
- }
60913
61011
  // ---------------------------------------------------------------------------
60914
61012
  // Grid rendering
60915
61013
  // ---------------------------------------------------------------------------
@@ -73615,9 +73713,9 @@ stores.inject(MyMetaStore, storeInstance);
73615
73713
  exports.tokenize = tokenize;
73616
73714
 
73617
73715
 
73618
- __info__.version = "18.0.21";
73619
- __info__.date = "2025-03-26T12:49:46.872Z";
73620
- __info__.hash = "c687e1c";
73716
+ __info__.version = "18.0.23";
73717
+ __info__.date = "2025-04-14T17:16:35.374Z";
73718
+ __info__.hash = "f560133";
73621
73719
 
73622
73720
 
73623
73721
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);