@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.
@@ -204,7 +204,7 @@
204
204
  const BOTTOMBAR_HEIGHT = 36;
205
205
  const DEFAULT_CELL_WIDTH = 96;
206
206
  const DEFAULT_CELL_HEIGHT = 23;
207
- const SCROLLBAR_WIDTH$1 = 15;
207
+ const SCROLLBAR_WIDTH = 15;
208
208
  const AUTOFILL_EDGE_LENGTH = 8;
209
209
  const ICON_EDGE_LENGTH = 18;
210
210
  const UNHIDE_ICON_EDGE_LENGTH = 14;
@@ -4075,7 +4075,7 @@
4075
4075
  this.spreadsheetPosition = useSpreadsheetPosition();
4076
4076
  }
4077
4077
  get maxHeight() {
4078
- return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH$1);
4078
+ return Math.max(0, this.viewportDimension.height - BOTTOMBAR_HEIGHT - SCROLLBAR_WIDTH);
4079
4079
  }
4080
4080
  get style() {
4081
4081
  // the props's position is expressed relative to the "body" element
@@ -19521,9 +19521,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
19521
19521
  break;
19522
19522
  }
19523
19523
  }
19524
- unsubscribe() {
19525
- this.mode = "inactive";
19526
- }
19527
19524
  // ---------------------------------------------------------------------------
19528
19525
  // Getters
19529
19526
  // ---------------------------------------------------------------------------
