@odoo/o-spreadsheet 16.4.33 → 16.4.36
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 +101 -33
- package/dist/o-spreadsheet.esm.js +101 -33
- package/dist/o-spreadsheet.iife.js +101 -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");
|
|
@@ -16542,7 +16570,7 @@ class BarChart extends AbstractChart {
|
|
|
16542
16570
|
constructor(definition, sheetId, getters) {
|
|
16543
16571
|
super(definition, sheetId, getters);
|
|
16544
16572
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
16545
|
-
this.labelRange =
|
|
16573
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
16546
16574
|
this.background = definition.background;
|
|
16547
16575
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
16548
16576
|
this.legendPosition = definition.legendPosition;
|
|
@@ -16787,7 +16815,7 @@ class GaugeChart extends AbstractChart {
|
|
|
16787
16815
|
type = "gauge";
|
|
16788
16816
|
constructor(definition, sheetId, getters) {
|
|
16789
16817
|
super(definition, sheetId, getters);
|
|
16790
|
-
this.dataRange =
|
|
16818
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
16791
16819
|
this.sectionRule = definition.sectionRule;
|
|
16792
16820
|
this.background = definition.background;
|
|
16793
16821
|
}
|
|
@@ -17126,7 +17154,7 @@ class LineChart extends AbstractChart {
|
|
|
17126
17154
|
constructor(definition, sheetId, getters) {
|
|
17127
17155
|
super(definition, sheetId, getters);
|
|
17128
17156
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17129
|
-
this.labelRange =
|
|
17157
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
17130
17158
|
this.background = definition.background;
|
|
17131
17159
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
17132
17160
|
this.legendPosition = definition.legendPosition;
|
|
@@ -17424,7 +17452,7 @@ class PieChart extends AbstractChart {
|
|
|
17424
17452
|
constructor(definition, sheetId, getters) {
|
|
17425
17453
|
super(definition, sheetId, getters);
|
|
17426
17454
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17427
|
-
this.labelRange =
|
|
17455
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
17428
17456
|
this.background = definition.background;
|
|
17429
17457
|
this.legendPosition = definition.legendPosition;
|
|
17430
17458
|
this.aggregated = definition.aggregated;
|
|
@@ -17592,8 +17620,8 @@ class ScorecardChart extends AbstractChart {
|
|
|
17592
17620
|
type = "scorecard";
|
|
17593
17621
|
constructor(definition, sheetId, getters) {
|
|
17594
17622
|
super(definition, sheetId, getters);
|
|
17595
|
-
this.keyValue =
|
|
17596
|
-
this.baseline =
|
|
17623
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
17624
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
17597
17625
|
this.baselineMode = definition.baselineMode;
|
|
17598
17626
|
this.baselineDescr = definition.baselineDescr;
|
|
17599
17627
|
this.background = definition.background;
|
|
@@ -20952,7 +20980,7 @@ class LineBarPieConfigPanel extends owl.Component {
|
|
|
20952
20980
|
}
|
|
20953
20981
|
const getters = this.env.model.getters;
|
|
20954
20982
|
const sheetId = getters.getActiveSheetId();
|
|
20955
|
-
const labelRange =
|
|
20983
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
20956
20984
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
20957
20985
|
if (dataSets.length) {
|
|
20958
20986
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -23417,14 +23445,14 @@ class FigureComponent extends owl.Component {
|
|
|
23417
23445
|
}
|
|
23418
23446
|
onKeyDown(ev) {
|
|
23419
23447
|
const figure = this.props.figure;
|
|
23420
|
-
|
|
23448
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
23449
|
+
switch (keyDownShortcut) {
|
|
23421
23450
|
case "Delete":
|
|
23422
23451
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
23423
23452
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
23424
23453
|
id: figure.id,
|
|
23425
23454
|
});
|
|
23426
23455
|
this.props.onFigureDeleted();
|
|
23427
|
-
ev.stopPropagation();
|
|
23428
23456
|
ev.preventDefault();
|
|
23429
23457
|
ev.stopPropagation();
|
|
23430
23458
|
break;
|
|
@@ -23445,7 +23473,22 @@ class FigureComponent extends owl.Component {
|
|
|
23445
23473
|
x: figure.x + delta[0],
|
|
23446
23474
|
y: figure.y + delta[1],
|
|
23447
23475
|
});
|
|
23476
|
+
ev.preventDefault();
|
|
23448
23477
|
ev.stopPropagation();
|
|
23478
|
+
break;
|
|
23479
|
+
case "Ctrl+A":
|
|
23480
|
+
// Maybe in the future we will implement a way to select all figures
|
|
23481
|
+
ev.preventDefault();
|
|
23482
|
+
ev.stopPropagation();
|
|
23483
|
+
break;
|
|
23484
|
+
case "Ctrl+Y":
|
|
23485
|
+
case "Ctrl+Z":
|
|
23486
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
23487
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
23488
|
+
}
|
|
23489
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
23490
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
23491
|
+
}
|
|
23449
23492
|
ev.preventDefault();
|
|
23450
23493
|
ev.stopPropagation();
|
|
23451
23494
|
break;
|
|
@@ -24170,7 +24213,7 @@ class Composer extends owl.Component {
|
|
|
24170
24213
|
Enter: this.processEnterKey,
|
|
24171
24214
|
Escape: this.processEscapeKey,
|
|
24172
24215
|
F2: () => console.warn("Not implemented"),
|
|
24173
|
-
F4: this.processF4Key,
|
|
24216
|
+
F4: (ev) => this.processF4Key(ev),
|
|
24174
24217
|
Tab: (ev) => this.processTabKey(ev),
|
|
24175
24218
|
};
|
|
24176
24219
|
keyCodeMapping = {
|
|
@@ -24272,9 +24315,10 @@ class Composer extends owl.Component {
|
|
|
24272
24315
|
processEscapeKey() {
|
|
24273
24316
|
this.env.model.dispatch("STOP_EDITION", { cancel: true });
|
|
24274
24317
|
}
|
|
24275
|
-
processF4Key() {
|
|
24318
|
+
processF4Key(ev) {
|
|
24276
24319
|
this.env.model.dispatch("CYCLE_EDITION_REFERENCES");
|
|
24277
24320
|
this.processContent();
|
|
24321
|
+
ev.stopPropagation();
|
|
24278
24322
|
}
|
|
24279
24323
|
processNumpadDecimal(ev) {
|
|
24280
24324
|
ev.stopPropagation();
|
|
@@ -24315,8 +24359,15 @@ class Composer extends owl.Component {
|
|
|
24315
24359
|
}
|
|
24316
24360
|
onPaste(ev) {
|
|
24317
24361
|
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24362
|
+
// let the browser clipboard work
|
|
24318
24363
|
ev.stopPropagation();
|
|
24319
24364
|
}
|
|
24365
|
+
else {
|
|
24366
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
24367
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
24368
|
+
// the native "paste" to occur.
|
|
24369
|
+
ev.preventDefault();
|
|
24370
|
+
}
|
|
24320
24371
|
}
|
|
24321
24372
|
/*
|
|
24322
24373
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -24325,10 +24376,6 @@ class Composer extends owl.Component {
|
|
|
24325
24376
|
if (!this.shouldProcessInputEvents) {
|
|
24326
24377
|
return;
|
|
24327
24378
|
}
|
|
24328
|
-
if (ev.inputType === "insertFromPaste" &&
|
|
24329
|
-
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24330
|
-
return;
|
|
24331
|
-
}
|
|
24332
24379
|
ev.stopPropagation();
|
|
24333
24380
|
let content;
|
|
24334
24381
|
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
@@ -24759,10 +24806,7 @@ class GridComposer extends owl.Component {
|
|
|
24759
24806
|
}
|
|
24760
24807
|
get containerStyle() {
|
|
24761
24808
|
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24762
|
-
return `
|
|
24763
|
-
position: absolute;
|
|
24764
|
-
z-index: -1000;
|
|
24765
|
-
`;
|
|
24809
|
+
return `z-index: -1000;`;
|
|
24766
24810
|
}
|
|
24767
24811
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24768
24812
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -33990,7 +34034,12 @@ class MergePlugin extends CorePlugin {
|
|
|
33990
34034
|
* if they have at least a common cell
|
|
33991
34035
|
*/
|
|
33992
34036
|
doesIntersectMerge(sheetId, zone) {
|
|
33993
|
-
|
|
34037
|
+
for (const merge of this.getMerges(sheetId)) {
|
|
34038
|
+
if (overlap(zone, merge)) {
|
|
34039
|
+
return true;
|
|
34040
|
+
}
|
|
34041
|
+
}
|
|
34042
|
+
return false;
|
|
33994
34043
|
}
|
|
33995
34044
|
/**
|
|
33996
34045
|
* Returns true if two columns have at least one merge in common
|
|
@@ -34587,6 +34636,9 @@ class RangeAdapter {
|
|
|
34587
34636
|
if (range.invalidXc) {
|
|
34588
34637
|
return range.invalidXc;
|
|
34589
34638
|
}
|
|
34639
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
34640
|
+
return INCORRECT_RANGE_STRING;
|
|
34641
|
+
}
|
|
34590
34642
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
34591
34643
|
return INCORRECT_RANGE_STRING;
|
|
34592
34644
|
}
|
|
@@ -37638,16 +37690,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
37638
37690
|
let newContent = undefined;
|
|
37639
37691
|
let newFormat = undefined;
|
|
37640
37692
|
let isExported = true;
|
|
37693
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37641
37694
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
37642
37695
|
if (formulaCell) {
|
|
37643
37696
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
37644
37697
|
isFormula = isExported;
|
|
37645
37698
|
if (!isExported) {
|
|
37646
|
-
|
|
37647
|
-
|
|
37699
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
37700
|
+
// nothing* ,we don't export it.
|
|
37701
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
37702
|
+
// the empty string.
|
|
37703
|
+
if (value !== "") {
|
|
37704
|
+
newContent = value.toString();
|
|
37705
|
+
newFormat = evaluatedCell.format;
|
|
37706
|
+
}
|
|
37648
37707
|
}
|
|
37649
37708
|
}
|
|
37650
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37651
37709
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
37652
37710
|
const format = newFormat
|
|
37653
37711
|
? getItemId(newFormat, data.formats)
|
|
@@ -43431,7 +43489,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
43431
43489
|
case "ADD_COLUMNS_ROWS": {
|
|
43432
43490
|
this.status = "invisible";
|
|
43433
43491
|
// If we add a col/row inside or before the cut area, we invalidate the clipboard
|
|
43434
|
-
if (this.state?.operation !== "CUT") {
|
|
43492
|
+
if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
|
|
43435
43493
|
return;
|
|
43436
43494
|
}
|
|
43437
43495
|
const isClipboardDirty = this.state.isColRowDirtyingClipboard(cmd.position === "before" ? cmd.base : cmd.base + 1, cmd.dimension);
|
|
@@ -43443,7 +43501,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
43443
43501
|
case "REMOVE_COLUMNS_ROWS": {
|
|
43444
43502
|
this.status = "invisible";
|
|
43445
43503
|
// If we remove a col/row inside or before the cut area, we invalidate the clipboard
|
|
43446
|
-
if (this.state?.operation !== "CUT") {
|
|
43504
|
+
if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
|
|
43447
43505
|
return;
|
|
43448
43506
|
}
|
|
43449
43507
|
for (let el of cmd.elements) {
|
|
@@ -46518,9 +46576,11 @@ class BottomBarSheet extends owl.Component {
|
|
|
46518
46576
|
if (ev.key === "Enter") {
|
|
46519
46577
|
ev.preventDefault();
|
|
46520
46578
|
this.stopEdition();
|
|
46579
|
+
this.env.focusableElement.focus();
|
|
46521
46580
|
}
|
|
46522
46581
|
if (ev.key === "Escape") {
|
|
46523
46582
|
this.cancelEdition();
|
|
46583
|
+
this.env.focusableElement.focus();
|
|
46524
46584
|
}
|
|
46525
46585
|
}
|
|
46526
46586
|
onClickSheetName(ev) {
|
|
@@ -48282,6 +48342,10 @@ class Spreadsheet extends owl.Component {
|
|
|
48282
48342
|
});
|
|
48283
48343
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
48284
48344
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
48345
|
+
// For some reason, the wheel event is not properly registered inside templates
|
|
48346
|
+
// in Chromium-based browsers based on chromium 125
|
|
48347
|
+
// This hack ensures the event declared in the template is properly registered/working
|
|
48348
|
+
owl.useExternalListener(document.body, "wheel", () => { });
|
|
48285
48349
|
this.bindModelEvents();
|
|
48286
48350
|
owl.onMounted(() => {
|
|
48287
48351
|
this.checkViewportSize();
|
|
@@ -51132,7 +51196,11 @@ function addRows(construct, data, sheet) {
|
|
|
51132
51196
|
let cellNode = escapeXml ``;
|
|
51133
51197
|
// Either formula or static value inside the cell
|
|
51134
51198
|
if (cell.isFormula) {
|
|
51135
|
-
|
|
51199
|
+
const res = addFormula(cell);
|
|
51200
|
+
if (!res) {
|
|
51201
|
+
continue;
|
|
51202
|
+
}
|
|
51203
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
51136
51204
|
}
|
|
51137
51205
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
51138
51206
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -52127,6 +52195,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
52127
52195
|
exports.tokenize = tokenize;
|
|
52128
52196
|
|
|
52129
52197
|
|
|
52130
|
-
__info__.version = '16.4.
|
|
52131
|
-
__info__.date = '2024-
|
|
52132
|
-
__info__.hash = '
|
|
52198
|
+
__info__.version = '16.4.36';
|
|
52199
|
+
__info__.date = '2024-06-10T09:33:43.623Z';
|
|
52200
|
+
__info__.hash = '3b15ed5';
|
|
@@ -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");
|
|
@@ -16538,7 +16566,7 @@ class BarChart extends AbstractChart {
|
|
|
16538
16566
|
constructor(definition, sheetId, getters) {
|
|
16539
16567
|
super(definition, sheetId, getters);
|
|
16540
16568
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
16541
|
-
this.labelRange =
|
|
16569
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
16542
16570
|
this.background = definition.background;
|
|
16543
16571
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
16544
16572
|
this.legendPosition = definition.legendPosition;
|
|
@@ -16783,7 +16811,7 @@ class GaugeChart extends AbstractChart {
|
|
|
16783
16811
|
type = "gauge";
|
|
16784
16812
|
constructor(definition, sheetId, getters) {
|
|
16785
16813
|
super(definition, sheetId, getters);
|
|
16786
|
-
this.dataRange =
|
|
16814
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
16787
16815
|
this.sectionRule = definition.sectionRule;
|
|
16788
16816
|
this.background = definition.background;
|
|
16789
16817
|
}
|
|
@@ -17122,7 +17150,7 @@ class LineChart extends AbstractChart {
|
|
|
17122
17150
|
constructor(definition, sheetId, getters) {
|
|
17123
17151
|
super(definition, sheetId, getters);
|
|
17124
17152
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17125
|
-
this.labelRange =
|
|
17153
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
17126
17154
|
this.background = definition.background;
|
|
17127
17155
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
17128
17156
|
this.legendPosition = definition.legendPosition;
|
|
@@ -17420,7 +17448,7 @@ class PieChart extends AbstractChart {
|
|
|
17420
17448
|
constructor(definition, sheetId, getters) {
|
|
17421
17449
|
super(definition, sheetId, getters);
|
|
17422
17450
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
17423
|
-
this.labelRange =
|
|
17451
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
17424
17452
|
this.background = definition.background;
|
|
17425
17453
|
this.legendPosition = definition.legendPosition;
|
|
17426
17454
|
this.aggregated = definition.aggregated;
|
|
@@ -17588,8 +17616,8 @@ class ScorecardChart extends AbstractChart {
|
|
|
17588
17616
|
type = "scorecard";
|
|
17589
17617
|
constructor(definition, sheetId, getters) {
|
|
17590
17618
|
super(definition, sheetId, getters);
|
|
17591
|
-
this.keyValue =
|
|
17592
|
-
this.baseline =
|
|
17619
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
17620
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
17593
17621
|
this.baselineMode = definition.baselineMode;
|
|
17594
17622
|
this.baselineDescr = definition.baselineDescr;
|
|
17595
17623
|
this.background = definition.background;
|
|
@@ -20948,7 +20976,7 @@ class LineBarPieConfigPanel extends Component {
|
|
|
20948
20976
|
}
|
|
20949
20977
|
const getters = this.env.model.getters;
|
|
20950
20978
|
const sheetId = getters.getActiveSheetId();
|
|
20951
|
-
const labelRange =
|
|
20979
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
20952
20980
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
20953
20981
|
if (dataSets.length) {
|
|
20954
20982
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -23413,14 +23441,14 @@ class FigureComponent extends Component {
|
|
|
23413
23441
|
}
|
|
23414
23442
|
onKeyDown(ev) {
|
|
23415
23443
|
const figure = this.props.figure;
|
|
23416
|
-
|
|
23444
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
23445
|
+
switch (keyDownShortcut) {
|
|
23417
23446
|
case "Delete":
|
|
23418
23447
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
23419
23448
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
23420
23449
|
id: figure.id,
|
|
23421
23450
|
});
|
|
23422
23451
|
this.props.onFigureDeleted();
|
|
23423
|
-
ev.stopPropagation();
|
|
23424
23452
|
ev.preventDefault();
|
|
23425
23453
|
ev.stopPropagation();
|
|
23426
23454
|
break;
|
|
@@ -23441,7 +23469,22 @@ class FigureComponent extends Component {
|
|
|
23441
23469
|
x: figure.x + delta[0],
|
|
23442
23470
|
y: figure.y + delta[1],
|
|
23443
23471
|
});
|
|
23472
|
+
ev.preventDefault();
|
|
23444
23473
|
ev.stopPropagation();
|
|
23474
|
+
break;
|
|
23475
|
+
case "Ctrl+A":
|
|
23476
|
+
// Maybe in the future we will implement a way to select all figures
|
|
23477
|
+
ev.preventDefault();
|
|
23478
|
+
ev.stopPropagation();
|
|
23479
|
+
break;
|
|
23480
|
+
case "Ctrl+Y":
|
|
23481
|
+
case "Ctrl+Z":
|
|
23482
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
23483
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
23484
|
+
}
|
|
23485
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
23486
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
23487
|
+
}
|
|
23445
23488
|
ev.preventDefault();
|
|
23446
23489
|
ev.stopPropagation();
|
|
23447
23490
|
break;
|
|
@@ -24166,7 +24209,7 @@ class Composer extends Component {
|
|
|
24166
24209
|
Enter: this.processEnterKey,
|
|
24167
24210
|
Escape: this.processEscapeKey,
|
|
24168
24211
|
F2: () => console.warn("Not implemented"),
|
|
24169
|
-
F4: this.processF4Key,
|
|
24212
|
+
F4: (ev) => this.processF4Key(ev),
|
|
24170
24213
|
Tab: (ev) => this.processTabKey(ev),
|
|
24171
24214
|
};
|
|
24172
24215
|
keyCodeMapping = {
|
|
@@ -24268,9 +24311,10 @@ class Composer extends Component {
|
|
|
24268
24311
|
processEscapeKey() {
|
|
24269
24312
|
this.env.model.dispatch("STOP_EDITION", { cancel: true });
|
|
24270
24313
|
}
|
|
24271
|
-
processF4Key() {
|
|
24314
|
+
processF4Key(ev) {
|
|
24272
24315
|
this.env.model.dispatch("CYCLE_EDITION_REFERENCES");
|
|
24273
24316
|
this.processContent();
|
|
24317
|
+
ev.stopPropagation();
|
|
24274
24318
|
}
|
|
24275
24319
|
processNumpadDecimal(ev) {
|
|
24276
24320
|
ev.stopPropagation();
|
|
@@ -24311,8 +24355,15 @@ class Composer extends Component {
|
|
|
24311
24355
|
}
|
|
24312
24356
|
onPaste(ev) {
|
|
24313
24357
|
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24358
|
+
// let the browser clipboard work
|
|
24314
24359
|
ev.stopPropagation();
|
|
24315
24360
|
}
|
|
24361
|
+
else {
|
|
24362
|
+
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
24363
|
+
// While we're not editing, we still have the focus and should therefore prevent
|
|
24364
|
+
// the native "paste" to occur.
|
|
24365
|
+
ev.preventDefault();
|
|
24366
|
+
}
|
|
24316
24367
|
}
|
|
24317
24368
|
/*
|
|
24318
24369
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
@@ -24321,10 +24372,6 @@ class Composer extends Component {
|
|
|
24321
24372
|
if (!this.shouldProcessInputEvents) {
|
|
24322
24373
|
return;
|
|
24323
24374
|
}
|
|
24324
|
-
if (ev.inputType === "insertFromPaste" &&
|
|
24325
|
-
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24326
|
-
return;
|
|
24327
|
-
}
|
|
24328
24375
|
ev.stopPropagation();
|
|
24329
24376
|
let content;
|
|
24330
24377
|
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
@@ -24755,10 +24802,7 @@ class GridComposer extends Component {
|
|
|
24755
24802
|
}
|
|
24756
24803
|
get containerStyle() {
|
|
24757
24804
|
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24758
|
-
return `
|
|
24759
|
-
position: absolute;
|
|
24760
|
-
z-index: -1000;
|
|
24761
|
-
`;
|
|
24805
|
+
return `z-index: -1000;`;
|
|
24762
24806
|
}
|
|
24763
24807
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24764
24808
|
const cell = this.env.model.getters.getActiveCell();
|
|
@@ -33986,7 +34030,12 @@ class MergePlugin extends CorePlugin {
|
|
|
33986
34030
|
* if they have at least a common cell
|
|
33987
34031
|
*/
|
|
33988
34032
|
doesIntersectMerge(sheetId, zone) {
|
|
33989
|
-
|
|
34033
|
+
for (const merge of this.getMerges(sheetId)) {
|
|
34034
|
+
if (overlap(zone, merge)) {
|
|
34035
|
+
return true;
|
|
34036
|
+
}
|
|
34037
|
+
}
|
|
34038
|
+
return false;
|
|
33990
34039
|
}
|
|
33991
34040
|
/**
|
|
33992
34041
|
* Returns true if two columns have at least one merge in common
|
|
@@ -34583,6 +34632,9 @@ class RangeAdapter {
|
|
|
34583
34632
|
if (range.invalidXc) {
|
|
34584
34633
|
return range.invalidXc;
|
|
34585
34634
|
}
|
|
34635
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
34636
|
+
return INCORRECT_RANGE_STRING;
|
|
34637
|
+
}
|
|
34586
34638
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
34587
34639
|
return INCORRECT_RANGE_STRING;
|
|
34588
34640
|
}
|
|
@@ -37634,16 +37686,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
37634
37686
|
let newContent = undefined;
|
|
37635
37687
|
let newFormat = undefined;
|
|
37636
37688
|
let isExported = true;
|
|
37689
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37637
37690
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
37638
37691
|
if (formulaCell) {
|
|
37639
37692
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
37640
37693
|
isFormula = isExported;
|
|
37641
37694
|
if (!isExported) {
|
|
37642
|
-
|
|
37643
|
-
|
|
37695
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
37696
|
+
// nothing* ,we don't export it.
|
|
37697
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
37698
|
+
// the empty string.
|
|
37699
|
+
if (value !== "") {
|
|
37700
|
+
newContent = value.toString();
|
|
37701
|
+
newFormat = evaluatedCell.format;
|
|
37702
|
+
}
|
|
37644
37703
|
}
|
|
37645
37704
|
}
|
|
37646
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
37647
37705
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
37648
37706
|
const format = newFormat
|
|
37649
37707
|
? getItemId(newFormat, data.formats)
|
|
@@ -43427,7 +43485,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
43427
43485
|
case "ADD_COLUMNS_ROWS": {
|
|
43428
43486
|
this.status = "invisible";
|
|
43429
43487
|
// If we add a col/row inside or before the cut area, we invalidate the clipboard
|
|
43430
|
-
if (this.state?.operation !== "CUT") {
|
|
43488
|
+
if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
|
|
43431
43489
|
return;
|
|
43432
43490
|
}
|
|
43433
43491
|
const isClipboardDirty = this.state.isColRowDirtyingClipboard(cmd.position === "before" ? cmd.base : cmd.base + 1, cmd.dimension);
|
|
@@ -43439,7 +43497,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
43439
43497
|
case "REMOVE_COLUMNS_ROWS": {
|
|
43440
43498
|
this.status = "invisible";
|
|
43441
43499
|
// If we remove a col/row inside or before the cut area, we invalidate the clipboard
|
|
43442
|
-
if (this.state?.operation !== "CUT") {
|
|
43500
|
+
if (this.state?.operation !== "CUT" || cmd.sheetId !== this.state?.sheetId) {
|
|
43443
43501
|
return;
|
|
43444
43502
|
}
|
|
43445
43503
|
for (let el of cmd.elements) {
|
|
@@ -46514,9 +46572,11 @@ class BottomBarSheet extends Component {
|
|
|
46514
46572
|
if (ev.key === "Enter") {
|
|
46515
46573
|
ev.preventDefault();
|
|
46516
46574
|
this.stopEdition();
|
|
46575
|
+
this.env.focusableElement.focus();
|
|
46517
46576
|
}
|
|
46518
46577
|
if (ev.key === "Escape") {
|
|
46519
46578
|
this.cancelEdition();
|
|
46579
|
+
this.env.focusableElement.focus();
|
|
46520
46580
|
}
|
|
46521
46581
|
}
|
|
46522
46582
|
onClickSheetName(ev) {
|
|
@@ -48278,6 +48338,10 @@ class Spreadsheet extends Component {
|
|
|
48278
48338
|
});
|
|
48279
48339
|
useExternalListener(window, "resize", () => this.render(true));
|
|
48280
48340
|
useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
48341
|
+
// For some reason, the wheel event is not properly registered inside templates
|
|
48342
|
+
// in Chromium-based browsers based on chromium 125
|
|
48343
|
+
// This hack ensures the event declared in the template is properly registered/working
|
|
48344
|
+
useExternalListener(document.body, "wheel", () => { });
|
|
48281
48345
|
this.bindModelEvents();
|
|
48282
48346
|
onMounted(() => {
|
|
48283
48347
|
this.checkViewportSize();
|
|
@@ -51128,7 +51192,11 @@ function addRows(construct, data, sheet) {
|
|
|
51128
51192
|
let cellNode = escapeXml ``;
|
|
51129
51193
|
// Either formula or static value inside the cell
|
|
51130
51194
|
if (cell.isFormula) {
|
|
51131
|
-
|
|
51195
|
+
const res = addFormula(cell);
|
|
51196
|
+
if (!res) {
|
|
51197
|
+
continue;
|
|
51198
|
+
}
|
|
51199
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
51132
51200
|
}
|
|
51133
51201
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
51134
51202
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -52091,6 +52159,6 @@ const constants = {
|
|
|
52091
52159
|
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 };
|
|
52092
52160
|
|
|
52093
52161
|
|
|
52094
|
-
__info__.version = '16.4.
|
|
52095
|
-
__info__.date = '2024-
|
|
52096
|
-
__info__.hash = '
|
|
52162
|
+
__info__.version = '16.4.36';
|
|
52163
|
+
__info__.date = '2024-06-10T09:33:43.623Z';
|
|
52164
|
+
__info__.hash = '3b15ed5';
|