@odoo/o-spreadsheet 16.0.12 → 16.0.14

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.
@@ -723,12 +723,20 @@ function getDefaultCellHeight(style, numberOfLines) {
723
723
  2 * PADDING_AUTORESIZE_VERTICAL);
724
724
  }
725
725
  function computeTextWidth(context, text, style) {
726
- context.save();
727
- context.font = computeTextFont(style);
728
- const textWidth = context.measureText(text).width;
729
- context.restore();
730
- return textWidth;
726
+ const font = computeTextFont(style);
727
+ if (!textWidthCache[font]) {
728
+ textWidthCache[font] = {};
729
+ }
730
+ if (textWidthCache[font][text] === undefined) {
731
+ context.save();
732
+ context.font = font;
733
+ const textWidth = context.measureText(text).width;
734
+ context.restore();
735
+ textWidthCache[font][text] = textWidth;
736
+ }
737
+ return textWidthCache[font][text];
731
738
  }
739
+ const textWidthCache = {};
732
740
  function computeTextFont(style) {
733
741
  const italic = style.italic ? "italic " : "";
734
742
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -1617,27 +1625,36 @@ function removeTrailingZeroes(numberString) {
1617
1625
  }
1618
1626
  return numberString.slice(0, i + 1) || undefined;
1619
1627
  }
1628
+ const leadingZeroesRegexp = /^0+/;
1620
1629
  /**
1621
1630
  * Limit the size of the decimal part of a number to the given number of digits.
1622
1631
  */
1623
1632
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1633
+ var _a;
1624
1634
  let integerDigits = "0";
1625
1635
  let resultDecimalDigits = decimalDigits;
1626
1636
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1627
1637
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1628
1638
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1629
1639
  const i = maxDecimals;
1630
- if (Number(Number(decimalDigits[i]) < 5)) {
1640
+ if (Number(decimalDigits[i]) < 5) {
1631
1641
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1632
1642
  }
1633
1643
  // round up
1644
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1634
1645
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1635
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1636
- integerDigits = (Number(integerDigits) + 1).toString();
1646
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1647
+ // e.g. carry over from 99 to 100
1648
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1649
+ if (carryOver && !leadingZeroes) {
1650
+ integerDigits = "1";
1637
1651
  resultDecimalDigits = undefined;
1638
1652
  }
1653
+ else if (carryOver) {
1654
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1655
+ }
1639
1656
  else {
1640
- resultDecimalDigits = slicedRoundedUp;
1657
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1641
1658
  }
1642
1659
  return { integerDigits, decimalDigits: resultDecimalDigits };
1643
1660
  }