@@ -20424,13 +20421,12 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20424
20421
  setup() {
20425
20422
  owl.onMounted(() => {
20426
20423
  const el = this.composerRef.el;
20424
+ if (this.props.isDefaultFocus) {
20425
+ this.env.focusableElement.setFocusableElement(el);
20426
+ }
20427
20427
  this.contentHelper.updateEl(el);
20428
20428
  this.processContent();
20429
20429
  });
20430
- owl.onWillUnmount(() => {
20431
- var _a, _b;
20432
- (_b = (_a = this.props).onComposerUnmounted) === null || _b === void 0 ? void 0 : _b.call(_a);
20433
- });
20434
20430
  owl.onPatched(() => {
20435
20431
  if (!this.isKeyStillDown) {
20436
20432
  this.processContent();
@@ -20441,7 +20437,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20441
20437
  // Handlers
20442
20438
  // ---------------------------------------------------------------------------
20443
20439
  processArrowKeys(ev) {
20444
- if (this.env.model.getters.isSelectingForComposer()) {
20440
+ if (this.env.model.getters.isSelectingForComposer() ||
20441
+ this.env.model.getters.getEditionMode() === "inactive") {
20445
20442
  this.functionDescriptionState.showDescription = false;
20446
20443
  // Prevent the default content editable behavior which moves the cursor
20447
20444
  // but don't stop the event and let it bubble to the grid which will
@@ -20474,21 +20471,23 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20474
20471
  processTabKey(ev) {
20475
20472
  ev.preventDefault();
20476
20473
  ev.stopPropagation();
20477
- if (this.autoCompleteState.showProvider && this.autocompleteAPI) {
20478
- const autoCompleteValue = this.autocompleteAPI.getValueToFill();
20479
- if (autoCompleteValue) {
20480
- this.autoComplete(autoCompleteValue);
20481
- return;
20474
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
20475
+ if (this.autoCompleteState.showProvider && this.autocompleteAPI) {
20476
+ const autoCompleteValue = this.autocompleteAPI.getValueToFill();
20477
+ if (autoCompleteValue) {
20478
+ this.autoComplete(autoCompleteValue);
20479
+ return;
20480
+ }
20482
20481
  }
20483
- }
20484
- else {
20485
- // when completing with tab, if there is no value to complete, the active cell will be moved to the right.
20486
- // we can't let the model think that it is for a ref selection.
20487
- // todo: check if this can be removed someday
20488
- this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20482
+ else {
20483
+ // when completing with tab, if there is no value to complete, the active cell will be moved to the right.
20484
+ // we can't let the model think that it is for a ref selection.
20485
+ // todo: check if this can be removed someday
20486
+ this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20487
+ }
20488
+ this.env.model.dispatch("STOP_EDITION");
20489
20489
  }
20490
20490
  const direction = ev.shiftKey ? "left" : "right";
20491
- this.env.model.dispatch("STOP_EDITION");
20492
20491
  this.env.model.selection.moveAnchorCell(direction, 1);
20493
20492
  }
20494
20493
  processEnterKey(ev) {
@@ -20520,6 +20519,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20520
20519
  this.compositionActive = false;
20521
20520
  }
20522
20521
  onKeydown(ev) {
20522
+ if (this.env.model.getters.getEditionMode() === "inactive") {
20523
+ return;
20524
+ }
20523
20525
  let handler = this.keyMapping[ev.key];
20524
20526
  if (handler) {
20525
20527
  handler.call(this, ev);
@@ -20530,23 +20532,46 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20530
20532
  }
20531
20533
  }
20532
20534
  updateCursorIfNeeded() {
20533
- if (!this.env.model.getters.isSelectingForComposer()) {
20535
+ const moveCursor = !this.env.model.getters.isSelectingForComposer() &&
20536
+ !(this.env.model.getters.getEditionMode() === "inactive");
20537
+ if (moveCursor) {
20534
20538
  const { start, end } = this.contentHelper.getCurrentSelection();
20535
20539
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
20536
20540
  this.isKeyStillDown = true;
20537
20541
  }
20538
20542
  }
20543
+ onPaste(ev) {
20544
+ if (this.env.model.getters.getEditionMode() !== "inactive") {
20545
+ ev.stopPropagation();
20546
+ }
20547
+ }
20539
20548
  /*
20540
20549
  * Triggered automatically by the content-editable between the keydown and key up
20541
20550
  * */
20542
- onInput() {
20543
- if (this.props.focus === "inactive" || !this.shouldProcessInputEvents) {
20551
+ onInput(ev) {
20552
+ var _a, _b;
20553
+ if (!this.shouldProcessInputEvents) {
20554
+ return;
20555
+ }
20556
+ if (ev.inputType === "insertFromPaste" &&
20557
+ this.env.model.getters.getEditionMode() === "inactive") {
20544
20558
  return;
20545
20559
  }
20560
+ ev.stopPropagation();
20561
+ let content;
20562
+ if (this.env.model.getters.getEditionMode() === "inactive") {
20563
+ content = ev.data || "";
20564
+ }
20565
+ else {
20566
+ const el = this.composerRef.el;
20567
+ content = el.childNodes.length ? el.textContent : "";
20568
+ }
20569
+ if (this.props.focus === "inactive") {
20570
+ return (_b = (_a = this.props).onComposerCellFocused) === null || _b === void 0 ? void 0 : _b.call(_a, content);
20571
+ }
20546
20572
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20547
- const el = this.composerRef.el;
20548
20573
  this.env.model.dispatch("SET_CURRENT_CONTENT", {
20549
- content: el.childNodes.length ? el.textContent : "",
20574
+ content,
20550
20575
  selection: this.contentHelper.getCurrentSelection(),
20551
20576
  });
20552
20577
  }
@@ -20593,9 +20618,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20593
20618
  }
20594
20619
  const newSelection = this.contentHelper.getCurrentSelection();
20595
20620
  this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
20596
- if (this.props.focus === "inactive") {
20597
- this.props.onComposerContentFocused(newSelection);
20598
- }
20621
+ this.props.onComposerContentFocused();
20622
+ if (this.props.focus === "inactive") ;
20599
20623
  this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
20600
20624
  this.processTokenAtCursor();
20601
20625
  }
@@ -20615,6 +20639,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20615
20639
  this.contentHelper.removeAll(); // removes the content of the composer, to be added just after
20616
20640
  this.shouldProcessInputEvents = false;
20617
20641
  if (this.props.focus !== "inactive") {
20642
+ this.contentHelper.el.focus();
20618
20643
  this.contentHelper.selectRange(0, 0); // move the cursor inside the composer at 0 0.
20619
20644
  }
20620
20645
  const content = this.getContent();
@@ -20783,10 +20808,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20783
20808
  Composer.defaultProps = {
20784
20809
  inputStyle: "",
20785
20810
  focus: "inactive",
20811
+ isDefaultFocus: false,
20786
20812
  };
20787
20813
 
20788
- const SCROLLBAR_WIDTH = 14;
20789
- const SCROLLBAR_HIGHT = 15;
20790
20814
  const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
20791
20815
  css /* scss */ `
20792
20816
  div.o-grid-composer {
@@ -20801,40 +20825,52 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20801
20825
  * It also applies the style of the cell to the composer input.
20802
20826
  */
20803
20827
  class GridComposer extends owl.Component {
20828
+ constructor() {
20829
+ super(...arguments);
20830
+ this.rect = undefined;
20831
+ this.isEditing = false;
20832
+ }
20833
+ get defaultRect() {
20834
+ return { x: 0, y: 0, width: 0, height: 0 };
20835
+ }
20804
20836
  setup() {
20805
- this.gridComposerRef = owl.useRef("gridComposer");
20806
- this.composerState = owl.useState({
20807
- rect: null,
20808
- delimitation: null,
20809
- });
20810
- const { col, row } = this.env.model.getters.getPosition();
20811
- this.zone = this.env.model.getters.expandZone(this.env.model.getters.getActiveSheetId(), {
20812
- left: col,
20813
- right: col,
20814
- top: row,
20815
- bottom: row,
20816
- });
20817
- this.rect = this.env.model.getters.getVisibleRect(this.zone);
20818
- owl.onMounted(() => {
20819
- const el = this.gridComposerRef.el;
20820
- //TODO Should be more correct to have a props that give the parent's clientHeight and clientWidth
20821
- const maxHeight = el.parentElement.clientHeight - this.rect.y - SCROLLBAR_HIGHT;
20822
- el.style.maxHeight = (maxHeight + "px");
20823
- const maxWidth = el.parentElement.clientWidth - this.rect.x - SCROLLBAR_WIDTH;
20824
- el.style.maxWidth = (maxWidth + "px");
20825
- this.composerState.rect = {
20826
- x: this.rect.x,
20827
- y: this.rect.y,
20828
- width: el.clientWidth,
20829
- height: el.clientHeight,
20830
- };
20831
- this.composerState.delimitation = {
20832
- width: el.parentElement.clientWidth,
20833
- height: el.parentElement.clientHeight,
20834
- };
20837
+ owl.onWillUpdateProps(() => {
20838
+ const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
20839
+ if (this.isEditing !== isEditing) {
20840
+ this.isEditing = isEditing;
20841
+ if (!isEditing) {
20842
+ this.rect = undefined;
20843
+ this.env.focusableElement.focus();
20844
+ return;
20845
+ }
20846
+ const position = this.env.model.getters.getPosition();
20847
+ const zone = this.env.model.getters.expandZone(this.env.model.getters.getActiveSheetId(), positionToZone(position));
20848
+ this.rect = this.env.model.getters.getVisibleRect(zone);
20849
+ }
20835
20850
  });
20836
20851
  }
20852
+ get composerProps() {
20853
+ const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
20854
+ return {
20855
+ rect: this.rect && { ...this.rect },
20856
+ delimitation: {
20857
+ width,
20858
+ height,
20859
+ },
20860
+ inputStyle: this.composerStyle,
20861
+ focus: this.props.focus,
20862
+ isDefaultFocus: true,
20863
+ onComposerContentFocused: this.props.onComposerContentFocused,
20864
+ onComposerCellFocused: this.props.onComposerCellFocused,
20865
+ };
20866
+ }
20837
20867
  get containerStyle() {
20868
+ if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
20869
+ return `
20870
+ position: absolute;
20871
+ z-index: -1000;
20872
+ `;
20873
+ }
20838
20874
  const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
20839
20875
  const cell = this.env.model.getters.getActiveCell();
20840
20876
  let style = {};
@@ -20857,12 +20893,18 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
20857
20893
  if (!isFormula) {
20858
20894
  textAlign = style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign) || "left";
20859
20895
  }
20896
+ const sheetDimensions = this.env.model.getters.getSheetViewDimensionWithHeaders();
20897
+ const maxWidth = sheetDimensions.width - this.rect.x;
20898
+ const maxHeight = sheetDimensions.height - this.rect.y;
20860
20899
  return `
20861
20900
  left: ${left - 1}px;
20862
20901
  top: ${top}px;
20863
20902
  min-width: ${width + 2}px;
20864
20903
  min-height: ${height + 1}px;
20865
20904
 
20905
+ max-width: ${maxWidth}px;
20906
+ max-height: ${maxHeight}px;
20907
+
20866
20908
  background: ${background};
20867
20909
  color: ${color};
20868
20910
 
@@ -22499,8 +22541,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22499
22541
  &.corner {
22500
22542
  right: 0px;
22501
22543
  bottom: 0px;
22502
- height: ${SCROLLBAR_WIDTH$1}px;
22503
- width: ${SCROLLBAR_WIDTH$1}px;
22544
+ height: ${SCROLLBAR_WIDTH}px;
22545
+ width: ${SCROLLBAR_WIDTH}px;
22504
22546
  border-top: 1px solid #e2e3e3;
22505
22547
  border-left: 1px solid #e2e3e3;
22506
22548
  }
@@ -22565,7 +22607,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22565
22607
  return {
22566
22608
  left: `${this.props.position.left + x}px`,
22567
22609
  bottom: "0px",
22568
- height: `${SCROLLBAR_WIDTH$1}px`,
22610
+ height: `${SCROLLBAR_WIDTH}px`,
22569
22611
  right: `0px`,
22570
22612
  };
22571
22613
  }
@@ -22607,7 +22649,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22607
22649
  return {
22608
22650
  top: `${this.props.position.top + y}px`,
22609
22651
  right: "0px",
22610
- width: `${SCROLLBAR_WIDTH$1}px`,
22652
+ width: `${SCROLLBAR_WIDTH}px`,
22611
22653
  bottom: `0px`,
22612
22654
  };
22613
22655
  }
@@ -22765,16 +22807,15 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22765
22807
  menuItems: [],
22766
22808
  });
22767
22809
  this.gridRef = owl.useRef("grid");
22768
- this.hiddenInput = owl.useRef("hiddenInput");
22769
22810
  this.canvasPosition = useAbsolutePosition(this.gridRef);
22770
22811
  this.hoveredCell = owl.useState({ col: undefined, row: undefined });
22771
22812
  owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
22772
22813
  owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
22773
22814
  owl.useExternalListener(document.body, "paste", this.paste);
22774
- owl.onMounted(() => this.focus());
22775
- this.props.exposeFocus(() => this.focus());
22815
+ owl.onMounted(() => this.focusDefaultElement());
22816
+ this.props.exposeFocus(() => this.focusDefaultElement());
22776
22817
  useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
22777
- owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
22818
+ owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
22778
22819
  this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
22779
22820
  this.moveCanvas(deltaX, deltaY);
22780
22821
  this.hoveredCell.col = undefined;
@@ -22789,19 +22830,18 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22789
22830
  return `
22790
22831
  top: ${HEADER_HEIGHT}px;
22791
22832
  left: ${HEADER_WIDTH}px;
22792
- height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH$1}px);
22793
- width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH$1}px);
22833
+ height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
22834
+ width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH}px);
22794
22835
  `;
22795
22836
  }
22796
22837
  onClosePopover() {
22797
22838
  this.closeOpenedPopover();
22798
- this.focus();
22839
+ this.focusDefaultElement();
22799
22840
  }
22800
- focus() {
22801
- var _a;
22841
+ focusDefaultElement() {
22802
22842
  if (!this.env.model.getters.getSelectedFigureId() &&
22803
22843
  this.env.model.getters.getEditionMode() === "inactive") {
22804
- (_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
22844
+ this.env.focusableElement.focus();
22805
22845
  }
22806
22846
  }
22807
22847
  get gridEl() {
@@ -22950,19 +22990,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
22950
22990
  return;
22951
22991
  }
22952
22992
  }
22953
- onInput(ev) {
22954
- // the user meant to paste in the sheet, not open the composer with the pasted content
22955
- if (!ev.isComposing && ev.inputType === "insertFromPaste") {
22956
- return;
22957
- }
22958
- if (ev.data) {
22959
- // if the user types a character on the grid, it means he wants to start composing the selected cell with that
22960
- // character
22961
- ev.preventDefault();
22962
- ev.stopPropagation();
22963
- this.props.onGridComposerCellFocused(ev.data);
22964
- }
22965
- }
22966
22993
  // ---------------------------------------------------------------------------
22967
22994
  // Context Menu
22968
22995
  // ---------------------------------------------------------------------------
@@ -23043,7 +23070,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
23043
23070
  }
23044
23071
  closeMenu() {
23045
23072
  this.menuState.isOpen = false;
23046
- this.focus();
23073
+ this.focusDefaultElement();
23047
23074
  }
23048
23075
  }
23049
23076
  Grid.template = "o-spreadsheet-Grid";
@@ -26739,7 +26766,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
26739
26766
  * a breaking change is made in the way the state is handled, and an upgrade
26740
26767
  * function should be defined
26741
26768
  */
26742
- const CURRENT_VERSION = 12;
26769
+ const CURRENT_VERSION = 12.5;
26743
26770
  const INITIAL_SHEET_ID = "Sheet1";
26744
26771
  /**
26745
26772
  * This function tries to load anything that could look like a valid
@@ -27005,6 +27032,31 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
27005
27032
  return data;
27006
27033
  },
27007
27034
  },
27035
+ {
27036
+ description: "Fix datafilter duplication",
27037
+ from: 12,
27038
+ to: 12.5,
27039
+ applyMigration(data) {
27040
+ for (let sheet of data.sheets || []) {
27041
+ let knownDataFilterZones = [];
27042
+ for (let filterTable of sheet.filterTables || []) {
27043
+ const zone = toZone(filterTable.range);
27044
+ // See commit message for the details
27045
+ const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
27046
+ if (intersectZoneIndex !== -1) {
27047
+ knownDataFilterZones[intersectZoneIndex] = zone;
27048
+ }
27049
+ else {
27050
+ knownDataFilterZones.push(zone);
27051
+ }
27052
+ }
27053
+ sheet.filterTables = knownDataFilterZones.map((zone) => ({
27054
+ range: zoneToXc(zone),
27055
+ }));
27056
+ }
27057
+ return data;
27058
+ },
27059
+ },
27008
27060
  ];
27009
27061
  /**
27010
27062
  * This function is used to repair faulty data independently of the migration.
@@ -27766,9 +27818,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
27766
27818
  allowDispatch(cmd) {
27767
27819
  switch (cmd.type) {
27768
27820
  case "UPDATE_CELL":
27769
- return this.checkCellOutOfSheet(cmd);
27821
+ return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
27770
27822
  case "CLEAR_CELL":
27771
- return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
27823
+ return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
27772
27824
  default:
27773
27825
  return 0 /* CommandResult.Success */;
27774
27826
  }
@@ -27900,9 +27952,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
27900
27952
  format: cell.format ? getItemId(cell.format, formats) : undefined,
27901
27953
  content: cell.content || undefined,
27902
27954
  };
27903
- if (cell.isFormula()) {
27904
- cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
27905
- }
27906
27955
  }
