@odoo/o-spreadsheet 16.3.2 → 16.3.4

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.
@@ -754,12 +754,20 @@ function getDefaultCellHeight(cell) {
754
754
  return computeTextLinesHeight(fontSize, numberOfLines) + 2 * PADDING_AUTORESIZE_VERTICAL;
755
755
  }
756
756
  function computeTextWidth(context, text, style) {
757
- context.save();
758
- context.font = computeTextFont(style);
759
- const textWidth = context.measureText(text).width;
760
- context.restore();
761
- return textWidth;
757
+ const font = computeTextFont(style);
758
+ if (!textWidthCache[font]) {
759
+ textWidthCache[font] = {};
760
+ }
761
+ if (textWidthCache[font][text] === undefined) {
762
+ context.save();
763
+ context.font = font;
764
+ const textWidth = context.measureText(text).width;
765
+ context.restore();
766
+ textWidthCache[font][text] = textWidth;
767
+ }
768
+ return textWidthCache[font][text];
762
769
  }
770
+ const textWidthCache = {};
763
771
  function fontSizeInPixels(fontSize) {
764
772
  return Math.round((fontSize * 96) / 72);
765
773
  }
@@ -1777,6 +1785,7 @@ function removeTrailingZeroes(numberString) {
1777
1785
  }
1778
1786
  return numberString.slice(0, i + 1) || undefined;
1779
1787
  }
1788
+ const leadingZeroesRegexp = /^0+/;
1780
1789
  /**
1781
1790
  * Limit the size of the decimal part of a number to the given number of digits.
1782
1791
  */
