@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.
@@ -719,12 +719,20 @@ function getDefaultCellHeight(style, numberOfLines) {
719
719
  2 * PADDING_AUTORESIZE_VERTICAL);
720
720
  }
721
721
  function computeTextWidth(context, text, style) {
722
- context.save();
723
- context.font = computeTextFont(style);
724
- const textWidth = context.measureText(text).width;
725
- context.restore();
726
- return textWidth;
722
+ const font = computeTextFont(style);
723
+ if (!textWidthCache[font]) {
724
+ textWidthCache[font] = {};
725
+ }
726
+ if (textWidthCache[font][text] === undefined) {
727
+ context.save();
728
+ context.font = font;
729
+ const textWidth = context.measureText(text).width;
730
+ context.restore();
731
+ textWidthCache[font][text] = textWidth;
732
+ }
733
+ return textWidthCache[font][text];
727
734
  }
735
+ const textWidthCache = {};
728
736
  function computeTextFont(style) {
729
737
  const italic = style.italic ? "italic " : "";
730
738
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -1613,27 +1621,36 @@ function removeTrailingZeroes(numberString) {
1613
1621
  }
1614
1622
  return numberString.slice(0, i + 1) || undefined;
1615
1623
  }
1624
+ const leadingZeroesRegexp = /^0+/;
1616
1625
  /**
1617
1626
  * Limit the size of the decimal part of a number to the given number of digits.
1618
1627
  */
1619
1628
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1629
+ var _a;
1620
1630
  let integerDigits = "0";
1621
1631
  let resultDecimalDigits = decimalDigits;
1622
1632
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1623
1633
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1624
1634
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1625
1635
  const i = maxDecimals;
1626
- if (Number(Number(decimalDigits[i]) < 5)) {
1636
+ if (Number(decimalDigits[i]) < 5) {
1627
1637
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1628
1638
  }
1629
1639
  // round up
1640
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1630
1641
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1631
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1632
- integerDigits = (Number(integerDigits) + 1).toString();
1642
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1643
+ // e.g. carry over from 99 to 100
1644
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1645
+ if (carryOver && !leadingZeroes) {
1646
+ integerDigits = "1";
1633
1647
  resultDecimalDigits = undefined;
1634
1648
  }
1649
+ else if (carryOver) {
1650
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1651
+ }
1635
1652
  else {
1636
- resultDecimalDigits = slicedRoundedUp;
1653
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1637
1654
  }
1638
1655
  return { integerDigits, decimalDigits: resultDecimalDigits };
1639
1656
  }
