@odoo/o-spreadsheet 16.1.13 → 16.1.15

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.
@@ -726,12 +726,20 @@ function getDefaultCellHeight(style) {
726
726
  return computeTextLinesHeight(fontSize) + 2 * PADDING_AUTORESIZE_VERTICAL;
727
727
  }
728
728
  function computeTextWidth(context, text, style) {
729
- context.save();
730
- context.font = computeTextFont(style);
731
- const textWidth = context.measureText(text).width;
732
- context.restore();
733
- return textWidth;
729
+ const font = computeTextFont(style);
730
+ if (!textWidthCache[font]) {
731
+ textWidthCache[font] = {};
732
+ }
733
+ if (textWidthCache[font][text] === undefined) {
734
+ context.save();
735
+ context.font = font;
736
+ const textWidth = context.measureText(text).width;
737
+ context.restore();
738
+ textWidthCache[font][text] = textWidth;
739
+ }
740
+ return textWidthCache[font][text];
734
741
  }
742
+ const textWidthCache = {};
735
743
  function computeTextFont(style) {
736
744
  const italic = style.italic ? "italic " : "";
737
745
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -1707,27 +1715,36 @@ function removeTrailingZeroes(numberString) {
1707
1715
  }
1708
1716
  return numberString.slice(0, i + 1) || undefined;
1709
1717
  }
1718
+ const leadingZeroesRegexp = /^0+/;
1710
1719
  /**
1711
1720
  * Limit the size of the decimal part of a number to the given number of digits.
1712
1721
  */
1713
1722
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1723
+ var _a;
1714
1724
  let integerDigits = "0";
1715
1725
  let resultDecimalDigits = decimalDigits;
1716
1726
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1717
1727
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1718
1728
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1719
1729
  const i = maxDecimals;
1720
- if (Number(Number(decimalDigits[i]) < 5)) {
1730
+ if (Number(decimalDigits[i]) < 5) {
1721
1731
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1722
1732
  }
1723
1733
  // round up
1734
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1724
1735
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1725
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1726
- integerDigits = (Number(integerDigits) + 1).toString();
1736
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1737
+ // e.g. carry over from 99 to 100
1738
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1739
+ if (carryOver && !leadingZeroes) {
1740
+ integerDigits = "1";
1727
1741
  resultDecimalDigits = undefined;
1728
1742
  }
1743
+ else if (carryOver) {
1744
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1745
+ }
1729
1746
  else {
1730
- resultDecimalDigits = slicedRoundedUp;
1747
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1731
1748
  }
1732
1749
  return { integerDigits, decimalDigits: resultDecimalDigits };
1733
1750
  }
@@ -17345,6 +17362,7 @@ class Composer extends owl.Component {
17345
17362
  (this.autoCompleteState.selectedIndex + 1) % this.autoCompleteState.values.length;
17346
17363
  }
17347
17364
  }
17365
+ this.updateCursorIfNeeded();
17348
17366
  }
