@odoo/o-spreadsheet 15.0.9 → 15.0.11

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.
@@ -2912,7 +2912,37 @@ function parseSheetLink(sheetLink) {
2912
2912
  function isDefined(argument) {
2913
2913
  return argument !== undefined;
2914
2914
  }
2915
- const DEBUG = {};
2915
+ const DEBUG = {};
2916
+ /**
2917
+ * Compares two objects.
2918
+ */
2919
+ function deepEquals(o1, o2) {
2920
+ if (o1 === o2)
2921
+ return true;
2922
+ if ((o1 && !o2) || (o2 && !o1))
2923
+ return false;
2924
+ if (typeof o1 !== typeof o2)
2925
+ return false;
2926
+ if (typeof o1 !== "object")
2927
+ return o1 === o2;
2928
+ // Objects can have different keys if the values are undefined
2929
+ const keys = new Set();
2930
+ Object.keys(o1).forEach((key) => keys.add(key));
2931
+ Object.keys(o2).forEach((key) => keys.add(key));
2932
+ for (let key of keys) {
2933
+ if (typeof o1[key] !== typeof o1[key])
2934
+ return false;
2935
+ if (typeof o1[key] === "object") {
2936
+ if (!deepEquals(o1[key], o2[key]))
2937
+ return false;
2938
+ }
2939
+ else {
2940
+ if (o1[key] !== o2[key])
2941
+ return false;
2942
+ }
2943
+ }
2944
+ return true;
2945
+ }
2916
2946
 
2917
2947
  /**
2918
2948
  * Convert from a cartesian reference to a Zone
@@ -19149,6 +19179,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19149
19179
  // stores the computed styles in the format of computedStyles.sheetName[col][row] = Style
19150
19180
  this.computedStyles = {};
19151
19181
  this.computedIcons = {};
19182
+ this.uuidGenerator = new UuidGenerator();
19152
19183
  /**
19153
19184
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
19154
19185
  */
@@ -19477,6 +19508,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19477
19508
  }
19478
19509
  currentRanges = currentRanges.concat(toAdd);
19479
19510
  const newRange = recomputeZones(currentRanges, toRemove);
19511
+ if (newRange.length === 0) {
19512
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
19513
+ return;
19514
+ }
19480
19515
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
19481
19516
  cf: {
19482
19517
  id: cf.id,
@@ -19502,13 +19537,20 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19502
19537
  this.adaptRules(origin.sheetId, cf, [xc], toRemoveRange);
19503
19538
  }
19504
19539
  else {
19505
- this.adaptRules(target.sheetId, cf, [xc], []);
19506
19540
  this.adaptRules(origin.sheetId, cf, [], toRemoveRange);
19541
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
19542
+ this.adaptRules(target.sheetId, cfToCopyTo, [xc], []);
19507
19543
  }
19508
19544
  }
19509
19545
  }
19510
19546
  }
19511
19547
  }
19548
+ getCFToCopyTo(targetSheetId, originCF) {
19549
+ const cfInTarget = this.getters
19550
+ .getConditionalFormats(targetSheetId)
19551
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
19552
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
19553
+ }
19512
19554
  }
19513
19555
  EvaluationConditionalFormatPlugin.getters = ["getConditionalStyle", "getConditionalIcon"];
19514
19556
  EvaluationConditionalFormatPlugin.modes = ["normal"];
@@ -24329,12 +24371,15 @@ function createXMLFile(doc, path, contentType) {
24329
24371
  };
24330
24372
  }
