@odoo/o-spreadsheet 17.0.23 → 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.
- package/dist/o-spreadsheet.cjs.js +141 -51
- package/dist/o-spreadsheet.d.ts +9 -3
- package/dist/o-spreadsheet.esm.js +141 -51
- package/dist/o-spreadsheet.iife.js +141 -51
- package/dist/o-spreadsheet.iife.min.js +354 -354
- package/dist/o_spreadsheet.xml +6 -4
- package/package.json +1 -1
|
@@ -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.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
let
|
|
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);
|
|
@@ -394,7 +408,10 @@ function deepCopy(obj) {
|
|
|
394
408
|
* Check if the object is a plain old javascript object.
|
|
395
409
|
*/
|
|
396
410
|
function isPlainObject(obj) {
|
|
397
|
-
return typeof obj === "object" &&
|
|
411
|
+
return (typeof obj === "object" &&
|
|
412
|
+
obj !== null &&
|
|
413
|
+
// obj.constructor can be undefined when there's no prototype (`Object.create(null, {})`)
|
|
414
|
+
(obj?.constructor === Object || obj?.constructor === undefined));
|
|
398
415
|
}
|
|
399
416
|
/**
|
|
400
417
|
* Sanitize the name of a sheet, by eventually removing quotes
|
|
@@ -4306,8 +4323,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
|
4306
4323
|
/**
|
|
4307
4324
|
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
4308
4325
|
*/
|
|
4309
|
-
function
|
|
4310
|
-
|
|
4326
|
+
function createValidRange(getters, sheetId, xc) {
|
|
4327
|
+
if (!xc)
|
|
4328
|
+
return;
|
|
4329
|
+
const range = getters.getRangeFromSheetXC(sheetId, xc);
|
|
4330
|
+
return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
|
|
4311
4331
|
}
|
|
4312
4332
|
/**
|
|
4313
4333
|
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
@@ -5235,8 +5255,8 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
5235
5255
|
type = "scorecard";
|
|
5236
5256
|
constructor(definition, sheetId, getters) {
|
|
5237
5257
|
super(definition, sheetId, getters);
|
|
5238
|
-
this.keyValue =
|
|
5239
|
-
this.baseline =
|
|
5258
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
5259
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
5240
5260
|
this.baselineMode = definition.baselineMode;
|
|
5241
5261
|
this.baselineDescr = definition.baselineDescr;
|
|
5242
5262
|
this.background = definition.background;
|
|
@@ -6707,6 +6727,7 @@ const FilterMenuPopoverBuilder = {
|
|
|
6707
6727
|
};
|
|
6708
6728
|
|
|
6709
6729
|
const macRegex = /Mac/i;
|
|
6730
|
+
const MODIFIER_KEYS$1 = ["Shift", "Control", "Alt", "Meta"];
|
|
6710
6731
|
/**
|
|
6711
6732
|
* Return true if the event was triggered from
|
|
6712
6733
|
* a child element.
|
|
@@ -6745,6 +6766,31 @@ function* iterateChildren(el) {
|
|
|
6745
6766
|
function getOpenedMenus() {
|
|
6746
6767
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
6747
6768
|
}
|
|
6769
|
+
const letterRegex = /^[a-zA-Z]$/;
|
|
6770
|
+
/**
|
|
6771
|
+
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
6772
|
+
*
|
|
6773
|
+
* @argument ev - The keyboard event to transform
|
|
6774
|
+
* @argument mode - Use either ev.key of ev.code to get the string shortcut
|
|
6775
|
+
*
|
|
6776
|
+
* @example
|
|
6777
|
+
* event : { ctrlKey: true, key: "a" } => "Ctrl+A"
|
|
6778
|
+
* event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
|
|
6779
|
+
*/
|
|
6780
|
+
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
6781
|
+
let keyDownString = "";
|
|
6782
|
+
if (!MODIFIER_KEYS$1.includes(ev.key)) {
|
|
6783
|
+
if (isCtrlKey(ev))
|
|
6784
|
+
keyDownString += "Ctrl+";
|
|
6785
|
+
if (ev.altKey)
|
|
6786
|
+
keyDownString += "Alt+";
|
|
6787
|
+
if (ev.shiftKey)
|
|
6788
|
+
keyDownString += "Shift+";
|
|
6789
|
+
}
|
|
6790
|
+
const key = mode === "key" ? ev.key : ev.code;
|
|
6791
|
+
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
6792
|
+
return keyDownString;
|
|
6793
|
+
}
|
|
6748
6794
|
function isMacOS() {
|
|
6749
6795
|
return Boolean(macRegex.test(navigator.userAgent));
|
|
6750
6796
|
}
|
|
@@ -6763,8 +6809,7 @@ function isCtrlKey(ev) {
|
|
|
6763
6809
|
*/
|
|
6764
6810
|
function useSpreadsheetRect() {
|
|
6765
6811
|
const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
6766
|
-
let spreadsheetElement =
|
|
6767
|
-
updatePosition();
|
|
6812
|
+
let spreadsheetElement = null;
|
|
6768
6813
|
function updatePosition() {
|
|
6769
6814
|
if (!spreadsheetElement) {
|
|
6770
6815
|
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
|
@@ -6902,7 +6947,7 @@ class Popover extends owl.Component {
|
|
|
6902
6947
|
if (!anchor)
|
|
6903
6948
|
return;
|
|
6904
6949
|
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
|
6905
|
-
|
|
6950
|
+
let elDims = {
|
|
6906
6951
|
width: el.getBoundingClientRect().width,
|
|
6907
6952
|
height: el.getBoundingClientRect().height,
|
|
6908
6953
|
};
|
|
@@ -6910,7 +6955,14 @@ class Popover extends owl.Component {
|
|
|
6910
6955
|
const popoverPositionHelper = this.props.positioning === "BottomLeft"
|
|
6911
6956
|
? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
|
|
6912
6957
|
: new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
|
|
6913
|
-
|
|
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);
|
|
6914
6966
|
for (const property of Object.keys(style)) {
|
|
6915
6967
|
el.style[property] = style[property];
|
|
6916
6968
|
}
|
|
@@ -6986,8 +7038,6 @@ class PopoverPositionContext {
|
|
|
6986
7038
|
const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
|
|
6987
7039
|
verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
|
|
6988
7040
|
const cssProperties = {
|
|
6989
|
-
"max-height": maxHeight + "px",
|
|
6990
|
-
"max-width": maxWidth + "px",
|
|
6991
7041
|
top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
|
|
6992
7042
|
this.spreadsheetOffset.y -
|
|
6993
7043
|
verticalOffset +
|
|
@@ -8537,7 +8587,7 @@ function chartToImage(runtime, figure, type) {
|
|
|
8537
8587
|
if ("chartJsConfig" in runtime) {
|
|
8538
8588
|
runtime.chartJsConfig.plugins = [backgroundColorChartJSPlugin];
|
|
8539
8589
|
// @ts-ignore
|
|
8540
|
-
const chart = new window.Chart(canvas, runtime.chartJsConfig);
|
|
8590
|
+
const chart = new window.Chart(canvas, deepCopy(runtime.chartJsConfig));
|
|
8541
8591
|
const imgContent = chart.toBase64Image();
|
|
8542
8592
|
chart.destroy();
|
|
8543
8593
|
div.remove();
|
|
@@ -8581,7 +8631,7 @@ class BarChart extends AbstractChart {
|
|
|
8581
8631
|
constructor(definition, sheetId, getters) {
|
|
8582
8632
|
super(definition, sheetId, getters);
|
|
8583
8633
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
8584
|
-
this.labelRange =
|
|
8634
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
8585
8635
|
this.background = definition.background;
|
|
8586
8636
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
8587
8637
|
this.legendPosition = definition.legendPosition;
|
|
@@ -8824,7 +8874,7 @@ class GaugeChart extends AbstractChart {
|
|
|
8824
8874
|
type = "gauge";
|
|
8825
8875
|
constructor(definition, sheetId, getters) {
|
|
8826
8876
|
super(definition, sheetId, getters);
|
|
8827
|
-
this.dataRange =
|
|
8877
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
8828
8878
|
this.sectionRule = definition.sectionRule;
|
|
8829
8879
|
this.background = definition.background;
|
|
8830
8880
|
}
|
|
@@ -9158,7 +9208,7 @@ class LineChart extends AbstractChart {
|
|
|
9158
9208
|
constructor(definition, sheetId, getters) {
|
|
9159
9209
|
super(definition, sheetId, getters);
|
|
9160
9210
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
9161
|
-
this.labelRange =
|
|
9211
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
9162
9212
|
this.background = definition.background;
|
|
9163
9213
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
9164
9214
|
this.legendPosition = definition.legendPosition;
|
|
@@ -9478,7 +9528,7 @@ class PieChart extends AbstractChart {
|
|
|
9478
9528
|
constructor(definition, sheetId, getters) {
|
|
9479
9529
|
super(definition, sheetId, getters);
|
|
9480
9530
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
9481
|
-
this.labelRange =
|
|
9531
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
9482
9532
|
this.background = definition.background;
|
|
9483
9533
|
this.legendPosition = definition.legendPosition;
|
|
9484
9534
|
this.aggregated = definition.aggregated;
|
|
@@ -21725,7 +21775,7 @@ class LineBarPieConfigPanel extends owl.Component {
|
|
|
21725
21775
|
}
|
|
21726
21776
|
const getters = this.env.model.getters;
|
|
21727
21777
|
const sheetId = getters.getActiveSheetId();
|
|
21728
|
-
const labelRange =
|
|
21778
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
21729
21779
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
21730
21780
|
if (dataSets.length) {
|
|
21731
21781
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -24946,13 +24996,17 @@ SplitIntoColumnsPanel.props = {
|
|
|
24946
24996
|
class SelectMenu extends owl.Component {
|
|
24947
24997
|
static template = "o-spreadsheet-SelectMenu";
|
|
24948
24998
|
static components = { Menu };
|
|
24999
|
+
menuId = new UuidGenerator().uuidv4();
|
|
24949
25000
|
selectRef = owl.useRef("select");
|
|
24950
25001
|
selectRect = useAbsoluteBoundingRect(this.selectRef);
|
|
24951
25002
|
state = owl.useState({
|
|
24952
25003
|
isMenuOpen: false,
|
|
24953
25004
|
});
|
|
24954
|
-
onClick() {
|
|
24955
|
-
this.
|
|
25005
|
+
onClick(ev) {
|
|
25006
|
+
if (ev.closedMenuId === this.menuId) {
|
|
25007
|
+
return;
|
|
25008
|
+
}
|
|
25009
|
+
this.state.isMenuOpen = !this.state.isMenuOpen;
|
|
24956
25010
|
}
|
|
24957
25011
|
onMenuClosed() {
|
|
24958
25012
|
this.state.isMenuOpen = false;
|
|
@@ -24960,7 +25014,7 @@ class SelectMenu extends owl.Component {
|
|
|
24960
25014
|
get menuPosition() {
|
|
24961
25015
|
return {
|
|
24962
25016
|
x: this.selectRect.x,
|
|
24963
|
-
y: this.selectRect.y,
|
|
25017
|
+
y: this.selectRect.y + this.selectRect.height,
|
|
24964
25018
|
};
|
|
24965
25019
|
}
|
|
24966
25020
|
}
|
|
@@ -25767,14 +25821,14 @@ class FigureComponent extends owl.Component {
|
|
|
25767
25821
|
}
|
|
25768
25822
|
onKeyDown(ev) {
|
|
25769
25823
|
const figure = this.props.figure;
|
|
25770
|
-
|
|
25824
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
25825
|
+
switch (keyDownShortcut) {
|
|
25771
25826
|
case "Delete":
|
|
25772
25827
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
25773
25828
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
25774
25829
|
id: figure.id,
|
|
25775
25830
|
});
|
|
25776
25831
|
this.props.onFigureDeleted();
|
|
25777
|
-
ev.stopPropagation();
|
|
25778
25832
|
ev.preventDefault();
|
|
25779
25833
|
ev.stopPropagation();
|
|
25780
25834
|
break;
|
|
@@ -25795,7 +25849,22 @@ class FigureComponent extends owl.Component {
|
|
|
25795
25849
|
x: figure.x + delta[0],
|
|
25796
25850
|
y: figure.y + delta[1],
|
|
25797
25851
|
});
|
|
25852
|
+
ev.preventDefault();
|
|
25853
|
+
ev.stopPropagation();
|
|
25854
|
+
break;
|
|
25855
|
+
case "Ctrl+A":
|
|
25856
|
+
// Maybe in the future we will implement a way to select all figures
|
|
25857
|
+
ev.preventDefault();
|
|
25798
25858
|
ev.stopPropagation();
|
|
25859
|
+
break;
|
|
25860
|
+
case "Ctrl+Y":
|
|
25861
|
+
case "Ctrl+Z":
|
|
25862
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
25863
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
25864
|
+
}
|
|
25865
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
25866
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
25867
|
+
}
|
|
25799
25868
|
ev.preventDefault();
|
|
25800
25869
|
ev.stopPropagation();
|
|
25801
25870
|
break;
|
|
@@ -26815,8 +26884,15 @@ class Composer extends owl.Component {
|
|
|
26815
26884
|
}
|
|
26816
26885
|
onPaste(ev) {
|
|
26817
26886
|
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
26887
|
+
// let the browser clipboard work
|
|
26818
26888
|
ev.stopPropagation();
|
|
26819
26889
|
}
|
|
26890
|
+
else {
|
|
26891
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
26892
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
26893
|
+
// the native "paste" to occur.
|
|
26894
|
+
ev.preventDefault();
|
|
26895
|
+
}
|
|
26820
26896
|
}
|
|
26821
26897
|
/*
|
|
26822
26898
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -26825,10 +26901,6 @@ class Composer extends owl.Component {
|
|
|
26825
26901
|
if (!this.shouldProcessInputEvents) {
|
|
26826
26902
|
return;
|
|
26827
26903
|
}
|
|
26828
|
-
if (ev.inputType === "insertFromPaste" &&
|
|
26829
|
-
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26830
|
-
return;
|
|
26831
|
-
}
|
|
26832
26904
|
ev.stopPropagation();
|
|
26833
26905
|
let content;
|
|
26834
26906
|
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
@@ -27276,10 +27348,7 @@ class GridComposer extends owl.Component {
|
|
|
27276
27348
|
}
|
|
27277
27349
|
get containerStyle() {
|
|
27278
27350
|
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
27279
|
-
return `
|
|
27280
|
-
position: absolute;
|
|
27281
|
-
z-index: -1000;
|
|
27282
|
-
`;
|
|
27351
|
+
return `z-index: -1000;`;
|
|
27283
27352
|
}
|
|
27284
27353
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
27285
27354
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -27976,7 +28045,7 @@ class FiguresContainer extends owl.Component {
|
|
|
27976
28045
|
});
|
|
27977
28046
|
}
|
|
27978
28047
|
getContainerRect(container) {
|
|
27979
|
-
const { width: viewWidth, height: viewHeight } = this.env.model.getters.
|
|
28048
|
+
const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
|
|
27980
28049
|
const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
|
|
27981
28050
|
const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
|
|
27982
28051
|
const width = viewWidth - x;
|
|
@@ -38572,6 +38641,9 @@ class RangeAdapter {
|
|
|
38572
38641
|
if (range.invalidXc) {
|
|
38573
38642
|
return range.invalidXc;
|
|
38574
38643
|
}
|
|
38644
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
38645
|
+
return INCORRECT_RANGE_STRING;
|
|
38646
|
+
}
|
|
38575
38647
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
38576
38648
|
return INCORRECT_RANGE_STRING;
|
|
38577
38649
|
}
|
|
@@ -42023,16 +42095,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
42023
42095
|
let newContent = undefined;
|
|
42024
42096
|
let newFormat = undefined;
|
|
42025
42097
|
let isExported = true;
|
|
42098
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
42026
42099
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
42027
42100
|
if (formulaCell) {
|
|
42028
42101
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
42029
42102
|
isFormula = isExported;
|
|
42030
42103
|
if (!isExported) {
|
|
42031
|
-
|
|
42032
|
-
|
|
42104
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
42105
|
+
// nothing* ,we don't export it.
|
|
42106
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
42107
|
+
// the empty string.
|
|
42108
|
+
if (value !== "") {
|
|
42109
|
+
newContent = value.toString();
|
|
42110
|
+
newFormat = evaluatedCell.format;
|
|
42111
|
+
}
|
|
42033
42112
|
}
|
|
42034
42113
|
}
|
|
42035
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
42036
42114
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
42037
42115
|
const format = newFormat
|
|
42038
42116
|
? getItemId(newFormat, data.formats)
|
|
@@ -44292,7 +44370,10 @@ class Session extends EventBus {
|
|
|
44292
44370
|
/**
|
|
44293
44371
|
* Notify the server that the user client left the collaborative session
|
|
44294
44372
|
*/
|
|
44295
|
-
leave() {
|
|
44373
|
+
leave(data) {
|
|
44374
|
+
if (Object.keys(this.clients).length === 1 && this.processedRevisions.size) {
|
|
44375
|
+
this.snapshot(data);
|
|
44376
|
+
}
|
|
44296
44377
|
delete this.clients[this.clientId];
|
|
44297
44378
|
this.transportService.leave(this.clientId);
|
|
44298
44379
|
this.transportService.sendMessage({
|
|
@@ -44305,6 +44386,9 @@ class Session extends EventBus {
|
|
|
44305
44386
|
* Send a snapshot of the spreadsheet to the collaboration server
|
|
44306
44387
|
*/
|
|
44307
44388
|
snapshot(data) {
|
|
44389
|
+
if (this.pendingMessages.length !== 0) {
|
|
44390
|
+
return;
|
|
44391
|
+
}
|
|
44308
44392
|
const snapshotId = this.uuidGenerator.uuidv4();
|
|
44309
44393
|
this.transportService.sendMessage({
|
|
44310
44394
|
type: "SNAPSHOT",
|
|
@@ -49085,10 +49169,8 @@ class EditionPlugin extends UIPlugin {
|
|
|
49085
49169
|
const refRange = this.getters.getRangeFromSheetXC(activeSheetId, xc);
|
|
49086
49170
|
return isEqual(this.getters.expandZone(activeSheetId, refRange.zone), oldZone);
|
|
49087
49171
|
});
|
|
49088
|
-
// this function assumes that the previous range is always found because
|
|
49089
|
-
// it's called when changing a highlight, which exists by definition
|
|
49090
49172
|
if (!previousRefToken) {
|
|
49091
|
-
|
|
49173
|
+
return;
|
|
49092
49174
|
}
|
|
49093
49175
|
const previousRange = this.getters.getRangeFromSheetXC(activeSheetId, previousRefToken.value);
|
|
49094
49176
|
this.selectionStart = previousRefToken.start;
|
|
@@ -51644,12 +51726,14 @@ class BottomBarSheet extends owl.Component {
|
|
|
51644
51726
|
if (ev.key === "Enter") {
|
|
51645
51727
|
ev.preventDefault();
|
|
51646
51728
|
this.stopEdition();
|
|
51729
|
+
this.env.focusableElement.focus();
|
|
51647
51730
|
}
|
|
51648
51731
|
if (ev.key === "Escape") {
|
|
51649
51732
|
this.cancelEdition();
|
|
51733
|
+
this.env.focusableElement.focus();
|
|
51650
51734
|
}
|
|
51651
51735
|
}
|
|
51652
|
-
|
|
51736
|
+
onMouseEventSheetName(ev) {
|
|
51653
51737
|
if (this.state.isEditing)
|
|
51654
51738
|
ev.stopPropagation();
|
|
51655
51739
|
}
|
|
@@ -56395,7 +56479,11 @@ function addRows(construct, data, sheet) {
|
|
|
56395
56479
|
let cellNode = escapeXml ``;
|
|
56396
56480
|
// Either formula or static value inside the cell
|
|
56397
56481
|
if (cell.isFormula) {
|
|
56398
|
-
|
|
56482
|
+
const res = addFormula(cell);
|
|
56483
|
+
if (!res) {
|
|
56484
|
+
continue;
|
|
56485
|
+
}
|
|
56486
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
56399
56487
|
}
|
|
56400
56488
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
56401
56489
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -56838,6 +56926,7 @@ class Model extends EventBus {
|
|
|
56838
56926
|
coreHandlers = [];
|
|
56839
56927
|
constructor(data = {}, config = {}, stateUpdateMessages = [], uuidGenerator = new UuidGenerator(), verboseImport = true) {
|
|
56840
56928
|
super();
|
|
56929
|
+
setDefaultTranslationMethod();
|
|
56841
56930
|
stateUpdateMessages = repairInitialMessages(data, stateUpdateMessages);
|
|
56842
56931
|
const workbookData = load(data, verboseImport);
|
|
56843
56932
|
this.state = new StateObserver();
|
|
@@ -56913,7 +57002,7 @@ class Model extends EventBus {
|
|
|
56913
57002
|
this.session.join(this.config.client);
|
|
56914
57003
|
}
|
|
56915
57004
|
leaveSession() {
|
|
56916
|
-
this.session.leave();
|
|
57005
|
+
this.session.leave(this.exportData());
|
|
56917
57006
|
}
|
|
56918
57007
|
setupUiPlugin(Plugin) {
|
|
56919
57008
|
const plugin = new Plugin(this.uiPluginConfig);
|
|
@@ -57337,6 +57426,7 @@ const helpers = {
|
|
|
57337
57426
|
createAction,
|
|
57338
57427
|
createActions,
|
|
57339
57428
|
transformRangeData,
|
|
57429
|
+
deepEquals,
|
|
57340
57430
|
};
|
|
57341
57431
|
const links = {
|
|
57342
57432
|
isMarkdownLink,
|
|
@@ -57415,6 +57505,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57415
57505
|
exports.tokenize = tokenize;
|
|
57416
57506
|
|
|
57417
57507
|
|
|
57418
|
-
__info__.version = "17.0.
|
|
57419
|
-
__info__.date = "2024-
|
|
57420
|
-
__info__.hash = "
|
|
57508
|
+
__info__.version = "17.0.27";
|
|
57509
|
+
__info__.date = "2024-07-02T09:01:48.383Z";
|
|
57510
|
+
__info__.hash = "c1c2d01";
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -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
|
-
|
|
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;
|