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