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