@odoo/o-spreadsheet 16.0.31 → 16.0.33

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) {
20557
+ return;
20558
+ }
20559
+ if (ev.inputType === "insertFromPaste" &&
20560
+ this.env.model.getters.getEditionMode() === "inactive") {
20547
20561
  return;
20548
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.
@@ -27769,9 +27821,9 @@ class CellPlugin extends CorePlugin {
27769
27821
  allowDispatch(cmd) {
27770
27822
  switch (cmd.type) {
27771
27823
  case "UPDATE_CELL":
27772
- return this.checkCellOutOfSheet(cmd);
27824
+ return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
27773
27825
  case "CLEAR_CELL":
27774
- return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
27826
+ return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
27775
27827
  default:
27776
27828
  return 0 /* CommandResult.Success */;
27777
27829
  }
@@ -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
  }
@@ -28130,6 +28182,18 @@ class CellPlugin extends CorePlugin {
28130
28182
  }
28131
28183
  return 0 /* CommandResult.Success */;
28132
28184
  }
28185
+ checkUselessUpdateCell(cmd) {
28186
+ const cell = this.getters.getCell(cmd.sheetId, cmd.col, cmd.row);
28187
+ const hasContent = "content" in cmd || "formula" in cmd;
28188
+ const hasStyle = "style" in cmd;
28189
+ const hasFormat = "format" in cmd;
28190
+ if ((!hasContent || (cell === null || cell === void 0 ? void 0 : cell.content) === cmd.content) &&
28191
+ (!hasStyle || deepEquals(cell === null || cell === void 0 ? void 0 : cell.style, cmd.style)) &&
28192
+ (!hasFormat || (cell === null || cell === void 0 ? void 0 : cell.format) === cmd.format)) {
28193
+ return 88 /* CommandResult.NoChanges */;
28194
+ }
28195
+ return 0 /* CommandResult.Success */;
28196
+ }
28133
28197
  }
28134
28198
  CellPlugin.getters = [
28135
28199
  "zoneToXC",
@@ -35370,9 +35434,6 @@ class SelectionInputPlugin extends UIPlugin {
35370
35434
  }
35371
35435
  }
35372
35436
  }
35373
- unsubscribe() {
35374
- this.unfocus();
35375
- }
35376
35437
  // ---------------------------------------------------------------------------
35377
35438
  // Getters || only callable by the parent
35378
35439
  // ---------------------------------------------------------------------------
@@ -35584,9 +35645,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
35584
35645
  }
35585
35646
  (_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.handle(cmd);
35586
35647
  }
35587
- unsubscribe() {
35588
- this.unfocus();
35589
- }
35590
35648
  // ---------------------------------------------------------------------------
35591
35649
  // Getters
35592
35650
  // ---------------------------------------------------------------------------
@@ -37985,6 +38043,19 @@ clickableCellRegistry.add("link", {
37985
38043
  sequence: 5,
37986
38044
  });
37987
38045
 
38046
+ class FocusableElement {
38047
+ constructor() {
38048
+ this.focusableElement = undefined;
38049
+ }
38050
+ setFocusableElement(element) {
38051
+ this.focusableElement = element;
38052
+ }
38053
+ focus() {
38054
+ var _a;
38055
+ (_a = this.focusableElement) === null || _a === void 0 ? void 0 : _a.focus();
38056
+ }
38057
+ }
38058
+
37988
38059
  // -----------------------------------------------------------------------------
37989
38060
  // SpreadSheet
37990
38061
  // -----------------------------------------------------------------------------
@@ -39128,8 +39199,8 @@ css /* scss */ `
39128
39199
  &.corner {
39129
39200
  right: 0px;
39130
39201
  bottom: 0px;
39131
- height: ${SCROLLBAR_WIDTH$1}px;
39132
- width: ${SCROLLBAR_WIDTH$1}px;
39202
+ height: ${SCROLLBAR_WIDTH}px;
39203
+ width: ${SCROLLBAR_WIDTH}px;
39133
39204
  border-top: 1px solid #e2e3e3;
39134
39205
  border-left: 1px solid #e2e3e3;
39135
39206
  }
@@ -39173,6 +39244,7 @@ class Spreadsheet extends owl.Component {
39173
39244
  toggleSidePanel: this.toggleSidePanel.bind(this),
39174
39245
  _t: Spreadsheet._t,
39175
39246
  clipboard: navigator.clipboard,
39247
+ focusableElement: new FocusableElement(),
39176
39248
  });
39177
39249
  owl.useExternalListener(window, "resize", () => this.render(true));
39178
39250
  owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
@@ -39275,17 +39347,18 @@ class Spreadsheet extends owl.Component {
39275
39347
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39276
39348
  this.composer.topBarFocus = "contentFocus";
39277
39349
  this.composer.gridFocusMode = "inactive";
39278
- this.setComposerContent({ selection } || {});
39350
+ this.setComposerContent({ selection });
39279
39351
  }
39280
- onGridComposerContentFocused() {
39352
+ onGridComposerContentFocused(selection) {
39281
39353
  if (this.model.getters.isReadonly()) {
39282
39354
  return;
39283
39355
  }
39284
39356
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39285
39357
  this.composer.topBarFocus = "inactive";
39286
39358
  this.composer.gridFocusMode = "contentFocus";
39287
- this.setComposerContent({});
39359
+ this.setComposerContent({ selection });
39288
39360
  }
39361
+ // TODO: either both are defined or none of them. change those args to an object
39289
39362
  onGridComposerCellFocused(content, selection) {
39290
39363
  if (this.model.getters.isReadonly()) {
39291
39364
  return;
@@ -40658,18 +40731,17 @@ class EventStream {
40658
40731
  if (this.observers.find((sub) => sub.owner === owner)) {
40659
40732
  throw new Error("You are already subscribed forever");
40660
40733
  }
40661
- if ((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) {
40734
+ if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) && this.mainSubscription.owner !== owner) {
40662
40735
  (_c = (_b = this.mainSubscription.callbacks).release) === null || _c === void 0 ? void 0 : _c.call(_b);
40663
40736
  }
40664
40737
  this.mainSubscription = { owner, callbacks };
40665
40738
  }
40666
40739
  release(owner) {
40667
- var _a, _b, _c, _d;
40740
+ var _a;
40668
40741
  if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) !== owner ||
40669
40742
  this.observers.find((sub) => sub.owner === owner)) {
40670
40743
  return;
40671
40744
  }
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
40745
  this.mainSubscription = this.defaultSubscription;
40674
40746
  }
40675
40747
  /**
@@ -43088,7 +43160,7 @@ const SPREADSHEET_DIMENSIONS = {
43088
43160
  BOTTOMBAR_HEIGHT,
43089
43161
  DEFAULT_CELL_WIDTH,
43090
43162
  DEFAULT_CELL_HEIGHT,
43091
- SCROLLBAR_WIDTH: SCROLLBAR_WIDTH$1,
43163
+ SCROLLBAR_WIDTH,
43092
43164
  };
43093
43165
  const registries = {
43094
43166
  autofillModifiersRegistry,
@@ -43199,6 +43271,6 @@ exports.setTranslationMethod = setTranslationMethod;
43199
43271
  exports.tokenize = tokenize;
43200
43272
 
43201
43273
 
43202
- __info__.version = '16.0.31';
43203
- __info__.date = '2024-02-02T13:44:18.740Z';
43204
- __info__.hash = 'a2e40a9';
43274
+ __info__.version = '16.0.33';
43275
+ __info__.date = '2024-02-16T14:49:10.674Z';
43276
+ __info__.hash = 'c0cefe8';