17349
17367
  processTabKey(ev) {
17350
17368
  var _a;
@@ -17403,9 +17421,12 @@ class Composer extends owl.Component {
17403
17421
  }
17404
17422
  else {
17405
17423
  ev.stopPropagation();
17424
+ this.updateCursorIfNeeded();
17406
17425
  }
17407
- const { start, end } = this.contentHelper.getCurrentSelection();
17426
+ }
17427
+ updateCursorIfNeeded() {
17408
17428
  if (!this.env.model.getters.isSelectingForComposer()) {
17429
+ const { start, end } = this.contentHelper.getCurrentSelection();
17409
17430
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
17410
17431
  this.isKeyStillDown = true;
17411
17432
  }
@@ -20036,6 +20057,7 @@ css /* scss */ `
20036
20057
  .o-color-picker-toggler {
20037
20058
  display: flex;
20038
20059
  .o-color-picker-toggler-sign {
20060
+ display: flex;
20039
20061
  margin: auto auto;
20040
20062
  width: 55%;
20041
20063
  height: 55%;
@@ -29546,7 +29568,14 @@ class FiltersPlugin extends CorePlugin {
29546
29568
  this.history.update("tables", filterTables);
29547
29569
  break;
29548
29570
  case "DUPLICATE_SHEET":
29549
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
29571
+ const tables = {};
29572
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
29573
+ if (filterTable) {
29574
+ const newFilterTable = deepCopy(filterTable);
29575
+ tables[newFilterTable.id] = newFilterTable;
29576
+ }
29577
+ }
29578
+ this.history.update("tables", cmd.sheetIdTo, tables);
29550
29579
  break;
29551
29580
  case "ADD_COLUMNS_ROWS":
29552
29581
  this.onAddColumnsRows(cmd);
@@ -33090,6 +33119,7 @@ class FilterEvaluationPlugin extends UIPlugin {
33090
33119
  }
33091
33120
  exportForExcel(data) {
33092
33121
  for (const sheetData of data.sheets) {
33122
+ const sheetId = sheetData.id;
33093
33123
  for (const tableData of sheetData.filterTables) {
33094
33124
  const tableZone = toZone(tableData.range);
33095
33125
  const filters = [];
@@ -33105,20 +33135,20 @@ class FilterEvaluationPlugin extends UIPlugin {
33105
33135
  if (!filter)
33106
33136
  continue;
33107
33137
  const valuesInFilterZone = filter.filteredZone
33108
- ? positions(filter.filteredZone)
33109
- .map(({ col, row }) => this.getters.getEvaluatedCell({ sheetId: sheetData.id, col, row }))
33110
- .filter((cell) => cell.type !== CellValueType.empty)
33111
- .map((cell) => cell.formattedValue)
33138
+ ? positions(filter.filteredZone).map((position) => this.getters.getEvaluatedCell({ sheetId, ...position }).formattedValue)
33112
33139
  : [];
33113
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33114
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33115
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33116
- // In xlsx, filter header should ALWAYS be a string and should be unique
33117
- const headerPosition = {
33118
- col: filter.col,
33119
- row: filter.zoneWithHeaders.top,
33120
- sheetId: sheetData.id,
33121
- };
33140
+ if (filteredValues.length) {
33141
+ const xlsxDisplayedValues = valuesInFilterZone
33142
+ .filter((val) => val)
33143
+ .filter((val) => !filteredValues.includes(val));
33144
+ filters.push({
33145
+ colId: i,
33146
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33147
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33148
+ });
33149
+ }
33150
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33151
+ const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top, sheetId };
33122
33152
  const headerString = this.getters.getEvaluatedCell(headerPosition).formattedValue;
33123
33153
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
33124
33154
  headerNames.push(headerName);
@@ -36147,15 +36177,15 @@ SelectionInputPlugin.getters = [];
36147
36177
  * This plugin handles this internal state.
36148
36178
  */
36149
36179
  class SelectionInputsManagerPlugin extends UIPlugin {
36180
+ get currentInput() {
36181
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36182
+ }
36150
36183
  constructor(config) {
36151
36184
  super(config);
36152
36185
  this.config = config;
36153
36186
  this.inputs = {};
36154
36187
  this.focusedInputId = null;
36155
36188
  }
36156
- get currentInput() {
36157
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
36158
- }
36159
36189
  // ---------------------------------------------------------------------------
36160
36190
  // Command Handling
36161
36191
  // ---------------------------------------------------------------------------
@@ -43286,15 +43316,10 @@ function addAutoFilter(table) {
43286
43316
  `;
43287
43317
  }
43288
43318
  function addFilterColumns(table) {
43289
- const tableZone = toZone(table.range);
43290
43319
  const columns = [];
43291
- for (const i of range(0, zoneToDimension(tableZone).width)) {
43292
- const filter = table.filters[i];
43293
- if (!filter || !filter.filteredValues.length) {
43294
- continue;
43295
- }
43320
+ for (const filter of table.filters) {
43296
43321
  const colXml = escapeXml /*xml*/ `
43297
- <filterColumn ${formatAttributes([["colId", i]])}>
43322
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
43298
43323
  ${addFilter(filter)}
43299
43324
  </filterColumn>
43300
43325
  `;
@@ -43303,9 +43328,10 @@ function addFilterColumns(table) {
43303
43328
  return columns;
43304
43329
  }
43305
43330
  function addFilter(filter) {
43306
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43331
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
43332
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
43307
43333
  return escapeXml /*xml*/ `
43308
- <filters>
43334
+ <filters ${formatAttributes(filterAttributes)}>
43309
43335
  ${joinXmlNodes(filterValues)}
43310
43336
  </filters>
43311
43337
  `;
@@ -44258,6 +44284,6 @@ exports.setTranslationMethod = setTranslationMethod;
44258
44284
  exports.tokenize = tokenize;
44259
44285
 
44260
44286
 
44261
- __info__.version = '16.1.13';
44262
- __info__.date = '2023-06-02T10:12:21.173Z';
44263
- __info__.hash = '5386a5b';
44287
+ __info__.version = '16.1.15';
44288
+ __info__.date = '2023-06-26T14:33:07.859Z';
44289
+ __info__.hash = '2b264ad';