24331
24373
  function xmlEscape(str) {
24332
- return String(str)
24374
+ return (String(str)
24333
24375
  .replace(/\&/g, "&")
24334
24376
  .replace(/\</g, "&lt;")
24335
24377
  .replace(/\>/g, "&gt;")
24336
24378
  .replace(/\"/g, "&quot;")
24337
- .replace(/\'/g, "&apos;");
24379
+ .replace(/\'/g, "&apos;")
24380
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
24381
+ // They are not valid at all in XML 1.0 (even escaped)
24382
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
24338
24383
  }
24339
24384
  function formatAttributes(attrs) {
24340
24385
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -31407,6 +31452,6 @@ exports.registries = registries;
31407
31452
  exports.setTranslationMethod = setTranslationMethod;
31408
31453
 
31409
31454
 
31410
- __info__.version = '15.0.9';
31411
- __info__.date = '2023-06-12T13:46:56.382Z';
31412
- __info__.hash = '40ae7eb';
31455
+ __info__.version = '15.0.11';
31456
+ __info__.date = '2023-10-19T14:17:19.414Z';
31457
+ __info__.hash = 'd1931c8';
@@ -3052,6 +3052,7 @@ declare class EvaluationConditionalFormatPlugin extends UIPlugin {
3052
3052
  private isStale;
3053
3053
  private computedStyles;
3054
3054
  private computedIcons;
3055
+ private uuidGenerator;
3055
3056
  handle(cmd: Command): void;
3056
3057
  finalize(): void;
3057
3058
  /**
@@ -3086,6 +3087,7 @@ declare class EvaluationConditionalFormatPlugin extends UIPlugin {
3086
3087
  */
3087
3088
  private adaptRules;
3088
3089
  private pasteCf;
3090
+ private getCFToCopyTo;
3089
3091
  }
3090
3092
 
3091
3093
  /**
@@ -2889,7 +2889,37 @@ function parseSheetLink(sheetLink) {
2889
2889
  function isDefined(argument) {
2890
2890
  return argument !== undefined;
2891
2891
  }
2892
- const DEBUG = {};
2892
+ const DEBUG = {};
2893
+ /**
2894
+ * Compares two objects.
2895
+ */
2896
+ function deepEquals(o1, o2) {
2897
+ if (o1 === o2)
2898
+ return true;
2899
+ if ((o1 && !o2) || (o2 && !o1))
2900
+ return false;
2901
+ if (typeof o1 !== typeof o2)
2902
+ return false;
2903
+ if (typeof o1 !== "object")
2904
+ return o1 === o2;
2905
+ // Objects can have different keys if the values are undefined
2906
+ const keys = new Set();
2907
+ Object.keys(o1).forEach((key) => keys.add(key));
2908
+ Object.keys(o2).forEach((key) => keys.add(key));
2909
+ for (let key of keys) {
2910
+ if (typeof o1[key] !== typeof o1[key])
2911
+ return false;
2912
+ if (typeof o1[key] === "object") {
2913
+ if (!deepEquals(o1[key], o2[key]))
2914
+ return false;
2915
+ }
2916
+ else {
2917
+ if (o1[key] !== o2[key])
2918
+ return false;
2919
+ }
2920
+ }
2921
+ return true;
2922
+ }
2893
2923
 
2894
2924
  /**
2895
2925
  * Convert from a cartesian reference to a Zone
@@ -19126,6 +19156,7 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19126
19156
  // stores the computed styles in the format of computedStyles.sheetName[col][row] = Style
19127
19157
  this.computedStyles = {};
19128
19158
  this.computedIcons = {};
19159
+ this.uuidGenerator = new UuidGenerator();
19129
19160
  /**
19130
19161
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
19131
19162
  */
@@ -19454,6 +19485,10 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19454
19485
  }
19455
19486
  currentRanges = currentRanges.concat(toAdd);
19456
19487
  const newRange = recomputeZones(currentRanges, toRemove);
19488
+ if (newRange.length === 0) {
19489
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
19490
+ return;
19491
+ }
19457
19492
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
19458
19493
  cf: {
19459
19494
  id: cf.id,
@@ -19479,13 +19514,20 @@ class EvaluationConditionalFormatPlugin extends UIPlugin {
19479
19514
  this.adaptRules(origin.sheetId, cf, [xc], toRemoveRange);
19480
19515
  }
19481
19516
  else {
19482
- this.adaptRules(target.sheetId, cf, [xc], []);
19483
19517
  this.adaptRules(origin.sheetId, cf, [], toRemoveRange);
19518
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
19519
+ this.adaptRules(target.sheetId, cfToCopyTo, [xc], []);
19484
19520
  }
19485
19521
  }
19486
19522
  }
19487
19523
  }
19488
19524
  }
19525
+ getCFToCopyTo(targetSheetId, originCF) {
19526
+ const cfInTarget = this.getters
19527
+ .getConditionalFormats(targetSheetId)
19528
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
19529
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
19530
+ }
19489
19531
  }