@@ -8363,6 +8380,7 @@ css /* scss */ `
8363
8380
  .o-color-picker-toggler {
8364
8381
  display: flex;
8365
8382
  .o-color-picker-toggler-sign {
8383
+ display: flex;
8366
8384
  margin: auto auto;
8367
8385
  width: 55%;
8368
8386
  height: 55%;
@@ -20235,6 +20253,7 @@ class Composer extends owl.Component {
20235
20253
  this.autocompleteAPI.moveDown();
20236
20254
  }
20237
20255
  }
20256
+ this.updateCursorIfNeeded();
20238
20257
  }
20239
20258
  processTabKey(ev) {
20240
20259
  ev.preventDefault();
@@ -20291,9 +20310,12 @@ class Composer extends owl.Component {
20291
20310
  }
20292
20311
  else {
20293
20312
  ev.stopPropagation();
20313
+ this.updateCursorIfNeeded();
20294
20314
  }
20295
- const { start, end } = this.contentHelper.getCurrentSelection();
20315
+ }
20316
+ updateCursorIfNeeded() {
20296
20317
  if (!this.env.model.getters.isSelectingForComposer()) {
20318
+ const { start, end } = this.contentHelper.getCurrentSelection();
20297
20319
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20298
20320
  this.isKeyStillDown = true;
20299
20321
  }
@@ -28633,7 +28655,14 @@ class FiltersPlugin extends CorePlugin {
28633
28655
  this.history.update("tables", filterTables);
28634
28656
  break;
28635
28657
  case "DUPLICATE_SHEET":
28636
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
28658
+ const tables = {};
28659
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
28660
+ if (filterTable) {
28661
+ const newFilterTable = deepCopy(filterTable);
28662
+ tables[newFilterTable.id] = newFilterTable;
28663
+ }
28664
+ }
28665
+ this.history.update("tables", cmd.sheetIdTo, tables);
28637
28666
  break;
28638
28667
  case "ADD_COLUMNS_ROWS":
28639
28668
  this.onAddColumnsRows(cmd);
@@ -33182,14 +33211,19 @@ class FilterEvaluationPlugin extends UIPlugin {
33182
33211
  if (!filter)
33183
33212
  continue;
33184
33213
  const valuesInFilterZone = filter.filteredZone
33185
- ? positions(filter.filteredZone)
33186
- .map((pos) => { var _a; return (_a = this.getters.getCell(sheetData.id, pos.col, pos.row)) === null || _a === void 0 ? void 0 : _a.formattedValue; })
33187
- .filter(isNonEmptyString)
33214
+ ? positions(filter.filteredZone).map((pos) => { var _a; return (_a = this.getters.getCell(sheetData.id, pos.col, pos.row)) === null || _a === void 0 ? void 0 : _a.formattedValue; })
33188
33215
  : [];
33189
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33190
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33191
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33192
- // In xlsx, filter header should ALWAYS be a string and should be unique
33216
+ if (filteredValues.length) {
33217
+ const xlsxDisplayedValues = valuesInFilterZone
33218
+ .filter(isNonEmptyString)
33219
+ .filter((val) => !filteredValues.includes(val));
33220
+ filters.push({
33221
+ colId: i,
33222
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33223
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33224
+ });
33225
+ }
33226
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33193
33227
  const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top };
33194
33228
  const headerString = (_a = this.getters.getCell(sheetData.id, headerPosition.col, headerPosition.row)) === null || _a === void 0 ? void 0 : _a.formattedValue;
33195
33229
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
@@ -35132,6 +35166,9 @@ SelectionInputPlugin.getters = [];
35132
35166
  * This plugin handles this internal state.
35133
35167
  */
35134
35168
  class SelectionInputsManagerPlugin extends UIPlugin {
35169
+ get currentInput() {
35170
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35171
+ }
35135
35172
  constructor(getters, state, dispatch, config, selection) {
35136
35173
  super(getters, state, dispatch, config, selection);
35137
35174
  this.state = state;
@@ -35139,9 +35176,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
35139
35176
  this.inputs = {};
35140
35177
  this.focusedInputId = null;
35141
35178
  }
35142
- get currentInput() {
35143
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35144
- }
35145
35179
  // ---------------------------------------------------------------------------
35146
35180
  // Command Handling
35147
35181
  // ---------------------------------------------------------------------------
@@ -41880,15 +41914,10 @@ function addAutoFilter(table) {
41880
41914
  `;
41881
41915
  }
41882
41916
  function addFilterColumns(table) {
41883
- const tableZone = toZone(table.range);
41884
41917
  const columns = [];
41885
- for (const i of range(0, zoneToDimension(tableZone).width)) {
41886
- const filter = table.filters[i];
41887
- if (!filter || !filter.filteredValues.length) {
41888
- continue;
41889
- }
41918
+ for (const filter of table.filters) {
41890
41919
  const colXml = escapeXml /*xml*/ `
41891
- <filterColumn ${formatAttributes([["colId", i]])}>
41920
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
41892
41921
  ${addFilter(filter)}
41893
41922
  </filterColumn>
41894
41923
  `;
@@ -41897,9 +41926,10 @@ function addFilterColumns(table) {
41897
41926
  return columns;
41898
41927
  }
41899
41928
  function addFilter(filter) {
41900
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41929
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41930
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
41901
41931
  return escapeXml /*xml*/ `
41902
- <filters>
41932
+ <filters ${formatAttributes(filterAttributes)}>
41903
41933
  ${joinXmlNodes(filterValues)}
41904
41934
  </filters>
41905
41935
  `;
@@ -42802,6 +42832,6 @@ exports.setTranslationMethod = setTranslationMethod;
42802
42832
  exports.tokenize = tokenize;
42803
42833
 
42804
42834
 
42805
- __info__.version = '16.0.12';
42806
- __info__.date = '2023-06-02T10:12:20.596Z';
42807
- __info__.hash = '9718465';
42835
+ __info__.version = '16.0.14';
42836
+ __info__.date = '2023-06-26T14:33:01.959Z';
42837
+ __info__.hash = '1e37a94';