@odoo/o-spreadsheet 16.4.34 → 16.4.37
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 +97 -33
- package/dist/o-spreadsheet.d.ts +5 -0
- package/dist/o-spreadsheet.esm.js +97 -33
- package/dist/o-spreadsheet.iife.js +97 -33
- package/dist/o-spreadsheet.iife.min.js +244 -244
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +1 -1
|
@@ -3236,8 +3236,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
|
3236
3236
|
/**
|
|
3237
3237
|
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
3238
3238
|
*/
|
|
3239
|
-
function
|
|
3240
|
-
|
|
3239
|
+
function createValidRange(getters, sheetId, xc) {
|
|
3240
|
+
if (!xc)
|
|
3241
|
+
return;
|
|
3242
|
+
const range = getters.getRangeFromSheetXC(sheetId, xc);
|
|
3243
|
+
return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
|
|
3241
3244
|
}
|
|
3242
3245
|
/**
|
|
3243
3246
|
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
@@ -5704,6 +5707,7 @@ const FilterMenuPopoverBuilder = {
|
|
|
5704
5707
|
};
|
|
5705
5708
|
|
|
5706
5709
|
const macRegex = /Mac/i;
|
|
5710
|
+
const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
|
|
5707
5711
|
/**
|
|
5708
5712
|
* Return true if the event was triggered from
|
|
5709
5713
|
* a child element.
|
|
@@ -5742,6 +5746,31 @@ function* iterateChildren(el) {
|
|
|
5742
5746
|
function getOpenedMenus() {
|
|
5743
5747
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5744
5748
|
}
|
|
5749
|
+
const letterRegex = /^[a-zA-Z]$/;
|
|
5750
|
+
/**
|
|
5751
|
+
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
5752
|
+
*
|
|
5753
|
+
* @argument ev - The keyboard event to transform
|
|
5754
|
+
* @argument mode - Use either ev.key of ev.code to get the string shortcut
|
|
5755
|
+
*
|
|
5756
|
+
* @example
|
|
5757
|
+
* event : { ctrlKey: true, key: "a" } => "Ctrl+A"
|
|
5758
|
+
* event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
|
|
5759
|
+
*/
|
|
5760
|
+
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
5761
|
+
let keyDownString = "";
|
|
5762
|
+
if (!MODIFIER_KEYS.includes(ev.key)) {
|
|
5763
|
+
if (isCtrlKey(ev))
|
|
5764
|
+
keyDownString += "Ctrl+";
|
|
5765
|
+
if (ev.altKey)
|
|
5766
|
+
keyDownString += "Alt+";
|
|
5767
|
+
if (ev.shiftKey)
|
|
5768
|
+
keyDownString += "Shift+";
|
|
5769
|
+
}
|
|
5770
|
+
const key = mode === "key" ? ev.key : ev.code;
|
|
5771
|
+
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
5772
|
+
return keyDownString;
|
|
5773
|
+
}
|
|
5745
5774
|
function isMacOS() {
|
|
5746
5775
|
return Boolean(macRegex.test(navigator.userAgent));
|
|
5747
5776
|
}
|
|
@@ -5760,8 +5789,7 @@ function isCtrlKey(ev) {
|
|
|
5760
5789
|
*/
|
|
5761
5790
|
function useSpreadsheetRect() {
|
|
5762
5791
|
const position = owl.useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
5763
|
-
let spreadsheetElement =
|
|
5764
|
-
updatePosition();
|
|
5792
|
+
let spreadsheetElement = null;
|
|
5765
5793
|
function updatePosition() {
|
|
5766
5794
|
if (!spreadsheetElement) {
|
|
5767
5795
|
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
|
@@ -5899,7 +5927,7 @@ class Popover extends owl.Component {
|
|
|
5899
5927
|
if (!anchor)
|
|
5900
5928
|
return;
|
|
5901
5929
|
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
|
5902
|
-
|
|
5930
|
+
let elDims = {
|
|
5903
5931
|
width: el.getBoundingClientRect().width,
|
|
5904
5932
|
height: el.getBoundingClientRect().height,
|
|
5905
5933
|
};
|
|
@@ -5907,7 +5935,14 @@ class Popover extends owl.Component {
|
|
|
5907
5935
|
const popoverPositionHelper = this.props.positioning === "BottomLeft"
|
|
5908
5936
|
? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
|
|
5909
5937
|
: new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
|
|
5910
|
-
|
|
5938
|
+
el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
|
|
5939
|
+
el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
|
|
5940
|
+
// Re-compute the dimensions after setting the max-width and max-height
|
|
5941
|
+
elDims = {
|
|
5942
|
+
width: el.getBoundingClientRect().width,
|
|
5943
|
+
height: el.getBoundingClientRect().height,
|
|
5944
|
+
};
|
|
5945
|
+
let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
|
|
5911
5946
|
for (const property of Object.keys(style)) {
|
|
5912
5947
|
el.style[property] = style[property];
|
|
5913
5948
|
}
|
|
@@ -5983,8 +6018,6 @@ class PopoverPositionContext {
|
|
|
5983
6018
|
const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
|
|
5984
6019
|
verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
|
|
5985
6020
|
const cssProperties = {
|
|
5986
|
-
"max-height": maxHeight + "px",
|
|
5987
|
-
"max-width": maxWidth + "px",
|
|
5988
6021
|
top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
|
|
5989
6022
|
this.spreadsheetOffset.y -
|
|
5990
6023
|
verticalOffset +
|
|
@@ -16542,7 +16575,7 @@ class BarChart extends AbstractChart {
|
|
|
16542
16575
|
constructor(definition, sheetId, getters) {
|
|
16543
16576
|
super(definition, sheetId, getters);
|
|
16544
16577
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
16545
|
-
this.labelRange =
|
|
16578
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
16546
16579
|
this.background = definition.background;
|
|
16547
16580
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
16548
16581
|
this.legendPosition = definition.legendPosition;
|
|
@@ -16787,7 +16820,7 @@ class GaugeChart extends AbstractChart {
|
|
|
16787
16820
|
type = "gauge";
|
|
16788
16821
|
constructor(definition, sheetId, getters) {
|
|
16789
16822
|
super(definition, sheetId, getters);
|
|
16790
|
-
this.dataRange =
|
|
16823
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
16791
16824
|
this.sectionRule = definition.sectionRule;
|
|
16792
16825
|
this.background = definition.background;
|
|
16793
16826
|
}
|
|
@@ -17126,7 +17159,7 @@ class LineChart extends AbstractChart {
|
|
|
17126
17159
|
constructor(definition, sheetId, getters) {
|
|
17127
17160
|
super(definition, sheetId, getters);
|
|
17128
17161
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17129
|
-
this.labelRange =
|
|
17162
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
17130
17163
|
this.background = definition.background;
|
|
17131
17164
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
17132
17165
|
this.legendPosition = definition.legendPosition;
|
|
@@ -17424,7 +17457,7 @@ class PieChart extends AbstractChart {
|
|
|
17424
17457
|
constructor(definition, sheetId, getters) {
|
|
17425
17458
|
super(definition, sheetId, getters);
|
|
17426
17459
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17427
|
-
this.labelRange =
|
|
17460
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
17428
17461
|
this.background = definition.background;
|
|
17429
17462
|
this.legendPosition = definition.legendPosition;
|
|
17430
17463
|
this.aggregated = definition.aggregated;
|
|
@@ -17592,8 +17625,8 @@ class ScorecardChart extends AbstractChart {
|
|
|
17592
17625
|
type = "scorecard";
|
|
17593
17626
|
constructor(definition, sheetId, getters) {
|
|
17594
17627
|
super(definition, sheetId, getters);
|
|
17595
|
-
this.keyValue =
|
|
17596
|
-
this.baseline =
|
|
17628
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
17629
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
17597
17630
|
this.baselineMode = definition.baselineMode;
|
|
17598
17631
|
this.baselineDescr = definition.baselineDescr;
|
|
17599
17632
|
this.background = definition.background;
|
|
@@ -20952,7 +20985,7 @@ class LineBarPieConfigPanel extends owl.Component {
|
|
|
20952
20985
|
}
|
|
20953
20986
|
const getters = this.env.model.getters;
|
|
20954
20987
|
const sheetId = getters.getActiveSheetId();
|
|
20955
|
-
const labelRange =
|
|
20988
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
20956
20989
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
20957
20990
|
if (dataSets.length) {
|
|
20958
20991
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -23417,14 +23450,14 @@ class FigureComponent extends owl.Component {
|
|
|
23417
23450
|
}
|
|
23418
23451
|
onKeyDown(ev) {
|
|
23419
23452
|
const figure = this.props.figure;
|
|
23420
|
-
|
|
23453
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
23454
|
+
switch (keyDownShortcut) {
|
|
23421
23455
|
case "Delete":
|
|
23422
23456
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
23423
23457
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
23424
23458
|
id: figure.id,
|
|
23425
23459
|
});
|
|
23426
23460
|
this.props.onFigureDeleted();
|
|
23427
|
-
ev.stopPropagation();
|
|
23428
23461
|
ev.preventDefault();
|
|
23429
23462
|
ev.stopPropagation();
|
|
23430
23463
|
break;
|
|
@@ -23445,7 +23478,22 @@ class FigureComponent extends owl.Component {
|
|
|
23445
23478
|
x: figure.x + delta[0],
|
|
23446
23479
|
y: figure.y + delta[1],
|
|
23447
23480
|
});
|
|
23481
|
+
ev.preventDefault();
|
|
23448
23482
|
ev.stopPropagation();
|
|
23483
|
+
break;
|
|
23484
|
+
case "Ctrl+A":
|
|
23485
|
+
// Maybe in the future we will implement a way to select all figures
|
|
23486
|
+
ev.preventDefault();
|
|
23487
|
+
ev.stopPropagation();
|
|
23488
|
+
break;
|
|
23489
|
+
case "Ctrl+Y":
|
|
23490
|
+
case "Ctrl+Z":
|
|
23491
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
23492
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
23493
|
+
}
|
|
23494
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
23495
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
23496
|
+
}
|
|
23449
23497
|
ev.preventDefault();
|
|
23450
23498
|
ev.stopPropagation();
|
|
23451
23499
|
break;
|
|
@@ -24316,8 +24364,15 @@ class Composer extends owl.Component {
|
|
|
24316
24364
|
}
|
|
24317
24365
|
onPaste(ev) {
|
|
24318
24366
|
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24367
|
+
// let the browser clipboard work
|
|
24319
24368
|
ev.stopPropagation();
|
|
24320
24369
|
}
|
|
24370
|
+
else {
|
|
24371
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
24372
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
24373
|
+
// the native "paste" to occur.
|
|
24374
|
+
ev.preventDefault();
|
|
24375
|
+
}
|
|
24321
24376
|
}
|
|
24322
24377
|
/*
|
|
24323
24378
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -24326,10 +24381,6 @@ class Composer extends owl.Component {
|
|
|
24326
24381
|
if (!this.shouldProcessInputEvents) {
|
|
24327
24382
|
return;
|
|
24328
24383
|
}
|
|
24329
|
-
if (ev.inputType === "insertFromPaste" &&
|
|
24330
|
-
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24331
|
-
return;
|
|
24332
|
-
}
|
|
24333
24384
|
ev.stopPropagation();
|
|
24334
24385
|
let content;
|
|
24335
24386
|
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
@@ -24760,10 +24811,7 @@ class GridComposer extends owl.Component {
|
|
|
24760
24811
|
}
|
|
24761
24812
|
get containerStyle() {
|
|
24762
24813
|
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24763
|
-
return `
|
|
24764
|
-
position: absolute;
|
|
24765
|
-
z-index: -1000;
|
|
24766
|
-
`;
|
|
24814
|
+
return `z-index: -1000;`;
|
|
24767
24815
|
}
|
|
24768
24816
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24769
24817
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -25346,7 +25394,7 @@ class FiguresContainer extends owl.Component {
|
|
|
25346
25394
|
});
|
|
25347
25395
|
}
|
|
25348
25396
|
getContainerRect(container) {
|
|
25349
|
-
const { width: viewWidth, height: viewHeight } = this.env.model.getters.
|
|
25397
|
+
const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
|
|
25350
25398
|
const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
|
|
25351
25399
|
const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
|
|
25352
25400
|
const width = viewWidth - x;
|
|
@@ -34593,6 +34641,9 @@ class RangeAdapter {
|
|
|
34593
34641
|
if (range.invalidXc) {
|
|
34594
34642
|
return range.invalidXc;
|
|
34595
34643
|
}
|
|
34644
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
34645
|
+
return INCORRECT_RANGE_STRING;
|
|
34646
|
+
}
|
|
34596
34647
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
34597
34648
|
return INCORRECT_RANGE_STRING;
|
|
34598
34649
|
}
|
|
@@ -37644,16 +37695,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
37644
37695
|
let newContent = undefined;
|
|
37645
37696
|
let newFormat = undefined;
|
|
37646
37697
|
let isExported = true;
|
|
37698
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37647
37699
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
37648
37700
|
if (formulaCell) {
|
|
37649
37701
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
37650
37702
|
isFormula = isExported;
|
|
37651
37703
|
if (!isExported) {
|
|
37652
|
-
|
|
37653
|
-
|
|
37704
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
37705
|
+
// nothing* ,we don't export it.
|
|
37706
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
37707
|
+
// the empty string.
|
|
37708
|
+
if (value !== "") {
|
|
37709
|
+
newContent = value.toString();
|
|
37710
|
+
newFormat = evaluatedCell.format;
|
|
37711
|
+
}
|
|
37654
37712
|
}
|
|
37655
37713
|
}
|
|
37656
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37657
37714
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
37658
37715
|
const format = newFormat
|
|
37659
37716
|
? getItemId(newFormat, data.formats)
|
|
@@ -46524,9 +46581,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
46524
46581
|
if (ev.key === "Enter") {
|
|
46525
46582
|
ev.preventDefault();
|
|
46526
46583
|
this.stopEdition();
|
|
46584
|
+
this.env.focusableElement.focus();
|
|
46527
46585
|
}
|
|
46528
46586
|
if (ev.key === "Escape") {
|
|
46529
46587
|
this.cancelEdition();
|
|
46588
|
+
this.env.focusableElement.focus();
|
|
46530
46589
|
}
|
|
46531
46590
|
}
|
|
46532
46591
|
onClickSheetName(ev) {
|
|
@@ -51142,7 +51201,11 @@ function addRows(construct, data, sheet) {
|
|
|
51142
51201
|
let cellNode = escapeXml ``;
|
|
51143
51202
|
// Either formula or static value inside the cell
|
|
51144
51203
|
if (cell.isFormula) {
|
|
51145
|
-
|
|
51204
|
+
const res = addFormula(cell);
|
|
51205
|
+
if (!res) {
|
|
51206
|
+
continue;
|
|
51207
|
+
}
|
|
51208
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
51146
51209
|
}
|
|
51147
51210
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
51148
51211
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -52070,6 +52133,7 @@ const helpers = {
|
|
|
52070
52133
|
isDefined: isDefined$1,
|
|
52071
52134
|
lazy,
|
|
52072
52135
|
genericRepeat,
|
|
52136
|
+
deepEquals,
|
|
52073
52137
|
};
|
|
52074
52138
|
const links = {
|
|
52075
52139
|
isMarkdownLink,
|
|
@@ -52137,6 +52201,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
52137
52201
|
exports.tokenize = tokenize;
|
|
52138
52202
|
|
|
52139
52203
|
|
|
52140
|
-
__info__.version = '16.4.
|
|
52141
|
-
__info__.date = '2024-
|
|
52142
|
-
__info__.hash = '
|
|
52204
|
+
__info__.version = '16.4.37';
|
|
52205
|
+
__info__.date = '2024-06-14T10:00:27.521Z';
|
|
52206
|
+
__info__.hash = '195b41b';
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -967,6 +967,10 @@ declare function isDefined<T>(argument: T | undefined): argument is T;
|
|
|
967
967
|
* Lazy value computed by the provided function.
|
|
968
968
|
*/
|
|
969
969
|
declare function lazy<T>(fn: (() => T) | T): Lazy<T>;
|
|
970
|
+
/**
|
|
971
|
+
* Compares two objects.
|
|
972
|
+
*/
|
|
973
|
+
declare function deepEquals(o1: any, o2: any): boolean;
|
|
970
974
|
|
|
971
975
|
interface ConstructorArgs {
|
|
972
976
|
readonly zone: Readonly<Zone | UnboundedZone>;
|
|
@@ -7363,6 +7367,7 @@ declare const helpers: {
|
|
|
7363
7367
|
isDefined: typeof isDefined;
|
|
7364
7368
|
lazy: typeof lazy;
|
|
7365
7369
|
genericRepeat: typeof genericRepeat;
|
|
7370
|
+
deepEquals: typeof deepEquals;
|
|
7366
7371
|
};
|
|
7367
7372
|
declare const links: {
|
|
7368
7373
|
isMarkdownLink: typeof isMarkdownLink;
|
|
@@ -3232,8 +3232,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
|
3232
3232
|
/**
|
|
3233
3233
|
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
3234
3234
|
*/
|
|
3235
|
-
function
|
|
3236
|
-
|
|
3235
|
+
function createValidRange(getters, sheetId, xc) {
|
|
3236
|
+
if (!xc)
|
|
3237
|
+
return;
|
|
3238
|
+
const range = getters.getRangeFromSheetXC(sheetId, xc);
|
|
3239
|
+
return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
|
|
3237
3240
|
}
|
|
3238
3241
|
/**
|
|
3239
3242
|
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
@@ -5700,6 +5703,7 @@ const FilterMenuPopoverBuilder = {
|
|
|
5700
5703
|
};
|
|
5701
5704
|
|
|
5702
5705
|
const macRegex = /Mac/i;
|
|
5706
|
+
const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
|
|
5703
5707
|
/**
|
|
5704
5708
|
* Return true if the event was triggered from
|
|
5705
5709
|
* a child element.
|
|
@@ -5738,6 +5742,31 @@ function* iterateChildren(el) {
|
|
|
5738
5742
|
function getOpenedMenus() {
|
|
5739
5743
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5740
5744
|
}
|
|
5745
|
+
const letterRegex = /^[a-zA-Z]$/;
|
|
5746
|
+
/**
|
|
5747
|
+
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
5748
|
+
*
|
|
5749
|
+
* @argument ev - The keyboard event to transform
|
|
5750
|
+
* @argument mode - Use either ev.key of ev.code to get the string shortcut
|
|
5751
|
+
*
|
|
5752
|
+
* @example
|
|
5753
|
+
* event : { ctrlKey: true, key: "a" } => "Ctrl+A"
|
|
5754
|
+
* event : { shift: true, alt: true, key: "Home" } => "Alt+Shift+Home"
|
|
5755
|
+
*/
|
|
5756
|
+
function keyboardEventToShortcutString(ev, mode = "key") {
|
|
5757
|
+
let keyDownString = "";
|
|
5758
|
+
if (!MODIFIER_KEYS.includes(ev.key)) {
|
|
5759
|
+
if (isCtrlKey(ev))
|
|
5760
|
+
keyDownString += "Ctrl+";
|
|
5761
|
+
if (ev.altKey)
|
|
5762
|
+
keyDownString += "Alt+";
|
|
5763
|
+
if (ev.shiftKey)
|
|
5764
|
+
keyDownString += "Shift+";
|
|
5765
|
+
}
|
|
5766
|
+
const key = mode === "key" ? ev.key : ev.code;
|
|
5767
|
+
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
5768
|
+
return keyDownString;
|
|
5769
|
+
}
|
|
5741
5770
|
function isMacOS() {
|
|
5742
5771
|
return Boolean(macRegex.test(navigator.userAgent));
|
|
5743
5772
|
}
|
|
@@ -5756,8 +5785,7 @@ function isCtrlKey(ev) {
|
|
|
5756
5785
|
*/
|
|
5757
5786
|
function useSpreadsheetRect() {
|
|
5758
5787
|
const position = useState({ x: 0, y: 0, width: 0, height: 0 });
|
|
5759
|
-
let spreadsheetElement =
|
|
5760
|
-
updatePosition();
|
|
5788
|
+
let spreadsheetElement = null;
|
|
5761
5789
|
function updatePosition() {
|
|
5762
5790
|
if (!spreadsheetElement) {
|
|
5763
5791
|
spreadsheetElement = document.querySelector(".o-spreadsheet");
|
|
@@ -5895,7 +5923,7 @@ class Popover extends Component {
|
|
|
5895
5923
|
if (!anchor)
|
|
5896
5924
|
return;
|
|
5897
5925
|
const propsMaxSize = { width: this.props.maxWidth, height: this.props.maxHeight };
|
|
5898
|
-
|
|
5926
|
+
let elDims = {
|
|
5899
5927
|
width: el.getBoundingClientRect().width,
|
|
5900
5928
|
height: el.getBoundingClientRect().height,
|
|
5901
5929
|
};
|
|
@@ -5903,7 +5931,14 @@ class Popover extends Component {
|
|
|
5903
5931
|
const popoverPositionHelper = this.props.positioning === "BottomLeft"
|
|
5904
5932
|
? new BottomLeftPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect)
|
|
5905
5933
|
: new TopRightPopoverContext(anchor, this.containerRect, propsMaxSize, spreadsheetRect);
|
|
5906
|
-
|
|
5934
|
+
el.style["max-height"] = popoverPositionHelper.getMaxHeight(elDims.height) + "px";
|
|
5935
|
+
el.style["max-width"] = popoverPositionHelper.getMaxWidth(elDims.width) + "px";
|
|
5936
|
+
// Re-compute the dimensions after setting the max-width and max-height
|
|
5937
|
+
elDims = {
|
|
5938
|
+
width: el.getBoundingClientRect().width,
|
|
5939
|
+
height: el.getBoundingClientRect().height,
|
|
5940
|
+
};
|
|
5941
|
+
let style = popoverPositionHelper.getCss(elDims, this.props.verticalOffset);
|
|
5907
5942
|
for (const property of Object.keys(style)) {
|
|
5908
5943
|
el.style[property] = style[property];
|
|
5909
5944
|
}
|
|
@@ -5979,8 +6014,6 @@ class PopoverPositionContext {
|
|
|
5979
6014
|
const shouldRenderAtRight = this.shouldRenderAtRight(elDims.width);
|
|
5980
6015
|
verticalOffset = shouldRenderAtBottom ? verticalOffset : -verticalOffset;
|
|
5981
6016
|
const cssProperties = {
|
|
5982
|
-
"max-height": maxHeight + "px",
|
|
5983
|
-
"max-width": maxWidth + "px",
|
|
5984
6017
|
top: this.getTopCoordinate(actualHeight, shouldRenderAtBottom) -
|
|
5985
6018
|
this.spreadsheetOffset.y -
|
|
5986
6019
|
verticalOffset +
|
|
@@ -16538,7 +16571,7 @@ class BarChart extends AbstractChart {
|
|
|
16538
16571
|
constructor(definition, sheetId, getters) {
|
|
16539
16572
|
super(definition, sheetId, getters);
|
|
16540
16573
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
16541
|
-
this.labelRange =
|
|
16574
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
16542
16575
|
this.background = definition.background;
|
|
16543
16576
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
16544
16577
|
this.legendPosition = definition.legendPosition;
|
|
@@ -16783,7 +16816,7 @@ class GaugeChart extends AbstractChart {
|
|
|
16783
16816
|
type = "gauge";
|
|
16784
16817
|
constructor(definition, sheetId, getters) {
|
|
16785
16818
|
super(definition, sheetId, getters);
|
|
16786
|
-
this.dataRange =
|
|
16819
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
16787
16820
|
this.sectionRule = definition.sectionRule;
|
|
16788
16821
|
this.background = definition.background;
|
|
16789
16822
|
}
|
|
@@ -17122,7 +17155,7 @@ class LineChart extends AbstractChart {
|
|
|
17122
17155
|
constructor(definition, sheetId, getters) {
|
|
17123
17156
|
super(definition, sheetId, getters);
|
|
17124
17157
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17125
|
-
this.labelRange =
|
|
17158
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
17126
17159
|
this.background = definition.background;
|
|
17127
17160
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
17128
17161
|
this.legendPosition = definition.legendPosition;
|
|
@@ -17420,7 +17453,7 @@ class PieChart extends AbstractChart {
|
|
|
17420
17453
|
constructor(definition, sheetId, getters) {
|
|
17421
17454
|
super(definition, sheetId, getters);
|
|
17422
17455
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17423
|
-
this.labelRange =
|
|
17456
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
17424
17457
|
this.background = definition.background;
|
|
17425
17458
|
this.legendPosition = definition.legendPosition;
|
|
17426
17459
|
this.aggregated = definition.aggregated;
|
|
@@ -17588,8 +17621,8 @@ class ScorecardChart extends AbstractChart {
|
|
|
17588
17621
|
type = "scorecard";
|
|
17589
17622
|
constructor(definition, sheetId, getters) {
|
|
17590
17623
|
super(definition, sheetId, getters);
|
|
17591
|
-
this.keyValue =
|
|
17592
|
-
this.baseline =
|
|
17624
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
17625
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
17593
17626
|
this.baselineMode = definition.baselineMode;
|
|
17594
17627
|
this.baselineDescr = definition.baselineDescr;
|
|
17595
17628
|
this.background = definition.background;
|
|
@@ -20948,7 +20981,7 @@ class LineBarPieConfigPanel extends Component {
|
|
|
20948
20981
|
}
|
|
20949
20982
|
const getters = this.env.model.getters;
|
|
20950
20983
|
const sheetId = getters.getActiveSheetId();
|
|
20951
|
-
const labelRange =
|
|
20984
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
20952
20985
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
20953
20986
|
if (dataSets.length) {
|
|
20954
20987
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -23413,14 +23446,14 @@ class FigureComponent extends Component {
|
|
|
23413
23446
|
}
|
|
23414
23447
|
onKeyDown(ev) {
|
|
23415
23448
|
const figure = this.props.figure;
|
|
23416
|
-
|
|
23449
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
23450
|
+
switch (keyDownShortcut) {
|
|
23417
23451
|
case "Delete":
|
|
23418
23452
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
23419
23453
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
23420
23454
|
id: figure.id,
|
|
23421
23455
|
});
|
|
23422
23456
|
this.props.onFigureDeleted();
|
|
23423
|
-
ev.stopPropagation();
|
|
23424
23457
|
ev.preventDefault();
|
|
23425
23458
|
ev.stopPropagation();
|
|
23426
23459
|
break;
|
|
@@ -23441,7 +23474,22 @@ class FigureComponent extends Component {
|
|
|
23441
23474
|
x: figure.x + delta[0],
|
|
23442
23475
|
y: figure.y + delta[1],
|
|
23443
23476
|
});
|
|
23477
|
+
ev.preventDefault();
|
|
23444
23478
|
ev.stopPropagation();
|
|
23479
|
+
break;
|
|
23480
|
+
case "Ctrl+A":
|
|
23481
|
+
// Maybe in the future we will implement a way to select all figures
|
|
23482
|
+
ev.preventDefault();
|
|
23483
|
+
ev.stopPropagation();
|
|
23484
|
+
break;
|
|
23485
|
+
case "Ctrl+Y":
|
|
23486
|
+
case "Ctrl+Z":
|
|
23487
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
23488
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
23489
|
+
}
|
|
23490
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
23491
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
23492
|
+
}
|
|
23445
23493
|
ev.preventDefault();
|
|
23446
23494
|
ev.stopPropagation();
|
|
23447
23495
|
break;
|
|
@@ -24312,8 +24360,15 @@ class Composer extends Component {
|
|
|
24312
24360
|
}
|
|
24313
24361
|
onPaste(ev) {
|
|
24314
24362
|
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24363
|
+
// let the browser clipboard work
|
|
24315
24364
|
ev.stopPropagation();
|
|
24316
24365
|
}
|
|
24366
|
+
else {
|
|
24367
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
24368
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
24369
|
+
// the native "paste" to occur.
|
|
24370
|
+
ev.preventDefault();
|
|
24371
|
+
}
|
|
24317
24372
|
}
|
|
24318
24373
|
/*
|
|
24319
24374
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -24322,10 +24377,6 @@ class Composer extends Component {
|
|
|
24322
24377
|
if (!this.shouldProcessInputEvents) {
|
|
24323
24378
|
return;
|
|
24324
24379
|
}
|
|
24325
|
-
if (ev.inputType === "insertFromPaste" &&
|
|
24326
|
-
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24327
|
-
return;
|
|
24328
|
-
}
|
|
24329
24380
|
ev.stopPropagation();
|
|
24330
24381
|
let content;
|
|
24331
24382
|
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
@@ -24756,10 +24807,7 @@ class GridComposer extends Component {
|
|
|
24756
24807
|
}
|
|
24757
24808
|
get containerStyle() {
|
|
24758
24809
|
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24759
|
-
return `
|
|
24760
|
-
position: absolute;
|
|
24761
|
-
z-index: -1000;
|
|
24762
|
-
`;
|
|
24810
|
+
return `z-index: -1000;`;
|
|
24763
24811
|
}
|
|
24764
24812
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24765
24813
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -25342,7 +25390,7 @@ class FiguresContainer extends Component {
|
|
|
25342
25390
|
});
|
|
25343
25391
|
}
|
|
25344
25392
|
getContainerRect(container) {
|
|
25345
|
-
const { width: viewWidth, height: viewHeight } = this.env.model.getters.
|
|
25393
|
+
const { width: viewWidth, height: viewHeight } = this.env.model.getters.getSheetViewDimension();
|
|
25346
25394
|
const { x: viewportX, y: viewportY } = this.env.model.getters.getMainViewportCoordinates();
|
|
25347
25395
|
const x = ["bottomRight", "topRight"].includes(container) ? viewportX : 0;
|
|
25348
25396
|
const width = viewWidth - x;
|
|
@@ -34589,6 +34637,9 @@ class RangeAdapter {
|
|
|
34589
34637
|
if (range.invalidXc) {
|
|
34590
34638
|
return range.invalidXc;
|
|
34591
34639
|
}
|
|
34640
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
34641
|
+
return INCORRECT_RANGE_STRING;
|
|
34642
|
+
}
|
|
34592
34643
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
34593
34644
|
return INCORRECT_RANGE_STRING;
|
|
34594
34645
|
}
|
|
@@ -37640,16 +37691,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
37640
37691
|
let newContent = undefined;
|
|
37641
37692
|
let newFormat = undefined;
|
|
37642
37693
|
let isExported = true;
|
|
37694
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37643
37695
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
37644
37696
|
if (formulaCell) {
|
|
37645
37697
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
37646
37698
|
isFormula = isExported;
|
|
37647
37699
|
if (!isExported) {
|
|
37648
|
-
|
|
37649
|
-
|
|
37700
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
37701
|
+
// nothing* ,we don't export it.
|
|
37702
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
37703
|
+
// the empty string.
|
|
37704
|
+
if (value !== "") {
|
|
37705
|
+
newContent = value.toString();
|
|
37706
|
+
newFormat = evaluatedCell.format;
|
|
37707
|
+
}
|
|
37650
37708
|
}
|
|
37651
37709
|
}
|
|
37652
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37653
37710
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
37654
37711
|
const format = newFormat
|
|
37655
37712
|
? getItemId(newFormat, data.formats)
|
|
@@ -46520,9 +46577,11 @@ class BottomBarSheet extends Component {
|
|
|
46520
46577
|
if (ev.key === "Enter") {
|
|
46521
46578
|
ev.preventDefault();
|
|
46522
46579
|
this.stopEdition();
|
|
46580
|
+
this.env.focusableElement.focus();
|
|
46523
46581
|
}
|
|
46524
46582
|
if (ev.key === "Escape") {
|
|
46525
46583
|
this.cancelEdition();
|
|
46584
|
+
this.env.focusableElement.focus();
|
|
46526
46585
|
}
|
|
46527
46586
|
}
|
|
46528
46587
|
onClickSheetName(ev) {
|
|
@@ -51138,7 +51197,11 @@ function addRows(construct, data, sheet) {
|
|
|
51138
51197
|
let cellNode = escapeXml ``;
|
|
51139
51198
|
// Either formula or static value inside the cell
|
|
51140
51199
|
if (cell.isFormula) {
|
|
51141
|
-
|
|
51200
|
+
const res = addFormula(cell);
|
|
51201
|
+
if (!res) {
|
|
51202
|
+
continue;
|
|
51203
|
+
}
|
|
51204
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
51142
51205
|
}
|
|
51143
51206
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
51144
51207
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -52066,6 +52129,7 @@ const helpers = {
|
|
|
52066
52129
|
isDefined: isDefined$1,
|
|
52067
52130
|
lazy,
|
|
52068
52131
|
genericRepeat,
|
|
52132
|
+
deepEquals,
|
|
52069
52133
|
};
|
|
52070
52134
|
const links = {
|
|
52071
52135
|
isMarkdownLink,
|
|
@@ -52101,6 +52165,6 @@ const constants = {
|
|
|
52101
52165
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
52102
52166
|
|
|
52103
52167
|
|
|
52104
|
-
__info__.version = '16.4.
|
|
52105
|
-
__info__.date = '2024-
|
|
52106
|
-
__info__.hash = '
|
|
52168
|
+
__info__.version = '16.4.37';
|
|
52169
|
+
__info__.date = '2024-06-14T10:00:27.521Z';
|
|
52170
|
+
__info__.hash = '195b41b';
|