@odoo/o-spreadsheet 16.0.31 → 16.0.32

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.
@@ -207,7 +207,7 @@ const TOPBAR_HEIGHT = 63;
207
207
  const BOTTOMBAR_HEIGHT = 36;
208
208
  const DEFAULT_CELL_WIDTH = 96;
209
209
  const DEFAULT_CELL_HEIGHT = 23;
210
- const SCROLLBAR_WIDTH$1 = 15;
210
+ const SCROLLBAR_WIDTH = 15;
211
211
  const AUTOFILL_EDGE_LENGTH = 8;
212
212
  const ICON_EDGE_LENGTH = 18;
213
213
  const UNHIDE_ICON_EDGE_LENGTH = 14;
@@ -4078,7 +4078,7 @@ class Popover extends owl.Component {
4078
4078
  this.spreadsheetPosition = useSpreadsheetPosition();
4079
4079
  }
4080
4080
  get maxHeight() {
4081
- return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
4081
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH);
4082
4082
  }
4083
4083
  get style() {
4084
4084
  // the props's position is expressed relative to the "body" element
@@ -19524,9 +19524,6 @@ class EditionPlugin extends UIPlugin {
19524
19524
  break;
19525
19525
  }
19526
19526
  }
19527
- unsubscribe() {
19528
- this.mode = "inactive";
19529
- }
19530
19527
  // ---------------------------------------------------------------------------
19531
19528
  // Getters
19532
19529
  // ---------------------------------------------------------------------------