27907
27956
  _sheet.cells = cells;
27908
27957
  }
@@ -27925,6 +27974,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
27925
27974
  const exportedCellData = sheet.cells[xc];
27926
27975
  exportedCellData.value = cell.evaluated.value;
27927
27976
  exportedCellData.isFormula = cell.isFormula();
27977
+ if (cell.isFormula()) {
27978
+ exportedCellData.content = this.buildFormulaContent(sheet.id, cell, cell.dependencies, true);
27979
+ }
27928
27980
  if (cell.format !== cell.evaluated.format) {
27929
27981
  exportedCellData.computedFormat = cell.evaluated.format;
27930
27982
  }
@@ -28127,6 +28179,18 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
28127
28179
  }
28128
28180
  return 0 /* CommandResult.Success */;
28129
28181
  }
28182
+ checkUselessUpdateCell(cmd) {
28183
+ const cell = this.getters.getCell(cmd.sheetId, cmd.col, cmd.row);
28184
+ const hasContent = "content" in cmd || "formula" in cmd;
28185
+ const hasStyle = "style" in cmd;
28186
+ const hasFormat = "format" in cmd;
28187
+ if ((!hasContent || (cell === null || cell === void 0 ? void 0 : cell.content) === cmd.content) &&
28188
+ (!hasStyle || deepEquals(cell === null || cell === void 0 ? void 0 : cell.style, cmd.style)) &&
28189
+ (!hasFormat || (cell === null || cell === void 0 ? void 0 : cell.format) === cmd.format)) {
28190
+ return 88 /* CommandResult.NoChanges */;
28191
+ }
28192
+ return 0 /* CommandResult.Success */;
28193
+ }
28130
28194
  }
