@odoo/o-spreadsheet 16.0.30 → 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;
@@ -1611,6 +1611,9 @@ function parseFormat(formatString) {
1611
1611
  function formatValue(value, format) {
1612
1612
  switch (typeof value) {
1613
1613
  case "string":
1614
+ if (value.includes('\\"')) {
1615
+ return value.replace(/\\"/g, '"');
1616
+ }
1614
1617
  return value;
1615
1618
  case "boolean":
1616
1619
  return value ? "TRUE" : "FALSE";
@@ -4075,7 +4078,7 @@ class Popover extends owl.Component {
4075
4078
  this.spreadsheetPosition = useSpreadsheetPosition();
4076
4079
  }
4077
4080
  get maxHeight() {
4078
- return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
4081
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH);
4079
4082
  }
4080
4083
  get style() {
4081
4084
  // the props's position is expressed relative to the "body" element
@@ -5583,6 +5586,12 @@ const INSERT_LINK = (env) => {
5583
5586
  let { col, row } = env.model.getters.getPosition();
5584
5587
  env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
5585
5588
  };
5589
+ const INSERT_LINK_NAME = (env) => {
5590
+ const sheetId = env.model.getters.getActiveSheetId();
5591
+ const { col, row } = env.model.getters.getPosition();
5592
+ const cell = env.model.getters.getCell(sheetId, col, row);
5593
+ return cell && cell.isLink() ? _lt("Edit link") : _lt("Insert link");
5594
+ };
5586
5595
  //------------------------------------------------------------------------------
5587
5596
  // Filters action
5588
5597
  //------------------------------------------------------------------------------
@@ -5720,7 +5729,7 @@ cellMenuRegistry
5720
5729
  action: DELETE_CELL_SHIFT_LEFT,
5721
5730
  })
5722
5731
  .add("insert_link", {
5723
- name: _lt("Insert link"),
5732
+ name: INSERT_LINK_NAME,
5724
5733
  separator: true,
5725
5734
  sequence: 150,
5726
5735
  action: INSERT_LINK,
@@ -19515,9 +19524,6 @@ class EditionPlugin extends UIPlugin {
19515
19524
  break;
19516
19525
  }
19517
19526
  }
19518
- unsubscribe() {
19519
- this.mode = "inactive";
19520
- }
19521
19527
  // ---------------------------------------------------------------------------
19522
19528
  // Getters
19523
19529
  // ---------------------------------------------------------------------------
@@ -20418,13 +20424,12 @@ class Composer extends owl.Component {
20418
20424
  setup() {
20419
20425
  owl.onMounted(() => {
20420
20426
  const el = this.composerRef.el;
20427
+ if (this.props.isDefaultFocus) {
20428
+ this.env.focusableElement.setFocusableElement(el);
20429
+ }
20421
20430
  this.contentHelper.updateEl(el);
20422
20431
  this.processContent();
20423
20432
  });
20424
- owl.onWillUnmount(() => {
20425
- var _a, _b;
20426
- (_b = (_a = this.props).onComposerUnmounted) === null || _b === void 0 ? void 0 : _b.call(_a);
20427
- });
20428
20433
  owl.onPatched(() => {
20429
20434
  if (!this.isKeyStillDown) {
20430
20435
  this.processContent();
@@ -20435,7 +20440,8 @@ class Composer extends owl.Component {
20435
20440
  // Handlers
20436
20441
  // ---------------------------------------------------------------------------
20437
20442
  processArrowKeys(ev) {
20438
- if (this.env.model.getters.isSelectingForComposer()) {
20443
+ if (this.env.model.getters.isSelectingForComposer() ||
20444
+ this.env.model.getters.getEditionMode() === "inactive") {
20439
20445
  this.functionDescriptionState.showDescription = false;
20440
20446
  // Prevent the default content editable behavior which moves the cursor
20441
20447
  // but don't stop the event and let it bubble to the grid which will
@@ -20468,21 +20474,23 @@ class Composer extends owl.Component {
20468
20474
  processTabKey(ev) {
20469
20475
  ev.preventDefault();
20470
20476
  ev.stopPropagation();
20471
- if (this.autoCompleteState.showProvider && this.autocompleteAPI) {
20472
- const autoCompleteValue = this.autocompleteAPI.getValueToFill();
20473
- if (autoCompleteValue) {
20474
- this.autoComplete(autoCompleteValue);
20475
- 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
+ }
20476
20484
  }
20477
- }
20478
- else {
20479
- // when completing with tab, if there is no value to complete, the active cell will be moved to the right.
20480
- // we can't let the model think that it is for a ref selection.
20481
- // todo: check if this can be removed someday
20482
- 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");
20483
20492
  }
20484
20493
  const direction = ev.shiftKey ? "left" : "right";
20485
- this.env.model.dispatch("STOP_EDITION");
20486
20494
  this.env.model.selection.moveAnchorCell(direction, 1);
20487
20495
  }
20488
20496
  processEnterKey(ev) {
@@ -20514,6 +20522,9 @@ class Composer extends owl.Component {
20514
20522
  this.compositionActive = false;
20515
20523
  }
20516
20524
  onKeydown(ev) {
20525
+ if (this.env.model.getters.getEditionMode() === "inactive") {
20526
+ return;
20527
+ }
20517
20528
  let handler = this.keyMapping[ev.key];
20518
20529
  if (handler) {
20519
20530
  handler.call(this, ev);
@@ -20524,23 +20535,46 @@ class Composer extends owl.Component {
20524
20535
  }
20525
20536
  }
20526
20537
  updateCursorIfNeeded() {
20527
- if (!this.env.model.getters.isSelectingForComposer()) {
20538
+ const moveCursor = !this.env.model.getters.isSelectingForComposer() &&
20539
+ !(this.env.model.getters.getEditionMode() === "inactive");
20540
+ if (moveCursor) {
20528
20541
  const { start, end } = this.contentHelper.getCurrentSelection();
20529
20542
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20530
20543
  this.isKeyStillDown = true;
20531
20544
  }
20532
20545
  }
20546
+ onPaste(ev) {
20547
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
20548
+ ev.stopPropagation();
20549
+ }
20550
+ }
20533
20551
  /*
20534
20552
  * Triggered automatically by the content-editable between the keydown and key up
20535
20553
  * */
20536
- onInput() {
20537
- if (this.props.focus === "inactive" || !this.shouldProcessInputEvents) {
20554
+ onInput(ev) {
20555
+ var _a, _b;
20556
+ if (!this.shouldProcessInputEvents) {
20557
+ return;
20558
+ }
20559
+ if (ev.inputType === "insertFromPaste" &&
20560
+ this.env.model.getters.getEditionMode() === "inactive") {
20538
20561
  return;
20539
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
+ }
20540
20575
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20541
- const el = this.composerRef.el;
20542
20576
  this.env.model.dispatch("SET_CURRENT_CONTENT", {
20543
- content: el.childNodes.length ? el.textContent : "",
20577
+ content,
20544
20578
  selection: this.contentHelper.getCurrentSelection(),
20545
20579
  });
20546
20580
  }
@@ -20587,9 +20621,8 @@ class Composer extends owl.Component {
20587
20621
  }
20588
20622
  const newSelection = this.contentHelper.getCurrentSelection();
20589
20623
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20590
- if (this.props.focus === "inactive") {
20591
- this.props.onComposerContentFocused(newSelection);
20592
- }
20624
+ this.props.onComposerContentFocused();
20625
+ if (this.props.focus === "inactive") ;
20593
20626
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
20594
20627
  this.processTokenAtCursor();
20595
20628
  }
@@ -20609,6 +20642,7 @@ class Composer extends owl.Component {
20609
20642
  this.contentHelper.removeAll(); // removes the content of the composer, to be added just after
20610
20643
  this.shouldProcessInputEvents = false;
20611
20644
  if (this.props.focus !== "inactive") {
20645
+ this.contentHelper.el.focus();
20612
20646
  this.contentHelper.selectRange(0, 0); // move the cursor inside the composer at 0 0.
20613
20647
  }
20614
20648
  const content = this.getContent();
@@ -20777,10 +20811,9 @@ Composer.components = { TextValueProvider, FunctionDescriptionProvider };
20777
20811
  Composer.defaultProps = {
20778
20812
  inputStyle: "",
20779
20813
  focus: "inactive",
20814
+ isDefaultFocus: false,
20780
20815
  };
20781
20816
 
20782
- const SCROLLBAR_WIDTH = 14;
20783
- const SCROLLBAR_HIGHT = 15;
20784
20817
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20785
20818
  css /* scss */ `
20786
20819
  div.o-grid-composer {
@@ -20795,40 +20828,52 @@ css /* scss */ `
20795
20828
  * It also applies the style of the cell to the composer input.
20796
20829
  */
20797
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
+ }
20798
20839
  setup() {
20799
- this.gridComposerRef = owl.useRef("gridComposer");
20800
- this.composerState = owl.useState({
20801
- rect: null,
20802
- delimitation: null,
20803
- });
20804
- const { col, row } = this.env.model.getters.getPosition();
20805
- this.zone = this.env.model.getters.expandZone(this.env.model.getters.getActiveSheetId(), {
20806
- left: col,
20807
- right: col,
20808
- top: row,
20809
- bottom: row,
20810
- });
20811
- this.rect = this.env.model.getters.getVisibleRect(this.zone);
20812
- owl.onMounted(() => {
20813
- const el = this.gridComposerRef.el;
20814
- //TODO Should be more correct to have a props that give the parent's clientHeight and clientWidth
20815
- const maxHeight = el.parentElement.clientHeight - this.rect.y - SCROLLBAR_HIGHT;
20816
- el.style.maxHeight = (maxHeight + "px");
20817
- const maxWidth = el.parentElement.clientWidth - this.rect.x - SCROLLBAR_WIDTH;
20818
- el.style.maxWidth = (maxWidth + "px");
20819
- this.composerState.rect = {
20820
- x: this.rect.x,
20821
- y: this.rect.y,
20822
- width: el.clientWidth,
20823
- height: el.clientHeight,
20824
- };
20825
- this.composerState.delimitation = {
20826
- width: el.parentElement.clientWidth,
20827
- height: el.parentElement.clientHeight,
20828
- };
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
+ }
20829
20853
  });
20830
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
+ }
20831
20870
  get containerStyle() {
20871
+ if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
20872
+ return `
20873
+ position: absolute;
20874
+ z-index: -1000;
20875
+ `;
20876
+ }
20832
20877
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
20833
20878
  const cell = this.env.model.getters.getActiveCell();
20834
20879
  let style = {};
@@ -20851,12 +20896,18 @@ class GridComposer extends owl.Component {
20851
20896
  if (!isFormula) {
20852
20897
  textAlign = style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign) || "left";
20853
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;
20854
20902
  return `
20855
20903
  left: ${left - 1}px;
20856
20904
  top: ${top}px;
20857
20905
  min-width: ${width + 2}px;
20858
20906
  min-height: ${height + 1}px;
20859
20907
 
20908
+ max-width: ${maxWidth}px;
20909
+ max-height: ${maxHeight}px;
20910
+
20860
20911
  background: ${background};
20861
20912
  color: ${color};
20862
20913
 
@@ -22493,8 +22544,8 @@ css /* scss */ `
22493
22544
  &.corner {
22494
22545
  right: 0px;
22495
22546
  bottom: 0px;
22496
- height: ${SCROLLBAR_WIDTH$1}px;
22497
- width: ${SCROLLBAR_WIDTH$1}px;
22547
+ height: ${SCROLLBAR_WIDTH}px;
22548
+ width: ${SCROLLBAR_WIDTH}px;
22498
22549
  border-top: 1px solid #e2e3e3;
22499
22550
  border-left: 1px solid #e2e3e3;
22500
22551
  }
@@ -22559,7 +22610,7 @@ class HorizontalScrollBar extends owl.Component {
22559
22610
  return {
22560
22611
  left: `${this.props.position.left + x}px`,
22561
22612
  bottom: "0px",
22562
- height: `${SCROLLBAR_WIDTH$1}px`,
22613
+ height: `${SCROLLBAR_WIDTH}px`,
22563
22614
  right: `0px`,
22564
22615
  };
22565
22616
  }
@@ -22601,7 +22652,7 @@ class VerticalScrollBar extends owl.Component {
22601
22652
  return {
22602
22653
  top: `${this.props.position.top + y}px`,
22603
22654
  right: "0px",
22604
- width: `${SCROLLBAR_WIDTH$1}px`,
22655
+ width: `${SCROLLBAR_WIDTH}px`,
22605
22656
  bottom: `0px`,
22606
22657
  };
22607
22658
  }
@@ -22759,16 +22810,15 @@ class Grid extends owl.Component {
22759
22810
  menuItems: [],
22760
22811
  });
22761
22812
  this.gridRef = owl.useRef("grid");
22762
- this.hiddenInput = owl.useRef("hiddenInput");
22763
22813
  this.canvasPosition = useAbsolutePosition(this.gridRef);
22764
22814
  this.hoveredCell = owl.useState({ col: undefined, row: undefined });
22765
22815
  owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
22766
22816
  owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
22767
22817
  owl.useExternalListener(document.body, "paste", this.paste);
22768
- owl.onMounted(() => this.focus());
22769
- this.props.exposeFocus(() => this.focus());
22818
+ owl.onMounted(() => this.focusDefaultElement());
22819
+ this.props.exposeFocus(() => this.focusDefaultElement());
22770
22820
  useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
22771
- owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
22821
+ owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
22772
22822
  this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
22773
22823
  this.moveCanvas(deltaX, deltaY);
22774
22824
  this.hoveredCell.col = undefined;
@@ -22783,19 +22833,18 @@ class Grid extends owl.Component {
22783
22833
  return `
22784
22834
  top: ${HEADER_HEIGHT}px;
22785
22835
  left: ${HEADER_WIDTH}px;
22786
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH$1}px);
22787
- 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);
22788
22838
  `;
22789
22839
  }
22790
22840
  onClosePopover() {
22791
22841
  this.closeOpenedPopover();
22792
- this.focus();
22842
+ this.focusDefaultElement();
22793
22843
  }
22794
- focus() {
22795
- var _a;
22844
+ focusDefaultElement() {
22796
22845
  if (!this.env.model.getters.getSelectedFigureId() &&
22797
22846
  this.env.model.getters.getEditionMode() === "inactive") {
22798
- (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
22847
+ this.env.focusableElement.focus();
22799
22848
  }
22800
22849
  }
22801
22850
  get gridEl() {
@@ -22944,19 +22993,6 @@ class Grid extends owl.Component {
22944
22993
  return;
22945
22994
  }
22946
22995
  }
22947
- onInput(ev) {
22948
- // the user meant to paste in the sheet, not open the composer with the pasted content
22949
- if (!ev.isComposing && ev.inputType === "insertFromPaste") {
22950
- return;
22951
- }
22952
- if (ev.data) {
22953
- // if the user types a character on the grid, it means he wants to start composing the selected cell with that
22954
- // character
22955
- ev.preventDefault();
22956
- ev.stopPropagation();
22957
- this.props.onGridComposerCellFocused(ev.data);
22958
- }
22959
- }
22960
22996
  // ---------------------------------------------------------------------------
22961
22997
  // Context Menu
22962
22998
  // ---------------------------------------------------------------------------
@@ -23037,7 +23073,7 @@ class Grid extends owl.Component {
23037
23073
  }
23038
23074
  closeMenu() {
23039
23075
  this.menuState.isOpen = false;
23040
- this.focus();
23076
+ this.focusDefaultElement();
23041
23077
  }
23042
23078
  }
23043
23079
  Grid.template = "o-spreadsheet-Grid";
@@ -26733,7 +26769,7 @@ function normalizeV9(formula) {
26733
26769
  * a breaking change is made in the way the state is handled, and an upgrade
26734
26770
  * function should be defined
26735
26771
  */
26736
- const CURRENT_VERSION = 12;
26772
+ const CURRENT_VERSION = 12.5;
26737
26773
  const INITIAL_SHEET_ID = "Sheet1";
26738
26774
  /**
26739
26775
  * This function tries to load anything that could look like a valid
@@ -26999,6 +27035,31 @@ const MIGRATIONS = [
26999
27035
  return data;
27000
27036
  },
27001
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
+ },
27002
27063
  ];
27003
27064
  /**
27004
27065
  * This function is used to repair faulty data independently of the migration.
@@ -27894,9 +27955,6 @@ class CellPlugin extends CorePlugin {
27894
27955
  format: cell.format ? getItemId(cell.format, formats) : undefined,
27895
27956
  content: cell.content || undefined,
27896
27957
  };
27897
- if (cell.isFormula()) {
27898
- cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
27899
- }
27900
27958
  }
27901
27959
  _sheet.cells = cells;
27902
27960
  }
@@ -27919,6 +27977,9 @@ class CellPlugin extends CorePlugin {
27919
27977
  const exportedCellData = sheet.cells[xc];
27920
27978
  exportedCellData.value = cell.evaluated.value;
27921
27979
  exportedCellData.isFormula = cell.isFormula();
27980
+ if (cell.isFormula()) {
27981
+ exportedCellData.content = this.buildFormulaContent(sheet.id, cell, cell.dependencies, true);
27982
+ }
27922
27983
  if (cell.format !== cell.evaluated.format) {
27923
27984
  exportedCellData.computedFormat = cell.evaluated.format;
27924
27985
  }
@@ -35361,9 +35422,6 @@ class SelectionInputPlugin extends UIPlugin {
35361
35422
  }
35362
35423
  }
35363
35424
  }
35364
- unsubscribe() {
35365
- this.unfocus();
35366
- }
35367
35425
  // ---------------------------------------------------------------------------
35368
35426
  // Getters || only callable by the parent
35369
35427
  // ---------------------------------------------------------------------------
@@ -35575,9 +35633,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
35575
35633
  }
35576
35634
  (_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.handle(cmd);
35577
35635
  }
35578
- unsubscribe() {
35579
- this.unfocus();
35580
- }
35581
35636
  // ---------------------------------------------------------------------------
35582
35637
  // Getters
35583
35638
  // ---------------------------------------------------------------------------
@@ -37976,6 +38031,19 @@ clickableCellRegistry.add("link", {
37976
38031
  sequence: 5,
37977
38032
  });
37978
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
+
37979
38047
  // -----------------------------------------------------------------------------
37980
38048
  // SpreadSheet
37981
38049
  // -----------------------------------------------------------------------------
@@ -39119,8 +39187,8 @@ css /* scss */ `
39119
39187
  &.corner {
39120
39188
  right: 0px;
39121
39189
  bottom: 0px;
39122
- height: ${SCROLLBAR_WIDTH$1}px;
39123
- width: ${SCROLLBAR_WIDTH$1}px;
39190
+ height: ${SCROLLBAR_WIDTH}px;
39191
+ width: ${SCROLLBAR_WIDTH}px;
39124
39192
  border-top: 1px solid #e2e3e3;
39125
39193
  border-left: 1px solid #e2e3e3;
39126
39194
  }
@@ -39164,6 +39232,7 @@ class Spreadsheet extends owl.Component {
39164
39232
  toggleSidePanel: this.toggleSidePanel.bind(this),
39165
39233
  _t: Spreadsheet._t,
39166
39234
  clipboard: navigator.clipboard,
39235
+ focusableElement: new FocusableElement(),
39167
39236
  });
39168
39237
  owl.useExternalListener(window, "resize", () => this.render(true));
39169
39238
  owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
@@ -39266,17 +39335,18 @@ class Spreadsheet extends owl.Component {
39266
39335
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39267
39336
  this.composer.topBarFocus = "contentFocus";
39268
39337
  this.composer.gridFocusMode = "inactive";
39269
- this.setComposerContent({ selection } || {});
39338
+ this.setComposerContent({ selection });
39270
39339
  }
39271
- onGridComposerContentFocused() {
39340
+ onGridComposerContentFocused(selection) {
39272
39341
  if (this.model.getters.isReadonly()) {
39273
39342
  return;
39274
39343
  }
39275
39344
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39276
39345
  this.composer.topBarFocus = "inactive";
39277
39346
  this.composer.gridFocusMode = "contentFocus";
39278
- this.setComposerContent({});
39347
+ this.setComposerContent({ selection });
39279
39348
  }
39349
+ // TODO: either both are defined or none of them. change those args to an object
39280
39350
  onGridComposerCellFocused(content, selection) {
39281
39351
  if (this.model.getters.isReadonly()) {
39282
39352
  return;
@@ -40649,18 +40719,17 @@ class EventStream {
40649
40719
  if (this.observers.find((sub) => sub.owner === owner)) {
40650
40720
  throw new Error("You are already subscribed forever");
40651
40721
  }
40652
- 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) {
40653
40723
  (_c = (_b = this.mainSubscription.callbacks).release) === null || _c === void 0 ? void 0 : _c.call(_b);
40654
40724
  }
40655
40725
  this.mainSubscription = { owner, callbacks };
40656
40726
  }
40657
40727
  release(owner) {
40658
- var _a, _b, _c, _d;
40728
+ var _a;
40659
40729
  if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) !== owner ||
40660
40730
  this.observers.find((sub) => sub.owner === owner)) {
40661
40731
  return;
40662
40732
  }
40663
- (_d = (_b = this.mainSubscription) === null || _b === void 0 ? void 0 : (_c = _b.callbacks).release) === null || _d === void 0 ? void 0 : _d.call(_c);
40664
40733
  this.mainSubscription = this.defaultSubscription;
40665
40734
  }
40666
40735
  /**
@@ -43079,7 +43148,7 @@ const SPREADSHEET_DIMENSIONS = {
43079
43148
  BOTTOMBAR_HEIGHT,
43080
43149
  DEFAULT_CELL_WIDTH,
43081
43150
  DEFAULT_CELL_HEIGHT,
43082
- SCROLLBAR_WIDTH: SCROLLBAR_WIDTH$1,
43151
+ SCROLLBAR_WIDTH,
43083
43152
  };
43084
43153
  const registries = {
43085
43154
  autofillModifiersRegistry,
@@ -43190,6 +43259,6 @@ exports.setTranslationMethod = setTranslationMethod;
43190
43259
  exports.tokenize = tokenize;
43191
43260
 
43192
43261
 
43193
- __info__.version = '16.0.30';
43194
- __info__.date = '2024-01-29T13:49:32.243Z';
43195
- __info__.hash = '49966d6';
43262
+ __info__.version = '16.0.32';
43263
+ __info__.date = '2024-02-09T13:05:36.074Z';
43264
+ __info__.hash = '452dce2';