19490
19532
  EvaluationConditionalFormatPlugin.getters = ["getConditionalStyle", "getConditionalIcon"];
19491
19533
  EvaluationConditionalFormatPlugin.modes = ["normal"];
@@ -24306,12 +24348,15 @@ function createXMLFile(doc, path, contentType) {
24306
24348
  };
24307
24349
  }
24308
24350
  function xmlEscape(str) {
24309
- return String(str)
24351
+ return (String(str)
24310
24352
  .replace(/\&/g, "&amp;")
24311
24353
  .replace(/\</g, "&lt;")
24312
24354
  .replace(/\>/g, "&gt;")
24313
24355
  .replace(/\"/g, "&quot;")
24314
- .replace(/\'/g, "&apos;");
24356
+ .replace(/\'/g, "&apos;")
24357
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
24358
+ // They are not valid at all in XML 1.0 (even escaped)
24359
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
24315
24360
  }
24316
24361
  function formatAttributes(attrs) {
24317
24362
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -31362,6 +31407,6 @@ const helpers = {
31362
31407
  export { CommandResult, CorePlugin, DATETIME_FORMAT, DataSource, DispatchResult, Model, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, DEBUG as __DEBUG__, __info__, astToFormula, cellTypes, convertAstNodes, coreTypes, functionCache, helpers, invalidateEvaluationCommands, normalize, parse, readonlyAllowedCommands, registries, setTranslationMethod };
31363
31408
 
31364
31409
 
31365
- __info__.version = '15.0.9';
31366
- __info__.date = '2023-06-12T13:46:56.382Z';
31367
- __info__.hash = '40ae7eb';
31410
+ __info__.version = '15.0.11';
31411
+ __info__.date = '2023-10-19T14:17:19.414Z';
31412
+ __info__.hash = 'd1931c8';
@@ -2909,7 +2909,37 @@
2909
2909
  function isDefined(argument) {
2910
2910
  return argument !== undefined;
2911
2911
  }
2912
- const DEBUG = {};
2912
+ const DEBUG = {};
2913
+ /**
2914
+ * Compares two objects.
2915
+ */
2916
+ function deepEquals(o1, o2) {
2917
+ if (o1 === o2)
2918
+ return true;
2919
+ if ((o1 && !o2) || (o2 && !o1))
2920
+ return false;
2921
+ if (typeof o1 !== typeof o2)
2922
+ return false;
2923
+ if (typeof o1 !== "object")
2924
+ return o1 === o2;
2925
+ // Objects can have different keys if the values are undefined
2926
+ const keys = new Set();
2927
+ Object.keys(o1).forEach((key) => keys.add(key));
2928
+ Object.keys(o2).forEach((key) => keys.add(key));
2929
+ for (let key of keys) {
2930
+ if (typeof o1[key] !== typeof o1[key])
2931
+ return false;
2932
+ if (typeof o1[key] === "object") {
2933
+ if (!deepEquals(o1[key], o2[key]))
2934
+ return false;
2935
+ }
2936
+ else {
2937
+ if (o1[key] !== o2[key])
2938
+ return false;
2939
+ }
2940
+ }
2941
+ return true;
2942
+ }
2913
2943
 
2914
2944
  /**
2915
2945
  * Convert from a cartesian reference to a Zone
@@ -19146,6 +19176,7 @@
19146
19176
  // stores the computed styles in the format of computedStyles.sheetName[col][row] = Style
19147
19177
  this.computedStyles = {};
19148
19178
  this.computedIcons = {};
19179
+ this.uuidGenerator = new UuidGenerator();
19149
19180
  /**
19150
19181
  * Execute the predicate to know if a conditional formatting rule should be applied to a cell
19151
19182
  */
@@ -19474,6 +19505,10 @@
19474
19505
  }
19475
19506
  currentRanges = currentRanges.concat(toAdd);
19476
19507
  const newRange = recomputeZones(currentRanges, toRemove);
19508
+ if (newRange.length === 0) {
19509
+ this.dispatch("REMOVE_CONDITIONAL_FORMAT", { id: cf.id, sheetId });
19510
+ return;
19511
+ }
19477
19512
  this.dispatch("ADD_CONDITIONAL_FORMAT", {
19478
19513
  cf: {
19479
19514
  id: cf.id,
@@ -19499,13 +19534,20 @@
19499
19534
  this.adaptRules(origin.sheetId, cf, [xc], toRemoveRange);
19500
19535
  }
19501
19536
  else {
19502
- this.adaptRules(target.sheetId, cf, [xc], []);
19503
19537
  this.adaptRules(origin.sheetId, cf, [], toRemoveRange);
19538
+ const cfToCopyTo = this.getCFToCopyTo(target.sheetId, cf);
19539
+ this.adaptRules(target.sheetId, cfToCopyTo, [xc], []);
19504
19540
  }
19505
19541
  }
19506
19542
  }
19507
19543
  }
19508
19544
  }
19545
+ getCFToCopyTo(targetSheetId, originCF) {
19546
+ const cfInTarget = this.getters
19547
+ .getConditionalFormats(targetSheetId)
19548
+ .find((cf) => cf.stopIfTrue === originCF.stopIfTrue && deepEquals(cf.rule, originCF.rule));
19549
+ return cfInTarget ? cfInTarget : { ...originCF, id: this.uuidGenerator.uuidv4(), ranges: [] };
19550
+ }
19509
19551
  }
19510
19552
  EvaluationConditionalFormatPlugin.getters = ["getConditionalStyle", "getConditionalIcon"];
19511
19553
  EvaluationConditionalFormatPlugin.modes = ["normal"];
@@ -24326,12 +24368,15 @@
24326
24368
  };
24327
24369
  }