28131
28195
  CellPlugin.getters = [
28132
28196
  "zoneToXC",
@@ -35367,9 +35431,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35367
35431
  }
35368
35432
  }
35369
35433
  }
35370
- unsubscribe() {
35371
- this.unfocus();
35372
- }
35373
35434
  // ---------------------------------------------------------------------------
35374
35435
  // Getters || only callable by the parent
35375
35436
  // ---------------------------------------------------------------------------
@@ -35581,9 +35642,6 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
35581
35642
  }
35582
35643
  (_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.handle(cmd);
35583
35644
  }
35584
- unsubscribe() {
35585
- this.unfocus();
35586
- }
35587
35645
  // ---------------------------------------------------------------------------
35588
35646
  // Getters
35589
35647
  // ---------------------------------------------------------------------------
@@ -37982,6 +38040,19 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
37982
38040
  sequence: 5,
37983
38041
  });
37984
38042
 
38043
+ class FocusableElement {
38044
+ constructor() {
38045
+ this.focusableElement = undefined;
38046
+ }
38047
+ setFocusableElement(element) {
38048
+ this.focusableElement = element;
38049
+ }
38050
+ focus() {
38051
+ var _a;
38052
+ (_a = this.focusableElement) === null || _a === void 0 ? void 0 : _a.focus();
38053
+ }
38054
+ }
38055
+
37985
38056
  // -----------------------------------------------------------------------------