@@ -20427,13 +20424,12 @@ class Composer extends owl.Component {
20427
20424
  setup() {
20428
20425
  owl.onMounted(() => {
20429
20426
  const el = this.composerRef.el;
20427
+ if (this.props.isDefaultFocus) {
20428
+ this.env.focusableElement.setFocusableElement(el);
20429
+ }
20430
20430
  this.contentHelper.updateEl(el);
20431
20431
  this.processContent();
20432
20432
  });
20433
- owl.onWillUnmount(() => {
20434
- var _a, _b;
20435
- (_b = (_a = this.props).onComposerUnmounted) === null || _b === void 0 ? void 0 : _b.call(_a);
20436
- });
20437
20433
  owl.onPatched(() => {
20438
20434
  if (!this.isKeyStillDown) {
20439
20435
  this.processContent();
@@ -20444,7 +20440,8 @@ class Composer extends owl.Component {
20444
20440
  // Handlers
20445
20441
  // ---------------------------------------------------------------------------
20446
20442
  processArrowKeys(ev) {
20447
- if (this.env.model.getters.isSelectingForComposer()) {
20443
+ if (this.env.model.getters.isSelectingForComposer() ||
20444
+ this.env.model.getters.getEditionMode() === "inactive") {
20448
20445
  this.functionDescriptionState.showDescription = false;
20449
20446
  // Prevent the default content editable behavior which moves the cursor
20450
20447
  // but don't stop the event and let it bubble to the grid which will
@@ -20477,21 +20474,23 @@ class Composer extends owl.Component {
20477
20474
  processTabKey(ev) {
20478
20475
  ev.preventDefault();
20479
20476
  ev.stopPropagation();
20480
- if (this.autoCompleteState.showProvider && this.autocompleteAPI) {
20481
- const autoCompleteValue = this.autocompleteAPI.getValueToFill();
20482
- if (autoCompleteValue) {
20483
- this.autoComplete(autoCompleteValue);
20484
- return;
20477
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
20478
+ if (this.autoCompleteState.showProvider && this.autocompleteAPI) {
20479
+ const autoCompleteValue = this.autocompleteAPI.getValueToFill();
20480
+ if (autoCompleteValue) {
20481
+ this.autoComplete(autoCompleteValue);
20482
+ return;
20483
+ }
20485
20484
  }
20486
- }
20487
- else {
20488
- // when completing with tab, if there is no value to complete, the active cell will be moved to the right.
20489
- // we can't let the model think that it is for a ref selection.
20490
- // todo: check if this can be removed someday
20491
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20485
+ else {
20486
+ // when completing with tab, if there is no value to complete, the active cell will be moved to the right.
20487
+ // we can't let the model think that it is for a ref selection.
20488
+ // todo: check if this can be removed someday
20489
+ this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20490
+ }
20491
+ this.env.model.dispatch("STOP_EDITION");
20492
20492
  }
20493
20493
  const direction = ev.shiftKey ? "left" : "right";
20494
- this.env.model.dispatch("STOP_EDITION");
20495
20494
  this.env.model.selection.moveAnchorCell(direction, 1);
20496
20495
  }
20497
20496
  processEnterKey(ev) {
@@ -20523,6 +20522,9 @@ class Composer extends owl.Component {
20523
20522
  this.compositionActive = false;
20524
20523
  }
20525
20524
  onKeydown(ev) {
20525
+ if (this.env.model.getters.getEditionMode() === "inactive") {
20526
+ return;
20527
+ }
20526
20528
  let handler = this.keyMapping[ev.key];
20527
20529
  if (handler) {
20528
20530
  handler.call(this, ev);
@@ -20533,23 +20535,46 @@ class Composer extends owl.Component {
20533
20535
  }
20534
20536
  }
20535
20537
  updateCursorIfNeeded() {
20536
- if (!this.env.model.getters.isSelectingForComposer()) {
20538
+ const moveCursor = !this.env.model.getters.isSelectingForComposer() &&
20539
+ !(this.env.model.getters.getEditionMode() === "inactive");
20540
+ if (moveCursor) {
20537
20541
  const { start, end } = this.contentHelper.getCurrentSelection();
20538
20542
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20539
20543
  this.isKeyStillDown = true;
20540
20544
  }
20541
20545
  }
20546
+ onPaste(ev) {
20547
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
20548
+ ev.stopPropagation();
20549
+ }
20550
+ }
20542
20551
  /*
20543
20552
  * Triggered automatically by the content-editable between the keydown and key up
20544
20553
  * */
20545
- onInput() {
20546
- if (this.props.focus === "inactive" || !this.shouldProcessInputEvents) {
20554
+ onInput(ev) {
20555
+ var _a, _b;
20556
+ if (!this.shouldProcessInputEvents) {
20547
20557
  return;
20548
20558
  }
20559
+ if (ev.inputType === "insertFromPaste" &&
20560
+ this.env.model.getters.getEditionMode() === "inactive") {
20561
+ return;
20562
+ }
20563
+ ev.stopPropagation();
20564
+ let content;
20565
+ if (this.env.model.getters.getEditionMode() === "inactive") {
20566
+ content = ev.data || "";
20567
+ }
20568
+ else {
20569
+ const el = this.composerRef.el;
20570
+ content = el.childNodes.length ? el.textContent : "";
20571
+ }
20572
+ if (this.props.focus === "inactive") {
20573
+ return (_b = (_a = this.props).onComposerCellFocused) === null || _b === void 0 ? void 0 : _b.call(_a, content);
20574
+ }
20549
20575
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20550
- const el = this.composerRef.el;
20551
20576
  this.env.model.dispatch("SET_CURRENT_CONTENT", {
20552
- content: el.childNodes.length ? el.textContent : "",
20577
+ content,
20553
20578
  selection: this.contentHelper.getCurrentSelection(),
20554
20579
  });
20555
20580
  }
@@ -20596,9 +20621,8 @@ class Composer extends owl.Component {
20596
20621
  }
20597
20622
  const newSelection = this.contentHelper.getCurrentSelection();
20598
20623
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20599
- if (this.props.focus === "inactive") {
20600
- this.props.onComposerContentFocused(newSelection);
20601
- }
20624
+ this.props.onComposerContentFocused();
20625
+ if (this.props.focus === "inactive") ;
20602
20626
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
20603
20627
  this.processTokenAtCursor();
20604
20628
  }
@@ -20618,6 +20642,7 @@ class Composer extends owl.Component {
20618
20642
  this.contentHelper.removeAll(); // removes the content of the composer, to be added just after
20619
20643
  this.shouldProcessInputEvents = false;
20620
20644
  if (this.props.focus !== "inactive") {
20645
+ this.contentHelper.el.focus();
20621
20646
  this.contentHelper.selectRange(0, 0); // move the cursor inside the composer at 0 0.
20622
20647
  }
20623
20648
  const content = this.getContent();
@@ -20786,10 +20811,9 @@ Composer.components = { TextValueProvider, FunctionDescriptionProvider };
20786
20811
  Composer.defaultProps = {
20787
20812
  inputStyle: "",
20788
20813
  focus: "inactive",
20814
+ isDefaultFocus: false,
20789
20815
  };
20790
20816
 
20791
- const SCROLLBAR_WIDTH = 14;
20792
- const SCROLLBAR_HIGHT = 15;
20793
20817
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20794
20818
  css /* scss */ `
20795
20819
  div.o-grid-composer {
@@ -20804,40 +20828,52 @@ css /* scss */ `
20804
20828
  * It also applies the style of the cell to the composer input.
20805
20829
  */
20806
20830
  class GridComposer extends owl.Component {
20831
+ constructor() {
20832
+ super(...arguments);
20833
+ this.rect = undefined;
20834
+ this.isEditing = false;
20835
+ }
20836
+ get defaultRect() {
20837
+ return { x: 0, y: 0, width: 0, height: 0 };
20838
+ }
20807
20839
  setup() {
20808
- this.gridComposerRef = owl.useRef("gridComposer");
20809
- this.composerState = owl.useState({
20810
- rect: null,
20811
- delimitation: null,
20812
- });
20813
- const { col, row } = this.env.model.getters.getPosition();
20814
- this.zone = this.env.model.getters.expandZone(this.env.model.getters.getActiveSheetId(), {
20815
- left: col,
20816
- right: col,
20817
- top: row,
20818
- bottom: row,
20819
- });
20820
- this.rect = this.env.model.getters.getVisibleRect(this.zone);
20821
- owl.onMounted(() => {
20822
- const el = this.gridComposerRef.el;
20823
- //TODO Should be more correct to have a props that give the parent's clientHeight and clientWidth
20824
- const maxHeight = el.parentElement.clientHeight - this.rect.y - SCROLLBAR_HIGHT;
20825
- el.style.maxHeight = (maxHeight + "px");
20826
- const maxWidth = el.parentElement.clientWidth - this.rect.x - SCROLLBAR_WIDTH;
20827
- el.style.maxWidth = (maxWidth + "px");
20828
- this.composerState.rect = {
20829
- x: this.rect.x,
20830
- y: this.rect.y,
20831
- width: el.clientWidth,
20832
- height: el.clientHeight,
20833
- };
20834
- this.composerState.delimitation = {
20835
- width: el.parentElement.clientWidth,
20836
- height: el.parentElement.clientHeight,
20837
- };
20840
+ owl.onWillUpdateProps(() => {
20841
+ const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
20842
+ if (this.isEditing !== isEditing) {
20843
+ this.isEditing = isEditing;
20844
+ if (!isEditing) {
20845
+ this.rect = undefined;
20846
+ this.env.focusableElement.focus();
20847
+ return;
20848
+ }
20849
+ const position = this.env.model.getters.getPosition();
20850
+ const zone = this.env.model.getters.expandZone(this.env.model.getters.getActiveSheetId(), positionToZone(position));
20851
+ this.rect = this.env.model.getters.getVisibleRect(zone);
20852
+ }
20838
20853
  });
20839
20854
  }
20855
+ get composerProps() {
20856
+ const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
20857
+ return {
20858
+ rect: this.rect && { ...this.rect },
20859
+ delimitation: {
20860
+ width,
20861
+ height,
20862
+ },
20863
+ inputStyle: this.composerStyle,
20864
+ focus: this.props.focus,
20865
+ isDefaultFocus: true,
20866
+ onComposerContentFocused: this.props.onComposerContentFocused,
20867
+ onComposerCellFocused: this.props.onComposerCellFocused,
20868
+ };
20869
+ }
20840
20870
  get containerStyle() {
20871
+ if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
20872
+ return `
20873
+ position: absolute;
20874
+ z-index: -1000;
20875
+ `;
20876
+ }
20841
20877
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
20842
20878
  const cell = this.env.model.getters.getActiveCell();
20843
20879
  let style = {};
@@ -20860,12 +20896,18 @@ class GridComposer extends owl.Component {
20860
20896
  if (!isFormula) {
20861
20897
  textAlign = style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign) || "left";
20862
20898
  }
20899
+ const sheetDimensions = this.env.model.getters.getSheetViewDimensionWithHeaders();
20900
+ const maxWidth = sheetDimensions.width - this.rect.x;
20901
+ const maxHeight = sheetDimensions.height - this.rect.y;
20863
20902
  return `
20864
20903
  left: ${left - 1}px;
20865
20904
  top: ${top}px;
20866
20905
  min-width: ${width + 2}px;
20867
20906
  min-height: ${height + 1}px;
20868
20907
 
20908
+ max-width: ${maxWidth}px;
20909
+ max-height: ${maxHeight}px;
20910
+
20869
20911
  background: ${background};
20870
20912
  color: ${color};
20871
20913
 
@@ -22502,8 +22544,8 @@ css /* scss */ `
22502
22544
  &.corner {
22503
22545
  right: 0px;
22504
22546
  bottom: 0px;
22505
- height: ${SCROLLBAR_WIDTH$1}px;
22506
- width: ${SCROLLBAR_WIDTH$1}px;
22547
+ height: ${SCROLLBAR_WIDTH}px;
22548
+ width: ${SCROLLBAR_WIDTH}px;
22507
22549
  border-top: 1px solid #e2e3e3;
22508
22550
  border-left: 1px solid #e2e3e3;
22509
22551
  }
@@ -22568,7 +22610,7 @@ class HorizontalScrollBar extends owl.Component {
22568
22610
  return {
22569
22611
  left: `${this.props.position.left + x}px`,
22570
22612
  bottom: "0px",
22571
- height: `${SCROLLBAR_WIDTH$1}px`,
22613
+ height: `${SCROLLBAR_WIDTH}px`,
22572
22614
  right: `0px`,
22573
22615
  };
22574
22616
  }
@@ -22610,7 +22652,7 @@ class VerticalScrollBar extends owl.Component {
22610
22652
  return {
22611
22653
  top: `${this.props.position.top + y}px`,
22612
22654
  right: "0px",
22613
- width: `${SCROLLBAR_WIDTH$1}px`,
22655
+ width: `${SCROLLBAR_WIDTH}px`,
22614
22656
  bottom: `0px`,
22615
22657
  };
22616
22658
  }
@@ -22768,16 +22810,15 @@ class Grid extends owl.Component {
22768
22810
  menuItems: [],
22769
22811
  });
22770
22812
  this.gridRef = owl.useRef("grid");
22771
- this.hiddenInput = owl.useRef("hiddenInput");
22772
22813
  this.canvasPosition = useAbsolutePosition(this.gridRef);
22773
22814
  this.hoveredCell = owl.useState({ col: undefined, row: undefined });
22774
22815
  owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
22775
22816
  owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
22776
22817
  owl.useExternalListener(document.body, "paste", this.paste);
22777
- owl.onMounted(() => this.focus());
22778
- this.props.exposeFocus(() => this.focus());
22818
+ owl.onMounted(() => this.focusDefaultElement());
22819
+ this.props.exposeFocus(() => this.focusDefaultElement());
22779
22820
  useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
22780
- owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
22821
+ owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
22781
22822
  this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
22782
22823
  this.moveCanvas(deltaX, deltaY);
22783
22824
  this.hoveredCell.col = undefined;
@@ -22792,19 +22833,18 @@ class Grid extends owl.Component {
22792
22833
  return `
22793
22834
  top: ${HEADER_HEIGHT}px;
22794
22835
  left: ${HEADER_WIDTH}px;
22795
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH$1}px);
22796
- width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH$1}px);
22836
+ height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
22837
+ width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH}px);
22797
22838
  `;
22798
22839
  }
22799
22840
  onClosePopover() {
22800
22841
  this.closeOpenedPopover();
22801
- this.focus();
22842
+ this.focusDefaultElement();
22802
22843
  }
22803
- focus() {
22804
- var _a;
22844
+ focusDefaultElement() {
22805
22845
  if (!this.env.model.getters.getSelectedFigureId() &&
22806
22846
  this.env.model.getters.getEditionMode() === "inactive") {
22807
- (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
22847
+ this.env.focusableElement.focus();
22808
22848
  }
22809
22849
  }
22810
22850
  get gridEl() {
@@ -22953,19 +22993,6 @@ class Grid extends owl.Component {
22953
22993
  return;
22954
22994
  }
22955
22995
  }
22956
- onInput(ev) {
22957
- // the user meant to paste in the sheet, not open the composer with the pasted content
22958
- if (!ev.isComposing && ev.inputType === "insertFromPaste") {
22959
- return;
22960
- }
22961
- if (ev.data) {
22962
- // if the user types a character on the grid, it means he wants to start composing the selected cell with that
22963
- // character
22964
- ev.preventDefault();
22965
- ev.stopPropagation();
22966
- this.props.onGridComposerCellFocused(ev.data);
22967
- }
22968
- }
22969
22996
  // ---------------------------------------------------------------------------
22970
22997
  // Context Menu
22971
22998
  // ---------------------------------------------------------------------------
@@ -23046,7 +23073,7 @@ class Grid extends owl.Component {
23046
23073
  }
23047
23074
  closeMenu() {
23048
23075
  this.menuState.isOpen = false;
23049
- this.focus();
23076
+ this.focusDefaultElement();
23050
23077
  }
23051
23078
  }
23052
23079
  Grid.template = "o-spreadsheet-Grid";
@@ -26742,7 +26769,7 @@ function normalizeV9(formula) {
26742
26769
  * a breaking change is made in the way the state is handled, and an upgrade
26743
26770
  * function should be defined
26744
26771
  */
26745
- const CURRENT_VERSION = 12;
26772
+ const CURRENT_VERSION = 12.5;
26746
26773
  const INITIAL_SHEET_ID = "Sheet1";
26747
26774
  /**
26748
26775
  * This function tries to load anything that could look like a valid
@@ -27008,6 +27035,31 @@ const MIGRATIONS = [
27008
27035
  return data;
27009
27036
  },
27010
27037
  },
27038
+ {
27039
+ description: "Fix datafilter duplication",
27040
+ from: 12,
27041
+ to: 12.5,
27042
+ applyMigration(data) {
27043
+ for (let sheet of data.sheets || []) {
27044
+ let knownDataFilterZones = [];
27045
+ for (let filterTable of sheet.filterTables || []) {
27046
+ const zone = toZone(filterTable.range);
27047
+ // See commit message for the details
27048
+ const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
27049
+ if (intersectZoneIndex !== -1) {
27050
+ knownDataFilterZones[intersectZoneIndex] = zone;
27051
+ }
27052
+ else {
27053
+ knownDataFilterZones.push(zone);
27054
+ }
27055
+ }
27056
+ sheet.filterTables = knownDataFilterZones.map((zone) => ({
27057
+ range: zoneToXc(zone),
27058
+ }));
27059
+ }
27060
+ return data;
27061
+ },
27062
+ },
27011
27063
  ];
27012
27064
  /**
27013
27065
  * This function is used to repair faulty data independently of the migration.
@@ -27903,9 +27955,6 @@ class CellPlugin extends CorePlugin {
27903
27955
  format: cell.format ? getItemId(cell.format, formats) : undefined,
27904
27956
  content: cell.content || undefined,
27905
27957
  };
27906
- if (cell.isFormula()) {
27907
- cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
27908
- }
27909
27958
  }
27910
27959
  _sheet.cells = cells;
27911
27960
  }
@@ -27928,6 +27977,9 @@ class CellPlugin extends CorePlugin {
27928
27977
  const exportedCellData = sheet.cells[xc];
27929
27978
  exportedCellData.value = cell.evaluated.value;
27930
27979
  exportedCellData.isFormula = cell.isFormula();
27980
+ if (cell.isFormula()) {
27981
+ exportedCellData.content = this.buildFormulaContent(sheet.id, cell, cell.dependencies, true);
27982
+ }
27931
27983
  if (cell.format !== cell.evaluated.format) {
27932
27984
  exportedCellData.computedFormat = cell.evaluated.format;
27933
27985
  }
@@ -35370,9 +35422,6 @@ class SelectionInputPlugin extends UIPlugin {
35370
35422
  }
35371
35423
  }
35372
35424
  }
35373
- unsubscribe() {
35374
- this.unfocus();
35375
- }
35376
35425
  // ---------------------------------------------------------------------------
35377
35426
  // Getters || only callable by the parent
35378
35427
  // ---------------------------------------------------------------------------
@@ -35584,9 +35633,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
35584
35633
  }
35585
35634
  (_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.handle(cmd);
35586
35635
  }
35587
- unsubscribe() {
35588
- this.unfocus();
35589
- }
35590
35636
  // ---------------------------------------------------------------------------
35591
35637
  // Getters
35592
35638
  // ---------------------------------------------------------------------------
@@ -37985,6 +38031,19 @@ clickableCellRegistry.add("link", {
37985
38031
  sequence: 5,
37986
38032
  });
37987
38033
 
38034
+ class FocusableElement {
38035
+ constructor() {
38036
+ this.focusableElement = undefined;
38037
+ }
38038
+ setFocusableElement(element) {
38039
+ this.focusableElement = element;
38040
+ }
38041
+ focus() {
38042
+ var _a;
38043
+ (_a = this.focusableElement) === null || _a === void 0 ? void 0 : _a.focus();
38044
+ }
38045
+ }
38046
+
37988
38047
  // -----------------------------------------------------------------------------
37989
38048
  // SpreadSheet
37990
38049
  // -----------------------------------------------------------------------------
@@ -39128,8 +39187,8 @@ css /* scss */ `
39128
39187
  &.corner {
39129
39188
  right: 0px;
39130
39189
  bottom: 0px;
39131
- height: ${SCROLLBAR_WIDTH$1}px;
39132
- width: ${SCROLLBAR_WIDTH$1}px;
39190
+ height: ${SCROLLBAR_WIDTH}px;
39191
+ width: ${SCROLLBAR_WIDTH}px;
39133
39192
  border-top: 1px solid #e2e3e3;
39134
39193
  border-left: 1px solid #e2e3e3;
39135
39194
  }
@@ -39173,6 +39232,7 @@ class Spreadsheet extends owl.Component {
39173
39232
  toggleSidePanel: this.toggleSidePanel.bind(this),
39174
39233
  _t: Spreadsheet._t,
39175
39234
  clipboard: navigator.clipboard,
39235
+ focusableElement: new FocusableElement(),
39176
39236
  });
39177
39237
  owl.useExternalListener(window, "resize", () => this.render(true));
39178
39238
  owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
@@ -39275,17 +39335,18 @@ class Spreadsheet extends owl.Component {
39275
39335
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39276
39336
  this.composer.topBarFocus = "contentFocus";
39277
39337
  this.composer.gridFocusMode = "inactive";
39278
- this.setComposerContent({ selection } || {});
39338
+ this.setComposerContent({ selection });
39279
39339
  }
39280
- onGridComposerContentFocused() {
39340
+ onGridComposerContentFocused(selection) {
39281
39341
  if (this.model.getters.isReadonly()) {
39282
39342
  return;
39283
39343
  }
39284
39344
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39285
39345
  this.composer.topBarFocus = "inactive";
39286
39346
  this.composer.gridFocusMode = "contentFocus";
39287
- this.setComposerContent({});
39347
+ this.setComposerContent({ selection });
39288
39348
  }
39349
+ // TODO: either both are defined or none of them. change those args to an object
39289
39350
  onGridComposerCellFocused(content, selection) {
39290
39351
  if (this.model.getters.isReadonly()) {
39291
39352
  return;
@@ -40658,18 +40719,17 @@ class EventStream {
40658
40719
  if (this.observers.find((sub) => sub.owner === owner)) {
40659
40720
  throw new Error("You are already subscribed forever");
40660
40721
  }
40661
- if ((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) {
40722
+ if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) && this.mainSubscription.owner !== owner) {
40662
40723
  (_c = (_b = this.mainSubscription.callbacks).release) === null || _c === void 0 ? void 0 : _c.call(_b);
40663
40724
  }
40664
40725
  this.mainSubscription = { owner, callbacks };
40665
40726
  }
40666
40727
  release(owner) {
40667
- var _a, _b, _c, _d;
40728
+ var _a;
40668
40729
  if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) !== owner ||
40669
40730
  this.observers.find((sub) => sub.owner === owner)) {
40670
40731
  return;
40671
40732
  }
40672
- (_d = (_b = this.mainSubscription) === null || _b === void 0 ? void 0 : (_c = _b.callbacks).release) === null || _d === void 0 ? void 0 : _d.call(_c);
40673
40733
  this.mainSubscription = this.defaultSubscription;
40674
40734
  }
40675
40735
  /**
@@ -43088,7 +43148,7 @@ const SPREADSHEET_DIMENSIONS = {
43088
43148
  BOTTOMBAR_HEIGHT,
43089
43149
  DEFAULT_CELL_WIDTH,
43090
43150
  DEFAULT_CELL_HEIGHT,
43091
- SCROLLBAR_WIDTH: SCROLLBAR_WIDTH$1,
43151
+ SCROLLBAR_WIDTH,
43092
43152
  };
43093
43153
  const registries = {
43094
43154
  autofillModifiersRegistry,
@@ -43199,6 +43259,6 @@ exports.setTranslationMethod = setTranslationMethod;
43199
43259
  exports.tokenize = tokenize;
43200
43260
 
43201
43261
 
43202
- __info__.version = '16.0.31';
43203
- __info__.date = '2024-02-02T13:44:18.740Z';
43204
- __info__.hash = 'a2e40a9';
43262
+ __info__.version = '16.0.32';
43263
+ __info__.date = '2024-02-09T13:05:36.074Z';
43264
+ __info__.hash = '452dce2';