@odoo/o-spreadsheet 18.1.10 → 18.1.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.
@@ -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.10
6
- * @date 2025-03-07T10:34:41.861Z
7
- * @hash 31e4526
5
+ * @version 18.1.11
6
+ * @date 2025-03-12T15:31:44.276Z
7
+ * @hash 7de2363
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
@@ -423,7 +423,6 @@
423
423
  * Sparse arrays remain sparse.
424
424
  */
425
425
  function deepCopy(obj) {
426
- const result = Array.isArray(obj) ? [] : {};
427
426
  switch (typeof obj) {
428
427
  case "object": {
429
428
  if (obj === null) {
@@ -435,8 +434,18 @@
435
434
  else if (!(isPlainObject(obj) || obj instanceof Array)) {
436
435
  throw new Error("Unsupported type: only objects and arrays are supported");
437
436
  }
438
- for (const key in obj) {
439
- result[key] = deepCopy(obj[key]);
437
+ const result = Array.isArray(obj) ? new Array(obj.length) : {};
438
+ if (Array.isArray(obj)) {
439
+ for (let i = 0, len = obj.length; i < len; i++) {
440
+ if (i in obj) {
441
+ result[i] = deepCopy(obj[i]);
442
+ }
443
+ }
444
+ }
445
+ else {
446
+ for (const key in obj) {
447
+ result[key] = deepCopy(obj[key]);
448
+ }
440
449
  }
441
450
  return result;
442
451
  }
@@ -2689,21 +2698,30 @@
2689
2698
  return mergedZones;
2690
2699
  }
2691
2700
 
2701
+ const globalReverseLookup$1 = new WeakMap();
2702
+ const globalIdCounter = new WeakMap();
2692
2703
  /**
2693
2704
  * Get the id of the given item (its key in the given dictionary).
2694
2705
  * If the given item does not exist in the dictionary, it creates one with a new id.
2695
2706
  */
2696
2707
  function getItemId(item, itemsDic) {
2697
- for (const key in itemsDic) {
2698
- if (deepEquals(itemsDic[key], item)) {
2699
- return parseInt(key, 10);
2700
- }
2708
+ if (!globalReverseLookup$1.has(itemsDic)) {
2709
+ globalReverseLookup$1.set(itemsDic, new Map());
2710
+ globalIdCounter.set(itemsDic, 0);
2711
+ }
2712
+ const reverseLookup = globalReverseLookup$1.get(itemsDic);
2713
+ const canonical = getCanonicalRepresentation(item);
2714
+ if (reverseLookup.has(canonical)) {
2715
+ const id = reverseLookup.get(canonical);
2716
+ itemsDic[id] = item;
2717
+ return id;
2701
2718
  }
2702
2719
  // Generate new Id if the item didn't exist in the dictionary
2703
- const ids = Object.keys(itemsDic);
2704
- const maxId = ids.length === 0 ? 0 : largeMax(ids.map((id) => parseInt(id, 10)));
2705
- itemsDic[maxId + 1] = item;
2706
- return maxId + 1;
2720
+ const newId = globalIdCounter.get(itemsDic) + 1;
2721
+ reverseLookup.set(canonical, newId);
2722
+ globalIdCounter.set(itemsDic, newId);
2723
+ itemsDic[newId] = item;
2724
+ return newId;
2707
2725
  }
2708
2726
  function groupItemIdsByZones(positionsByItemId) {
2709
2727
  const result = {};
@@ -2727,6 +2745,33 @@
2727
2745
  }
2728
2746
  }
2729
2747
  }
2748
+ function getCanonicalRepresentation(item) {
2749
+ if (item === null)
2750
+ return "null";
2751
+ if (item === undefined)
2752
+ return "undefined";
2753
+ if (typeof item !== "object")
2754
+ return String(item);
2755
+ if (Array.isArray(item)) {
2756
+ const len = item.length;
2757
+ let result = "[";
2758
+ for (let i = 0; i < len; i++) {
2759
+ if (i > 0)
2760
+ result += ",";
2761
+ result += getCanonicalRepresentation(item[i]);
2762
+ }
2763
+ return result + "]";
2764
+ }
2765
+ const keys = Object.keys(item).sort();
2766
+ let repr = "{";
2767
+ for (const key of keys) {
2768
+ if (item[key] !== undefined) {
2769
+ repr += `"${key}":${getCanonicalRepresentation(item[key])},`;
2770
+ }
2771
+ }
2772
+ repr += "}";
2773
+ return repr;
2774
+ }
2730
2775
 
2731
2776
  // -----------------------------------------------------------------------------
2732
2777
  // Date Type
@@ -8280,7 +8325,8 @@
8280
8325
  const possibleValues = pivot
8281
8326
  .getPossibleFieldValues(columns[i])
8282
8327
  .map((v) => v.value);
8283
- if (!possibleValues.includes(sortedColumn.domain[i].value)) {
8328
+ if (!possibleValues.includes(sortedColumn.domain[i].value) &&
8329
+ !(sortedColumn.domain[i].value === null && possibleValues.includes(""))) {
8284
8330
  return false;
8285
8331
  }
8286
8332
  }
@@ -11155,6 +11201,7 @@ stores.inject(MyMetaStore, storeInstance);
11155
11201
  const autoCompleteProviders = new Registry();
11156
11202
 
11157
11203
  autoCompleteProviders.add("dataValidation", {
11204
+ displayAllOnInitialContent: true,
11158
11205
  getProposals(tokenAtCursor, content) {
11159
11206
  if (content.startsWith("=")) {
11160
11207
  return [];
@@ -21451,6 +21498,15 @@ stores.inject(MyMetaStore, storeInstance);
21451
21498
  const exactMatch = proposals?.find((p) => p.text === tokenAtCursor.value);
21452
21499
  // remove tokens that are likely to be other parts of the formula that slipped in the token if it's a string
21453
21500
  const searchTerm = tokenAtCursor.value.replace(/[ ,\(\)]/g, "");
21501
+ if (this._currentContent === this.initialContent &&
21502
+ provider.displayAllOnInitialContent &&
21503
+ proposals?.length) {
21504
+ return {
21505
+ proposals,
21506
+ selectProposal: provider.selectProposal,
21507
+ autoSelectFirstProposal: provider.autoSelectFirstProposal ?? false,
21508
+ };
21509
+ }
21454
21510
  if (exactMatch && this._currentContent !== this.initialContent) {
21455
21511
  // this means the user has chosen a proposal
21456
21512
  return;
@@ -24336,16 +24392,25 @@ stores.inject(MyMetaStore, storeInstance);
24336
24392
  }
24337
24393
  return id;
24338
24394
  }
24395
+ const globalReverseLookup = new WeakMap();
24339
24396
  function pushElement(property, propertyList) {
24340
- let len = propertyList.length;
24341
- const operator = typeof property === "object" ? deepEquals : (a, b) => a === b;
24342
- for (let i = 0; i < len; i++) {
24343
- if (operator(property, propertyList[i])) {
24344
- return i;
24397
+ let reverseLookup = globalReverseLookup.get(propertyList);
24398
+ if (!reverseLookup) {
24399
+ reverseLookup = new Map();
24400
+ for (let i = 0; i < propertyList.length; i++) {
24401
+ const canonical = getCanonicalRepresentation(propertyList[i]);
24402
+ reverseLookup.set(canonical, i);
24345
24403
  }
24404
+ globalReverseLookup.set(propertyList, reverseLookup);
24405
+ }
24406
+ const canonical = getCanonicalRepresentation(property);
24407
+ if (reverseLookup.has(canonical)) {
24408
+ return reverseLookup.get(canonical);
24346
24409
  }
24347
- propertyList[propertyList.length] = property;
24348
- return propertyList.length - 1;
24410
+ const maxId = propertyList.length;
24411
+ propertyList.push(property);
24412
+ reverseLookup.set(canonical, maxId);
24413
+ return maxId;
24349
24414
  }
24350
24415
  const chartIds = [];
24351
24416
  /**
@@ -26192,7 +26257,7 @@ stores.inject(MyMetaStore, storeInstance);
26192
26257
  title: { text: chartTitle },
26193
26258
  type: CHART_TYPE_CONVERSION_MAP[chartType],
26194
26259
  dataSets: this.extractChartDatasets(this.querySelectorAll(rootChartElement, `c:${chartType}`), chartType),
26195
- labelRange: this.extractChildTextContent(rootChartElement, `c:ser ${chartType === "scatterChart" ? "c:numRef" : "c:cat"} c:f`),
26260
+ labelRange: this.extractLabelRange(chartType, rootChartElement),
26196
26261
  backgroundColor: this.extractChildAttr(rootChartElement, "c:chartSpace > c:spPr a:srgbClr", "val", {
26197
26262
  default: "ffffff",
26198
26263
  }).asString(),
@@ -26204,6 +26269,13 @@ stores.inject(MyMetaStore, storeInstance);
26204
26269
  };
26205
26270
  })[0];
26206
26271
  }
26272
+ extractLabelRange(chartType, rootChartElement) {
26273
+ if (chartType === "scatterChart") {
26274
+ return (this.extractChildTextContent(rootChartElement, `c:ser c:strRef c:f`) ||
26275
+ this.extractChildTextContent(rootChartElement, `c:ser c:numRef c:f`));
26276
+ }
26277
+ return this.extractChildTextContent(rootChartElement, `c:ser c:cat c:f`);
26278
+ }
26207
26279
  extractComboChart(chartElement) {
26208
26280
  // Title can be separated into multiple xml elements (for styling and such), we only import the text
26209
26281
  const chartTitle = this.mapOnElements({ parent: chartElement, query: "c:title a:t" }, (textElement) => {
@@ -36205,6 +36277,7 @@ stores.inject(MyMetaStore, storeInstance);
36205
36277
  fingerprintStore.enable();
36206
36278
  }
36207
36279
  },
36280
+ isReadonlyAllowed: true,
36208
36281
  icon: "o-spreadsheet-Icon.IRREGULARITY_MAP",
36209
36282
  };
36210
36283
  const viewFormulas = {
@@ -50410,6 +50483,9 @@ stores.inject(MyMetaStore, storeInstance);
50410
50483
  this.MAX_SIZE_MARGIN = 90;
50411
50484
  this.MIN_ELEMENT_SIZE = MIN_COL_WIDTH;
50412
50485
  }
50486
+ get sheetId() {
50487
+ return this.env.model.getters.getActiveSheetId();
50488
+ }
50413
50489
  _getEvOffset(ev) {
50414
50490
  return ev.offsetX;
50415
50491
  }
@@ -50432,10 +50508,10 @@ stores.inject(MyMetaStore, storeInstance);
50432
50508
  return this.env.model.getters.getEdgeScrollCol(position, position, position);
50433
50509
  }
50434
50510
  _getDimensionsInViewport(index) {
50435
- return this.env.model.getters.getColDimensionsInViewport(this.env.model.getters.getActiveSheetId(), index);
50511
+ return this.env.model.getters.getColDimensionsInViewport(this.sheetId, index);
50436
50512
  }
50437
50513
  _getElementSize(index) {
50438
- return this.env.model.getters.getColSize(this.env.model.getters.getActiveSheetId(), index);
50514
+ return this.env.model.getters.getColSize(this.sheetId, index);
50439
50515
  }
50440
50516
  _getMaxSize() {
50441
50517
  return this.colResizerRef.el.clientWidth;
@@ -50446,7 +50522,7 @@ stores.inject(MyMetaStore, storeInstance);
50446
50522
  const cols = this.env.model.getters.getActiveCols();
50447
50523
  this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
50448
50524
  dimension: "COL",
50449
- sheetId: this.env.model.getters.getActiveSheetId(),
50525
+ sheetId: this.sheetId,
50450
50526
  elements: cols.has(index) ? [...cols] : [index],
50451
50527
  size,
50452
50528
  });
@@ -50459,7 +50535,7 @@ stores.inject(MyMetaStore, storeInstance);
50459
50535
  elements.push(colIndex);
50460
50536
  }
50461
50537
  const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
50462
- sheetId: this.env.model.getters.getActiveSheetId(),
50538
+ sheetId: this.sheetId,
50463
50539
  dimension: "COL",
50464
50540
  base: this.state.base,
50465
50541
  elements,
@@ -50478,7 +50554,7 @@ stores.inject(MyMetaStore, storeInstance);
50478
50554
  _fitElementSize(index) {
50479
50555
  const cols = this.env.model.getters.getActiveCols();
50480
50556
  this.env.model.dispatch("AUTORESIZE_COLUMNS", {
50481
- sheetId: this.env.model.getters.getActiveSheetId(),
50557
+ sheetId: this.sheetId,
50482
50558
  cols: cols.has(index) ? [...cols] : [index],
50483
50559
  });
50484
50560
  }
@@ -50489,7 +50565,7 @@ stores.inject(MyMetaStore, storeInstance);
50489
50565
  return this.env.model.getters.getActiveCols();
50490
50566
  }
50491
50567
  _getPreviousVisibleElement(index) {
50492
- const sheetId = this.env.model.getters.getActiveSheetId();
50568
+ const sheetId = this.sheetId;
50493
50569
  let row;
50494
50570
  for (row = index - 1; row >= 0; row--) {
50495
50571
  if (!this.env.model.getters.isColHidden(sheetId, row)) {
@@ -50500,7 +50576,7 @@ stores.inject(MyMetaStore, storeInstance);
50500
50576
  }
50501
50577
  unhide(hiddenElements) {
50502
50578
  this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
50503
- sheetId: this.env.model.getters.getActiveSheetId(),
50579
+ sheetId: this.sheetId,
50504
50580
  elements: hiddenElements,
50505
50581
  dimension: "COL",
50506
50582
  });
@@ -50516,7 +50592,7 @@ stores.inject(MyMetaStore, storeInstance);
50516
50592
  left: 0;
50517
50593
  right: 0;
50518
50594
  width: ${HEADER_WIDTH}px;
50519
- height: 100%;
50595
+ height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
50520
50596
  &.o-dragging {
50521
50597
  cursor: grabbing;
50522
50598
  }
@@ -50574,6 +50650,9 @@ stores.inject(MyMetaStore, storeInstance);
50574
50650
  this.MIN_ELEMENT_SIZE = MIN_ROW_HEIGHT;
50575
50651
  }
50576
50652
  rowResizerRef;
50653
+ get sheetId() {
50654
+ return this.env.model.getters.getActiveSheetId();
50655
+ }
50577
50656
  _getEvOffset(ev) {
50578
50657
  return ev.offsetY;
50579
50658
  }
@@ -50596,10 +50675,10 @@ stores.inject(MyMetaStore, storeInstance);
50596
50675
  return this.env.model.getters.getEdgeScrollRow(position, position, position);
50597
50676
  }
50598
50677
  _getDimensionsInViewport(index) {
50599
- return this.env.model.getters.getRowDimensionsInViewport(this.env.model.getters.getActiveSheetId(), index);
50678
+ return this.env.model.getters.getRowDimensionsInViewport(this.sheetId, index);
50600
50679
  }
50601
50680
  _getElementSize(index) {
50602
- return this.env.model.getters.getRowSize(this.env.model.getters.getActiveSheetId(), index);
50681
+ return this.env.model.getters.getRowSize(this.sheetId, index);
50603
50682
  }
50604
50683
  _getMaxSize() {
50605
50684
  return this.rowResizerRef.el.clientHeight;
@@ -50610,7 +50689,7 @@ stores.inject(MyMetaStore, storeInstance);
50610
50689
  const rows = this.env.model.getters.getActiveRows();
50611
50690
  this.env.model.dispatch("RESIZE_COLUMNS_ROWS", {
50612
50691
  dimension: "ROW",
50613
- sheetId: this.env.model.getters.getActiveSheetId(),
50692
+ sheetId: this.sheetId,
50614
50693
  elements: rows.has(index) ? [...rows] : [index],
50615
50694
  size,
50616
50695
  });
@@ -50623,7 +50702,7 @@ stores.inject(MyMetaStore, storeInstance);
50623
50702
  elements.push(rowIndex);
50624
50703
  }
50625
50704
  const result = this.env.model.dispatch("MOVE_COLUMNS_ROWS", {
50626
- sheetId: this.env.model.getters.getActiveSheetId(),
50705
+ sheetId: this.sheetId,
50627
50706
  dimension: "ROW",
50628
50707
  base: this.state.base,
50629
50708
  elements,
@@ -50642,7 +50721,7 @@ stores.inject(MyMetaStore, storeInstance);
50642
50721
  _fitElementSize(index) {
50643
50722
  const rows = this.env.model.getters.getActiveRows();
50644
50723
  this.env.model.dispatch("AUTORESIZE_ROWS", {
50645
- sheetId: this.env.model.getters.getActiveSheetId(),
50724
+ sheetId: this.sheetId,
50646
50725
  rows: rows.has(index) ? [...rows] : [index],
50647
50726
  });
50648
50727
  }
@@ -50653,7 +50732,7 @@ stores.inject(MyMetaStore, storeInstance);
50653
50732
  return this.env.model.getters.getActiveRows();
50654
50733
  }
50655
50734
  _getPreviousVisibleElement(index) {
50656
- const sheetId = this.env.model.getters.getActiveSheetId();
50735
+ const sheetId = this.sheetId;
50657
50736
  let row;
50658
50737
  for (row = index - 1; row >= 0; row--) {
50659
50738
  if (!this.env.model.getters.isRowHidden(sheetId, row)) {
@@ -50664,7 +50743,7 @@ stores.inject(MyMetaStore, storeInstance);
50664
50743
  }
50665
50744
  unhide(hiddenElements) {
50666
50745
  this.env.model.dispatch("UNHIDE_COLUMNS_ROWS", {
50667
- sheetId: this.env.model.getters.getActiveSheetId(),
50746
+ sheetId: this.sheetId,
50668
50747
  dimension: "ROW",
50669
50748
  elements: hiddenElements,
50670
50749
  });
@@ -67903,7 +67982,8 @@ stores.inject(MyMetaStore, storeInstance);
67903
67982
  ? this.getters.getSheetViewVisibleCols()
67904
67983
  : this.getters.getSheetViewVisibleRows();
67905
67984
  const startIndex = visibleHeaders.findIndex((header) => referenceHeaderIndex >= header);
67906
- const endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
67985
+ let endIndex = visibleHeaders.findIndex((header) => targetHeaderIndex <= header);
67986
+ endIndex = endIndex === -1 ? visibleHeaders.length : endIndex;
67907
67987
  const relevantIndexes = visibleHeaders.slice(startIndex, endIndex);
67908
67988
  let offset = 0;
67909
67989
  for (const i of relevantIndexes) {
@@ -74010,7 +74090,7 @@ stores.inject(MyMetaStore, storeInstance);
74010
74090
  }
74011
74091
  if (alignAttrs.length > 0) {
74012
74092
  attributes.push(["applyAlignment", "1"]); // for Libre Office
74013
- styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)}>${escapeXml /*xml*/ `<alignment ${formatAttributes(alignAttrs)} />`}</xf> `);
74093
+ styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)}><alignment ${formatAttributes(alignAttrs)} /></xf> `);
74014
74094
  }
74015
74095
  else {
74016
74096
  styleNodes.push(escapeXml /*xml*/ `<xf ${formatAttributes(attributes)} />`);
@@ -74178,6 +74258,9 @@ stores.inject(MyMetaStore, storeInstance);
74178
74258
  }
74179
74259
  function addRows(construct, data, sheet) {
74180
74260
  const rowNodes = [];
74261
+ const styles = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.styles));
74262
+ const borders = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.borders));
74263
+ const formats = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.formats));
74181
74264
  for (let r = 0; r < sheet.rowNumber; r++) {
74182
74265
  const rowAttrs = [["r", r + 1]];
74183
74266
  const row = sheet.rows[r] || {};
@@ -74193,9 +74276,6 @@ stores.inject(MyMetaStore, storeInstance);
74193
74276
  if (row.collapsed) {
74194
74277
  rowAttrs.push(["collapsed", 1]);
74195
74278
  }
74196
- const styles = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.styles));
74197
- const borders = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.borders));
74198
- const formats = new PositionMap(iterateItemIdsPositions(sheet.id, sheet.formats));
74199
74279
  const cellNodes = [];
74200
74280
  for (let c = 0; c < sheet.colNumber; c++) {
74201
74281
  const xc = toXC(c, r);
@@ -75467,9 +75547,9 @@ stores.inject(MyMetaStore, storeInstance);
75467
75547
  exports.tokenize = tokenize;
75468
75548
 
75469
75549
 
75470
- __info__.version = "18.1.10";
75471
- __info__.date = "2025-03-07T10:34:41.861Z";
75472
- __info__.hash = "31e4526";
75550
+ __info__.version = "18.1.11";
75551
+ __info__.date = "2025-03-12T15:31:44.276Z";
75552
+ __info__.hash = "7de2363";
75473
75553
 
75474
75554
 
75475
75555
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);