@@ -8359,6 +8376,7 @@ css /* scss */ `
8359
8376
  .o-color-picker-toggler {
8360
8377
  display: flex;
8361
8378
  .o-color-picker-toggler-sign {
8379
+ display: flex;
8362
8380
  margin: auto auto;
8363
8381
  width: 55%;
8364
8382
  height: 55%;
@@ -20231,6 +20249,7 @@ class Composer extends Component {
20231
20249
  this.autocompleteAPI.moveDown();
20232
20250
  }
20233
20251
  }
20252
+ this.updateCursorIfNeeded();
20234
20253
  }
20235
20254
  processTabKey(ev) {
20236
20255
  ev.preventDefault();
@@ -20287,9 +20306,12 @@ class Composer extends Component {
20287
20306
  }
20288
20307
  else {
20289
20308
  ev.stopPropagation();
20309
+ this.updateCursorIfNeeded();
20290
20310
  }
20291
- const { start, end } = this.contentHelper.getCurrentSelection();
20311
+ }
20312
+ updateCursorIfNeeded() {
20292
20313
  if (!this.env.model.getters.isSelectingForComposer()) {
20314
+ const { start, end } = this.contentHelper.getCurrentSelection();
20293
20315
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20294
20316
  this.isKeyStillDown = true;
20295
20317
  }
@@ -28629,7 +28651,14 @@ class FiltersPlugin extends CorePlugin {
28629
28651
  this.history.update("tables", filterTables);
28630
28652
  break;
28631
28653
  case "DUPLICATE_SHEET":
28632
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
28654
+ const tables = {};
28655
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
28656
+ if (filterTable) {
28657
+ const newFilterTable = deepCopy(filterTable);
28658
+ tables[newFilterTable.id] = newFilterTable;
28659
+ }
28660
+ }
28661
+ this.history.update("tables", cmd.sheetIdTo, tables);
28633
28662
  break;
28634
28663
  case "ADD_COLUMNS_ROWS":
28635
28664
  this.onAddColumnsRows(cmd);
@@ -33178,14 +33207,19 @@ class FilterEvaluationPlugin extends UIPlugin {
33178
33207
  if (!filter)
33179
33208
  continue;
33180
33209
  const valuesInFilterZone = filter.filteredZone
33181
- ? positions(filter.filteredZone)
33182
- .map((pos) => { var _a; return (_a = this.getters.getCell(sheetData.id, pos.col, pos.row)) === null || _a === void 0 ? void 0 : _a.formattedValue; })
33183
- .filter(isNonEmptyString)
33210
+ ? 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; })
33184
33211
  : [];
33185
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33186
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33187
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33188
- // In xlsx, filter header should ALWAYS be a string and should be unique
33212
+ if (filteredValues.length) {
33213
+ const xlsxDisplayedValues = valuesInFilterZone
33214
+ .filter(isNonEmptyString)
33215
+ .filter((val) => !filteredValues.includes(val));
33216
+ filters.push({
33217
+ colId: i,
33218
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33219
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33220
+ });
33221
+ }
33222
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33189
33223
  const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top };
33190
33224
  const headerString = (_a = this.getters.getCell(sheetData.id, headerPosition.col, headerPosition.row)) === null || _a === void 0 ? void 0 : _a.formattedValue;
33191
33225
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
@@ -35128,6 +35162,9 @@ SelectionInputPlugin.getters = [];
35128
35162
  * This plugin handles this internal state.
35129
35163
  */
35130
35164
  class SelectionInputsManagerPlugin extends UIPlugin {
35165
+ get currentInput() {
35166
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35167
+ }
35131
35168
  constructor(getters, state, dispatch, config, selection) {
35132
35169
  super(getters, state, dispatch, config, selection);
35133
35170
  this.state = state;
@@ -35135,9 +35172,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
35135
35172
  this.inputs = {};
35136
35173
  this.focusedInputId = null;
35137
35174
  }
35138
- get currentInput() {
35139
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35140
- }
35141
35175
  // ---------------------------------------------------------------------------
35142
35176
  // Command Handling
35143
35177
  // ---------------------------------------------------------------------------
@@ -41876,15 +41910,10 @@ function addAutoFilter(table) {
41876
41910
  `;
41877
41911
  }