24328
24370
  function xmlEscape(str) {
24329
- return String(str)
24371
+ return (String(str)
24330
24372
  .replace(/\&/g, "&amp;")
24331
24373
  .replace(/\</g, "&lt;")
24332
24374
  .replace(/\>/g, "&gt;")
24333
24375
  .replace(/\"/g, "&quot;")
24334
- .replace(/\'/g, "&apos;");
24376
+ .replace(/\'/g, "&apos;")
24377
+ // Delete all ASCII control characters except for TAB (\x09), LF (\x0A) and CR (\x0D)
24378
+ // They are not valid at all in XML 1.0 (even escaped)
24379
+ .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, ""));
24335
24380
  }
24336
24381
  function formatAttributes(attrs) {
24337
24382
  return new XMLString(attrs.map(([key, val]) => `${key}="${xmlEscape(val)}"`).join(" "));
@@ -31406,9 +31451,9 @@
31406
31451
  Object.defineProperty(exports, '__esModule', { value: true });
31407
31452
 
31408
31453
 
31409
- __info__.version = '15.0.9';
31410
- __info__.date = '2023-06-12T13:46:56.382Z';
31411
- __info__.hash = '40ae7eb';
31454
+ __info__.version = '15.0.11';
31455
+ __info__.date = '2023-10-19T14:17:19.414Z';
31456
+ __info__.hash = 'd1931c8';
31412
31457
 
31413
31458
 
31414
31459
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);