@odoo/o-spreadsheet 17.1.3 → 17.1.4
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 +219 -134
- package/dist/o-spreadsheet.d.ts +35 -18
- package/dist/o-spreadsheet.esm.js +219 -134
- package/dist/o-spreadsheet.iife.js +219 -134
- package/dist/o-spreadsheet.iife.min.js +288 -288
- package/dist/o_spreadsheet.xml +15 -33
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
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.1.
|
|
6
|
-
* @date 2024-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.4
|
|
6
|
+
* @date 2024-02-09T13:09:13.430Z
|
|
7
|
+
* @hash 16d3ece
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2940,6 +2940,9 @@ function formatValue(value, { format, locale }) {
|
|
|
2940
2940
|
}
|
|
2941
2941
|
switch (typeof value) {
|
|
2942
2942
|
case "string":
|
|
2943
|
+
if (value.includes('\\"')) {
|
|
2944
|
+
return value.replace(/\\"/g, '"');
|
|
2945
|
+
}
|
|
2943
2946
|
return value;
|
|
2944
2947
|
case "boolean":
|
|
2945
2948
|
return value ? "TRUE" : "FALSE";
|
|
@@ -4993,14 +4996,8 @@ function createDataSets(getters, dataSetsString, sheetId, dataSetsHaveTitle) {
|
|
|
4993
4996
|
: undefined));
|
|
4994
4997
|
}
|
|
4995
4998
|
}
|
|
4996
|
-
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
4997
|
-
// A single cell. If it's only the title, the dataset is not added.
|
|
4998
|
-
if (!dataSetsHaveTitle) {
|
|
4999
|
-
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
5000
|
-
}
|
|
5001
|
-
}
|
|
5002
4999
|
else {
|
|
5003
|
-
/* 1 row or 1 column */
|
|
5000
|
+
/* 1 cell, 1 row or 1 column */
|
|
5004
5001
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
5005
5002
|
? {
|
|
5006
5003
|
top: zone.top,
|
|
@@ -7443,7 +7440,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
7443
7440
|
while (!chars.isOver()) {
|
|
7444
7441
|
let token = tokenizeSpace(chars) ||
|
|
7445
7442
|
tokenizeArgsSeparator(chars, locale) ||
|
|
7446
|
-
|
|
7443
|
+
tokenizeParenthesis(chars) ||
|
|
7447
7444
|
tokenizeOperator(chars) ||
|
|
7448
7445
|
tokenizeString(chars) ||
|
|
7449
7446
|
tokenizeDebugger(chars) ||
|
|
@@ -7464,15 +7461,14 @@ function tokenizeDebugger(chars) {
|
|
|
7464
7461
|
}
|
|
7465
7462
|
return null;
|
|
7466
7463
|
}
|
|
7467
|
-
const
|
|
7468
|
-
"(": "LEFT_PAREN",
|
|
7469
|
-
")": "RIGHT_PAREN",
|
|
7464
|
+
const parenthesis = {
|
|
7465
|
+
"(": { type: "LEFT_PAREN", value: "(" },
|
|
7466
|
+
")": { type: "RIGHT_PAREN", value: ")" },
|
|
7470
7467
|
};
|
|
7471
|
-
function
|
|
7472
|
-
if (chars.current
|
|
7468
|
+
function tokenizeParenthesis(chars) {
|
|
7469
|
+
if (chars.current === "(" || chars.current === ")") {
|
|
7473
7470
|
const value = chars.shift();
|
|
7474
|
-
|
|
7475
|
-
return { type, value };
|
|
7471
|
+
return parenthesis[value];
|
|
7476
7472
|
}
|
|
7477
7473
|
return null;
|
|
7478
7474
|
}
|
|
@@ -7493,7 +7489,12 @@ function tokenizeOperator(chars) {
|
|
|
7493
7489
|
}
|
|
7494
7490
|
return null;
|
|
7495
7491
|
}
|
|
7492
|
+
const FIRST_POSSIBLE_NUMBER_CHARS = new Set("0123456789");
|
|
7496
7493
|
function tokenizeNumber(chars, locale) {
|
|
7494
|
+
if (!FIRST_POSSIBLE_NUMBER_CHARS.has(chars.current) &&
|
|
7495
|
+
chars.current !== locale.decimalSeparator) {
|
|
7496
|
+
return null;
|
|
7497
|
+
}
|
|
7497
7498
|
const match = chars.remaining().match(getFormulaNumberRegex(locale.decimalSeparator));
|
|
7498
7499
|
if (match) {
|
|
7499
7500
|
chars.advanceBy(match[0].length);
|
|
@@ -7518,7 +7519,7 @@ function tokenizeString(chars) {
|
|
|
7518
7519
|
}
|
|
7519
7520
|
return null;
|
|
7520
7521
|
}
|
|
7521
|
-
const separatorRegexp =
|
|
7522
|
+
const separatorRegexp = /^[\w\.!\$]+/;
|
|
7522
7523
|
/**
|
|
7523
7524
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
7524
7525
|
* formula, which is not a string. So:
|
|
@@ -7558,8 +7559,11 @@ function tokenizeSymbol(chars) {
|
|
|
7558
7559
|
};
|
|
7559
7560
|
}
|
|
7560
7561
|
}
|
|
7561
|
-
|
|
7562
|
-
|
|
7562
|
+
const match = chars.remaining().match(separatorRegexp);
|
|
7563
|
+
if (match) {
|
|
7564
|
+
const value = match[0];
|
|
7565
|
+
result += value;
|
|
7566
|
+
chars.advanceBy(value.length);
|
|
7563
7567
|
}
|
|
7564
7568
|
if (result.length) {
|
|
7565
7569
|
const value = result;
|
|
@@ -7621,7 +7625,10 @@ class TokenizingChars {
|
|
|
7621
7625
|
return this.text.substring(this.currentIndex);
|
|
7622
7626
|
}
|
|
7623
7627
|
currentStartsWith(str) {
|
|
7624
|
-
|
|
7628
|
+
if (this.current !== str[0]) {
|
|
7629
|
+
return false;
|
|
7630
|
+
}
|
|
7631
|
+
for (let j = 1; j < str.length; j++) {
|
|
7625
7632
|
if (this.text[this.currentIndex + j] !== str[j]) {
|
|
7626
7633
|
return false;
|
|
7627
7634
|
}
|
|
@@ -8653,7 +8660,7 @@ class BarChart extends AbstractChart {
|
|
|
8653
8660
|
return undefined;
|
|
8654
8661
|
const dataSets = this.dataSets
|
|
8655
8662
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
8656
|
-
.filter((ds) => ds.range !== ""
|
|
8663
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
8657
8664
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
8658
8665
|
return {
|
|
8659
8666
|
...this.getDefinition(),
|
|
@@ -9231,7 +9238,7 @@ class LineChart extends AbstractChart {
|
|
|
9231
9238
|
return undefined;
|
|
9232
9239
|
const dataSets = this.dataSets
|
|
9233
9240
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
9234
|
-
.filter((ds) => ds.range !== ""
|
|
9241
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
9235
9242
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
9236
9243
|
return {
|
|
9237
9244
|
...this.getDefinition(),
|
|
@@ -9537,7 +9544,7 @@ class PieChart extends AbstractChart {
|
|
|
9537
9544
|
return undefined;
|
|
9538
9545
|
const dataSets = this.dataSets
|
|
9539
9546
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
9540
|
-
.filter((ds) => ds.range !== ""
|
|
9547
|
+
.filter((ds) => ds.range !== "" && ds.range !== CellErrorType.InvalidReference);
|
|
9541
9548
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
9542
9549
|
return {
|
|
9543
9550
|
...this.getDefinition(),
|
|
@@ -18684,6 +18691,9 @@ const HLOOKUP = {
|
|
|
18684
18691
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18685
18692
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18686
18693
|
assert(() => 1 <= _index && _index <= range[0].length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18694
|
+
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18695
|
+
return searchKey;
|
|
18696
|
+
}
|
|
18687
18697
|
const getValueFromRange = (range, index) => range[index][0].value;
|
|
18688
18698
|
const _isSorted = toBoolean(isSorted.value);
|
|
18689
18699
|
const colIndex = _isSorted
|
|
@@ -18851,6 +18861,9 @@ const VLOOKUP = {
|
|
|
18851
18861
|
compute: function (searchKey, range, index, isSorted = { value: DEFAULT_IS_SORTED }) {
|
|
18852
18862
|
const _index = Math.trunc(toNumber(index?.value, this.locale));
|
|
18853
18863
|
assert(() => 1 <= _index && _index <= range.length, _t("[[FUNCTION_NAME]] evaluates to an out of bounds range."));
|
|
18864
|
+
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18865
|
+
return searchKey;
|
|
18866
|
+
}
|
|
18854
18867
|
const getValueFromRange = (range, index) => range[0][index].value;
|
|
18855
18868
|
const _isSorted = toBoolean(isSorted.value);
|
|
18856
18869
|
const rowIndex = _isSorted
|
|
@@ -18890,6 +18903,9 @@ const XLOOKUP = {
|
|
|
18890
18903
|
assert(() => lookupDirection === "col"
|
|
18891
18904
|
? returnRange[0].length === lookupRange[0].length
|
|
18892
18905
|
: returnRange.length === lookupRange.length, _t("return_range should have the same dimensions as lookup_range."));
|
|
18906
|
+
if (searchKey && isEvaluationError(searchKey.value)) {
|
|
18907
|
+
return [[searchKey]];
|
|
18908
|
+
}
|
|
18893
18909
|
const getElement = lookupDirection === "col"
|
|
18894
18910
|
? (range, index) => range[0][index].value
|
|
18895
18911
|
: (range, index) => range[index][0].value;
|
|
@@ -26971,15 +26987,17 @@ class Composer extends owl.Component {
|
|
|
26971
26987
|
focus: {
|
|
26972
26988
|
validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
|
|
26973
26989
|
},
|
|
26974
|
-
onComposerContentFocused: Function,
|
|
26975
26990
|
inputStyle: { type: String, optional: true },
|
|
26976
26991
|
rect: { type: Object, optional: true },
|
|
26977
26992
|
delimitation: { type: Object, optional: true },
|
|
26978
|
-
|
|
26993
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
26994
|
+
onComposerContentFocused: Function,
|
|
26995
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
26979
26996
|
};
|
|
26980
26997
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
26981
26998
|
static defaultProps = {
|
|
26982
26999
|
inputStyle: "",
|
|
27000
|
+
isDefaultFocus: false,
|
|
26983
27001
|
};
|
|
26984
27002
|
composerRef = owl.useRef("o_composer");
|
|
26985
27003
|
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
|
@@ -27036,7 +27054,6 @@ class Composer extends owl.Component {
|
|
|
27036
27054
|
F4: this.processF4Key,
|
|
27037
27055
|
Tab: (ev) => this.processTabKey(ev, "right"),
|
|
27038
27056
|
"Shift+Tab": (ev) => this.processTabKey(ev, "left"),
|
|
27039
|
-
"Ctrl+ ": this.processSpaceKey,
|
|
27040
27057
|
};
|
|
27041
27058
|
keyCodeMapping = {
|
|
27042
27059
|
NumpadDecimal: this.processNumpadDecimal,
|
|
@@ -27044,12 +27061,12 @@ class Composer extends owl.Component {
|
|
|
27044
27061
|
setup() {
|
|
27045
27062
|
owl.onMounted(() => {
|
|
27046
27063
|
const el = this.composerRef.el;
|
|
27064
|
+
if (this.props.isDefaultFocus) {
|
|
27065
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
27066
|
+
}
|
|
27047
27067
|
this.contentHelper.updateEl(el);
|
|
27048
27068
|
this.processTokenAtCursor();
|
|
27049
27069
|
});
|
|
27050
|
-
owl.onWillUnmount(() => {
|
|
27051
|
-
this.props.onComposerUnmounted?.();
|
|
27052
|
-
});
|
|
27053
27070
|
owl.useEffect(() => {
|
|
27054
27071
|
this.processContent();
|
|
27055
27072
|
});
|
|
@@ -27058,7 +27075,8 @@ class Composer extends owl.Component {
|
|
|
27058
27075
|
// Handlers
|
|
27059
27076
|
// ---------------------------------------------------------------------------
|
|
27060
27077
|
processArrowKeys(ev) {
|
|
27061
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
27078
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
27079
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
27062
27080
|
this.functionDescriptionState.showDescription = false;
|
|
27063
27081
|
// Prevent the default content editable behavior which moves the cursor
|
|
27064
27082
|
ev.preventDefault();
|
|
@@ -27101,23 +27119,19 @@ class Composer extends owl.Component {
|
|
|
27101
27119
|
processTabKey(ev, direction) {
|
|
27102
27120
|
ev.preventDefault();
|
|
27103
27121
|
ev.stopPropagation();
|
|
27104
|
-
|
|
27105
|
-
|
|
27106
|
-
|
|
27107
|
-
|
|
27108
|
-
|
|
27109
|
-
|
|
27122
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
27123
|
+
const state = this.autoCompleteState;
|
|
27124
|
+
if (state.showProvider && state.selectedIndex !== undefined) {
|
|
27125
|
+
const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
|
|
27126
|
+
if (autoCompleteValue) {
|
|
27127
|
+
this.autoComplete(autoCompleteValue);
|
|
27128
|
+
return;
|
|
27129
|
+
}
|
|
27110
27130
|
}
|
|
27131
|
+
interactiveStopEdition(this.env);
|
|
27111
27132
|
}
|
|
27112
|
-
interactiveStopEdition(this.env);
|
|
27113
27133
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
27114
27134
|
}
|
|
27115
|
-
processSpaceKey(ev) {
|
|
27116
|
-
ev.preventDefault();
|
|
27117
|
-
ev.stopPropagation();
|
|
27118
|
-
this.showFunctionAutocomplete("");
|
|
27119
|
-
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
27120
|
-
}
|
|
27121
27135
|
processEnterKey(ev, direction) {
|
|
27122
27136
|
ev.preventDefault();
|
|
27123
27137
|
ev.stopPropagation();
|
|
@@ -27179,6 +27193,9 @@ class Composer extends owl.Component {
|
|
|
27179
27193
|
this.compositionActive = false;
|
|
27180
27194
|
}
|
|
27181
27195
|
onKeydown(ev) {
|
|
27196
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
27197
|
+
return;
|
|
27198
|
+
}
|
|
27182
27199
|
if (ev.key.startsWith("Arrow")) {
|
|
27183
27200
|
this.processArrowKeys(ev);
|
|
27184
27201
|
return;
|
|
@@ -27192,14 +27209,33 @@ class Composer extends owl.Component {
|
|
|
27192
27209
|
ev.stopPropagation();
|
|
27193
27210
|
}
|
|
27194
27211
|
}
|
|
27212
|
+
onPaste(ev) {
|
|
27213
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
27214
|
+
ev.stopPropagation();
|
|
27215
|
+
}
|
|
27216
|
+
}
|
|
27195
27217
|
/*
|
|
27196
27218
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
27197
27219
|
* */
|
|
27198
27220
|
onInput(ev) {
|
|
27199
|
-
if (
|
|
27221
|
+
if (!this.shouldProcessInputEvents) {
|
|
27222
|
+
return;
|
|
27223
|
+
}
|
|
27224
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
27225
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
27200
27226
|
return;
|
|
27201
27227
|
}
|
|
27202
|
-
|
|
27228
|
+
ev.stopPropagation();
|
|
27229
|
+
let content;
|
|
27230
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
27231
|
+
content = ev.data || "";
|
|
27232
|
+
}
|
|
27233
|
+
else {
|
|
27234
|
+
content = this.contentHelper.getText();
|
|
27235
|
+
}
|
|
27236
|
+
if (this.props.focus === "inactive") {
|
|
27237
|
+
return this.props.onComposerCellFocused?.(content);
|
|
27238
|
+
}
|
|
27203
27239
|
let selection = this.contentHelper.getCurrentSelection();
|
|
27204
27240
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
27205
27241
|
this.env.model.dispatch("SET_CURRENT_CONTENT", {
|
|
@@ -27275,9 +27311,8 @@ class Composer extends owl.Component {
|
|
|
27275
27311
|
}
|
|
27276
27312
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
27277
27313
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
27278
|
-
|
|
27279
|
-
|
|
27280
|
-
}
|
|
27314
|
+
this.props.onComposerContentFocused();
|
|
27315
|
+
if (this.props.focus === "inactive") ;
|
|
27281
27316
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
27282
27317
|
this.processTokenAtCursor();
|
|
27283
27318
|
}
|
|
@@ -27444,7 +27479,7 @@ class Composer extends owl.Component {
|
|
|
27444
27479
|
const highlights = this.env.model.getters.getHighlights();
|
|
27445
27480
|
const refSheet = sheetName
|
|
27446
27481
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
27447
|
-
: this.env.model.getters.getCurrentEditedCell()
|
|
27482
|
+
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
|
27448
27483
|
const highlight = highlights.find((highlight) => {
|
|
27449
27484
|
if (highlight.sheetId !== refSheet)
|
|
27450
27485
|
return false;
|
|
@@ -27571,56 +27606,30 @@ class GridComposer extends owl.Component {
|
|
|
27571
27606
|
focus: {
|
|
27572
27607
|
validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value),
|
|
27573
27608
|
},
|
|
27574
|
-
|
|
27609
|
+
onComposerCellFocused: Function,
|
|
27575
27610
|
onComposerContentFocused: Function,
|
|
27576
27611
|
gridDims: Object,
|
|
27577
27612
|
};
|
|
27578
27613
|
static components = { Composer };
|
|
27579
|
-
|
|
27580
|
-
|
|
27581
|
-
rect;
|
|
27614
|
+
rect = this.defaultRect;
|
|
27615
|
+
isEditing = false;
|
|
27582
27616
|
isCellReferenceVisible;
|
|
27583
|
-
|
|
27617
|
+
get defaultRect() {
|
|
27618
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
27619
|
+
}
|
|
27584
27620
|
setup() {
|
|
27585
|
-
this.gridComposerRef = owl.useRef("gridComposer");
|
|
27586
|
-
this.composerState = owl.useState({
|
|
27587
|
-
rect: undefined,
|
|
27588
|
-
delimitation: undefined,
|
|
27589
|
-
});
|
|
27590
|
-
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
|
27591
|
-
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
|
27592
|
-
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
|
27593
|
-
this.isCellReferenceVisible = false;
|
|
27594
|
-
owl.onMounted(() => {
|
|
27595
|
-
const el = this.gridComposerRef.el;
|
|
27596
|
-
this.composerState.rect = {
|
|
27597
|
-
x: this.rect.x,
|
|
27598
|
-
y: this.rect.y,
|
|
27599
|
-
width: el.clientWidth,
|
|
27600
|
-
height: el.clientHeight,
|
|
27601
|
-
};
|
|
27602
|
-
this.composerState.delimitation = {
|
|
27603
|
-
width: this.props.gridDims.width,
|
|
27604
|
-
height: this.props.gridDims.height,
|
|
27605
|
-
};
|
|
27606
|
-
});
|
|
27607
27621
|
owl.onWillUpdateProps(() => {
|
|
27608
|
-
|
|
27609
|
-
|
|
27610
|
-
}
|
|
27611
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27612
|
-
const zone = this.env.model.getters.getSelectedZone();
|
|
27613
|
-
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
27614
|
-
if (!deepEquals(rect, this.rect) ||
|
|
27615
|
-
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
27616
|
-
this.isCellReferenceVisible = true;
|
|
27617
|
-
}
|
|
27622
|
+
this.updateComponentPosition();
|
|
27623
|
+
this.updateCellReferenceVisibility();
|
|
27618
27624
|
});
|
|
27619
27625
|
}
|
|
27620
27626
|
get shouldDisplayCellReference() {
|
|
27621
27627
|
return this.isCellReferenceVisible;
|
|
27622
27628
|
}
|
|
27623
27629
|
get cellReference() {
|
|
27630
|
+
if (!this.env.model.getters.getCurrentEditedCell()) {
|
|
27631
|
+
return "";
|
|
27632
|
+
}
|
|
27624
27633
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
27625
27634
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
27626
27635
|
return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
|
|
@@ -27632,7 +27641,27 @@ class GridComposer extends owl.Component {
|
|
|
27632
27641
|
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
|
27633
27642
|
});
|
|
27634
27643
|
}
|
|
27644
|
+
get composerProps() {
|
|
27645
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
27646
|
+
return {
|
|
27647
|
+
rect: { ...this.rect },
|
|
27648
|
+
delimitation: {
|
|
27649
|
+
width,
|
|
27650
|
+
height,
|
|
27651
|
+
},
|
|
27652
|
+
focus: this.props.focus,
|
|
27653
|
+
isDefaultFocus: true,
|
|
27654
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
27655
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
27656
|
+
};
|
|
27657
|
+
}
|
|
27635
27658
|
get containerStyle() {
|
|
27659
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
27660
|
+
return `
|
|
27661
|
+
position: absolute;
|
|
27662
|
+
z-index: -1000;
|
|
27663
|
+
`;
|
|
27664
|
+
}
|
|
27636
27665
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
27637
27666
|
const cell = this.env.model.getters.getActiveCell();
|
|
27638
27667
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -27652,6 +27681,8 @@ class GridComposer extends owl.Component {
|
|
|
27652
27681
|
if (!isFormula) {
|
|
27653
27682
|
textAlign = style.align || cell.defaultAlign;
|
|
27654
27683
|
}
|
|
27684
|
+
const maxHeight = this.props.gridDims.height - this.rect.y;
|
|
27685
|
+
const maxWidth = this.props.gridDims.width - this.rect.x;
|
|
27655
27686
|
/**
|
|
27656
27687
|
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
|
27657
27688
|
* including all the paddings/margins of the composer
|
|
@@ -27663,6 +27694,8 @@ class GridComposer extends owl.Component {
|
|
|
27663
27694
|
top: `${top}px`,
|
|
27664
27695
|
"min-width": `${width + 1}px`,
|
|
27665
27696
|
"min-height": `${height + 1}px`,
|
|
27697
|
+
"max-width": `${maxWidth}px`,
|
|
27698
|
+
"max-height": `${maxHeight}px`,
|
|
27666
27699
|
background,
|
|
27667
27700
|
color,
|
|
27668
27701
|
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
|
@@ -27672,13 +27705,31 @@ class GridComposer extends owl.Component {
|
|
|
27672
27705
|
"text-align": textAlign,
|
|
27673
27706
|
});
|
|
27674
27707
|
}
|
|
27675
|
-
|
|
27676
|
-
const
|
|
27677
|
-
|
|
27678
|
-
|
|
27679
|
-
|
|
27680
|
-
|
|
27681
|
-
|
|
27708
|
+
updateComponentPosition() {
|
|
27709
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
27710
|
+
if (this.isEditing !== isEditing) {
|
|
27711
|
+
this.isEditing = isEditing;
|
|
27712
|
+
if (!isEditing) {
|
|
27713
|
+
this.rect = this.defaultRect;
|
|
27714
|
+
this.env.focusableElement.focus();
|
|
27715
|
+
return;
|
|
27716
|
+
}
|
|
27717
|
+
const position = this.env.model.getters.getActivePosition();
|
|
27718
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
27719
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
27720
|
+
}
|
|
27721
|
+
}
|
|
27722
|
+
updateCellReferenceVisibility() {
|
|
27723
|
+
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
|
27724
|
+
return;
|
|
27725
|
+
}
|
|
27726
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27727
|
+
const zone = this.env.model.getters.getSelectedZone();
|
|
27728
|
+
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
27729
|
+
if (!deepEquals(rect, this.rect) ||
|
|
27730
|
+
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
27731
|
+
this.isCellReferenceVisible = true;
|
|
27732
|
+
}
|
|
27682
27733
|
}
|
|
27683
27734
|
}
|
|
27684
27735
|
|
|
@@ -28778,7 +28829,6 @@ class GridOverlay extends owl.Component {
|
|
|
28778
28829
|
this.props.onCellDoubleClicked(col, row);
|
|
28779
28830
|
}
|
|
28780
28831
|
onContextMenu(ev) {
|
|
28781
|
-
ev.preventDefault();
|
|
28782
28832
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
28783
28833
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
28784
28834
|
}
|
|
@@ -29843,7 +29893,6 @@ class Grid extends owl.Component {
|
|
|
29843
29893
|
HEADER_WIDTH = HEADER_WIDTH;
|
|
29844
29894
|
menuState;
|
|
29845
29895
|
gridRef;
|
|
29846
|
-
hiddenInput;
|
|
29847
29896
|
onMouseWheel;
|
|
29848
29897
|
canvasPosition;
|
|
29849
29898
|
hoveredCell;
|
|
@@ -29854,15 +29903,14 @@ class Grid extends owl.Component {
|
|
|
29854
29903
|
menuItems: [],
|
|
29855
29904
|
});
|
|
29856
29905
|
this.gridRef = owl.useRef("grid");
|
|
29857
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
29858
29906
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
29859
29907
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
29860
29908
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
29861
29909
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
29862
29910
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
29863
29911
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
29864
|
-
owl.onMounted(() => this.
|
|
29865
|
-
this.props.exposeFocus(() => this.
|
|
29912
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
29913
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
29866
29914
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
29867
29915
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
29868
29916
|
this.moveCanvas(deltaX, deltaY);
|
|
@@ -29886,7 +29934,7 @@ class Grid extends owl.Component {
|
|
|
29886
29934
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
29887
29935
|
this.closeOpenedPopover();
|
|
29888
29936
|
}
|
|
29889
|
-
this.
|
|
29937
|
+
this.focusDefaultElement();
|
|
29890
29938
|
}
|
|
29891
29939
|
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
|
29892
29940
|
// down itself
|
|
@@ -30065,10 +30113,10 @@ class Grid extends owl.Component {
|
|
|
30065
30113
|
"Alt+Shift+ArrowUp": () => this.processHeaderGroupingKey("up"),
|
|
30066
30114
|
"Alt+Shift+ArrowDown": () => this.processHeaderGroupingKey("down"),
|
|
30067
30115
|
};
|
|
30068
|
-
|
|
30116
|
+
focusDefaultElement() {
|
|
30069
30117
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
30070
30118
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
30071
|
-
this.
|
|
30119
|
+
this.env.focusableElement.focus();
|
|
30072
30120
|
}
|
|
30073
30121
|
}
|
|
30074
30122
|
get gridEl() {
|
|
@@ -30204,19 +30252,6 @@ class Grid extends owl.Component {
|
|
|
30204
30252
|
return;
|
|
30205
30253
|
}
|
|
30206
30254
|
}
|
|
30207
|
-
onInput(ev) {
|
|
30208
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
30209
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
30210
|
-
return;
|
|
30211
|
-
}
|
|
30212
|
-
if (ev.data) {
|
|
30213
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
30214
|
-
// character
|
|
30215
|
-
ev.preventDefault();
|
|
30216
|
-
ev.stopPropagation();
|
|
30217
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
30218
|
-
}
|
|
30219
|
-
}
|
|
30220
30255
|
// ---------------------------------------------------------------------------
|
|
30221
30256
|
// Context Menu
|
|
30222
30257
|
// ---------------------------------------------------------------------------
|
|
@@ -30331,7 +30366,7 @@ class Grid extends owl.Component {
|
|
|
30331
30366
|
}
|
|
30332
30367
|
closeMenu() {
|
|
30333
30368
|
this.menuState.isOpen = false;
|
|
30334
|
-
this.
|
|
30369
|
+
this.focusDefaultElement();
|
|
30335
30370
|
}
|
|
30336
30371
|
processHeaderGroupingKey(direction) {
|
|
30337
30372
|
if (this.env.model.getters.getSelectedZones().length !== 1) {
|
|
@@ -34248,6 +34283,31 @@ const MIGRATIONS = [
|
|
|
34248
34283
|
return data;
|
|
34249
34284
|
},
|
|
34250
34285
|
},
|
|
34286
|
+
{
|
|
34287
|
+
description: "Fix datafilter duplication",
|
|
34288
|
+
from: 12,
|
|
34289
|
+
to: 12.5,
|
|
34290
|
+
applyMigration(data) {
|
|
34291
|
+
for (let sheet of data.sheets || []) {
|
|
34292
|
+
let knownDataFilterZones = [];
|
|
34293
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
34294
|
+
const zone = toZone(filterTable.range);
|
|
34295
|
+
// See commit message for the details
|
|
34296
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
34297
|
+
if (intersectZoneIndex !== -1) {
|
|
34298
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
34299
|
+
}
|
|
34300
|
+
else {
|
|
34301
|
+
knownDataFilterZones.push(zone);
|
|
34302
|
+
}
|
|
34303
|
+
}
|
|
34304
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
34305
|
+
range: zoneToXc(zone),
|
|
34306
|
+
}));
|
|
34307
|
+
}
|
|
34308
|
+
return data;
|
|
34309
|
+
},
|
|
34310
|
+
},
|
|
34251
34311
|
{
|
|
34252
34312
|
description: "Change Border description structure",
|
|
34253
34313
|
from: 12,
|
|
@@ -36034,9 +36094,6 @@ class CellPlugin extends CorePlugin {
|
|
|
36034
36094
|
format: cell.format ? getItemId(cell.format, formats) : undefined,
|
|
36035
36095
|
content: cell.content || undefined,
|
|
36036
36096
|
};
|
|
36037
|
-
if (cell instanceof FormulaCellWithDependencies) {
|
|
36038
|
-
cells[xc].content = cell.contentWithFixedReferences || undefined;
|
|
36039
|
-
}
|
|
36040
36097
|
}
|
|
36041
36098
|
_sheet.cells = cells;
|
|
36042
36099
|
}
|
|
@@ -36288,8 +36345,11 @@ class CellPlugin extends CorePlugin {
|
|
|
36288
36345
|
* being a computed property to rebuild the dependencies XC.
|
|
36289
36346
|
*/
|
|
36290
36347
|
createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
|
|
36291
|
-
const dependencies =
|
|
36292
|
-
|
|
36348
|
+
const dependencies = [];
|
|
36349
|
+
for (const xc of compiledFormula.dependencies) {
|
|
36350
|
+
dependencies.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
36351
|
+
}
|
|
36352
|
+
return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString);
|
|
36293
36353
|
}
|
|
36294
36354
|
createErrorFormula(id, content, format, style, error) {
|
|
36295
36355
|
return {
|
|
@@ -36343,7 +36403,7 @@ class FormulaCellWithDependencies {
|
|
|
36343
36403
|
const tokens = compiledFormula.tokens.map((token) => {
|
|
36344
36404
|
if (token.type === "REFERENCE") {
|
|
36345
36405
|
const index = rangeIndex++;
|
|
36346
|
-
return new RangeReferenceToken(
|
|
36406
|
+
return new RangeReferenceToken(dependencies, index, this.sheetId, this.getRangeString);
|
|
36347
36407
|
}
|
|
36348
36408
|
return token;
|
|
36349
36409
|
});
|
|
@@ -36370,13 +36430,20 @@ class FormulaCellWithDependencies {
|
|
|
36370
36430
|
}
|
|
36371
36431
|
}
|
|
36372
36432
|
class RangeReferenceToken {
|
|
36373
|
-
|
|
36433
|
+
ranges;
|
|
36434
|
+
rangeIndex;
|
|
36435
|
+
sheetId;
|
|
36436
|
+
getRangeString;
|
|
36374
36437
|
type = "REFERENCE";
|
|
36375
|
-
constructor(
|
|
36376
|
-
this.
|
|
36438
|
+
constructor(ranges, rangeIndex, sheetId, getRangeString) {
|
|
36439
|
+
this.ranges = ranges;
|
|
36440
|
+
this.rangeIndex = rangeIndex;
|
|
36441
|
+
this.sheetId = sheetId;
|
|
36442
|
+
this.getRangeString = getRangeString;
|
|
36377
36443
|
}
|
|
36378
36444
|
get value() {
|
|
36379
|
-
|
|
36445
|
+
const range = this.ranges[this.rangeIndex];
|
|
36446
|
+
return this.getRangeString(range, this.sheetId);
|
|
36380
36447
|
}
|
|
36381
36448
|
}
|
|
36382
36449
|
|
|
@@ -41911,7 +41978,13 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
41911
41978
|
const format = newFormat
|
|
41912
41979
|
? getItemId(newFormat, data.formats)
|
|
41913
41980
|
: exportedCellData.format;
|
|
41914
|
-
|
|
41981
|
+
let content;
|
|
41982
|
+
if (formulaCell instanceof FormulaCellWithDependencies) {
|
|
41983
|
+
content = formulaCell.contentWithFixedReferences;
|
|
41984
|
+
}
|
|
41985
|
+
else {
|
|
41986
|
+
content = !isExported ? newContent : exportedCellData.content;
|
|
41987
|
+
}
|
|
41915
41988
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
41916
41989
|
}
|
|
41917
41990
|
}
|
|
@@ -51095,6 +51168,16 @@ class ImageProvider {
|
|
|
51095
51168
|
}
|
|
51096
51169
|
}
|
|
51097
51170
|
|
|
51171
|
+
class FocusableElement {
|
|
51172
|
+
focusableElement = undefined;
|
|
51173
|
+
setFocusableElement(element) {
|
|
51174
|
+
this.focusableElement = element;
|
|
51175
|
+
}
|
|
51176
|
+
focus() {
|
|
51177
|
+
this.focusableElement?.focus();
|
|
51178
|
+
}
|
|
51179
|
+
}
|
|
51180
|
+
|
|
51098
51181
|
const RIPPLE_KEY_FRAMES = [
|
|
51099
51182
|
{ transform: "scale(0)" },
|
|
51100
51183
|
{ transform: "scale(0.8)", offset: 0.33 },
|
|
@@ -53249,6 +53332,7 @@ class Spreadsheet extends owl.Component {
|
|
|
53249
53332
|
toggleSidePanel: this.toggleSidePanel.bind(this),
|
|
53250
53333
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
53251
53334
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
53335
|
+
focusableElement: new FocusableElement(),
|
|
53252
53336
|
});
|
|
53253
53337
|
owl.useEffect(() => {
|
|
53254
53338
|
/**
|
|
@@ -53367,16 +53451,17 @@ class Spreadsheet extends owl.Component {
|
|
|
53367
53451
|
}
|
|
53368
53452
|
this.composer.topBarFocus = "contentFocus";
|
|
53369
53453
|
this.composer.gridFocusMode = "inactive";
|
|
53370
|
-
this.setComposerContent({ selection }
|
|
53454
|
+
this.setComposerContent({ selection });
|
|
53371
53455
|
}
|
|
53372
|
-
onGridComposerContentFocused() {
|
|
53456
|
+
onGridComposerContentFocused(selection) {
|
|
53373
53457
|
if (this.model.getters.isReadonly()) {
|
|
53374
53458
|
return;
|
|
53375
53459
|
}
|
|
53376
53460
|
this.composer.topBarFocus = "inactive";
|
|
53377
53461
|
this.composer.gridFocusMode = "contentFocus";
|
|
53378
|
-
this.setComposerContent({});
|
|
53462
|
+
this.setComposerContent({ selection });
|
|
53379
53463
|
}
|
|
53464
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
53380
53465
|
onGridComposerCellFocused(content, selection) {
|
|
53381
53466
|
if (this.model.getters.isReadonly()) {
|
|
53382
53467
|
return;
|
|
@@ -57100,6 +57185,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
57100
57185
|
exports.tokenize = tokenize;
|
|
57101
57186
|
|
|
57102
57187
|
|
|
57103
|
-
__info__.version = "17.1.
|
|
57104
|
-
__info__.date = "2024-02-
|
|
57105
|
-
__info__.hash = "
|
|
57188
|
+
__info__.version = "17.1.4";
|
|
57189
|
+
__info__.date = "2024-02-09T13:09:13.430Z";
|
|
57190
|
+
__info__.hash = "16d3ece";
|