@@ -1787,17 +1796,24 @@ function limitDecimalDigits(decimalDigits, maxDecimals) {
1787
1796
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1788
1797
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1789
1798
  const i = maxDecimals;
1790
- if (Number(Number(decimalDigits[i]) < 5)) {
1799
+ if (Number(decimalDigits[i]) < 5) {
1791
1800
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1792
1801
  }
1793
1802
  // round up
1803
+ const leadingZeroes = slicedDecimalDigits.match(leadingZeroesRegexp)?.[0] || "";
1794
1804
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1795
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1796
- integerDigits = (Number(integerDigits) + 1).toString();
1805
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1806
+ // e.g. carry over from 99 to 100
1807
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1808
+ if (carryOver && !leadingZeroes) {
1809
+ integerDigits = "1";
1797
1810
  resultDecimalDigits = undefined;
1798
1811
  }
1812
+ else if (carryOver) {
1813
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1814
+ }
1799
1815
  else {
1800
- resultDecimalDigits = slicedRoundedUp;
1816
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1801
1817
  }
1802
1818
  return { integerDigits, decimalDigits: resultDecimalDigits };
1803
1819
  }
@@ -9511,9 +9527,9 @@ const ARG_TYPES = [
9511
9527
  "META",
9512
9528
  ];
9513
9529
  function arg(definition, description = "") {
9514
- return makeArg(`${definition} ${description}`);
9530
+ return makeArg(definition, description);
9515
9531
  }
9516
- function makeArg(str) {
9532
+ function makeArg(str, description) {
9517
9533
  let parts = str.match(ARG_REGEXP);
9518
9534
  let name = parts[1].trim();
9519
9535
  let types = [];
@@ -9543,7 +9559,6 @@ function makeArg(str) {
9543
9559
  defaultValue = param.trim().slice(8);
9544
9560
  }
9545
9561
  }
9546
- let description = parts[3].trim();
9547
9562
  const result = {
9548
9563
  name,
9549
9564
  description,
@@ -17948,6 +17963,7 @@ css /* scss */ `
17948
17963
  .o-color-picker-toggler-button {
17949
17964
  display: flex;
17950
17965
  .o-color-picker-toggler-sign {
17966
+ display: flex;
17951
17967
  margin: auto auto;
17952
17968
  width: 55%;
17953
17969
  height: 55%;
@@ -20923,6 +20939,7 @@ class Composer extends owl.Component {
20923
20939
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
20924
20940
  }
20925
20941
  }
20942
+ this.updateCursorIfNeeded();
20926
20943
  }
20927
20944
  processTabKey(ev) {
20928
20945
  ev.preventDefault();
@@ -20991,10 +21008,12 @@ class Composer extends owl.Component {
20991
21008
  }
20992
21009
  else {
20993
21010
  ev.stopPropagation();
21011
+ this.updateCursorIfNeeded();
20994
21012
  }
20995
- const { start, end } = this.contentHelper.getCurrentSelection();
20996
- if (!this.env.model.getters.isSelectingForComposer() &&
20997
- !(ev.key === "Enter" && (ev.altKey || ev.ctrlKey))) {
21013
+ }
21014
+ updateCursorIfNeeded() {
21015
+ if (!this.env.model.getters.isSelectingForComposer()) {
21016
+ const { start, end } = this.contentHelper.getCurrentSelection();
20998
21017
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20999
21018
  this.isKeyStillDown = true;
21000
21019
  }
@@ -21052,7 +21071,12 @@ class Composer extends owl.Component {
21052
21071
  };
21053
21072
  });
21054
21073
  if (searchTerm) {
21055
- values = fuzzyLookup(searchTerm, values, (t) => t.text);
21074
+ if (searchTerm.toLowerCase() === "true" || searchTerm.toLowerCase() === "false") {
21075
+ values = [];
21076
+ }
21077
+ else {
21078
+ values = fuzzyLookup(searchTerm, values, (t) => t.text);
21079
+ }
21056
21080
  }
21057
21081
  else {
21058
21082
  // alphabetical order
@@ -30635,7 +30659,14 @@ class FiltersPlugin extends CorePlugin {
30635
30659
  this.history.update("tables", filterTables);
30636
30660
  break;
30637
30661
  case "DUPLICATE_SHEET":
30638
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
30662
+ const tables = {};
30663
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
30664
+ if (filterTable) {
30665
+ const newFilterTable = deepCopy(filterTable);
30666
+ tables[newFilterTable.id] = newFilterTable;
30667
+ }
30668
+ }
30669
+ this.history.update("tables", cmd.sheetIdTo, tables);
30639
30670
  break;
30640
30671
  case "ADD_COLUMNS_ROWS":
30641
30672
  this.onAddColumnsRows(cmd);
@@ -34184,6 +34215,7 @@ class FilterEvaluationPlugin extends UIPlugin {
34184
34215
  }
34185
34216
  exportForExcel(data) {
34186
34217
  for (const sheetData of data.sheets) {
34218
+ const sheetId = sheetData.id;
34187
34219
  for (const tableData of sheetData.filterTables) {
34188
34220
  const tableZone = toZone(tableData.range);
34189
34221
  const filters = [];
@@ -34199,20 +34231,20 @@ class FilterEvaluationPlugin extends UIPlugin {
34199
34231
  if (!filter)
34200
34232
  continue;
34201
34233
  const valuesInFilterZone = filter.filteredZone
34202
- ? positions(filter.filteredZone)
34203
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
34204
- .filter((cell) => cell.type !== CellValueType.empty)
34205
- .map((cell) => cell.formattedValue)
34234
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
34206
34235
  : [];
34207
- // In xlsx, filtered values = values that are displayed, not values that are hidden
34208
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
34209
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
34210
- // In xlsx, filter header should ALWAYS be a string and should be unique
34211
- const headerPosition = {
34212
- col: filter.col,
34213
- row: filter.zoneWithHeaders.top,
34214
- sheetId: sheetData.id,
34215
- };
34236
+ if (filteredValues.length) {
34237
+ const xlsxDisplayedValues = valuesInFilterZone
34238
+ .filter((val) => val)
34239
+ .filter((val) => !filteredValues.includes(val));
34240
+ filters.push({
34241
+ colId: i,
34242
+ displayedValues: [...new Set(xlsxDisplayedValues)],
34243
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
34244
+ });
34245
+ }
34246
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
34247
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
34216
34248
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
34217
34249
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
34218
34250
  headerNames.push(headerName);
@@ -43284,11 +43316,9 @@ TopBarComposer.props = {
43284
43316
  onComposerContentFocused: Function,
43285
43317
  };
43286
43318
 
43287
- // -----------------------------------------------------------------------------
43288
- // TopBar
43289
- // -----------------------------------------------------------------------------
43290
43319
  css /* scss */ `
43291
43320
  .o-font-size-editor {
43321
+ height: calc(100% - 4px);
43292
43322
  input.o-font-size {
43293
43323
  outline-color: ${SELECTION_BORDER_COLOR};
43294
43324
  height: 20px;
@@ -43301,13 +43331,13 @@ css /* scss */ `
43301
43331
  input::-webkit-inner-spin-button {
43302
43332
  -webkit-appearance: none;
43303
43333
  }
43304
-
43305
- .o-text-options > div {
43306
- line-height: 26px;
43307
- padding: 3px 12px;
43308
- &:hover {
43309
- background-color: rgba(0, 0, 0, 0.08);
43310
- }
43334
+ }
43335
+ .o-text-options > div {
43336
+ cursor: pointer;
43337
+ line-height: 26px;
43338
+ padding: 3px 12px;
43339
+ &:hover {
43340
+ background-color: rgba(0, 0, 0, 0.08);
43311
43341
  }
43312
43342
  }
43313
43343
  `;
@@ -43372,6 +43402,7 @@ class FontSizeEditor extends owl.Component {
43372
43402
  FontSizeEditor.props = {
43373
43403
  onToggle: Function,
43374
43404
  dropdownStyle: String,
43405
+ class: String,
43375
43406
  };
43376
43407
 
43377
43408
  // -----------------------------------------------------------------------------
@@ -46540,15 +46571,10 @@ function addAutoFilter(table) {
46540
46571
  `;
46541
46572
  }
46542
46573
  function addFilterColumns(table) {
46543
- const tableZone = toZone(table.range);
46544
46574
  const columns = [];
46545
- for (const i of range(0, zoneToDimension(tableZone).numberOfCols)) {
46546
- const filter = table.filters[i];
46547
- if (!filter || !filter.filteredValues.length) {
46548
- continue;
46549
- }
46575
+ for (const filter of table.filters) {
46550
46576
  const colXml = escapeXml /*xml*/ `
46551
- <filterColumn ${formatAttributes([["colId", i]])}>
46577
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
46552
46578
  ${addFilter(filter)}
46553
46579
  </filterColumn>
46554
46580
  `;
@@ -46557,9 +46583,10 @@ function addFilterColumns(table) {
46557
46583
  return columns;
46558
46584
  }
46559
46585
  function addFilter(filter) {
46560
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46586
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
46587
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
46561
46588
  return escapeXml /*xml*/ `
46562
- <filters>
46589
+ <filters ${formatAttributes(filterAttributes)}>
46563
46590
  ${joinXmlNodes(filterValues)}
46564
46591
  </filters>
46565
46592
  `;
@@ -46678,8 +46705,13 @@ function addHyperlinks(construct, data, sheetIndex) {
46678
46705
  const sheetId = parseSheetUrl(url);
46679
46706
  const sheet = data.sheets.find((sheet) => sheet.id === sheetId);
46680
46707
  const location = sheet ? `${sheet.name}!A1` : INCORRECT_RANGE_STRING;
46708
+ const hyperlinkAttributes = [
46709
+ ["display", label],
46710
+ ["location", location],
46711
+ ["ref", xc],
46712
+ ];
46681
46713
  linkNodes.push(escapeXml /*xml*/ `
46682
- <hyperlink display="${label}" location="${location}" ref="${xc}"/>
46714
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46683
46715
  `);
46684
46716
  }
46685
46717
  else {
@@ -46688,8 +46720,12 @@ function addHyperlinks(construct, data, sheetIndex) {
46688
46720
  type: XLSX_RELATION_TYPE.hyperlink,
46689
46721
  targetMode: "External",
46690
46722
  });
46723
+ const hyperlinkAttributes = [
46724
+ ["r:id", linkRelId],
46725
+ ["ref", xc],
46726
+ ];
46691
46727
  linkNodes.push(escapeXml /*xml*/ `
46692
- <hyperlink r:id="${linkRelId}" ref="${xc}"/>
46728
+ <hyperlink ${formatAttributes(hyperlinkAttributes)}/>
46693
46729
  `);
46694
46730
  }
46695
46731
  }
@@ -47597,6 +47633,6 @@ exports.setTranslationMethod = setTranslationMethod;
47597
47633
  exports.tokenize = tokenize;
47598
47634
 
47599
47635
 
47600
- __info__.version = '16.3.2';
47601
- __info__.date = '2023-06-02T10:13:46.734Z';
47602
- __info__.hash = '69a4378';
47636
+ __info__.version = '16.3.4';
47637
+ __info__.date = '2023-06-26T14:34:27.019Z';
47638
+ __info__.hash = '94f9dcd';