41878
41912
  function addFilterColumns(table) {
41879
- const tableZone = toZone(table.range);
41880
41913
  const columns = [];
41881
- for (const i of range(0, zoneToDimension(tableZone).width)) {
41882
- const filter = table.filters[i];
41883
- if (!filter || !filter.filteredValues.length) {
41884
- continue;
41885
- }
41914
+ for (const filter of table.filters) {
41886
41915
  const colXml = escapeXml /*xml*/ `
41887
- <filterColumn ${formatAttributes([["colId", i]])}>
41916
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
41888
41917
  ${addFilter(filter)}
41889
41918
  </filterColumn>
41890
41919
  `;
@@ -41893,9 +41922,10 @@ function addFilterColumns(table) {
41893
41922
  return columns;
41894
41923
  }
41895
41924
  function addFilter(filter) {
41896
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41925
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41926
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
41897
41927
  return escapeXml /*xml*/ `
41898
- <filters>
41928
+ <filters ${formatAttributes(filterAttributes)}>
41899
41929
  ${joinXmlNodes(filterValues)}
41900
41930
  </filters>
41901
41931
  `;
@@ -42770,6 +42800,6 @@ function addFunction(functionName, functionDescription) {
42770
42800
  export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, cellTypes, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
42771
42801
 
42772
42802
 
42773
- __info__.version = '16.0.12';
42774
- __info__.date = '2023-06-02T10:12:20.596Z';
42775
- __info__.hash = '9718465';
42803
+ __info__.version = '16.0.14';
42804
+ __info__.date = '2023-06-26T14:33:01.959Z';
42805
+ __info__.hash = '1e37a94';
@@ -720,12 +720,20 @@
720
720
  2 * PADDING_AUTORESIZE_VERTICAL);
721
721
  }
722
722
  function computeTextWidth(context, text, style) {
723
- context.save();
724
- context.font = computeTextFont(style);
725
- const textWidth = context.measureText(text).width;
726
- context.restore();
727
- return textWidth;
723
+ const font = computeTextFont(style);
724
+ if (!textWidthCache[font]) {
725
+ textWidthCache[font] = {};
726
+ }
727
+ if (textWidthCache[font][text] === undefined) {
728
+ context.save();
729
+ context.font = font;
730
+ const textWidth = context.measureText(text).width;
731
+ context.restore();
732
+ textWidthCache[font][text] = textWidth;
733
+ }
734
+ return textWidthCache[font][text];
728
735
  }
736
+ const textWidthCache = {};
729
737
  function computeTextFont(style) {
730
738
  const italic = style.italic ? "italic " : "";
731
739
  const weight = style.bold ? "bold" : DEFAULT_FONT_WEIGHT;
@@ -1614,27 +1622,36 @@
1614
1622
  }
1615
1623
  return numberString.slice(0, i + 1) || undefined;
1616
1624
  }
1625
+ const leadingZeroesRegexp = /^0+/;
1617
1626
  /**
1618
1627
  * Limit the size of the decimal part of a number to the given number of digits.
1619
1628
  */
1620
1629
  function limitDecimalDigits(decimalDigits, maxDecimals) {
1630
+ var _a;
1621
1631
  let integerDigits = "0";
1622
1632
  let resultDecimalDigits = decimalDigits;
1623
1633
  // Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
1624
1634
  // but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
1625
1635
  let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
1626
1636
  const i = maxDecimals;
1627
- if (Number(Number(decimalDigits[i]) < 5)) {
1637
+ if (Number(decimalDigits[i]) < 5) {
1628
1638
  return { integerDigits, decimalDigits: slicedDecimalDigits };
1629
1639
  }
1630
1640
  // round up
1641
+ const leadingZeroes = ((_a = slicedDecimalDigits.match(leadingZeroesRegexp)) === null || _a === void 0 ? void 0 : _a[0]) || "";
1631
1642
  const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
1632
- if (slicedRoundedUp.length > slicedDecimalDigits.length) {
1633
- integerDigits = (Number(integerDigits) + 1).toString();
1643
+ const withoutLeadingZeroes = slicedDecimalDigits.slice(leadingZeroes.length);
1644
+ // e.g. carry over from 99 to 100
1645
+ const carryOver = slicedRoundedUp.length > withoutLeadingZeroes.length;
1646
+ if (carryOver && !leadingZeroes) {
1647
+ integerDigits = "1";
1634
1648
  resultDecimalDigits = undefined;
1635
1649
  }
1650
+ else if (carryOver) {
1651
+ resultDecimalDigits = leadingZeroes.slice(0, -1) + slicedRoundedUp;
1652
+ }
1636
1653
  else {
1637
- resultDecimalDigits = slicedRoundedUp;
1654
+ resultDecimalDigits = leadingZeroes + slicedRoundedUp;
1638
1655
  }
1639
1656
  return { integerDigits, decimalDigits: resultDecimalDigits };
1640
1657
  }
@@ -8360,6 +8377,7 @@
8360
8377
  .o-color-picker-toggler {
8361
8378
  display: flex;
8362
8379
  .o-color-picker-toggler-sign {
8380
+ display: flex;
8363
8381
  margin: auto auto;
8364
8382
  width: 55%;
8365
8383
  height: 55%;
@@ -20232,6 +20250,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20232
20250
  this.autocompleteAPI.moveDown();
20233
20251
  }
20234
20252
  }
20253
+ this.updateCursorIfNeeded();
20235
20254
  }
20236
20255
  processTabKey(ev) {
20237
20256
  ev.preventDefault();
@@ -20288,9 +20307,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20288
20307
  }
20289
20308
  else {
20290
20309
  ev.stopPropagation();
20310
+ this.updateCursorIfNeeded();
20291
20311
  }
20292
- const { start, end } = this.contentHelper.getCurrentSelection();
20312
+ }
20313
+ updateCursorIfNeeded() {
20293
20314
  if (!this.env.model.getters.isSelectingForComposer()) {
20315
+ const { start, end } = this.contentHelper.getCurrentSelection();
20294
20316
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20295
20317
  this.isKeyStillDown = true;
20296
20318
  }
@@ -28630,7 +28652,14 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
28630
28652
  this.history.update("tables", filterTables);
28631
28653
  break;
28632
28654
  case "DUPLICATE_SHEET":
28633
- this.history.update("tables", cmd.sheetIdTo, deepCopy(this.tables[cmd.sheetId]));
28655
+ const tables = {};
28656
+ for (const filterTable of Object.values(this.tables[cmd.sheetId] || {})) {
28657
+ if (filterTable) {
28658
+ const newFilterTable = deepCopy(filterTable);
28659
+ tables[newFilterTable.id] = newFilterTable;
28660
+ }
28661
+ }
28662
+ this.history.update("tables", cmd.sheetIdTo, tables);
28634
28663
  break;
28635
28664
  case "ADD_COLUMNS_ROWS":
28636
28665
  this.onAddColumnsRows(cmd);
@@ -33179,14 +33208,19 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
33179
33208
  if (!filter)
33180
33209
  continue;
33181
33210
  const valuesInFilterZone = filter.filteredZone
33182
- ? positions(filter.filteredZone)
33183
- .map((pos) => { var _a; return (_a = this.getters.getCell(sheetData.id, pos.col, pos.row)) === null || _a === void 0 ? void 0 : _a.formattedValue; })
33184
- .filter(isNonEmptyString)
33211
+ ? 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; })
33185
33212
  : [];
33186
- // In xlsx, filtered values = values that are displayed, not values that are hidden
33187
- const xlsxFilteredValues = valuesInFilterZone.filter((val) => !filteredValues.includes(val));
33188
- filters.push({ colId: i, filteredValues: [...new Set(xlsxFilteredValues)] });
33189
- // In xlsx, filter header should ALWAYS be a string and should be unique
33213
+ if (filteredValues.length) {
33214
+ const xlsxDisplayedValues = valuesInFilterZone
33215
+ .filter(isNonEmptyString)
33216
+ .filter((val) => !filteredValues.includes(val));
33217
+ filters.push({
33218
+ colId: i,
33219
+ displayedValues: [...new Set(xlsxDisplayedValues)],
33220
+ displayBlanks: !filteredValues.includes("") && valuesInFilterZone.some((val) => !val),
33221
+ });
33222
+ }
33223
+ // In xlsx, filter header should ALWAYS be a string and should be unique in the table
33190
33224
  const headerPosition = { col: filter.col, row: filter.zoneWithHeaders.top };
33191
33225
  const headerString = (_a = this.getters.getCell(sheetData.id, headerPosition.col, headerPosition.row)) === null || _a === void 0 ? void 0 : _a.formattedValue;
33192
33226
  const headerName = this.getUniqueColNameForExcel(i, headerString, headerNames);
@@ -35129,6 +35163,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35129
35163
  * This plugin handles this internal state.
35130
35164
  */
35131
35165
  class SelectionInputsManagerPlugin extends UIPlugin {
35166
+ get currentInput() {
35167
+ return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35168
+ }
35132
35169
  constructor(getters, state, dispatch, config, selection) {
35133
35170
  super(getters, state, dispatch, config, selection);
35134
35171
  this.state = state;
@@ -35136,9 +35173,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35136
35173
  this.inputs = {};
35137
35174
  this.focusedInputId = null;
35138
35175
  }
35139
- get currentInput() {
35140
- return this.focusedInputId ? this.inputs[this.focusedInputId] : null;
35141
- }
35142
35176
  // ---------------------------------------------------------------------------
35143
35177
  // Command Handling
35144
35178
  // ---------------------------------------------------------------------------
@@ -41877,15 +41911,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
41877
41911
  `;
41878
41912
  }
41879
41913
  function addFilterColumns(table) {
41880
- const tableZone = toZone(table.range);
41881
41914
  const columns = [];
41882
- for (const i of range(0, zoneToDimension(tableZone).width)) {
41883
- const filter = table.filters[i];
41884
- if (!filter || !filter.filteredValues.length) {
41885
- continue;
41886
- }
41915
+ for (const filter of table.filters) {
41887
41916
  const colXml = escapeXml /*xml*/ `
41888
- <filterColumn ${formatAttributes([["colId", i]])}>
41917
+ <filterColumn ${formatAttributes([["colId", filter.colId]])}>
41889
41918
  ${addFilter(filter)}
41890
41919
  </filterColumn>
41891
41920
  `;
@@ -41894,9 +41923,10 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
41894
41923
  return columns;
41895
41924
  }
41896
41925
  function addFilter(filter) {
41897
- const filterValues = filter.filteredValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41926
+ const filterValues = filter.displayedValues.map((val) => escapeXml /*xml*/ `<filter ${formatAttributes([["val", val]])}/>`);
41927
+ const filterAttributes = filter.displayBlanks ? [["blank", 1]] : [];
41898
41928
  return escapeXml /*xml*/ `
41899
- <filters>
41929
+ <filters ${formatAttributes(filterAttributes)}>
41900
41930
  ${joinXmlNodes(filterValues)}
41901
41931
  </filters>
41902
41932
  `;
@@ -42801,9 +42831,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
42801
42831
  Object.defineProperty(exports, '__esModule', { value: true });
42802
42832
 
42803
42833
 
42804
- __info__.version = '16.0.12';
42805
- __info__.date = '2023-06-02T10:12:20.596Z';
42806
- __info__.hash = '9718465';
42834
+ __info__.version = '16.0.14';
42835
+ __info__.date = '2023-06-26T14:33:01.959Z';
42836
+ __info__.hash = '1e37a94';
42807
42837
 
42808
42838
 
42809
42839
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);