@odoo/o-spreadsheet 16.4.20 → 16.4.23
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 +270 -175
- package/dist/o-spreadsheet.d.ts +31 -16
- package/dist/o-spreadsheet.esm.js +270 -175
- package/dist/o-spreadsheet.iife.js +270 -175
- package/dist/o-spreadsheet.iife.min.js +103 -110
- package/dist/o_spreadsheet.xml +15 -33
- package/package.json +1 -1
|
@@ -702,18 +702,18 @@
|
|
|
702
702
|
return true;
|
|
703
703
|
}
|
|
704
704
|
class JetSet extends Set {
|
|
705
|
-
|
|
705
|
+
addMany(iterable) {
|
|
706
706
|
for (const element of iterable) {
|
|
707
707
|
super.add(element);
|
|
708
708
|
}
|
|
709
709
|
return this;
|
|
710
710
|
}
|
|
711
|
-
|
|
712
|
-
let
|
|
711
|
+
deleteMany(iterable) {
|
|
712
|
+
let wasDeleted = false;
|
|
713
713
|
for (const element of iterable) {
|
|
714
|
-
|
|
714
|
+
wasDeleted ||= super.delete(element);
|
|
715
715
|
}
|
|
716
|
-
return
|
|
716
|
+
return wasDeleted;
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
/**
|
|
@@ -1839,6 +1839,9 @@
|
|
|
1839
1839
|
function formatValue(value, { format, locale }) {
|
|
1840
1840
|
switch (typeof value) {
|
|
1841
1841
|
case "string":
|
|
1842
|
+
if (value.includes('\\"')) {
|
|
1843
|
+
return value.replace(/\\"/g, '"');
|
|
1844
|
+
}
|
|
1842
1845
|
return value;
|
|
1843
1846
|
case "boolean":
|
|
1844
1847
|
return value ? "TRUE" : "FALSE";
|
|
@@ -15236,6 +15239,9 @@
|
|
|
15236
15239
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
15237
15240
|
return false;
|
|
15238
15241
|
}
|
|
15242
|
+
if (locale.thousandsSeparator === locale.decimalSeparator) {
|
|
15243
|
+
return false;
|
|
15244
|
+
}
|
|
15239
15245
|
try {
|
|
15240
15246
|
formatValue(1, { locale, format: "#,##0.00" });
|
|
15241
15247
|
formatValue(1, { locale, format: locale.dateFormat });
|
|
@@ -15326,7 +15332,7 @@
|
|
|
15326
15332
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
15327
15333
|
return content;
|
|
15328
15334
|
}
|
|
15329
|
-
return content.replace(locale.decimalSeparator, ".");
|
|
15335
|
+
return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
|
|
15330
15336
|
}
|
|
15331
15337
|
/**
|
|
15332
15338
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -15972,14 +15978,8 @@
|
|
|
15972
15978
|
: undefined));
|
|
15973
15979
|
}
|
|
15974
15980
|
}
|
|
15975
|
-
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
15976
|
-
// A single cell. If it's only the title, the dataset is not added.
|
|
15977
|
-
if (!dataSetsHaveTitle) {
|
|
15978
|
-
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
15979
|
-
}
|
|
15980
|
-
}
|
|
15981
15981
|
else {
|
|
15982
|
-
/* 1 row or 1 column */
|
|
15982
|
+
/* 1 cell, 1 row or 1 column */
|
|
15983
15983
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
15984
15984
|
? {
|
|
15985
15985
|
top: zone.top,
|
|
@@ -16028,8 +16028,10 @@
|
|
|
16028
16028
|
}
|
|
16029
16029
|
const dataRange = ds.dataRange.clone({ zone: dataZone });
|
|
16030
16030
|
return {
|
|
16031
|
-
label: ds.labelCell
|
|
16032
|
-
|
|
16031
|
+
label: ds.labelCell
|
|
16032
|
+
? getters.getRangeString(ds.labelCell, "forceSheetReference", true)
|
|
16033
|
+
: undefined,
|
|
16034
|
+
range: getters.getRangeString(dataRange, "forceSheetReference", true),
|
|
16033
16035
|
};
|
|
16034
16036
|
}
|
|
16035
16037
|
function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
|
|
@@ -16042,7 +16044,7 @@
|
|
|
16042
16044
|
zone.top = zone.top + 1;
|
|
16043
16045
|
}
|
|
16044
16046
|
const range = labelRange.clone({ zone });
|
|
16045
|
-
return getters.getRangeString(range, "forceSheetReference");
|
|
16047
|
+
return getters.getRangeString(range, "forceSheetReference", true);
|
|
16046
16048
|
}
|
|
16047
16049
|
/**
|
|
16048
16050
|
* Transform a chart definition which supports dataSets (dataSets and LabelRange)
|
|
@@ -16579,7 +16581,7 @@
|
|
|
16579
16581
|
return undefined;
|
|
16580
16582
|
const dataSets = this.dataSets
|
|
16581
16583
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
16582
|
-
.filter((ds) => ds.range !== ""
|
|
16584
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
16583
16585
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
16584
16586
|
return {
|
|
16585
16587
|
...this.getDefinition(),
|
|
@@ -17167,7 +17169,7 @@
|
|
|
17167
17169
|
return undefined;
|
|
17168
17170
|
const dataSets = this.dataSets
|
|
17169
17171
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
17170
|
-
.filter((ds) => ds.range !== ""
|
|
17172
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
17171
17173
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
17172
17174
|
return {
|
|
17173
17175
|
...this.getDefinition(),
|
|
@@ -17454,7 +17456,7 @@
|
|
|
17454
17456
|
return undefined;
|
|
17455
17457
|
const dataSets = this.dataSets
|
|
17456
17458
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
17457
|
-
.filter((ds) => ds.range !== ""
|
|
17459
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
17458
17460
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
17459
17461
|
return {
|
|
17460
17462
|
...this.getDefinition(),
|
|
@@ -18632,6 +18634,12 @@
|
|
|
18632
18634
|
let { col, row } = env.model.getters.getActivePosition();
|
|
18633
18635
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
18634
18636
|
};
|
|
18637
|
+
const INSERT_LINK_NAME = (env) => {
|
|
18638
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18639
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
18640
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
18641
|
+
return cell && cell.link ? _lt("Edit link") : _lt("Insert link");
|
|
18642
|
+
};
|
|
18635
18643
|
//------------------------------------------------------------------------------
|
|
18636
18644
|
// Filters action
|
|
18637
18645
|
//------------------------------------------------------------------------------
|
|
@@ -19172,7 +19180,7 @@
|
|
|
19172
19180
|
})
|
|
19173
19181
|
.add("insert_link", {
|
|
19174
19182
|
...insertLink,
|
|
19175
|
-
name:
|
|
19183
|
+
name: INSERT_LINK_NAME,
|
|
19176
19184
|
sequence: 150,
|
|
19177
19185
|
separator: true,
|
|
19178
19186
|
});
|
|
@@ -24083,6 +24091,7 @@
|
|
|
24083
24091
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
24084
24092
|
static defaultProps = {
|
|
24085
24093
|
inputStyle: "",
|
|
24094
|
+
isDefaultFocus: false,
|
|
24086
24095
|
};
|
|
24087
24096
|
composerRef = owl.useRef("o_composer");
|
|
24088
24097
|
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
|
@@ -24135,7 +24144,6 @@
|
|
|
24135
24144
|
F2: () => console.warn("Not implemented"),
|
|
24136
24145
|
F4: this.processF4Key,
|
|
24137
24146
|
Tab: (ev) => this.processTabKey(ev),
|
|
24138
|
-
" ": (ev) => this.processSpaceKey(ev),
|
|
24139
24147
|
};
|
|
24140
24148
|
keyCodeMapping = {
|
|
24141
24149
|
NumpadDecimal: this.processNumpadDecimal,
|
|
@@ -24143,11 +24151,11 @@
|
|
|
24143
24151
|
setup() {
|
|
24144
24152
|
owl.onMounted(() => {
|
|
24145
24153
|
const el = this.composerRef.el;
|
|
24154
|
+
if (this.props.isDefaultFocus) {
|
|
24155
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
24156
|
+
}
|
|
24146
24157
|
this.contentHelper.updateEl(el);
|
|
24147
24158
|
});
|
|
24148
|
-
owl.onWillUnmount(() => {
|
|
24149
|
-
this.props.onComposerUnmounted?.();
|
|
24150
|
-
});
|
|
24151
24159
|
owl.useEffect(() => {
|
|
24152
24160
|
this.processContent();
|
|
24153
24161
|
});
|
|
@@ -24156,7 +24164,8 @@
|
|
|
24156
24164
|
// Handlers
|
|
24157
24165
|
// ---------------------------------------------------------------------------
|
|
24158
24166
|
processArrowKeys(ev) {
|
|
24159
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
24167
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
24168
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24160
24169
|
this.functionDescriptionState.showDescription = false;
|
|
24161
24170
|
// Prevent the default content editable behavior which moves the cursor
|
|
24162
24171
|
ev.preventDefault();
|
|
@@ -24195,25 +24204,19 @@
|
|
|
24195
24204
|
processTabKey(ev) {
|
|
24196
24205
|
ev.preventDefault();
|
|
24197
24206
|
ev.stopPropagation();
|
|
24198
|
-
if (this.
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24202
|
-
|
|
24207
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24208
|
+
if (this.autoCompleteState.showProvider) {
|
|
24209
|
+
const autoCompleteValue = this.autoCompleteState.values[this.autoCompleteState.selectedIndex]?.text;
|
|
24210
|
+
if (autoCompleteValue) {
|
|
24211
|
+
this.autoComplete(autoCompleteValue);
|
|
24212
|
+
return;
|
|
24213
|
+
}
|
|
24203
24214
|
}
|
|
24215
|
+
this.env.model.dispatch("STOP_EDITION");
|
|
24204
24216
|
}
|
|
24205
24217
|
const direction = ev.shiftKey ? "left" : "right";
|
|
24206
|
-
this.env.model.dispatch("STOP_EDITION");
|
|
24207
24218
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
24208
24219
|
}
|
|
24209
|
-
processSpaceKey(ev) {
|
|
24210
|
-
if (ev.ctrlKey) {
|
|
24211
|
-
ev.preventDefault();
|
|
24212
|
-
ev.stopPropagation();
|
|
24213
|
-
this.showAutocomplete("");
|
|
24214
|
-
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24215
|
-
}
|
|
24216
|
-
}
|
|
24217
24220
|
processEnterKey(ev) {
|
|
24218
24221
|
ev.preventDefault();
|
|
24219
24222
|
ev.stopPropagation();
|
|
@@ -24265,6 +24268,9 @@
|
|
|
24265
24268
|
this.compositionActive = false;
|
|
24266
24269
|
}
|
|
24267
24270
|
onKeydown(ev) {
|
|
24271
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24272
|
+
return;
|
|
24273
|
+
}
|
|
24268
24274
|
let handler = this.keyMapping[ev.key] || this.keyCodeMapping[ev.code];
|
|
24269
24275
|
if (handler) {
|
|
24270
24276
|
handler.call(this, ev);
|
|
@@ -24273,14 +24279,33 @@
|
|
|
24273
24279
|
ev.stopPropagation();
|
|
24274
24280
|
}
|
|
24275
24281
|
}
|
|
24282
|
+
onPaste(ev) {
|
|
24283
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24284
|
+
ev.stopPropagation();
|
|
24285
|
+
}
|
|
24286
|
+
}
|
|
24276
24287
|
/*
|
|
24277
24288
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
24278
24289
|
* */
|
|
24279
24290
|
onInput(ev) {
|
|
24280
|
-
if (
|
|
24291
|
+
if (!this.shouldProcessInputEvents) {
|
|
24292
|
+
return;
|
|
24293
|
+
}
|
|
24294
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
24295
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24281
24296
|
return;
|
|
24282
24297
|
}
|
|
24283
|
-
|
|
24298
|
+
ev.stopPropagation();
|
|
24299
|
+
let content;
|
|
24300
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24301
|
+
content = ev.data || "";
|
|
24302
|
+
}
|
|
24303
|
+
else {
|
|
24304
|
+
content = this.contentHelper.getText();
|
|
24305
|
+
}
|
|
24306
|
+
if (this.props.focus === "inactive") {
|
|
24307
|
+
return this.props.onComposerCellFocused?.(content);
|
|
24308
|
+
}
|
|
24284
24309
|
let selection = this.contentHelper.getCurrentSelection();
|
|
24285
24310
|
if (ev.inputType === "insertParagraph") {
|
|
24286
24311
|
const start = Math.min(selection.start, selection.end);
|
|
@@ -24358,9 +24383,8 @@
|
|
|
24358
24383
|
}
|
|
24359
24384
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
24360
24385
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24361
|
-
|
|
24362
|
-
|
|
24363
|
-
}
|
|
24386
|
+
this.props.onComposerContentFocused();
|
|
24387
|
+
if (this.props.focus === "inactive") ;
|
|
24364
24388
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
24365
24389
|
this.processTokenAtCursor();
|
|
24366
24390
|
}
|
|
@@ -24527,7 +24551,7 @@
|
|
|
24527
24551
|
const highlights = this.env.model.getters.getHighlights();
|
|
24528
24552
|
const refSheet = sheetName
|
|
24529
24553
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
24530
|
-
: this.env.model.getters.getCurrentEditedCell()
|
|
24554
|
+
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
|
24531
24555
|
const highlight = highlights.find((highlight) => {
|
|
24532
24556
|
if (highlight.sheetId !== refSheet)
|
|
24533
24557
|
return false;
|
|
@@ -24607,12 +24631,13 @@
|
|
|
24607
24631
|
}
|
|
24608
24632
|
}
|
|
24609
24633
|
Composer.props = {
|
|
24610
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24611
|
-
onComposerContentFocused: Function,
|
|
24612
24634
|
inputStyle: { type: String, optional: true },
|
|
24613
24635
|
rect: { type: Object, optional: true },
|
|
24614
24636
|
delimitation: { type: Object, optional: true },
|
|
24615
|
-
|
|
24637
|
+
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24638
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
24639
|
+
onComposerContentFocused: Function,
|
|
24640
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
24616
24641
|
};
|
|
24617
24642
|
|
|
24618
24643
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -24646,51 +24671,26 @@
|
|
|
24646
24671
|
class GridComposer extends owl.Component {
|
|
24647
24672
|
static template = "o-spreadsheet-GridComposer";
|
|
24648
24673
|
static components = { Composer };
|
|
24649
|
-
|
|
24650
|
-
|
|
24651
|
-
|
|
24674
|
+
// TODORAR see if we can keep it undefined
|
|
24675
|
+
rect = this.defaultRect;
|
|
24676
|
+
isEditing = false;
|
|
24652
24677
|
isCellReferenceVisible;
|
|
24653
|
-
|
|
24678
|
+
get defaultRect() {
|
|
24679
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
24680
|
+
}
|
|
24654
24681
|
setup() {
|
|
24655
|
-
this.gridComposerRef = owl.useRef("gridComposer");
|
|
24656
|
-
this.composerState = owl.useState({
|
|
24657
|
-
rect: undefined,
|
|
24658
|
-
delimitation: undefined,
|
|
24659
|
-
});
|
|
24660
|
-
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
|
24661
|
-
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
|
24662
|
-
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
|
24663
|
-
this.isCellReferenceVisible = false;
|
|
24664
|
-
owl.onMounted(() => {
|
|
24665
|
-
const el = this.gridComposerRef.el;
|
|
24666
|
-
this.composerState.rect = {
|
|
24667
|
-
x: this.rect.x,
|
|
24668
|
-
y: this.rect.y,
|
|
24669
|
-
width: el.clientWidth,
|
|
24670
|
-
height: el.clientHeight,
|
|
24671
|
-
};
|
|
24672
|
-
this.composerState.delimitation = {
|
|
24673
|
-
width: this.props.gridDims.width,
|
|
24674
|
-
height: this.props.gridDims.height,
|
|
24675
|
-
};
|
|
24676
|
-
});
|
|
24677
24682
|
owl.onWillUpdateProps(() => {
|
|
24678
|
-
|
|
24679
|
-
|
|
24680
|
-
}
|
|
24681
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24682
|
-
const zone = this.env.model.getters.getSelectedZone();
|
|
24683
|
-
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24684
|
-
if (!deepEquals(rect, this.rect) ||
|
|
24685
|
-
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24686
|
-
this.isCellReferenceVisible = true;
|
|
24687
|
-
}
|
|
24683
|
+
this.updateComponentPosition();
|
|
24684
|
+
this.updateCellReferenceVisibility();
|
|
24688
24685
|
});
|
|
24689
24686
|
}
|
|
24690
24687
|
get shouldDisplayCellReference() {
|
|
24691
24688
|
return this.isCellReferenceVisible;
|
|
24692
24689
|
}
|
|
24693
24690
|
get cellReference() {
|
|
24691
|
+
if (!this.env.model.getters.getCurrentEditedCell()) {
|
|
24692
|
+
return "";
|
|
24693
|
+
}
|
|
24694
24694
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
24695
24695
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
24696
24696
|
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
|
@@ -24702,7 +24702,27 @@
|
|
|
24702
24702
|
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
|
24703
24703
|
});
|
|
24704
24704
|
}
|
|
24705
|
+
get composerProps() {
|
|
24706
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
24707
|
+
return {
|
|
24708
|
+
rect: { ...this.rect },
|
|
24709
|
+
delimitation: {
|
|
24710
|
+
width,
|
|
24711
|
+
height,
|
|
24712
|
+
},
|
|
24713
|
+
focus: this.props.focus,
|
|
24714
|
+
isDefaultFocus: true,
|
|
24715
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
24716
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
24717
|
+
};
|
|
24718
|
+
}
|
|
24705
24719
|
get containerStyle() {
|
|
24720
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24721
|
+
return `
|
|
24722
|
+
position: absolute;
|
|
24723
|
+
z-index: -1000;
|
|
24724
|
+
`;
|
|
24725
|
+
}
|
|
24706
24726
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24707
24727
|
const cell = this.env.model.getters.getActiveCell();
|
|
24708
24728
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -24722,6 +24742,8 @@
|
|
|
24722
24742
|
if (!isFormula) {
|
|
24723
24743
|
textAlign = style.align || cell.defaultAlign;
|
|
24724
24744
|
}
|
|
24745
|
+
const maxHeight = this.props.gridDims.height - this.rect.y;
|
|
24746
|
+
const maxWidth = this.props.gridDims.width - this.rect.x;
|
|
24725
24747
|
/**
|
|
24726
24748
|
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
|
24727
24749
|
* including all the paddings/margins of the composer
|
|
@@ -24733,6 +24755,8 @@
|
|
|
24733
24755
|
top: `${top}px`,
|
|
24734
24756
|
"min-width": `${width + 1}px`,
|
|
24735
24757
|
"min-height": `${height + 1}px`,
|
|
24758
|
+
"max-width": `${maxWidth}px`,
|
|
24759
|
+
"max-height": `${maxHeight}px`,
|
|
24736
24760
|
background,
|
|
24737
24761
|
color,
|
|
24738
24762
|
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
|
@@ -24742,20 +24766,38 @@
|
|
|
24742
24766
|
"text-align": textAlign,
|
|
24743
24767
|
});
|
|
24744
24768
|
}
|
|
24745
|
-
|
|
24746
|
-
const
|
|
24747
|
-
|
|
24748
|
-
|
|
24749
|
-
|
|
24750
|
-
|
|
24751
|
-
|
|
24769
|
+
updateComponentPosition() {
|
|
24770
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
24771
|
+
if (this.isEditing !== isEditing) {
|
|
24772
|
+
this.isEditing = isEditing;
|
|
24773
|
+
if (!isEditing) {
|
|
24774
|
+
this.rect = this.defaultRect;
|
|
24775
|
+
this.env.focusableElement.focus();
|
|
24776
|
+
return;
|
|
24777
|
+
}
|
|
24778
|
+
const position = this.env.model.getters.getActivePosition();
|
|
24779
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
24780
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
24781
|
+
}
|
|
24782
|
+
}
|
|
24783
|
+
updateCellReferenceVisibility() {
|
|
24784
|
+
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
|
24785
|
+
return;
|
|
24786
|
+
}
|
|
24787
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24788
|
+
const zone = this.env.model.getters.getSelectedZone();
|
|
24789
|
+
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24790
|
+
if (!deepEquals(rect, this.rect) ||
|
|
24791
|
+
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24792
|
+
this.isCellReferenceVisible = true;
|
|
24793
|
+
}
|
|
24752
24794
|
}
|
|
24753
24795
|
}
|
|
24754
24796
|
GridComposer.props = {
|
|
24755
24797
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24756
|
-
onComposerUnmounted: Function,
|
|
24757
24798
|
onComposerContentFocused: Function,
|
|
24758
24799
|
gridDims: Object,
|
|
24800
|
+
onComposerCellFocused: Function,
|
|
24759
24801
|
};
|
|
24760
24802
|
|
|
24761
24803
|
const CSS$1 = css /* scss */ `
|
|
@@ -25636,7 +25678,6 @@
|
|
|
25636
25678
|
this.props.onCellDoubleClicked(col, row);
|
|
25637
25679
|
}
|
|
25638
25680
|
onContextMenu(ev) {
|
|
25639
|
-
ev.preventDefault();
|
|
25640
25681
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
25641
25682
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
25642
25683
|
}
|
|
@@ -26729,7 +26770,6 @@
|
|
|
26729
26770
|
HEADER_WIDTH = HEADER_WIDTH;
|
|
26730
26771
|
menuState;
|
|
26731
26772
|
gridRef;
|
|
26732
|
-
hiddenInput;
|
|
26733
26773
|
onMouseWheel;
|
|
26734
26774
|
canvasPosition;
|
|
26735
26775
|
hoveredCell;
|
|
@@ -26740,17 +26780,16 @@
|
|
|
26740
26780
|
menuItems: [],
|
|
26741
26781
|
});
|
|
26742
26782
|
this.gridRef = owl.useRef("grid");
|
|
26743
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
26744
26783
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
26745
26784
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
26746
26785
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
26747
26786
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
26748
26787
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
26749
26788
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
26750
|
-
owl.onMounted(() => this.
|
|
26751
|
-
this.props.exposeFocus(() => this.
|
|
26789
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
26790
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
26752
26791
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
26753
|
-
owl.useEffect(() => this.
|
|
26792
|
+
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
26754
26793
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
26755
26794
|
this.moveCanvas(deltaX, deltaY);
|
|
26756
26795
|
this.hoveredCell.col = undefined;
|
|
@@ -26773,7 +26812,7 @@
|
|
|
26773
26812
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
26774
26813
|
this.closeOpenedPopover();
|
|
26775
26814
|
}
|
|
26776
|
-
this.
|
|
26815
|
+
this.focusDefaultElement();
|
|
26777
26816
|
}
|
|
26778
26817
|
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
|
26779
26818
|
// down itself
|
|
@@ -26946,10 +26985,10 @@
|
|
|
26946
26985
|
PAGEUP: () => this.env.model.dispatch("SHIFT_VIEWPORT_UP"),
|
|
26947
26986
|
"CTRL+K": () => INSERT_LINK(this.env),
|
|
26948
26987
|
};
|
|
26949
|
-
|
|
26988
|
+
focusDefaultElement() {
|
|
26950
26989
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
26951
26990
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26952
|
-
this.
|
|
26991
|
+
this.env.focusableElement.focus();
|
|
26953
26992
|
}
|
|
26954
26993
|
}
|
|
26955
26994
|
get gridEl() {
|
|
@@ -27093,19 +27132,6 @@
|
|
|
27093
27132
|
return;
|
|
27094
27133
|
}
|
|
27095
27134
|
}
|
|
27096
|
-
onInput(ev) {
|
|
27097
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
27098
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
27099
|
-
return;
|
|
27100
|
-
}
|
|
27101
|
-
if (ev.data) {
|
|
27102
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
27103
|
-
// character
|
|
27104
|
-
ev.preventDefault();
|
|
27105
|
-
ev.stopPropagation();
|
|
27106
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
27107
|
-
}
|
|
27108
|
-
}
|
|
27109
27135
|
// ---------------------------------------------------------------------------
|
|
27110
27136
|
// Context Menu
|
|
27111
27137
|
// ---------------------------------------------------------------------------
|
|
@@ -27218,7 +27244,7 @@
|
|
|
27218
27244
|
}
|
|
27219
27245
|
closeMenu() {
|
|
27220
27246
|
this.menuState.isOpen = false;
|
|
27221
|
-
this.
|
|
27247
|
+
this.focusDefaultElement();
|
|
27222
27248
|
}
|
|
27223
27249
|
}
|
|
27224
27250
|
Grid.props = {
|
|
@@ -30878,6 +30904,31 @@
|
|
|
30878
30904
|
return data;
|
|
30879
30905
|
},
|
|
30880
30906
|
},
|
|
30907
|
+
{
|
|
30908
|
+
description: "Fix datafilter duplication",
|
|
30909
|
+
from: 12,
|
|
30910
|
+
to: 12.5,
|
|
30911
|
+
applyMigration(data) {
|
|
30912
|
+
for (let sheet of data.sheets || []) {
|
|
30913
|
+
let knownDataFilterZones = [];
|
|
30914
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
30915
|
+
const zone = toZone(filterTable.range);
|
|
30916
|
+
// See commit message for the details
|
|
30917
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
30918
|
+
if (intersectZoneIndex !== -1) {
|
|
30919
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
30920
|
+
}
|
|
30921
|
+
else {
|
|
30922
|
+
knownDataFilterZones.push(zone);
|
|
30923
|
+
}
|
|
30924
|
+
}
|
|
30925
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
30926
|
+
range: zoneToXc(zone),
|
|
30927
|
+
}));
|
|
30928
|
+
}
|
|
30929
|
+
return data;
|
|
30930
|
+
},
|
|
30931
|
+
},
|
|
30881
30932
|
{
|
|
30882
30933
|
description: "Change Border description structure",
|
|
30883
30934
|
from: 12,
|
|
@@ -31797,9 +31848,9 @@
|
|
|
31797
31848
|
allowDispatch(cmd) {
|
|
31798
31849
|
switch (cmd.type) {
|
|
31799
31850
|
case "UPDATE_CELL":
|
|
31800
|
-
return this.
|
|
31851
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
31801
31852
|
case "CLEAR_CELL":
|
|
31802
|
-
return this.checkValidations(cmd, this.
|
|
31853
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
31803
31854
|
default:
|
|
31804
31855
|
return 0 /* CommandResult.Success */;
|
|
31805
31856
|
}
|
|
@@ -31965,13 +32016,13 @@
|
|
|
31965
32016
|
/*
|
|
31966
32017
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
31967
32018
|
*/
|
|
31968
|
-
buildFormulaContent(sheetId, cell, dependencies) {
|
|
32019
|
+
buildFormulaContent(sheetId, cell, dependencies, useFixedZone = false) {
|
|
31969
32020
|
const ranges = dependencies || cell.dependencies;
|
|
31970
32021
|
let rangeIndex = 0;
|
|
31971
32022
|
return concat(cell.compiledFormula.tokens.map((token) => {
|
|
31972
32023
|
if (token.type === "REFERENCE") {
|
|
31973
32024
|
const range = ranges[rangeIndex++];
|
|
31974
|
-
return this.getters.getRangeString(range, sheetId);
|
|
32025
|
+
return this.getters.getRangeString(range, sheetId, useFixedZone);
|
|
31975
32026
|
}
|
|
31976
32027
|
return token.value;
|
|
31977
32028
|
}));
|
|
@@ -32093,10 +32144,7 @@
|
|
|
32093
32144
|
else {
|
|
32094
32145
|
style = before ? before.style : undefined;
|
|
32095
32146
|
}
|
|
32096
|
-
const
|
|
32097
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
32098
|
-
detectDateFormat(afterContent, locale) ||
|
|
32099
|
-
detectNumberFormat(afterContent);
|
|
32147
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
32100
32148
|
/* Read the following IF as:
|
|
32101
32149
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
32102
32150
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -32137,12 +32185,11 @@
|
|
|
32137
32185
|
}
|
|
32138
32186
|
createLiteralCell(id, content, format, style) {
|
|
32139
32187
|
const locale = this.getters.getLocale();
|
|
32140
|
-
content = parseLiteral(content, locale).toString();
|
|
32141
32188
|
return {
|
|
32142
32189
|
id,
|
|
32143
|
-
content,
|
|
32190
|
+
content: parseLiteral(content, locale).toString(),
|
|
32144
32191
|
style,
|
|
32145
|
-
format,
|
|
32192
|
+
format: format || detectDateFormat(content, locale) || detectNumberFormat(content),
|
|
32146
32193
|
isFormula: false,
|
|
32147
32194
|
};
|
|
32148
32195
|
}
|
|
@@ -32203,6 +32250,18 @@
|
|
|
32203
32250
|
}
|
|
32204
32251
|
return 0 /* CommandResult.Success */;
|
|
32205
32252
|
}
|
|
32253
|
+
checkUselessUpdateCell(cmd) {
|
|
32254
|
+
const cell = this.getters.getCell(cmd);
|
|
32255
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
32256
|
+
const hasStyle = "style" in cmd;
|
|
32257
|
+
const hasFormat = "format" in cmd;
|
|
32258
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
32259
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
32260
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
32261
|
+
return 98 /* CommandResult.NoChanges */;
|
|
32262
|
+
}
|
|
32263
|
+
return 0 /* CommandResult.Success */;
|
|
32264
|
+
}
|
|
32206
32265
|
}
|
|
32207
32266
|
class FormulaCellWithDependencies {
|
|
32208
32267
|
id;
|
|
@@ -32540,7 +32599,13 @@
|
|
|
32540
32599
|
}
|
|
32541
32600
|
}
|
|
32542
32601
|
exportForExcel(data) {
|
|
32543
|
-
|
|
32602
|
+
if (data.sheets) {
|
|
32603
|
+
for (let sheet of data.sheets) {
|
|
32604
|
+
if (this.cfRules[sheet.id]) {
|
|
32605
|
+
sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
|
|
32606
|
+
}
|
|
32607
|
+
}
|
|
32608
|
+
}
|
|
32544
32609
|
}
|
|
32545
32610
|
// ---------------------------------------------------------------------------
|
|
32546
32611
|
// Getters
|
|
@@ -32605,11 +32670,11 @@
|
|
|
32605
32670
|
// ---------------------------------------------------------------------------
|
|
32606
32671
|
// Private
|
|
32607
32672
|
// ---------------------------------------------------------------------------
|
|
32608
|
-
mapToConditionalFormat(sheetId, cf) {
|
|
32673
|
+
mapToConditionalFormat(sheetId, cf, options = { useFixedReference: false }) {
|
|
32609
32674
|
return {
|
|
32610
32675
|
...cf,
|
|
32611
32676
|
ranges: cf.ranges.map((range) => {
|
|
32612
|
-
return this.getters.getRangeString(range, sheetId);
|
|
32677
|
+
return this.getters.getRangeString(range, sheetId, options.useFixedReference);
|
|
32613
32678
|
}),
|
|
32614
32679
|
};
|
|
32615
32680
|
}
|
|
@@ -34446,8 +34511,9 @@
|
|
|
34446
34511
|
*
|
|
34447
34512
|
* @param range the range (received from getRangeFromXC or getRangeFromZone)
|
|
34448
34513
|
* @param forSheetId the id of the sheet where the range string is supposed to be used.
|
|
34514
|
+
* @param [useFixedZone=false] if true, the range will be returned with fixed row and column
|
|
34449
34515
|
*/
|
|
34450
|
-
getRangeString(range, forSheetId) {
|
|
34516
|
+
getRangeString(range, forSheetId, useFixedZone = false) {
|
|
34451
34517
|
if (!range) {
|
|
34452
34518
|
return INCORRECT_RANGE_STRING;
|
|
34453
34519
|
}
|
|
@@ -34474,7 +34540,7 @@
|
|
|
34474
34540
|
if (prefixSheet && !sheetName) {
|
|
34475
34541
|
return INCORRECT_RANGE_STRING;
|
|
34476
34542
|
}
|
|
34477
|
-
let rangeString = this.getRangePartString(rangeImpl, 0);
|
|
34543
|
+
let rangeString = this.getRangePartString(rangeImpl, 0, useFixedZone);
|
|
34478
34544
|
if (rangeImpl.parts && rangeImpl.parts.length === 2) {
|
|
34479
34545
|
// this if converts A2:A2 into A2 except if any part of the original range had fixed row or column (with $)
|
|
34480
34546
|
if (rangeImpl.zone.top !== rangeImpl.zone.bottom ||
|
|
@@ -34484,7 +34550,7 @@
|
|
|
34484
34550
|
rangeImpl.parts[1].rowFixed ||
|
|
34485
34551
|
rangeImpl.parts[1].colFixed) {
|
|
34486
34552
|
rangeString += ":";
|
|
34487
|
-
rangeString += this.getRangePartString(rangeImpl, 1);
|
|
34553
|
+
rangeString += this.getRangePartString(rangeImpl, 1, useFixedZone);
|
|
34488
34554
|
}
|
|
34489
34555
|
}
|
|
34490
34556
|
return `${prefixSheet ? sheetName + "!" : ""}${rangeString}`;
|
|
@@ -34525,13 +34591,13 @@
|
|
|
34525
34591
|
/**
|
|
34526
34592
|
* Get a Xc string that represent a part of a range
|
|
34527
34593
|
*/
|
|
34528
|
-
getRangePartString(range, part) {
|
|
34594
|
+
getRangePartString(range, part, useFixedZone = false) {
|
|
34529
34595
|
const colFixed = range.parts && range.parts[part]?.colFixed ? "$" : "";
|
|
34530
34596
|
const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
|
|
34531
34597
|
const rowFixed = range.parts && range.parts[part]?.rowFixed ? "$" : "";
|
|
34532
34598
|
const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
|
|
34533
34599
|
let str = "";
|
|
34534
|
-
if (range.isFullCol) {
|
|
34600
|
+
if (range.isFullCol && !useFixedZone) {
|
|
34535
34601
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
34536
34602
|
str = colFixed + col + rowFixed + row;
|
|
34537
34603
|
}
|
|
@@ -34539,7 +34605,7 @@
|
|
|
34539
34605
|
str = colFixed + col;
|
|
34540
34606
|
}
|
|
34541
34607
|
}
|
|
34542
|
-
else if (range.isFullRow) {
|
|
34608
|
+
else if (range.isFullRow && !useFixedZone) {
|
|
34543
34609
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
34544
34610
|
str = colFixed + col + rowFixed + row;
|
|
34545
34611
|
}
|
|
@@ -36336,7 +36402,15 @@
|
|
|
36336
36402
|
if (!this.rTrees[sheetId]) {
|
|
36337
36403
|
return;
|
|
36338
36404
|
}
|
|
36339
|
-
this.rTrees[sheetId].remove(item,
|
|
36405
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
36406
|
+
}
|
|
36407
|
+
rtreeItemComparer(left, right) {
|
|
36408
|
+
return (left.data == right.data &&
|
|
36409
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
36410
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
36411
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
36412
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
36413
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
36340
36414
|
}
|
|
36341
36415
|
}
|
|
36342
36416
|
/**
|
|
@@ -36414,7 +36488,7 @@
|
|
|
36414
36488
|
const queue = Array.from(ranges).reverse();
|
|
36415
36489
|
while (queue.length > 0) {
|
|
36416
36490
|
const range = queue.pop();
|
|
36417
|
-
visited.
|
|
36491
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
36418
36492
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
36419
36493
|
for (const positionId of impactedPositionIds) {
|
|
36420
36494
|
if (!visited.has(positionId)) {
|
|
@@ -36422,7 +36496,7 @@
|
|
|
36422
36496
|
}
|
|
36423
36497
|
}
|
|
36424
36498
|
}
|
|
36425
|
-
visited.
|
|
36499
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
36426
36500
|
return visited;
|
|
36427
36501
|
}
|
|
36428
36502
|
}
|
|
@@ -36553,9 +36627,9 @@
|
|
|
36553
36627
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
36554
36628
|
const cellsToCompute = new JetSet(cells);
|
|
36555
36629
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
36556
|
-
cellsToCompute.
|
|
36557
|
-
cellsToCompute.
|
|
36558
|
-
cellsToCompute.
|
|
36630
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
36631
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
36632
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
36559
36633
|
this.evaluate(cellsToCompute);
|
|
36560
36634
|
}
|
|
36561
36635
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -36569,7 +36643,7 @@
|
|
|
36569
36643
|
}
|
|
36570
36644
|
if (!content) {
|
|
36571
36645
|
// The previous content could have blocked some array formulas
|
|
36572
|
-
impactedPositionIds.
|
|
36646
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
36573
36647
|
}
|
|
36574
36648
|
}
|
|
36575
36649
|
return impactedPositionIds;
|
|
@@ -36617,7 +36691,7 @@
|
|
|
36617
36691
|
}
|
|
36618
36692
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
36619
36693
|
const cells = new JetSet(arrayFormulas);
|
|
36620
|
-
cells.
|
|
36694
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
36621
36695
|
return cells;
|
|
36622
36696
|
}
|
|
36623
36697
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -36768,7 +36842,7 @@
|
|
|
36768
36842
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
36769
36843
|
// check if formula dependencies present in the spread zone
|
|
36770
36844
|
// if so, they need to be recomputed
|
|
36771
|
-
this.nextPositionsToUpdate.
|
|
36845
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
36772
36846
|
};
|
|
36773
36847
|
}
|
|
36774
36848
|
invalidateSpreading(positionId) {
|
|
@@ -36783,8 +36857,8 @@
|
|
|
36783
36857
|
continue;
|
|
36784
36858
|
}
|
|
36785
36859
|
this.evaluatedCells.delete(child);
|
|
36786
|
-
this.nextPositionsToUpdate.
|
|
36787
|
-
this.nextPositionsToUpdate.
|
|
36860
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
36861
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
36788
36862
|
}
|
|
36789
36863
|
this.spreadingRelations.removeNode(positionId);
|
|
36790
36864
|
}
|
|
@@ -37144,7 +37218,13 @@
|
|
|
37144
37218
|
const format = newFormat
|
|
37145
37219
|
? getItemId(newFormat, data.formats)
|
|
37146
37220
|
: exportedCellData.format;
|
|
37147
|
-
|
|
37221
|
+
let content;
|
|
37222
|
+
if (formulaCell instanceof FormulaCellWithDependencies) {
|
|
37223
|
+
content = this.getters.buildFormulaContent(exportedSheetData.id, formulaCell, formulaCell.dependencies, true);
|
|
37224
|
+
}
|
|
37225
|
+
else {
|
|
37226
|
+
content = !isExported ? newContent : exportedCellData.content;
|
|
37227
|
+
}
|
|
37148
37228
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
37149
37229
|
}
|
|
37150
37230
|
}
|
|
@@ -43663,7 +43743,7 @@
|
|
|
43663
43743
|
this.replaceText(ref, this.selectionInitialStart, this.selectionEnd);
|
|
43664
43744
|
}
|
|
43665
43745
|
getZoneReference(zone) {
|
|
43666
|
-
const inputSheetId = this.getters.getCurrentEditedCell().
|
|
43746
|
+
const inputSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43667
43747
|
const sheetId = this.getters.getActiveSheetId();
|
|
43668
43748
|
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
43669
43749
|
return this.getters.getSelectionRangeString(range, inputSheetId);
|
|
@@ -43677,7 +43757,7 @@
|
|
|
43677
43757
|
_fixedParts.pop();
|
|
43678
43758
|
}
|
|
43679
43759
|
const newRange = range.clone({ parts: _fixedParts });
|
|
43680
|
-
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().
|
|
43760
|
+
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId());
|
|
43681
43761
|
}
|
|
43682
43762
|
/**
|
|
43683
43763
|
* Replace the current selection by a new text.
|
|
@@ -43710,7 +43790,7 @@
|
|
|
43710
43790
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43711
43791
|
return;
|
|
43712
43792
|
}
|
|
43713
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43793
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43714
43794
|
const XCs = this.getReferencedRanges().map((range) => this.getters.getRangeString(range, editionSheetId));
|
|
43715
43795
|
const colorsToKeep = {};
|
|
43716
43796
|
for (const xc of XCs) {
|
|
@@ -43739,7 +43819,7 @@
|
|
|
43739
43819
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43740
43820
|
return [];
|
|
43741
43821
|
}
|
|
43742
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43822
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43743
43823
|
const rangeColor = (rangeString) => {
|
|
43744
43824
|
const colorIndex = this.colorIndexByRange[rangeString];
|
|
43745
43825
|
return colors$1[colorIndex % colors$1.length];
|
|
@@ -43757,7 +43837,7 @@
|
|
|
43757
43837
|
* Return ranges currently referenced in the composer
|
|
43758
43838
|
*/
|
|
43759
43839
|
getReferencedRanges() {
|
|
43760
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43840
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43761
43841
|
const referenceRanges = this.currentTokens
|
|
43762
43842
|
.filter((token) => token.type === "REFERENCE")
|
|
43763
43843
|
.map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
|
|
@@ -45721,6 +45801,16 @@
|
|
|
45721
45801
|
}
|
|
45722
45802
|
}
|
|
45723
45803
|
|
|
45804
|
+
class FocusableElement {
|
|
45805
|
+
focusableElement = undefined;
|
|
45806
|
+
setFocusableElement(element) {
|
|
45807
|
+
this.focusableElement = element;
|
|
45808
|
+
}
|
|
45809
|
+
focus() {
|
|
45810
|
+
this.focusableElement?.focus();
|
|
45811
|
+
}
|
|
45812
|
+
}
|
|
45813
|
+
|
|
45724
45814
|
const RIPPLE_KEY_FRAMES = [
|
|
45725
45815
|
{ transform: "scale(0)" },
|
|
45726
45816
|
{ transform: "scale(0.8)", offset: 0.33 },
|
|
@@ -47763,6 +47853,7 @@
|
|
|
47763
47853
|
_t: Spreadsheet._t,
|
|
47764
47854
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
47765
47855
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
47856
|
+
focusableElement: new FocusableElement(),
|
|
47766
47857
|
});
|
|
47767
47858
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
47768
47859
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
@@ -47869,17 +47960,18 @@
|
|
|
47869
47960
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47870
47961
|
this.composer.topBarFocus = "contentFocus";
|
|
47871
47962
|
this.composer.gridFocusMode = "inactive";
|
|
47872
|
-
this.setComposerContent({ selection }
|
|
47963
|
+
this.setComposerContent({ selection });
|
|
47873
47964
|
}
|
|
47874
|
-
onGridComposerContentFocused() {
|
|
47965
|
+
onGridComposerContentFocused(selection) {
|
|
47875
47966
|
if (this.model.getters.isReadonly()) {
|
|
47876
47967
|
return;
|
|
47877
47968
|
}
|
|
47878
47969
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47879
47970
|
this.composer.topBarFocus = "inactive";
|
|
47880
47971
|
this.composer.gridFocusMode = "contentFocus";
|
|
47881
|
-
this.setComposerContent({});
|
|
47972
|
+
this.setComposerContent({ selection });
|
|
47882
47973
|
}
|
|
47974
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
47883
47975
|
onGridComposerCellFocused(content, selection) {
|
|
47884
47976
|
if (this.model.getters.isReadonly()) {
|
|
47885
47977
|
return;
|
|
@@ -49291,11 +49383,10 @@
|
|
|
49291
49383
|
* next cluster if the given cell is outside a cluster or at the border of a cluster in the given direction.
|
|
49292
49384
|
*/
|
|
49293
49385
|
getEndOfCluster(startPosition, dim, dir) {
|
|
49294
|
-
const sheet = this.getters.getActiveSheet();
|
|
49295
49386
|
let currentPosition = startPosition;
|
|
49296
49387
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
49297
49388
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
49298
|
-
let mode = !this.
|
|
49389
|
+
let mode = !this.isEvaluatedCellEmpty(currentPosition) && !this.isEvaluatedCellEmpty(nextCellPosition)
|
|
49299
49390
|
? "endOfCluster"
|
|
49300
49391
|
: "nextCluster";
|
|
49301
49392
|
while (true) {
|
|
@@ -49305,7 +49396,7 @@
|
|
|
49305
49396
|
currentPosition.row === nextCellPosition.row) {
|
|
49306
49397
|
break;
|
|
49307
49398
|
}
|
|
49308
|
-
const isNextCellEmpty = this.
|
|
49399
|
+
const isNextCellEmpty = this.isEvaluatedCellEmpty(nextCellPosition);
|
|
49309
49400
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
49310
49401
|
break;
|
|
49311
49402
|
}
|
|
@@ -49319,10 +49410,20 @@
|
|
|
49319
49410
|
return dim === "cols" ? currentPosition.col : currentPosition.row;
|
|
49320
49411
|
}
|
|
49321
49412
|
/**
|
|
49322
|
-
*
|
|
49323
|
-
* check
|
|
49413
|
+
* Checks if a cell is empty (i.e. does not have a content). If the cell is part of a merge,
|
|
49414
|
+
* the check applies to the main cell of the merge.
|
|
49324
49415
|
*/
|
|
49325
|
-
isCellEmpty({ col, row }
|
|
49416
|
+
isCellEmpty({ col, row }) {
|
|
49417
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49418
|
+
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49419
|
+
return !(this.getters.getCorrespondingFormulaCell(position) || this.getters.getCell(position)?.content);
|
|
49420
|
+
}
|
|
49421
|
+
/**
|
|
49422
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
49423
|
+
* the check applies to the main cell of the merge.
|
|
49424
|
+
*/
|
|
49425
|
+
isEvaluatedCellEmpty({ col, row }) {
|
|
49426
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49326
49427
|
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49327
49428
|
const cell = this.getters.getEvaluatedCell(position);
|
|
49328
49429
|
return cell.type === CellValueType.empty;
|
|
@@ -49800,12 +49901,7 @@
|
|
|
49800
49901
|
attrs.push(["t", "str"]);
|
|
49801
49902
|
cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
|
|
49802
49903
|
}
|
|
49803
|
-
node = escapeXml /*xml*/ `
|
|
49804
|
-
<f>
|
|
49805
|
-
${XlsxFormula}
|
|
49806
|
-
</f>
|
|
49807
|
-
${cycle}
|
|
49808
|
-
`;
|
|
49904
|
+
node = escapeXml /*xml*/ ` <f> ${XlsxFormula} </f> ${cycle} `;
|
|
49809
49905
|
return { attrs, node };
|
|
49810
49906
|
}
|
|
49811
49907
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -50624,11 +50720,10 @@
|
|
|
50624
50720
|
({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader));
|
|
50625
50721
|
}
|
|
50626
50722
|
attributes.push(...additionalAttrs);
|
|
50627
|
-
|
|
50628
|
-
|
|
50629
|
-
|
|
50630
|
-
|
|
50631
|
-
`);
|
|
50723
|
+
// prettier-ignore
|
|
50724
|
+
cellNodes.push(escapeXml /*xml*/ `<c ${formatAttributes(attributes)}>
|
|
50725
|
+
${cellNode}
|
|
50726
|
+
</c>`);
|
|
50632
50727
|
}
|
|
50633
50728
|
}
|
|
50634
50729
|
if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden) {
|
|
@@ -51611,9 +51706,9 @@
|
|
|
51611
51706
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
51612
51707
|
|
|
51613
51708
|
|
|
51614
|
-
__info__.version = '16.4.
|
|
51615
|
-
__info__.date = '2024-
|
|
51616
|
-
__info__.hash = '
|
|
51709
|
+
__info__.version = '16.4.23';
|
|
51710
|
+
__info__.date = '2024-02-16T14:23:29.521Z';
|
|
51711
|
+
__info__.hash = 'cb5db1a';
|
|
51617
51712
|
|
|
51618
51713
|
|
|
51619
51714
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|