37986
38057
  // SpreadSheet
37987
38058
  // -----------------------------------------------------------------------------
@@ -39125,8 +39196,8 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39125
39196
  &.corner {
39126
39197
  right: 0px;
39127
39198
  bottom: 0px;
39128
- height: ${SCROLLBAR_WIDTH$1}px;
39129
- width: ${SCROLLBAR_WIDTH$1}px;
39199
+ height: ${SCROLLBAR_WIDTH}px;
39200
+ width: ${SCROLLBAR_WIDTH}px;
39130
39201
  border-top: 1px solid #e2e3e3;
39131
39202
  border-left: 1px solid #e2e3e3;
39132
39203
  }
@@ -39170,6 +39241,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39170
39241
  toggleSidePanel: this.toggleSidePanel.bind(this),
39171
39242
  _t: Spreadsheet._t,
39172
39243
  clipboard: navigator.clipboard,
39244
+ focusableElement: new FocusableElement(),
39173
39245
  });
39174
39246
  owl.useExternalListener(window, "resize", () => this.render(true));
39175
39247
  owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
@@ -39272,17 +39344,18 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
39272
39344
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39273
39345
  this.composer.topBarFocus = "contentFocus";
39274
39346
  this.composer.gridFocusMode = "inactive";
39275
- this.setComposerContent({ selection } || {});
39347
+ this.setComposerContent({ selection });
39276
39348
  }
