@odoo/o-spreadsheet 17.0.25 → 17.0.27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,18 +2,19 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.25
6
- * @date 2024-06-10T09:33:40.022Z
7
- * @hash 1f01394
5
+ * @version 17.0.27
6
+ * @date 2024-07-02T09:01:48.383Z
7
+ * @hash c1c2d01
8
8
  */
9
9
 
10
10
  'use strict';
11
11
 
12
12
  var owl = require('@odoo/owl');
13
13
 
14
- // define a mock translation function, when o-spreadsheet runs in standalone it doesn't translate any string
15
- let _translate = (s) => s;
16
- let _loaded = () => false;
14
+ const defaultTranslate = (s) => s;
15
+ const defaultLoaded = () => false;
16
+ let _translate = defaultTranslate;
17
+ let _loaded = defaultLoaded;
17
18
  function sprintf(s, ...values) {
18
19
  if (values.length === 1 && typeof values[0] === "object" && !(values[0] instanceof String)) {
19
20
  const valuesDict = values[0];
@@ -25,7 +26,8 @@ function sprintf(s, ...values) {
25
26
  return s;
26
27
  }
27
28
  /***
28
- * Allow to inject a translation function from outside o-spreadsheet.
29
+ * Allow to inject a translation function from outside o-spreadsheet. This should be called before instantiating
30
+ * a model.
29
31
  * @param tfn the function that will do the translation
30
32
  * @param loaded a function that returns true when the translation is loaded
31
33
  */
@@ -33,6 +35,18 @@ function setTranslationMethod(tfn, loaded = () => true) {
33
35
  _translate = tfn;
34
36
  _loaded = loaded;
35
37
  }
38
+ /**
39
+ * If no translation function has been set, this will mark the translation are loaded.
40
+ *
41
+ * By default, the translations should not be set as loaded, otherwise top-level translated constants will never be
42
+ * translated. But if by the time the model is instantiated no custom translation function has been set, we can set
43
+ * the default translation function as loaded so o-spreadsheet can be run in standalone with no translations.
44
+ */
45
+ function setDefaultTranslationMethod() {
46
+ if (_translate === defaultTranslate && _loaded === defaultLoaded) {
47
+ _loaded = () => true;
48
+ }
49
+ }
36
50
  const _t = function (s, ...values) {
37
51
  if (!_loaded()) {
38
52
  return new LazyTranslatedString(s, values);
@@ -6933,7 +6947,7 @@ class Popover extends owl.Component {
6933
6947
  if (!anchor)
6934
6948
  return;
6935
6949
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
6936
- const elDims = {
6950
+ let elDims = {
6937
6951
  width: el.getBoundingClientRect().width,
6938
6952
  height: el.getBoundingClientRect().height,
6939
6953
  };
@@ -6941,7 +6955,14 @@ class Popover extends owl.Component {
6941
6955
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
6942
6956
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
6943
6957
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
6944
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6958
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
6959
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
6960
+ // Re-compute the dimensions after setting the max-width and max-height
6961
+ elDims = {
6962
+ width: el.getBoundingClientRect().width,
6963
+ height: el.getBoundingClientRect().height,
6964
+ };
6965
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6945
6966
  for (const property of Object.keys(style)) {
6946
6967
  el.style[property] = style[property];
6947
6968
  }
@@ -7017,8 +7038,6 @@ class PopoverPositionContext {
7017
7038
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
7018
7039
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
7019
7040
  const cssProperties = {
7020
- "max-height": maxHeight + "px",
7021
- "max-width": maxWidth + "px",
7022
7041
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
7023
7042
  this.spreadsheetOffset.y -
7024
7043
  verticalOffset +
@@ -24977,13 +24996,17 @@ SplitIntoColumnsPanel.props = {
24977
24996
  class SelectMenu extends owl.Component {
24978
24997
  static template = "o-spreadsheet-SelectMenu";
24979
24998
  static components = { Menu };
24999
+ menuId = new UuidGenerator().uuidv4();
24980
25000
  selectRef = owl.useRef("select");
24981
25001
  selectRect = useAbsoluteBoundingRect(this.selectRef);
24982
25002
  state = owl.useState({
24983
25003
  isMenuOpen: false,
24984
25004
  });
24985
- onClick() {
24986
- this.state.isMenuOpen = true;
25005
+ onClick(ev) {
25006
+ if (ev.closedMenuId === this.menuId) {
25007
+ return;
25008
+ }
25009
+ this.state.isMenuOpen = !this.state.isMenuOpen;
24987
25010
  }
24988
25011
  onMenuClosed() {
24989
25012
  this.state.isMenuOpen = false;
@@ -24991,7 +25014,7 @@ class SelectMenu extends owl.Component {
24991
25014
  get menuPosition() {
24992
25015
  return {
24993
25016
  x: this.selectRect.x,
24994
- y: this.selectRect.y,
25017
+ y: this.selectRect.y + this.selectRect.height,
24995
25018
  };
24996
25019
  }
24997
25020
  }
@@ -28022,7 +28045,7 @@ class FiguresContainer extends owl.Component {
28022
28045
  });
28023
28046
  }
28024
28047
  getContainerRect(container) {
28025
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
28048
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
28026
28049
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
28027
28050
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
28028
28051
  const width = viewWidth - x;
@@ -44347,7 +44370,10 @@ class Session extends EventBus {
44347
44370
  /**
44348
44371
  * Notify the server that the user client left the collaborative session
44349
44372
  */
44350
- leave() {
44373
+ leave(data) {
44374
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
44375
+ this.snapshot(data);
44376
+ }
44351
44377
  delete this.clients[this.clientId];
44352
44378
  this.transportService.leave(this.clientId);
44353
44379
  this.transportService.sendMessage({
@@ -44360,6 +44386,9 @@ class Session extends EventBus {
44360
44386
  * Send a snapshot of the spreadsheet to the collaboration server
44361
44387
  */
44362
44388
  snapshot(data) {
44389
+ if (this.pendingMessages.length !== 0) {
44390
+ return;
44391
+ }
44363
44392
  const snapshotId = this.uuidGenerator.uuidv4();
44364
44393
  this.transportService.sendMessage({
44365
44394
  type: "SNAPSHOT",
@@ -49140,10 +49169,8 @@ class EditionPlugin extends UIPlugin {
49140
49169
  const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
49141
49170
  return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
49142
49171
  });
49143
- // this function assumes that the previous range is always found because
49144
- // it's called when changing a highlight, which exists by definition
49145
49172
  if (!previousRefToken) {
49146
- throw new Error("Previous range not found");
49173
+ return;
49147
49174
  }
49148
49175
  const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
49149
49176
  this.selectionStart = previousRefToken.start;
@@ -51706,7 +51733,7 @@ class BottomBarSheet extends owl.Component {
51706
51733
  this.env.focusableElement.focus();
51707
51734
  }
51708
51735
  }
51709
- onClickSheetName(ev) {
51736
+ onMouseEventSheetName(ev) {
51710
51737
  if (this.state.isEditing)
51711
51738
  ev.stopPropagation();
51712
51739
  }
@@ -56899,6 +56926,7 @@ class Model extends EventBus {
56899
56926
  coreHandlers = [];
56900
56927
  constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
56901
56928
  super();
56929
+ setDefaultTranslationMethod();
56902
56930
  stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
56903
56931
  const workbookData = load(data, verboseImport);
56904
56932
  this.state = new StateObserver();
@@ -56974,7 +57002,7 @@ class Model extends EventBus {
56974
57002
  this.session.join(this.config.client);
56975
57003
  }
56976
57004
  leaveSession() {
56977
- this.session.leave();
57005
+ this.session.leave(this.exportData());
56978
57006
  }
56979
57007
  setupUiPlugin(Plugin) {
56980
57008
  const plugin = new Plugin(this.uiPluginConfig);
@@ -57398,6 +57426,7 @@ const helpers = {
57398
57426
  createAction,
57399
57427
  createActions,
57400
57428
  transformRangeData,
57429
+ deepEquals,
57401
57430
  };
57402
57431
  const links = {
57403
57432
  isMarkdownLink,
@@ -57476,6 +57505,6 @@ exports.setTranslationMethod = setTranslationMethod;
57476
57505
  exports.tokenize = tokenize;
57477
57506
 
57478
57507
 
57479
- __info__.version = "17.0.25";
57480
- __info__.date = "2024-06-10T09:33:40.022Z";
57481
- __info__.hash = "1f01394";
57508
+ __info__.version = "17.0.27";
57509
+ __info__.date = "2024-07-02T09:01:48.383Z";
57510
+ __info__.hash = "c1c2d01";
@@ -852,7 +852,7 @@ declare class Session extends EventBus<CollaborativeEvent> {
852
852
  /**
853
853
  * Notify the server that the user client left the collaborative session
854
854
  */
855
- leave(): void;
855
+ leave(data: WorkbookData): void;
856
856
  /**
857
857
  * Send a snapshot of the spreadsheet to the collaboration server
858
858
  */
@@ -993,6 +993,10 @@ declare function isDefined<T>(argument: T | undefined): argument is T;
993
993
  * Lazy value computed by the provided function.
994
994
  */
995
995
  declare function lazy<T>(fn: (() => T) | T): Lazy<T>;
996
+ /**
997
+ * Compares two objects.
998
+ */
999
+ declare function deepEquals(o1: any, o2: any, ignoreFunctions?: "ignoreFunctions"): boolean;
996
1000
 
997
1001
  interface ConstructorArgs {
998
1002
  readonly zone: Readonly<Zone | UnboundedZone>;
@@ -6189,7 +6193,7 @@ declare class BottomBarSheet extends Component<Props$v, SpreadsheetChildEnv> {
6189
6193
  private activateSheet;
6190
6194
  onDblClick(): void;
6191
6195
  onKeyDown(ev: KeyboardEvent): void;
6192
- onClickSheetName(ev: MouseEvent): void;
6196
+ onMouseEventSheetName(ev: MouseEvent): void;
6193
6197
  private startEdition;
6194
6198
  private stopEdition;
6195
6199
  private cancelEdition;
@@ -7819,7 +7823,8 @@ type SprintfValues = (string | String | number)[] | [{
7819
7823
  }];
7820
7824
  type TranslationFunction = (string: string, ...values: SprintfValues) => string;
7821
7825
  /***
7822
- * Allow to inject a translation function from outside o-spreadsheet.
7826
+ * Allow to inject a translation function from outside o-spreadsheet. This should be called before instantiating
7827
+ * a model.
7823
7828
  * @param tfn the function that will do the translation
7824
7829
  * @param loaded a function that returns true when the translation is loaded
7825
7830
  */
@@ -7934,6 +7939,7 @@ declare const helpers: {
7934
7939
  createAction: typeof createAction;
7935
7940
  createActions: typeof createActions;
7936
7941
  transformRangeData: typeof transformRangeData;
7942
+ deepEquals: typeof deepEquals;
7937
7943
  };
7938
7944
  declare const links: {
7939
7945
  isMarkdownLink: typeof isMarkdownLink;
@@ -2,16 +2,17 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.25
6
- * @date 2024-06-10T09:33:40.022Z
7
- * @hash 1f01394
5
+ * @version 17.0.27
6
+ * @date 2024-07-02T09:01:48.383Z
7
+ * @hash c1c2d01
8
8
  */
9
9
 
10
10
  import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
11
11
 
12
- // define a mock translation function, when o-spreadsheet runs in standalone it doesn't translate any string
13
- let _translate = (s) => s;
14
- let _loaded = () => false;
12
+ const defaultTranslate = (s) => s;
13
+ const defaultLoaded = () => false;
14
+ let _translate = defaultTranslate;
15
+ let _loaded = defaultLoaded;
15
16
  function sprintf(s, ...values) {
16
17
  if (values.length === 1 && typeof values[0] === "object" && !(values[0] instanceof String)) {
17
18
  const valuesDict = values[0];
@@ -23,7 +24,8 @@ function sprintf(s, ...values) {
23
24
  return s;
24
25
  }
25
26
  /***
26
- * Allow to inject a translation function from outside o-spreadsheet.
27
+ * Allow to inject a translation function from outside o-spreadsheet. This should be called before instantiating
28
+ * a model.
27
29
  * @param tfn the function that will do the translation
28
30
  * @param loaded a function that returns true when the translation is loaded
29
31
  */
@@ -31,6 +33,18 @@ function setTranslationMethod(tfn, loaded = () => true) {
31
33
  _translate = tfn;
32
34
  _loaded = loaded;
33
35
  }
36
+ /**
37
+ * If no translation function has been set, this will mark the translation are loaded.
38
+ *
39
+ * By default, the translations should not be set as loaded, otherwise top-level translated constants will never be
40
+ * translated. But if by the time the model is instantiated no custom translation function has been set, we can set
41
+ * the default translation function as loaded so o-spreadsheet can be run in standalone with no translations.
42
+ */
43
+ function setDefaultTranslationMethod() {
44
+ if (_translate === defaultTranslate && _loaded === defaultLoaded) {
45
+ _loaded = () => true;
46
+ }
47
+ }
34
48
  const _t = function (s, ...values) {
35
49
  if (!_loaded()) {
36
50
  return new LazyTranslatedString(s, values);
@@ -6931,7 +6945,7 @@ class Popover extends Component {
6931
6945
  if (!anchor)
6932
6946
  return;
6933
6947
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
6934
- const elDims = {
6948
+ let elDims = {
6935
6949
  width: el.getBoundingClientRect().width,
6936
6950
  height: el.getBoundingClientRect().height,
6937
6951
  };
@@ -6939,7 +6953,14 @@ class Popover extends Component {
6939
6953
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
6940
6954
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
6941
6955
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
6942
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6956
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
6957
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
6958
+ // Re-compute the dimensions after setting the max-width and max-height
6959
+ elDims = {
6960
+ width: el.getBoundingClientRect().width,
6961
+ height: el.getBoundingClientRect().height,
6962
+ };
6963
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6943
6964
  for (const property of Object.keys(style)) {
6944
6965
  el.style[property] = style[property];
6945
6966
  }
@@ -7015,8 +7036,6 @@ class PopoverPositionContext {
7015
7036
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
7016
7037
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
7017
7038
  const cssProperties = {
7018
- "max-height": maxHeight + "px",
7019
- "max-width": maxWidth + "px",
7020
7039
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
7021
7040
  this.spreadsheetOffset.y -
7022
7041
  verticalOffset +
@@ -24975,13 +24994,17 @@ SplitIntoColumnsPanel.props = {
24975
24994
  class SelectMenu extends Component {
24976
24995
  static template = "o-spreadsheet-SelectMenu";
24977
24996
  static components = { Menu };
24997
+ menuId = new UuidGenerator().uuidv4();
24978
24998
  selectRef = useRef("select");
24979
24999
  selectRect = useAbsoluteBoundingRect(this.selectRef);
24980
25000
  state = useState({
24981
25001
  isMenuOpen: false,
24982
25002
  });
24983
- onClick() {
24984
- this.state.isMenuOpen = true;
25003
+ onClick(ev) {
25004
+ if (ev.closedMenuId === this.menuId) {
25005
+ return;
25006
+ }
25007
+ this.state.isMenuOpen = !this.state.isMenuOpen;
24985
25008
  }
24986
25009
  onMenuClosed() {
24987
25010
  this.state.isMenuOpen = false;
@@ -24989,7 +25012,7 @@ class SelectMenu extends Component {
24989
25012
  get menuPosition() {
24990
25013
  return {
24991
25014
  x: this.selectRect.x,
24992
- y: this.selectRect.y,
25015
+ y: this.selectRect.y + this.selectRect.height,
24993
25016
  };
24994
25017
  }
24995
25018
  }
@@ -28020,7 +28043,7 @@ class FiguresContainer extends Component {
28020
28043
  });
28021
28044
  }
28022
28045
  getContainerRect(container) {
28023
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
28046
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
28024
28047
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
28025
28048
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
28026
28049
  const width = viewWidth - x;
@@ -44345,7 +44368,10 @@ class Session extends EventBus {
44345
44368
  /**
44346
44369
  * Notify the server that the user client left the collaborative session
44347
44370
  */
44348
- leave() {
44371
+ leave(data) {
44372
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
44373
+ this.snapshot(data);
44374
+ }
44349
44375
  delete this.clients[this.clientId];
44350
44376
  this.transportService.leave(this.clientId);
44351
44377
  this.transportService.sendMessage({
@@ -44358,6 +44384,9 @@ class Session extends EventBus {
44358
44384
  * Send a snapshot of the spreadsheet to the collaboration server
44359
44385
  */
44360
44386
  snapshot(data) {
44387
+ if (this.pendingMessages.length !== 0) {
44388
+ return;
44389
+ }
44361
44390
  const snapshotId = this.uuidGenerator.uuidv4();
44362
44391
  this.transportService.sendMessage({
44363
44392
  type: "SNAPSHOT",
@@ -49138,10 +49167,8 @@ class EditionPlugin extends UIPlugin {
49138
49167
  const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
49139
49168
  return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
49140
49169
  });
49141
- // this function assumes that the previous range is always found because
49142
- // it's called when changing a highlight, which exists by definition
49143
49170
  if (!previousRefToken) {
49144
- throw new Error("Previous range not found");
49171
+ return;
49145
49172
  }
49146
49173
  const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
49147
49174
  this.selectionStart = previousRefToken.start;
@@ -51704,7 +51731,7 @@ class BottomBarSheet extends Component {
51704
51731
  this.env.focusableElement.focus();
51705
51732
  }
51706
51733
  }
51707
- onClickSheetName(ev) {
51734
+ onMouseEventSheetName(ev) {
51708
51735
  if (this.state.isEditing)
51709
51736
  ev.stopPropagation();
51710
51737
  }
@@ -56897,6 +56924,7 @@ class Model extends EventBus {
56897
56924
  coreHandlers = [];
56898
56925
  constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
56899
56926
  super();
56927
+ setDefaultTranslationMethod();
56900
56928
  stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
56901
56929
  const workbookData = load(data, verboseImport);
56902
56930
  this.state = new StateObserver();
@@ -56972,7 +57000,7 @@ class Model extends EventBus {
56972
57000
  this.session.join(this.config.client);
56973
57001
  }
56974
57002
  leaveSession() {
56975
- this.session.leave();
57003
+ this.session.leave(this.exportData());
56976
57004
  }
56977
57005
  setupUiPlugin(Plugin) {
56978
57006
  const plugin = new Plugin(this.uiPluginConfig);
@@ -57396,6 +57424,7 @@ const helpers = {
57396
57424
  createAction,
57397
57425
  createActions,
57398
57426
  transformRangeData,
57427
+ deepEquals,
57399
57428
  };
57400
57429
  const links = {
57401
57430
  isMarkdownLink,
@@ -57439,6 +57468,6 @@ const constants = {
57439
57468
  export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
57440
57469
 
57441
57470
 
57442
- __info__.version = "17.0.25";
57443
- __info__.date = "2024-06-10T09:33:40.022Z";
57444
- __info__.hash = "1f01394";
57471
+ __info__.version = "17.0.27";
57472
+ __info__.date = "2024-07-02T09:01:48.383Z";
57473
+ __info__.hash = "c1c2d01";
@@ -2,17 +2,18 @@
2
2
  /**
3
3
  * This file is generated by o-spreadsheet build tools. Do not edit it.
4
4
  * @see https://github.com/odoo/o-spreadsheet
5
- * @version 17.0.25
6
- * @date 2024-06-10T09:33:40.022Z
7
- * @hash 1f01394
5
+ * @version 17.0.27
6
+ * @date 2024-07-02T09:01:48.383Z
7
+ * @hash c1c2d01
8
8
  */
9
9
 
10
10
  (function (exports, owl) {
11
11
  'use strict';
12
12
 
13
- // define a mock translation function, when o-spreadsheet runs in standalone it doesn't translate any string
14
- let _translate = (s) => s;
15
- let _loaded = () => false;
13
+ const defaultTranslate = (s) => s;
14
+ const defaultLoaded = () => false;
15
+ let _translate = defaultTranslate;
16
+ let _loaded = defaultLoaded;
16
17
  function sprintf(s, ...values) {
17
18
  if (values.length === 1 && typeof values[0] === "object" && !(values[0] instanceof String)) {
18
19
  const valuesDict = values[0];
@@ -24,7 +25,8 @@
24
25
  return s;
25
26
  }
26
27
  /***
27
- * Allow to inject a translation function from outside o-spreadsheet.
28
+ * Allow to inject a translation function from outside o-spreadsheet. This should be called before instantiating
29
+ * a model.
28
30
  * @param tfn the function that will do the translation
29
31
  * @param loaded a function that returns true when the translation is loaded
30
32
  */
@@ -32,6 +34,18 @@
32
34
  _translate = tfn;
33
35
  _loaded = loaded;
34
36
  }
37
+ /**
38
+ * If no translation function has been set, this will mark the translation are loaded.
39
+ *
40
+ * By default, the translations should not be set as loaded, otherwise top-level translated constants will never be
41
+ * translated. But if by the time the model is instantiated no custom translation function has been set, we can set
42
+ * the default translation function as loaded so o-spreadsheet can be run in standalone with no translations.
43
+ */
44
+ function setDefaultTranslationMethod() {
45
+ if (_translate === defaultTranslate && _loaded === defaultLoaded) {
46
+ _loaded = () => true;
47
+ }
48
+ }
35
49
  const _t = function (s, ...values) {
36
50
  if (!_loaded()) {
37
51
  return new LazyTranslatedString(s, values);
@@ -6932,7 +6946,7 @@
6932
6946
  if (!anchor)
6933
6947
  return;
6934
6948
  const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
6935
- const elDims = {
6949
+ let elDims = {
6936
6950
  width: el.getBoundingClientRect().width,
6937
6951
  height: el.getBoundingClientRect().height,
6938
6952
  };
@@ -6940,7 +6954,14 @@
6940
6954
  const popoverPositionHelper = this.props.positioning === "BottomLeft"
6941
6955
  ? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
6942
6956
  : new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
6943
- const style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6957
+ el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
6958
+ el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
6959
+ // Re-compute the dimensions after setting the max-width and max-height
6960
+ elDims = {
6961
+ width: el.getBoundingClientRect().width,
6962
+ height: el.getBoundingClientRect().height,
6963
+ };
6964
+ let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
6944
6965
  for (const property of Object.keys(style)) {
6945
6966
  el.style[property] = style[property];
6946
6967
  }
@@ -7016,8 +7037,6 @@
7016
7037
  const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
7017
7038
  verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
7018
7039
  const cssProperties = {
7019
- "max-height": maxHeight + "px",
7020
- "max-width": maxWidth + "px",
7021
7040
  top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
7022
7041
  this.spreadsheetOffset.y -
7023
7042
  verticalOffset +
@@ -24976,13 +24995,17 @@
24976
24995
  class SelectMenu extends owl.Component {
24977
24996
  static template = "o-spreadsheet-SelectMenu";
24978
24997
  static components = { Menu };
24998
+ menuId = new UuidGenerator().uuidv4();
24979
24999
  selectRef = owl.useRef("select");
24980
25000
  selectRect = useAbsoluteBoundingRect(this.selectRef);
24981
25001
  state = owl.useState({
24982
25002
  isMenuOpen: false,
24983
25003
  });
24984
- onClick() {
24985
- this.state.isMenuOpen = true;
25004
+ onClick(ev) {
25005
+ if (ev.closedMenuId === this.menuId) {
25006
+ return;
25007
+ }
25008
+ this.state.isMenuOpen = !this.state.isMenuOpen;
24986
25009
  }
24987
25010
  onMenuClosed() {
24988
25011
  this.state.isMenuOpen = false;
@@ -24990,7 +25013,7 @@
24990
25013
  get menuPosition() {
24991
25014
  return {
24992
25015
  x: this.selectRect.x,
24993
- y: this.selectRect.y,
25016
+ y: this.selectRect.y + this.selectRect.height,
24994
25017
  };
24995
25018
  }
24996
25019
  }
@@ -28021,7 +28044,7 @@
28021
28044
  });
28022
28045
  }
28023
28046
  getContainerRect(container) {
28024
- const { width: viewWidth, height: viewHeight } = this.env.model.getters.getMainViewportRect();
28047
+ const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
28025
28048
  const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
28026
28049
  const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
28027
28050
  const width = viewWidth - x;
@@ -44346,7 +44369,10 @@
44346
44369
  /**
44347
44370
  * Notify the server that the user client left the collaborative session
44348
44371
  */
44349
- leave() {
44372
+ leave(data) {
44373
+ if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
44374
+ this.snapshot(data);
44375
+ }
44350
44376
  delete this.clients[this.clientId];
44351
44377
  this.transportService.leave(this.clientId);
44352
44378
  this.transportService.sendMessage({
@@ -44359,6 +44385,9 @@
44359
44385
  * Send a snapshot of the spreadsheet to the collaboration server
44360
44386
  */
44361
44387
  snapshot(data) {
44388
+ if (this.pendingMessages.length !== 0) {
44389
+ return;
44390
+ }
44362
44391
  const snapshotId = this.uuidGenerator.uuidv4();
44363
44392
  this.transportService.sendMessage({
44364
44393
  type: "SNAPSHOT",
@@ -49139,10 +49168,8 @@
49139
49168
  const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
49140
49169
  return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
49141
49170
  });
49142
- // this function assumes that the previous range is always found because
49143
- // it's called when changing a highlight, which exists by definition
49144
49171
  if (!previousRefToken) {
49145
- throw new Error("Previous range not found");
49172
+ return;
49146
49173
  }
49147
49174
  const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
49148
49175
  this.selectionStart = previousRefToken.start;
@@ -51705,7 +51732,7 @@
51705
51732
  this.env.focusableElement.focus();
51706
51733
  }
51707
51734
  }
51708
- onClickSheetName(ev) {
51735
+ onMouseEventSheetName(ev) {
51709
51736
  if (this.state.isEditing)
51710
51737
  ev.stopPropagation();
51711
51738
  }
@@ -56898,6 +56925,7 @@
56898
56925
  coreHandlers = [];
56899
56926
  constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
56900
56927
  super();
56928
+ setDefaultTranslationMethod();
56901
56929
  stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
56902
56930
  const workbookData = load(data, verboseImport);
56903
56931
  this.state = new StateObserver();
@@ -56973,7 +57001,7 @@
56973
57001
  this.session.join(this.config.client);
56974
57002
  }
56975
57003
  leaveSession() {
56976
- this.session.leave();
57004
+ this.session.leave(this.exportData());
56977
57005
  }
56978
57006
  setupUiPlugin(Plugin) {
56979
57007
  const plugin = new Plugin(this.uiPluginConfig);
@@ -57397,6 +57425,7 @@
57397
57425
  createAction,
57398
57426
  createActions,
57399
57427
  transformRangeData,
57428
+ deepEquals,
57400
57429
  };
57401
57430
  const links = {
57402
57431
  isMarkdownLink,
@@ -57475,9 +57504,9 @@
57475
57504
  exports.tokenize = tokenize;
57476
57505
 
57477
57506
 
57478
- __info__.version = "17.0.25";
57479
- __info__.date = "2024-06-10T09:33:40.022Z";
57480
- __info__.hash = "1f01394";
57507
+ __info__.version = "17.0.27";
57508
+ __info__.date = "2024-07-02T09:01:48.383Z";
57509
+ __info__.hash = "c1c2d01";
57481
57510
 
57482
57511
 
57483
57512
  })(this.o_spreadsheet = this.o_spreadsheet || {}, owl);