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