39277
- onGridComposerContentFocused() {
39349
+ onGridComposerContentFocused(selection) {
39278
39350
  if (this.model.getters.isReadonly()) {
39279
39351
  return;
39280
39352
  }
39281
39353
  this.model.dispatch("UNFOCUS_SELECTION_INPUT");
39282
39354
  this.composer.topBarFocus = "inactive";
39283
39355
  this.composer.gridFocusMode = "contentFocus";
39284
- this.setComposerContent({});
39356
+ this.setComposerContent({ selection });
39285
39357
  }
39358
+ // TODO: either both are defined or none of them. change those args to an object
39286
39359
  onGridComposerCellFocused(content, selection) {
39287
39360
  if (this.model.getters.isReadonly()) {
39288
39361
  return;
@@ -40655,18 +40728,17 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
40655
40728
  if (this.observers.find((sub) => sub.owner === owner)) {
40656
40729
  throw new Error("You are already subscribed forever");
40657
40730
  }
40658
- if ((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) {
40731
+ if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) && this.mainSubscription.owner !== owner) {
40659
40732
  (_c = (_b = this.mainSubscription.callbacks).release) === null || _c === void 0 ? void 0 : _c.call(_b);
40660
40733
  }
40661
40734
  this.mainSubscription = { owner, callbacks };
40662
40735
  }
40663
40736
  release(owner) {
40664
- var _a, _b, _c, _d;
40737
+ var _a;
40665
40738
  if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) !== owner ||
40666
40739
  this.observers.find((sub) => sub.owner === owner)) {
40667
40740
  return;
40668
40741
  }
40669
- (_d = (_b = this.mainSubscription) === null || _b === void 0 ? void 0 : (_c = _b.callbacks).release) === null || _d === void 0 ? void 0 : _d.call(_c);
40670
40742
  this.mainSubscription = this.defaultSubscription;
40671
40743
  }
40672
40744
  /**
@@ -43085,7 +43157,7 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43085
43157
  BOTTOMBAR_HEIGHT,
43086
43158
  DEFAULT_CELL_WIDTH,
43087
43159
  DEFAULT_CELL_HEIGHT,
43088
- SCROLLBAR_WIDTH: SCROLLBAR_WIDTH$1,
43160
+ SCROLLBAR_WIDTH,
43089
43161
  };
43090
43162
  const registries = {
43091
43163
  autofillModifiersRegistry,
@@ -43198,9 +43270,9 @@ day_count_convention (number, default=${DEFAULT_DAY_COUNT_CONVENTION} ) ${_lt("A
43198
43270
  Object.defineProperty(exports, '__esModule', { value: true });
43199
43271
 
43200
43272
 
43201
- __info__.version = '16.0.31';
43202
- __info__.date = '2024-02-02T13:44:18.740Z';
43203
- __info__.hash = 'a2e40a9';
43273
+ __info__.version = '16.0.33';
43274
+ __info__.date = '2024-02-16T14:49:10.674Z';
43275
+ __info__.hash = 'c0cefe8';
43204
43276
 
43205
43277
 
43206
43278
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);