@odoo/o-spreadsheet 17.1.3 → 17.1.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.
@@ -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 17.1.3
6
- * @date 2024-02-02T13:46:54.332Z
7
- * @hash 798f979
5
+ * @version 17.1.4
6
+ * @date 2024-02-09T13:09:13.430Z
7
+ * @hash 16d3ece
8
8
  */
9
9
 
10
10
  'use strict';
@@ -2940,6 +2940,9 @@ function formatValue(value, { format, locale }) {
2940
2940
  }
2941
2941
  switch (typeof value) {
2942
2942
  case "string":
2943
+ if (value.includes('\\"')) {
2944
+ return value.replace(/\\"/g, '"');
2945
+ }
2943
2946
  return value;
2944
2947
  case "boolean":
2945
2948
  return value ? "TRUE" : "FALSE";
@@ -4993,14 +4996,8 @@ function createDataSets(getters, dataSetsString, sheetId, dataSetsHaveTitle) {
4993
4996
  : undefined));
4994
4997
  }
4995
4998
  }
4996
- else if (zone.left === zone.right && zone.top === zone.bottom) {
4997
- // A single cell. If it's only the title, the dataset is not added.
4998
- if (!dataSetsHaveTitle) {
4999
- dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
5000
- }
5001
- }
5002
4999
  else {
5003
- /* 1 row or 1 column */
5000
+ /* 1 cell, 1 row or 1 column */
5004
5001
  dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
5005
5002
  ? {
5006
5003
  top: zone.top,
@@ -7443,7 +7440,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
7443
7440
  while (!chars.isOver()) {
7444
7441
  let token = tokenizeSpace(chars) ||
7445
7442
  tokenizeArgsSeparator(chars, locale) ||
7446
- tokenizeMisc(chars) ||
7443
+ tokenizeParenthesis(chars) ||
7447
7444
  tokenizeOperator(chars) ||
7448
7445
  tokenizeString(chars) ||
7449
7446
  tokenizeDebugger(chars) ||
@@ -7464,15 +7461,14 @@ function tokenizeDebugger(chars) {
7464
7461
  }
7465
7462
  return null;
7466
7463
  }
7467
- const misc$1 = {
7468
- "(": "LEFT_PAREN",
7469
- ")": "RIGHT_PAREN",
7464
+ const parenthesis = {
7465
+ "(": { type: "LEFT_PAREN", value: "(" },
7466
+ ")": { type: "RIGHT_PAREN", value: ")" },
7470
7467
  };
7471
- function tokenizeMisc(chars) {
7472
- if (chars.current in misc$1) {
7468
+ function tokenizeParenthesis(chars) {
7469
+ if (chars.current === "(" || chars.current === ")") {
7473
7470
  const value = chars.shift();
7474
- const type = misc$1[value];
7475
- return { type, value };
7471
+ return parenthesis[value];
7476
7472
  }
7477
7473
  return null;
7478
7474
  }
@@ -7493,7 +7489,12 @@ function tokenizeOperator(chars) {
7493
7489
  }
7494
7490
  return null;
7495
7491
  }
7492
+ const FIRST_POSSIBLE_NUMBER_CHARS = new Set("0123456789");
7496
7493
  function tokenizeNumber(chars, locale) {
7494
+ if (!FIRST_POSSIBLE_NUMBER_CHARS.has(chars.current) &&
7495
+ chars.current !== locale.decimalSeparator) {
7496
+ return null;
7497
+ }
7497
7498
  const match = chars.remaining().match(getFormulaNumberRegex(locale.decimalSeparator));
7498
7499
  if (match) {
7499
7500
  chars.advanceBy(match[0].length);
@@ -7518,7 +7519,7 @@ function tokenizeString(chars) {
7518
7519
  }
7519
7520
  return null;
7520
7521
  }
7521
- const separatorRegexp = /\w|\.|!|\$/;
7522
+ const separatorRegexp = /^[\w\.!\$]+/;
7522
7523
  /**
7523
7524
  * A "Symbol" is just basically any word-like element that can appear in a
7524
7525
  * formula, which is not a string. So:
@@ -7558,8 +7559,11 @@ function tokenizeSymbol(chars) {
7558
7559
  };
7559
7560
  }
7560
7561
  }
7561
- while (chars.current && separatorRegexp.test(chars.current)) {
7562
- result += chars.shift();
7562
+ const match = chars.remaining().match(separatorRegexp);
7563
+ if (match) {
7564
+ const value = match[0];
7565
+ result += value;
7566
+ chars.advanceBy(value.length);
7563
7567
  }
7564
7568
  if (result.length) {
7565
7569
  const value = result;
@@ -7621,7 +7625,10 @@ class TokenizingChars {
7621
7625
  return this.text.substring(this.currentIndex);
7622
7626
  }
7623
7627
  currentStartsWith(str) {
7624
- for (let j = 0; j < str.length; j++) {
7628
+ if (this.current !== str[0]) {
7629
+ return false;
7630
+ }
7631
+ for (let j = 1; j < str.length; j++) {
7625
7632
  if (this.text[this.currentIndex + j] !== str[j]) {
7626
7633
  return false;
7627
7634
  }
@@ -8653,7 +8660,7 @@ class BarChart extends AbstractChart {
8653
8660
  return undefined;
8654
8661
  const dataSets = this.dataSets
8655
8662
  .map((ds) => toExcelDataset(this.getters, ds))
8656
- .filter((ds) => ds.range !== ""); // && range !== CellErrorType.InvalidReference ? show incorrect #ref ?
8663
+ .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
8657
8664
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
8658
8665
  return {
8659
8666
  ...this.getDefinition(),
@@ -9231,7 +9238,7 @@ class LineChart extends AbstractChart {
9231
9238
  return undefined;
9232
9239
  const dataSets = this.dataSets
9233
9240
  .map((ds) => toExcelDataset(this.getters, ds))
9234
- .filter((ds) => ds.range !== ""); // && range !== CellErrorType.InvalidReference ? show incorrect #ref ?
9241
+ .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
9235
9242
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
9236
9243
  return {
9237
9244
  ...this.getDefinition(),
@@ -9537,7 +9544,7 @@ class PieChart extends AbstractChart {
9537
9544
  return undefined;
9538
9545
  const dataSets = this.dataSets
9539
9546
  .map((ds) => toExcelDataset(this.getters, ds))
9540
- .filter((ds) => ds.range !== ""); // && range !== CellErrorType.InvalidReference ? show incorrect #ref ?
9547
+ .filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
9541
9548
  const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
9542
9549
  return {
9543
9550
  ...this.getDefinition(),
@@ -18684,6 +18691,9 @@ const HLOOKUP = {
18684
18691
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18685
18692
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18686
18693
  assert(() => 1 <= _index && _index <= range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18694
+ if (searchKey && isEvaluationError(searchKey.value)) {
18695
+ return searchKey;
18696
+ }
18687
18697
  const getValueFromRange = (range, index) => range[index][0].value;
18688
18698
  const _isSorted = toBoolean(isSorted.value);
18689
18699
  const colIndex = _isSorted
@@ -18851,6 +18861,9 @@ const VLOOKUP = {
18851
18861
  compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
18852
18862
  const _index = Math.trunc(toNumber(index?.value, this.locale));
18853
18863
  assert(() => 1 <= _index && _index <= range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
18864
+ if (searchKey && isEvaluationError(searchKey.value)) {
18865
+ return searchKey;
18866
+ }
18854
18867
  const getValueFromRange = (range, index) => range[0][index].value;
18855
18868
  const _isSorted = toBoolean(isSorted.value);
18856
18869
  const rowIndex = _isSorted
@@ -18890,6 +18903,9 @@ const XLOOKUP = {
18890
18903
  assert(() => lookupDirection === "col"
18891
18904
  ? returnRange[0].length === lookupRange[0].length
18892
18905
  : returnRange.length === lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
18906
+ if (searchKey && isEvaluationError(searchKey.value)) {
18907
+ return [[searchKey]];
18908
+ }
18893
18909
  const getElement = lookupDirection === "col"
18894
18910
  ? (range, index) => range[0][index].value
18895
18911
  : (range, index) => range[index][0].value;
@@ -26971,15 +26987,17 @@ class Composer extends owl.Component {
26971
26987
  focus: {
26972
26988
  validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
26973
26989
  },
26974
- onComposerContentFocused: Function,
26975
26990
  inputStyle: { type: String, optional: true },
26976
26991
  rect: { type: Object, optional: true },
26977
26992
  delimitation: { type: Object, optional: true },
26978
- onComposerUnmounted: { type: Function, optional: true },
26993
+ onComposerCellFocused: { type: Function, optional: true },
26994
+ onComposerContentFocused: Function,
26995
+ isDefaultFocus: { type: Boolean, optional: true },
26979
26996
  };
26980
26997
  static components = { TextValueProvider, FunctionDescriptionProvider };
26981
26998
  static defaultProps = {
26982
26999
  inputStyle: "",
27000
+ isDefaultFocus: false,
26983
27001
  };
26984
27002
  composerRef = owl.useRef("o_composer");
26985
27003
  contentHelper = new ContentEditableHelper(this.composerRef.el);
@@ -27036,7 +27054,6 @@ class Composer extends owl.Component {
27036
27054
  F4: this.processF4Key,
27037
27055
  Tab: (ev) => this.processTabKey(ev, "right"),
27038
27056
  "Shift+Tab": (ev) => this.processTabKey(ev, "left"),
27039
- "Ctrl+ ": this.processSpaceKey,
27040
27057
  };
27041
27058
  keyCodeMapping = {
27042
27059
  NumpadDecimal: this.processNumpadDecimal,
@@ -27044,12 +27061,12 @@ class Composer extends owl.Component {
27044
27061
  setup() {
27045
27062
  owl.onMounted(() => {
27046
27063
  const el = this.composerRef.el;
27064
+ if (this.props.isDefaultFocus) {
27065
+ this.env.focusableElement.setFocusableElement(el);
27066
+ }
27047
27067
  this.contentHelper.updateEl(el);
27048
27068
  this.processTokenAtCursor();
27049
27069
  });
27050
- owl.onWillUnmount(() => {
27051
- this.props.onComposerUnmounted?.();
27052
- });
27053
27070
  owl.useEffect(() => {
27054
27071
  this.processContent();
27055
27072
  });
@@ -27058,7 +27075,8 @@ class Composer extends owl.Component {
27058
27075
  // Handlers
27059
27076
  // ---------------------------------------------------------------------------
27060
27077
  processArrowKeys(ev) {
27061
- if (this.env.model.getters.isSelectingForComposer()) {
27078
+ if (this.env.model.getters.isSelectingForComposer() ||
27079
+ this.env.model.getters.getEditionMode() === "inactive") {
27062
27080
  this.functionDescriptionState.showDescription = false;
27063
27081
  // Prevent the default content editable behavior which moves the cursor
27064
27082
  ev.preventDefault();
@@ -27101,23 +27119,19 @@ class Composer extends owl.Component {
27101
27119
  processTabKey(ev, direction) {
27102
27120
  ev.preventDefault();
27103
27121
  ev.stopPropagation();
27104
- const state = this.autoCompleteState;
27105
- if (state.showProvider && state.selectedIndex !== undefined) {
27106
- const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
27107
- if (autoCompleteValue) {
27108
- this.autoComplete(autoCompleteValue);
27109
- return;
27122
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
27123
+ const state = this.autoCompleteState;
27124
+ if (state.showProvider && state.selectedIndex !== undefined) {
27125
+ const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
27126
+ if (autoCompleteValue) {
27127
+ this.autoComplete(autoCompleteValue);
27128
+ return;
27129
+ }
27110
27130
  }
27131
+ interactiveStopEdition(this.env);
27111
27132
  }
27112
- interactiveStopEdition(this.env);
27113
27133
  this.env.model.selection.moveAnchorCell(direction, 1);
27114
27134
  }
27115
- processSpaceKey(ev) {
27116
- ev.preventDefault();
27117
- ev.stopPropagation();
27118
- this.showFunctionAutocomplete("");
27119
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
27120
- }
27121
27135
  processEnterKey(ev, direction) {
27122
27136
  ev.preventDefault();
27123
27137
  ev.stopPropagation();
@@ -27179,6 +27193,9 @@ class Composer extends owl.Component {
27179
27193
  this.compositionActive = false;
27180
27194
  }
27181
27195
  onKeydown(ev) {
27196
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27197
+ return;
27198
+ }
27182
27199
  if (ev.key.startsWith("Arrow")) {
27183
27200
  this.processArrowKeys(ev);
27184
27201
  return;
@@ -27192,14 +27209,33 @@ class Composer extends owl.Component {
27192
27209
  ev.stopPropagation();
27193
27210
  }
27194
27211
  }
27212
+ onPaste(ev) {
27213
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
27214
+ ev.stopPropagation();
27215
+ }
27216
+ }
27195
27217
  /*
27196
27218
  * Triggered automatically by the content-editable between the keydown and key up
27197
27219
  * */
27198
27220
  onInput(ev) {
27199
- if (this.props.focus === "inactive" || !this.shouldProcessInputEvents) {
27221
+ if (!this.shouldProcessInputEvents) {
27222
+ return;
27223
+ }
27224
+ if (ev.inputType === "insertFromPaste" &&
27225
+ this.env.model.getters.getEditionMode() === "inactive") {
27200
27226
  return;
27201
27227
  }
27202
- let content = this.contentHelper.getText();
27228
+ ev.stopPropagation();
27229
+ let content;
27230
+ if (this.env.model.getters.getEditionMode() === "inactive") {
27231
+ content = ev.data || "";
27232
+ }
27233
+ else {
27234
+ content = this.contentHelper.getText();
27235
+ }
27236
+ if (this.props.focus === "inactive") {
27237
+ return this.props.onComposerCellFocused?.(content);
27238
+ }
27203
27239
  let selection = this.contentHelper.getCurrentSelection();
27204
27240
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
27205
27241
  this.env.model.dispatch("SET_CURRENT_CONTENT", {
@@ -27275,9 +27311,8 @@ class Composer extends owl.Component {
27275
27311
  }
27276
27312
  const newSelection = this.contentHelper.getCurrentSelection();
27277
27313
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
27278
- if (this.props.focus === "inactive") {
27279
- this.props.onComposerContentFocused(newSelection);
27280
- }
27314
+ this.props.onComposerContentFocused();
27315
+ if (this.props.focus === "inactive") ;
27281
27316
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
27282
27317
  this.processTokenAtCursor();
27283
27318
  }
@@ -27444,7 +27479,7 @@ class Composer extends owl.Component {
27444
27479
  const highlights = this.env.model.getters.getHighlights();
27445
27480
  const refSheet = sheetName
27446
27481
  ? this.env.model.getters.getSheetIdByName(sheetName)
27447
- : this.env.model.getters.getCurrentEditedCell().sheetId;
27482
+ : this.env.model.getters.getCurrentEditedCell()?.sheetId;
27448
27483
  const highlight = highlights.find((highlight) => {
27449
27484
  if (highlight.sheetId !== refSheet)
27450
27485
  return false;
@@ -27571,56 +27606,30 @@ class GridComposer extends owl.Component {
27571
27606
  focus: {
27572
27607
  validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
27573
27608
  },
27574
- onComposerUnmounted: Function,
27609
+ onComposerCellFocused: Function,
27575
27610
  onComposerContentFocused: Function,
27576
27611
  gridDims: Object,
27577
27612
  };
27578
27613
  static components = { Composer };
27579
- gridComposerRef;
27580
- zone;
27581
- rect;
27614
+ rect = this.defaultRect;
27615
+ isEditing = false;
27582
27616
  isCellReferenceVisible;
27583
- composerState;
27617
+ get defaultRect() {
27618
+ return { x: 0, y: 0, width: 0, height: 0 };
27619
+ }
27584
27620
  setup() {
27585
- this.gridComposerRef = owl.useRef("gridComposer");
27586
- this.composerState = owl.useState({
27587
- rect: undefined,
27588
- delimitation: undefined,
27589
- });
27590
- const { sheetId, col, row } = this.env.model.getters.getActivePosition();
27591
- this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
27592
- this.rect = this.env.model.getters.getVisibleRect(this.zone);
27593
- this.isCellReferenceVisible = false;
27594
- owl.onMounted(() => {
27595
- const el = this.gridComposerRef.el;
27596
- this.composerState.rect = {
27597
- x: this.rect.x,
27598
- y: this.rect.y,
27599
- width: el.clientWidth,
27600
- height: el.clientHeight,
27601
- };
27602
- this.composerState.delimitation = {
27603
- width: this.props.gridDims.width,
27604
- height: this.props.gridDims.height,
27605
- };
27606
- });
27607
27621
  owl.onWillUpdateProps(() => {
27608
- if (this.isCellReferenceVisible) {
27609
- return;
27610
- }
27611
- const sheetId = this.env.model.getters.getActiveSheetId();
27612
- const zone = this.env.model.getters.getSelectedZone();
27613
- const rect = this.env.model.getters.getVisibleRect(zone);
27614
- if (!deepEquals(rect, this.rect) ||
27615
- sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
27616
- this.isCellReferenceVisible = true;
27617
- }
27622
+ this.updateComponentPosition();
27623
+ this.updateCellReferenceVisibility();
27618
27624
  });
27619
27625
  }
27620
27626
  get shouldDisplayCellReference() {
27621
27627
  return this.isCellReferenceVisible;
27622
27628
  }
27623
27629
  get cellReference() {
27630
+ if (!this.env.model.getters.getCurrentEditedCell()) {
27631
+ return "";
27632
+ }
27624
27633
  const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
27625
27634
  const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
27626
27635
  return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
@@ -27632,7 +27641,27 @@ class GridComposer extends owl.Component {
27632
27641
  top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
27633
27642
  });
27634
27643
  }
27644
+ get composerProps() {
27645
+ const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
27646
+ return {
27647
+ rect: { ...this.rect },
27648
+ delimitation: {
27649
+ width,
27650
+ height,
27651
+ },
27652
+ focus: this.props.focus,
27653
+ isDefaultFocus: true,
27654
+ onComposerContentFocused: this.props.onComposerContentFocused,
27655
+ onComposerCellFocused: this.props.onComposerCellFocused,
27656
+ };
27657
+ }
27635
27658
  get containerStyle() {
27659
+ if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
27660
+ return `
27661
+ position: absolute;
27662
+ z-index: -1000;
27663
+ `;
27664
+ }
27636
27665
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
27637
27666
  const cell = this.env.model.getters.getActiveCell();
27638
27667
  const position = this.env.model.getters.getActivePosition();
@@ -27652,6 +27681,8 @@ class GridComposer extends owl.Component {
27652
27681
  if (!isFormula) {
27653
27682
  textAlign = style.align || cell.defaultAlign;
27654
27683
  }
27684
+ const maxHeight = this.props.gridDims.height - this.rect.y;
27685
+ const maxWidth = this.props.gridDims.width - this.rect.x;
27655
27686
  /**
27656
27687
  * min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
27657
27688
  * including all the paddings/margins of the composer
@@ -27663,6 +27694,8 @@ class GridComposer extends owl.Component {
27663
27694
  top: `${top}px`,
27664
27695
  "min-width": `${width + 1}px`,
27665
27696
  "min-height": `${height + 1}px`,
27697
+ "max-width": `${maxWidth}px`,
27698
+ "max-height": `${maxHeight}px`,
27666
27699
  background,
27667
27700
  color,
27668
27701
  "font-size": `${fontSizeInPixels(fontSize)}px`,
@@ -27672,13 +27705,31 @@ class GridComposer extends owl.Component {
27672
27705
  "text-align": textAlign,
27673
27706
  });
27674
27707
  }
27675
- get composerStyle() {
27676
- const maxHeight = this.props.gridDims.height - this.rect.y;
27677
- const maxWidth = this.props.gridDims.width - this.rect.x;
27678
- return cssPropertiesToCss({
27679
- "max-width": `${maxWidth}px`,
27680
- "max-height": `${maxHeight}px`,
27681
- });
27708
+ updateComponentPosition() {
27709
+ const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
27710
+ if (this.isEditing !== isEditing) {
27711
+ this.isEditing = isEditing;
27712
+ if (!isEditing) {
27713
+ this.rect = this.defaultRect;
27714
+ this.env.focusableElement.focus();
27715
+ return;
27716
+ }
27717
+ const position = this.env.model.getters.getActivePosition();
27718
+ const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
27719
+ this.rect = this.env.model.getters.getVisibleRect(zone);
27720
+ }
27721
+ }
27722
+ updateCellReferenceVisibility() {
27723
+ if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
27724
+ return;
27725
+ }
27726
+ const sheetId = this.env.model.getters.getActiveSheetId();
27727
+ const zone = this.env.model.getters.getSelectedZone();
27728
+ const rect = this.env.model.getters.getVisibleRect(zone);
27729
+ if (!deepEquals(rect, this.rect) ||
27730
+ sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
27731
+ this.isCellReferenceVisible = true;
27732
+ }
27682
27733
  }
27683
27734
  }
27684
27735
 
@@ -28778,7 +28829,6 @@ class GridOverlay extends owl.Component {
28778
28829
  this.props.onCellDoubleClicked(col, row);
28779
28830
  }
28780
28831
  onContextMenu(ev) {
28781
- ev.preventDefault();
28782
28832
  const [col, row] = this.getCartesianCoordinates(ev);
28783
28833
  this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
28784
28834
  }
@@ -29843,7 +29893,6 @@ class Grid extends owl.Component {
29843
29893
  HEADER_WIDTH = HEADER_WIDTH;
29844
29894
  menuState;
29845
29895
  gridRef;
29846
- hiddenInput;
29847
29896
  onMouseWheel;
29848
29897
  canvasPosition;
29849
29898
  hoveredCell;
@@ -29854,15 +29903,14 @@ class Grid extends owl.Component {
29854
29903
  menuItems: [],
29855
29904
  });
29856
29905
  this.gridRef = owl.useRef("grid");
29857
- this.hiddenInput = owl.useRef("hiddenInput");
29858
29906
  this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
29859
29907
  this.hoveredCell = owl.useState({ col: undefined, row: undefined });
29860
29908
  owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
29861
29909
  owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
29862
29910
  owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
29863
29911
  owl.useExternalListener(document.body, "paste", this.paste);
29864
- owl.onMounted(() => this.focus());
29865
- this.props.exposeFocus(() => this.focus());
29912
+ owl.onMounted(() => this.focusDefaultElement());
29913
+ this.props.exposeFocus(() => this.focusDefaultElement());
29866
29914
  useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
29867
29915
  this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
29868
29916
  this.moveCanvas(deltaX, deltaY);
@@ -29886,7 +29934,7 @@ class Grid extends owl.Component {
29886
29934
  if (this.env.model.getters.hasOpenedPopover()) {
29887
29935
  this.closeOpenedPopover();
29888
29936
  }
29889
- this.focus();
29937
+ this.focusDefaultElement();
29890
29938
  }
29891
29939
  // this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
29892
29940
  // down itself
@@ -30065,10 +30113,10 @@ class Grid extends owl.Component {
30065
30113
  "Alt+Shift+ArrowUp": () => this.processHeaderGroupingKey("up"),
30066
30114
  "Alt+Shift+ArrowDown": () => this.processHeaderGroupingKey("down"),
30067
30115
  };
30068
- focus() {
30116
+ focusDefaultElement() {
30069
30117
  if (!this.env.model.getters.getSelectedFigureId() &&
30070
30118
  this.env.model.getters.getEditionMode() === "inactive") {
30071
- this.hiddenInput.el?.focus();
30119
+ this.env.focusableElement.focus();
30072
30120
  }
30073
30121
  }
30074
30122
  get gridEl() {
@@ -30204,19 +30252,6 @@ class Grid extends owl.Component {
30204
30252
  return;
30205
30253
  }
30206
30254
  }
30207
- onInput(ev) {
30208
- // the user meant to paste in the sheet, not open the composer with the pasted content
30209
- if (!ev.isComposing && ev.inputType === "insertFromPaste") {
30210
- return;
30211
- }
30212
- if (ev.data) {
30213
- // if the user types a character on the grid, it means he wants to start composing the selected cell with that
30214
- // character
30215
- ev.preventDefault();
30216
- ev.stopPropagation();
30217
- this.props.onGridComposerCellFocused(ev.data);
30218
- }
30219
- }
30220
30255
  // ---------------------------------------------------------------------------
30221
30256
  // Context Menu
30222
30257
  // ---------------------------------------------------------------------------
@@ -30331,7 +30366,7 @@ class Grid extends owl.Component {
30331
30366
  }
30332
30367
  closeMenu() {
30333
30368
  this.menuState.isOpen = false;
30334
- this.focus();
30369
+ this.focusDefaultElement();
30335
30370
  }
30336
30371
  processHeaderGroupingKey(direction) {
30337
30372
  if (this.env.model.getters.getSelectedZones().length !== 1) {
@@ -34248,6 +34283,31 @@ const MIGRATIONS = [
34248
34283
  return data;
34249
34284
  },
34250
34285
  },
34286
+ {
34287
+ description: "Fix datafilter duplication",
34288
+ from: 12,
34289
+ to: 12.5,
34290
+ applyMigration(data) {
34291
+ for (let sheet of data.sheets || []) {
34292
+ let knownDataFilterZones = [];
34293
+ for (let filterTable of sheet.filterTables || []) {
34294
+ const zone = toZone(filterTable.range);
34295
+ // See commit message for the details
34296
+ const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
34297
+ if (intersectZoneIndex !== -1) {
34298
+ knownDataFilterZones[intersectZoneIndex] = zone;
34299
+ }
34300
+ else {
34301
+ knownDataFilterZones.push(zone);
34302
+ }
34303
+ }
34304
+ sheet.filterTables = knownDataFilterZones.map((zone) => ({
34305
+ range: zoneToXc(zone),
34306
+ }));
34307
+ }
34308
+ return data;
34309
+ },
34310
+ },
34251
34311
  {
34252
34312
  description: "Change Border description structure",
34253
34313
  from: 12,
@@ -36034,9 +36094,6 @@ class CellPlugin extends CorePlugin {
36034
36094
  format: cell.format ? getItemId(cell.format, formats) : undefined,
36035
36095
  content: cell.content || undefined,
36036
36096
  };
36037
- if (cell instanceof FormulaCellWithDependencies) {
36038
- cells[xc].content = cell.contentWithFixedReferences || undefined;
36039
- }
36040
36097
  }
36041
36098
  _sheet.cells = cells;
36042
36099
  }
@@ -36288,8 +36345,11 @@ class CellPlugin extends CorePlugin {
36288
36345
  * being a computed property to rebuild the dependencies XC.
36289
36346
  */
36290
36347
  createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
36291
- const dependencies = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
36292
- return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString.bind(this));
36348
+ const dependencies = [];
36349
+ for (const xc of compiledFormula.dependencies) {
36350
+ dependencies.push(this.getters.getRangeFromSheetXC(sheetId, xc));
36351
+ }
36352
+ return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString);
36293
36353
  }
36294
36354
  createErrorFormula(id, content, format, style, error) {
36295
36355
  return {
@@ -36343,7 +36403,7 @@ class FormulaCellWithDependencies {
36343
36403
  const tokens = compiledFormula.tokens.map((token) => {
36344
36404
  if (token.type === "REFERENCE") {
36345
36405
  const index = rangeIndex++;
36346
- return new RangeReferenceToken(() => this.getRangeString(dependencies[index], this.sheetId));
36406
+ return new RangeReferenceToken(dependencies, index, this.sheetId, this.getRangeString);
36347
36407
  }
36348
36408
  return token;
36349
36409
  });
@@ -36370,13 +36430,20 @@ class FormulaCellWithDependencies {
36370
36430
  }
36371
36431
  }
36372
36432
  class RangeReferenceToken {
36373
- getValue;
36433
+ ranges;
36434
+ rangeIndex;
36435
+ sheetId;
36436
+ getRangeString;
36374
36437
  type = "REFERENCE";
36375
- constructor(getValue) {
36376
- this.getValue = getValue;
36438
+ constructor(ranges, rangeIndex, sheetId, getRangeString) {
36439
+ this.ranges = ranges;
36440
+ this.rangeIndex = rangeIndex;
36441
+ this.sheetId = sheetId;
36442
+ this.getRangeString = getRangeString;
36377
36443
  }
36378
36444
  get value() {
36379
- return this.getValue();
36445
+ const range = this.ranges[this.rangeIndex];
36446
+ return this.getRangeString(range, this.sheetId);
36380
36447
  }
36381
36448
  }
36382
36449
 
@@ -41911,7 +41978,13 @@ class EvaluationPlugin extends UIPlugin {
41911
41978
  const format = newFormat
41912
41979
  ? getItemId(newFormat, data.formats)
41913
41980
  : exportedCellData.format;
41914
- const content = !isExported ? newContent : exportedCellData.content;
41981
+ let content;
41982
+ if (formulaCell instanceof FormulaCellWithDependencies) {
41983
+ content = formulaCell.contentWithFixedReferences;
41984
+ }
41985
+ else {
41986
+ content = !isExported ? newContent : exportedCellData.content;
41987
+ }
41915
41988
  exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
41916
41989
  }
41917
41990
  }
@@ -51095,6 +51168,16 @@ class ImageProvider {
51095
51168
  }
51096
51169
  }
51097
51170
 
51171
+ class FocusableElement {
51172
+ focusableElement = undefined;
51173
+ setFocusableElement(element) {
51174
+ this.focusableElement = element;
51175
+ }
51176
+ focus() {
51177
+ this.focusableElement?.focus();
51178
+ }
51179
+ }
51180
+
51098
51181
  const RIPPLE_KEY_FRAMES = [
51099
51182
  { transform: "scale(0)" },
51100
51183
  { transform: "scale(0.8)", offset: 0.33 },
@@ -53249,6 +53332,7 @@ class Spreadsheet extends owl.Component {
53249
53332
  toggleSidePanel: this.toggleSidePanel.bind(this),
53250
53333
  clipboard: this.env.clipboard || instantiateClipboard(),
53251
53334
  startCellEdition: (content) => this.onGridComposerCellFocused(content),
53335
+ focusableElement: new FocusableElement(),
53252
53336
  });
53253
53337
  owl.useEffect(() => {
53254
53338
  /**
@@ -53367,16 +53451,17 @@ class Spreadsheet extends owl.Component {
53367
53451
  }
53368
53452
  this.composer.topBarFocus = "contentFocus";
53369
53453
  this.composer.gridFocusMode = "inactive";
53370
- this.setComposerContent({ selection } || {});
53454
+ this.setComposerContent({ selection });
53371
53455
  }
53372
- onGridComposerContentFocused() {
53456
+ onGridComposerContentFocused(selection) {
53373
53457
  if (this.model.getters.isReadonly()) {
53374
53458
  return;
53375
53459
  }
53376
53460
  this.composer.topBarFocus = "inactive";
53377
53461
  this.composer.gridFocusMode = "contentFocus";
53378
- this.setComposerContent({});
53462
+ this.setComposerContent({ selection });
53379
53463
  }
53464
+ // TODO: either both are defined or none of them. change those args to an object
53380
53465
  onGridComposerCellFocused(content, selection) {
53381
53466
  if (this.model.getters.isReadonly()) {
53382
53467
  return;
@@ -57100,6 +57185,6 @@ exports.setTranslationMethod = setTranslationMethod;
57100
57185
  exports.tokenize = tokenize;
57101
57186
 
57102
57187
 
57103
- __info__.version = "17.1.3";
57104
- __info__.date = "2024-02-02T13:46:54.332Z";
57105
- __info__.hash = "798f979";
57188
+ __info__.version = "17.1.4";
57189
+ __info__.date = "2024-02-09T13:09:13.430Z";
57190
+ __info__.hash = "16d3ece";