@odoo/o-spreadsheet 16.4.21 → 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 +238 -144
- package/dist/o-spreadsheet.d.ts +28 -14
- package/dist/o-spreadsheet.esm.js +238 -144
- package/dist/o-spreadsheet.iife.js +238 -144
- package/dist/o-spreadsheet.iife.min.js +100 -100
- package/dist/o_spreadsheet.xml +15 -33
- package/package.json +1 -1
|
@@ -705,18 +705,18 @@ function isConsecutive(iterable) {
|
|
|
705
705
|
return true;
|
|
706
706
|
}
|
|
707
707
|
class JetSet extends Set {
|
|
708
|
-
|
|
708
|
+
addMany(iterable) {
|
|
709
709
|
for (const element of iterable) {
|
|
710
710
|
super.add(element);
|
|
711
711
|
}
|
|
712
712
|
return this;
|
|
713
713
|
}
|
|
714
|
-
|
|
715
|
-
let
|
|
714
|
+
deleteMany(iterable) {
|
|
715
|
+
let wasDeleted = false;
|
|
716
716
|
for (const element of iterable) {
|
|
717
|
-
|
|
717
|
+
wasDeleted ||= super.delete(element);
|
|
718
718
|
}
|
|
719
|
-
return
|
|
719
|
+
return wasDeleted;
|
|
720
720
|
}
|
|
721
721
|
}
|
|
722
722
|
/**
|
|
@@ -1842,6 +1842,9 @@ function parseFormat(formatString) {
|
|
|
1842
1842
|
function formatValue(value, { format, locale }) {
|
|
1843
1843
|
switch (typeof value) {
|
|
1844
1844
|
case "string":
|
|
1845
|
+
if (value.includes('\\"')) {
|
|
1846
|
+
return value.replace(/\\"/g, '"');
|
|
1847
|
+
}
|
|
1845
1848
|
return value;
|
|
1846
1849
|
case "boolean":
|
|
1847
1850
|
return value ? "TRUE" : "FALSE";
|
|
@@ -15239,6 +15242,9 @@ function isValidLocale(locale) {
|
|
|
15239
15242
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
15240
15243
|
return false;
|
|
15241
15244
|
}
|
|
15245
|
+
if (locale.thousandsSeparator === locale.decimalSeparator) {
|
|
15246
|
+
return false;
|
|
15247
|
+
}
|
|
15242
15248
|
try {
|
|
15243
15249
|
formatValue(1, { locale, format: "#,##0.00" });
|
|
15244
15250
|
formatValue(1, { locale, format: locale.dateFormat });
|
|
@@ -15329,7 +15335,7 @@ function canonicalizeNumberLiteral(content, locale) {
|
|
|
15329
15335
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
15330
15336
|
return content;
|
|
15331
15337
|
}
|
|
15332
|
-
return content.replace(locale.decimalSeparator, ".");
|
|
15338
|
+
return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
|
|
15333
15339
|
}
|
|
15334
15340
|
/**
|
|
15335
15341
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -18631,6 +18637,12 @@ const INSERT_LINK = (env) => {
|
|
|
18631
18637
|
let { col, row } = env.model.getters.getActivePosition();
|
|
18632
18638
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
18633
18639
|
};
|
|
18640
|
+
const INSERT_LINK_NAME = (env) => {
|
|
18641
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18642
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
18643
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
18644
|
+
return cell && cell.link ? _lt("Edit link") : _lt("Insert link");
|
|
18645
|
+
};
|
|
18634
18646
|
//------------------------------------------------------------------------------
|
|
18635
18647
|
// Filters action
|
|
18636
18648
|
//------------------------------------------------------------------------------
|
|
@@ -19171,7 +19183,7 @@ cellMenuRegistry
|
|
|
19171
19183
|
})
|
|
19172
19184
|
.add("insert_link", {
|
|
19173
19185
|
...insertLink,
|
|
19174
|
-
name:
|
|
19186
|
+
name: INSERT_LINK_NAME,
|
|
19175
19187
|
sequence: 150,
|
|
19176
19188
|
separator: true,
|
|
19177
19189
|
});
|
|
@@ -24082,6 +24094,7 @@ class Composer extends owl.Component {
|
|
|
24082
24094
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
24083
24095
|
static defaultProps = {
|
|
24084
24096
|
inputStyle: "",
|
|
24097
|
+
isDefaultFocus: false,
|
|
24085
24098
|
};
|
|
24086
24099
|
composerRef = owl.useRef("o_composer");
|
|
24087
24100
|
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
|
@@ -24134,7 +24147,6 @@ class Composer extends owl.Component {
|
|
|
24134
24147
|
F2: () => console.warn("Not implemented"),
|
|
24135
24148
|
F4: this.processF4Key,
|
|
24136
24149
|
Tab: (ev) => this.processTabKey(ev),
|
|
24137
|
-
" ": (ev) => this.processSpaceKey(ev),
|
|
24138
24150
|
};
|
|
24139
24151
|
keyCodeMapping = {
|
|
24140
24152
|
NumpadDecimal: this.processNumpadDecimal,
|
|
@@ -24142,11 +24154,11 @@ class Composer extends owl.Component {
|
|
|
24142
24154
|
setup() {
|
|
24143
24155
|
owl.onMounted(() => {
|
|
24144
24156
|
const el = this.composerRef.el;
|
|
24157
|
+
if (this.props.isDefaultFocus) {
|
|
24158
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
24159
|
+
}
|
|
24145
24160
|
this.contentHelper.updateEl(el);
|
|
24146
24161
|
});
|
|
24147
|
-
owl.onWillUnmount(() => {
|
|
24148
|
-
this.props.onComposerUnmounted?.();
|
|
24149
|
-
});
|
|
24150
24162
|
owl.useEffect(() => {
|
|
24151
24163
|
this.processContent();
|
|
24152
24164
|
});
|
|
@@ -24155,7 +24167,8 @@ class Composer extends owl.Component {
|
|
|
24155
24167
|
// Handlers
|
|
24156
24168
|
// ---------------------------------------------------------------------------
|
|
24157
24169
|
processArrowKeys(ev) {
|
|
24158
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
24170
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
24171
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24159
24172
|
this.functionDescriptionState.showDescription = false;
|
|
24160
24173
|
// Prevent the default content editable behavior which moves the cursor
|
|
24161
24174
|
ev.preventDefault();
|
|
@@ -24194,25 +24207,19 @@ class Composer extends owl.Component {
|
|
|
24194
24207
|
processTabKey(ev) {
|
|
24195
24208
|
ev.preventDefault();
|
|
24196
24209
|
ev.stopPropagation();
|
|
24197
|
-
if (this.
|
|
24198
|
-
|
|
24199
|
-
|
|
24200
|
-
|
|
24201
|
-
|
|
24210
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24211
|
+
if (this.autoCompleteState.showProvider) {
|
|
24212
|
+
const autoCompleteValue = this.autoCompleteState.values[this.autoCompleteState.selectedIndex]?.text;
|
|
24213
|
+
if (autoCompleteValue) {
|
|
24214
|
+
this.autoComplete(autoCompleteValue);
|
|
24215
|
+
return;
|
|
24216
|
+
}
|
|
24202
24217
|
}
|
|
24218
|
+
this.env.model.dispatch("STOP_EDITION");
|
|
24203
24219
|
}
|
|
24204
24220
|
const direction = ev.shiftKey ? "left" : "right";
|
|
24205
|
-
this.env.model.dispatch("STOP_EDITION");
|
|
24206
24221
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
24207
24222
|
}
|
|
24208
|
-
processSpaceKey(ev) {
|
|
24209
|
-
if (ev.ctrlKey) {
|
|
24210
|
-
ev.preventDefault();
|
|
24211
|
-
ev.stopPropagation();
|
|
24212
|
-
this.showAutocomplete("");
|
|
24213
|
-
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24214
|
-
}
|
|
24215
|
-
}
|
|
24216
24223
|
processEnterKey(ev) {
|
|
24217
24224
|
ev.preventDefault();
|
|
24218
24225
|
ev.stopPropagation();
|
|
@@ -24264,6 +24271,9 @@ class Composer extends owl.Component {
|
|
|
24264
24271
|
this.compositionActive = false;
|
|
24265
24272
|
}
|
|
24266
24273
|
onKeydown(ev) {
|
|
24274
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24275
|
+
return;
|
|
24276
|
+
}
|
|
24267
24277
|
let handler = this.keyMapping[ev.key] || this.keyCodeMapping[ev.code];
|
|
24268
24278
|
if (handler) {
|
|
24269
24279
|
handler.call(this, ev);
|
|
@@ -24272,14 +24282,33 @@ class Composer extends owl.Component {
|
|
|
24272
24282
|
ev.stopPropagation();
|
|
24273
24283
|
}
|
|
24274
24284
|
}
|
|
24285
|
+
onPaste(ev) {
|
|
24286
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
24287
|
+
ev.stopPropagation();
|
|
24288
|
+
}
|
|
24289
|
+
}
|
|
24275
24290
|
/*
|
|
24276
24291
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
24277
24292
|
* */
|
|
24278
24293
|
onInput(ev) {
|
|
24279
|
-
if (
|
|
24294
|
+
if (!this.shouldProcessInputEvents) {
|
|
24280
24295
|
return;
|
|
24281
24296
|
}
|
|
24282
|
-
|
|
24297
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
24298
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
24299
|
+
return;
|
|
24300
|
+
}
|
|
24301
|
+
ev.stopPropagation();
|
|
24302
|
+
let content;
|
|
24303
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
24304
|
+
content = ev.data || "";
|
|
24305
|
+
}
|
|
24306
|
+
else {
|
|
24307
|
+
content = this.contentHelper.getText();
|
|
24308
|
+
}
|
|
24309
|
+
if (this.props.focus === "inactive") {
|
|
24310
|
+
return this.props.onComposerCellFocused?.(content);
|
|
24311
|
+
}
|
|
24283
24312
|
let selection = this.contentHelper.getCurrentSelection();
|
|
24284
24313
|
if (ev.inputType === "insertParagraph") {
|
|
24285
24314
|
const start = Math.min(selection.start, selection.end);
|
|
@@ -24357,9 +24386,8 @@ class Composer extends owl.Component {
|
|
|
24357
24386
|
}
|
|
24358
24387
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
24359
24388
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
24360
|
-
|
|
24361
|
-
|
|
24362
|
-
}
|
|
24389
|
+
this.props.onComposerContentFocused();
|
|
24390
|
+
if (this.props.focus === "inactive") ;
|
|
24363
24391
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
24364
24392
|
this.processTokenAtCursor();
|
|
24365
24393
|
}
|
|
@@ -24526,7 +24554,7 @@ class Composer extends owl.Component {
|
|
|
24526
24554
|
const highlights = this.env.model.getters.getHighlights();
|
|
24527
24555
|
const refSheet = sheetName
|
|
24528
24556
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
24529
|
-
: this.env.model.getters.getCurrentEditedCell()
|
|
24557
|
+
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
|
24530
24558
|
const highlight = highlights.find((highlight) => {
|
|
24531
24559
|
if (highlight.sheetId !== refSheet)
|
|
24532
24560
|
return false;
|
|
@@ -24606,12 +24634,13 @@ class Composer extends owl.Component {
|
|
|
24606
24634
|
}
|
|
24607
24635
|
}
|
|
24608
24636
|
Composer.props = {
|
|
24609
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24610
|
-
onComposerContentFocused: Function,
|
|
24611
24637
|
inputStyle: { type: String, optional: true },
|
|
24612
24638
|
rect: { type: Object, optional: true },
|
|
24613
24639
|
delimitation: { type: Object, optional: true },
|
|
24614
|
-
|
|
24640
|
+
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24641
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
24642
|
+
onComposerContentFocused: Function,
|
|
24643
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
24615
24644
|
};
|
|
24616
24645
|
|
|
24617
24646
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -24645,51 +24674,26 @@ css /* scss */ `
|
|
|
24645
24674
|
class GridComposer extends owl.Component {
|
|
24646
24675
|
static template = "o-spreadsheet-GridComposer";
|
|
24647
24676
|
static components = { Composer };
|
|
24648
|
-
|
|
24649
|
-
|
|
24650
|
-
|
|
24677
|
+
// TODORAR see if we can keep it undefined
|
|
24678
|
+
rect = this.defaultRect;
|
|
24679
|
+
isEditing = false;
|
|
24651
24680
|
isCellReferenceVisible;
|
|
24652
|
-
|
|
24681
|
+
get defaultRect() {
|
|
24682
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
24683
|
+
}
|
|
24653
24684
|
setup() {
|
|
24654
|
-
this.gridComposerRef = owl.useRef("gridComposer");
|
|
24655
|
-
this.composerState = owl.useState({
|
|
24656
|
-
rect: undefined,
|
|
24657
|
-
delimitation: undefined,
|
|
24658
|
-
});
|
|
24659
|
-
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
|
24660
|
-
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
|
24661
|
-
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
|
24662
|
-
this.isCellReferenceVisible = false;
|
|
24663
|
-
owl.onMounted(() => {
|
|
24664
|
-
const el = this.gridComposerRef.el;
|
|
24665
|
-
this.composerState.rect = {
|
|
24666
|
-
x: this.rect.x,
|
|
24667
|
-
y: this.rect.y,
|
|
24668
|
-
width: el.clientWidth,
|
|
24669
|
-
height: el.clientHeight,
|
|
24670
|
-
};
|
|
24671
|
-
this.composerState.delimitation = {
|
|
24672
|
-
width: this.props.gridDims.width,
|
|
24673
|
-
height: this.props.gridDims.height,
|
|
24674
|
-
};
|
|
24675
|
-
});
|
|
24676
24685
|
owl.onWillUpdateProps(() => {
|
|
24677
|
-
|
|
24678
|
-
|
|
24679
|
-
}
|
|
24680
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24681
|
-
const zone = this.env.model.getters.getSelectedZone();
|
|
24682
|
-
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24683
|
-
if (!deepEquals(rect, this.rect) ||
|
|
24684
|
-
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24685
|
-
this.isCellReferenceVisible = true;
|
|
24686
|
-
}
|
|
24686
|
+
this.updateComponentPosition();
|
|
24687
|
+
this.updateCellReferenceVisibility();
|
|
24687
24688
|
});
|
|
24688
24689
|
}
|
|
24689
24690
|
get shouldDisplayCellReference() {
|
|
24690
24691
|
return this.isCellReferenceVisible;
|
|
24691
24692
|
}
|
|
24692
24693
|
get cellReference() {
|
|
24694
|
+
if (!this.env.model.getters.getCurrentEditedCell()) {
|
|
24695
|
+
return "";
|
|
24696
|
+
}
|
|
24693
24697
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
24694
24698
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
24695
24699
|
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
|
@@ -24701,7 +24705,27 @@ class GridComposer extends owl.Component {
|
|
|
24701
24705
|
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
|
24702
24706
|
});
|
|
24703
24707
|
}
|
|
24708
|
+
get composerProps() {
|
|
24709
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
24710
|
+
return {
|
|
24711
|
+
rect: { ...this.rect },
|
|
24712
|
+
delimitation: {
|
|
24713
|
+
width,
|
|
24714
|
+
height,
|
|
24715
|
+
},
|
|
24716
|
+
focus: this.props.focus,
|
|
24717
|
+
isDefaultFocus: true,
|
|
24718
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
24719
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
24720
|
+
};
|
|
24721
|
+
}
|
|
24704
24722
|
get containerStyle() {
|
|
24723
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
24724
|
+
return `
|
|
24725
|
+
position: absolute;
|
|
24726
|
+
z-index: -1000;
|
|
24727
|
+
`;
|
|
24728
|
+
}
|
|
24705
24729
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
24706
24730
|
const cell = this.env.model.getters.getActiveCell();
|
|
24707
24731
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -24721,6 +24745,8 @@ class GridComposer extends owl.Component {
|
|
|
24721
24745
|
if (!isFormula) {
|
|
24722
24746
|
textAlign = style.align || cell.defaultAlign;
|
|
24723
24747
|
}
|
|
24748
|
+
const maxHeight = this.props.gridDims.height - this.rect.y;
|
|
24749
|
+
const maxWidth = this.props.gridDims.width - this.rect.x;
|
|
24724
24750
|
/**
|
|
24725
24751
|
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
|
24726
24752
|
* including all the paddings/margins of the composer
|
|
@@ -24732,6 +24758,8 @@ class GridComposer extends owl.Component {
|
|
|
24732
24758
|
top: `${top}px`,
|
|
24733
24759
|
"min-width": `${width + 1}px`,
|
|
24734
24760
|
"min-height": `${height + 1}px`,
|
|
24761
|
+
"max-width": `${maxWidth}px`,
|
|
24762
|
+
"max-height": `${maxHeight}px`,
|
|
24735
24763
|
background,
|
|
24736
24764
|
color,
|
|
24737
24765
|
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
|
@@ -24741,20 +24769,38 @@ class GridComposer extends owl.Component {
|
|
|
24741
24769
|
"text-align": textAlign,
|
|
24742
24770
|
});
|
|
24743
24771
|
}
|
|
24744
|
-
|
|
24745
|
-
const
|
|
24746
|
-
|
|
24747
|
-
|
|
24748
|
-
|
|
24749
|
-
|
|
24750
|
-
|
|
24772
|
+
updateComponentPosition() {
|
|
24773
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
24774
|
+
if (this.isEditing !== isEditing) {
|
|
24775
|
+
this.isEditing = isEditing;
|
|
24776
|
+
if (!isEditing) {
|
|
24777
|
+
this.rect = this.defaultRect;
|
|
24778
|
+
this.env.focusableElement.focus();
|
|
24779
|
+
return;
|
|
24780
|
+
}
|
|
24781
|
+
const position = this.env.model.getters.getActivePosition();
|
|
24782
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
24783
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
24784
|
+
}
|
|
24785
|
+
}
|
|
24786
|
+
updateCellReferenceVisibility() {
|
|
24787
|
+
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
|
24788
|
+
return;
|
|
24789
|
+
}
|
|
24790
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
24791
|
+
const zone = this.env.model.getters.getSelectedZone();
|
|
24792
|
+
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
24793
|
+
if (!deepEquals(rect, this.rect) ||
|
|
24794
|
+
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
24795
|
+
this.isCellReferenceVisible = true;
|
|
24796
|
+
}
|
|
24751
24797
|
}
|
|
24752
24798
|
}
|
|
24753
24799
|
GridComposer.props = {
|
|
24754
24800
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
24755
|
-
onComposerUnmounted: Function,
|
|
24756
24801
|
onComposerContentFocused: Function,
|
|
24757
24802
|
gridDims: Object,
|
|
24803
|
+
onComposerCellFocused: Function,
|
|
24758
24804
|
};
|
|
24759
24805
|
|
|
24760
24806
|
const CSS$1 = css /* scss */ `
|
|
@@ -25635,7 +25681,6 @@ class GridOverlay extends owl.Component {
|
|
|
25635
25681
|
this.props.onCellDoubleClicked(col, row);
|
|
25636
25682
|
}
|
|
25637
25683
|
onContextMenu(ev) {
|
|
25638
|
-
ev.preventDefault();
|
|
25639
25684
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
25640
25685
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
25641
25686
|
}
|
|
@@ -26728,7 +26773,6 @@ class Grid extends owl.Component {
|
|
|
26728
26773
|
HEADER_WIDTH = HEADER_WIDTH;
|
|
26729
26774
|
menuState;
|
|
26730
26775
|
gridRef;
|
|
26731
|
-
hiddenInput;
|
|
26732
26776
|
onMouseWheel;
|
|
26733
26777
|
canvasPosition;
|
|
26734
26778
|
hoveredCell;
|
|
@@ -26739,17 +26783,16 @@ class Grid extends owl.Component {
|
|
|
26739
26783
|
menuItems: [],
|
|
26740
26784
|
});
|
|
26741
26785
|
this.gridRef = owl.useRef("grid");
|
|
26742
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
26743
26786
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
26744
26787
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
26745
26788
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
26746
26789
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
26747
26790
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
26748
26791
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
26749
|
-
owl.onMounted(() => this.
|
|
26750
|
-
this.props.exposeFocus(() => this.
|
|
26792
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
26793
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
26751
26794
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
26752
|
-
owl.useEffect(() => this.
|
|
26795
|
+
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
26753
26796
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
26754
26797
|
this.moveCanvas(deltaX, deltaY);
|
|
26755
26798
|
this.hoveredCell.col = undefined;
|
|
@@ -26772,7 +26815,7 @@ class Grid extends owl.Component {
|
|
|
26772
26815
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
26773
26816
|
this.closeOpenedPopover();
|
|
26774
26817
|
}
|
|
26775
|
-
this.
|
|
26818
|
+
this.focusDefaultElement();
|
|
26776
26819
|
}
|
|
26777
26820
|
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
|
26778
26821
|
// down itself
|
|
@@ -26945,10 +26988,10 @@ class Grid extends owl.Component {
|
|
|
26945
26988
|
PAGEUP: () => this.env.model.dispatch("SHIFT_VIEWPORT_UP"),
|
|
26946
26989
|
"CTRL+K": () => INSERT_LINK(this.env),
|
|
26947
26990
|
};
|
|
26948
|
-
|
|
26991
|
+
focusDefaultElement() {
|
|
26949
26992
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
26950
26993
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26951
|
-
this.
|
|
26994
|
+
this.env.focusableElement.focus();
|
|
26952
26995
|
}
|
|
26953
26996
|
}
|
|
26954
26997
|
get gridEl() {
|
|
@@ -27092,19 +27135,6 @@ class Grid extends owl.Component {
|
|
|
27092
27135
|
return;
|
|
27093
27136
|
}
|
|
27094
27137
|
}
|
|
27095
|
-
onInput(ev) {
|
|
27096
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
27097
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
27098
|
-
return;
|
|
27099
|
-
}
|
|
27100
|
-
if (ev.data) {
|
|
27101
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
27102
|
-
// character
|
|
27103
|
-
ev.preventDefault();
|
|
27104
|
-
ev.stopPropagation();
|
|
27105
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
27106
|
-
}
|
|
27107
|
-
}
|
|
27108
27138
|
// ---------------------------------------------------------------------------
|
|
27109
27139
|
// Context Menu
|
|
27110
27140
|
// ---------------------------------------------------------------------------
|
|
@@ -27217,7 +27247,7 @@ class Grid extends owl.Component {
|
|
|
27217
27247
|
}
|
|
27218
27248
|
closeMenu() {
|
|
27219
27249
|
this.menuState.isOpen = false;
|
|
27220
|
-
this.
|
|
27250
|
+
this.focusDefaultElement();
|
|
27221
27251
|
}
|
|
27222
27252
|
}
|
|
27223
27253
|
Grid.props = {
|
|
@@ -30877,6 +30907,31 @@ const MIGRATIONS = [
|
|
|
30877
30907
|
return data;
|
|
30878
30908
|
},
|
|
30879
30909
|
},
|
|
30910
|
+
{
|
|
30911
|
+
description: "Fix datafilter duplication",
|
|
30912
|
+
from: 12,
|
|
30913
|
+
to: 12.5,
|
|
30914
|
+
applyMigration(data) {
|
|
30915
|
+
for (let sheet of data.sheets || []) {
|
|
30916
|
+
let knownDataFilterZones = [];
|
|
30917
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
30918
|
+
const zone = toZone(filterTable.range);
|
|
30919
|
+
// See commit message for the details
|
|
30920
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
30921
|
+
if (intersectZoneIndex !== -1) {
|
|
30922
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
30923
|
+
}
|
|
30924
|
+
else {
|
|
30925
|
+
knownDataFilterZones.push(zone);
|
|
30926
|
+
}
|
|
30927
|
+
}
|
|
30928
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
30929
|
+
range: zoneToXc(zone),
|
|
30930
|
+
}));
|
|
30931
|
+
}
|
|
30932
|
+
return data;
|
|
30933
|
+
},
|
|
30934
|
+
},
|
|
30880
30935
|
{
|
|
30881
30936
|
description: "Change Border description structure",
|
|
30882
30937
|
from: 12,
|
|
@@ -31796,9 +31851,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31796
31851
|
allowDispatch(cmd) {
|
|
31797
31852
|
switch (cmd.type) {
|
|
31798
31853
|
case "UPDATE_CELL":
|
|
31799
|
-
return this.
|
|
31854
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
31800
31855
|
case "CLEAR_CELL":
|
|
31801
|
-
return this.checkValidations(cmd, this.
|
|
31856
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
31802
31857
|
default:
|
|
31803
31858
|
return 0 /* CommandResult.Success */;
|
|
31804
31859
|
}
|
|
@@ -31930,10 +31985,6 @@ class CellPlugin extends CorePlugin {
|
|
|
31930
31985
|
format: cell.format ? getItemId(cell.format, formats) : undefined,
|
|
31931
31986
|
content: cell.content || undefined,
|
|
31932
31987
|
};
|
|
31933
|
-
// if there is a formula but no dependencies (maybe because the cell is in error), no need to recompute the formula text
|
|
31934
|
-
if (cell.isFormula && cell.dependencies.length) {
|
|
31935
|
-
cells[xc].content = this.buildFormulaContent(_sheet.id, cell, cell.dependencies, true);
|
|
31936
|
-
}
|
|
31937
31988
|
}
|
|
31938
31989
|
_sheet.cells = cells;
|
|
31939
31990
|
}
|
|
@@ -32096,10 +32147,7 @@ class CellPlugin extends CorePlugin {
|
|
|
32096
32147
|
else {
|
|
32097
32148
|
style = before ? before.style : undefined;
|
|
32098
32149
|
}
|
|
32099
|
-
const
|
|
32100
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
32101
|
-
detectDateFormat(afterContent, locale) ||
|
|
32102
|
-
detectNumberFormat(afterContent);
|
|
32150
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
32103
32151
|
/* Read the following IF as:
|
|
32104
32152
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
32105
32153
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -32140,12 +32188,11 @@ class CellPlugin extends CorePlugin {
|
|
|
32140
32188
|
}
|
|
32141
32189
|
createLiteralCell(id, content, format, style) {
|
|
32142
32190
|
const locale = this.getters.getLocale();
|
|
32143
|
-
content = parseLiteral(content, locale).toString();
|
|
32144
32191
|
return {
|
|
32145
32192
|
id,
|
|
32146
|
-
content,
|
|
32193
|
+
content: parseLiteral(content, locale).toString(),
|
|
32147
32194
|
style,
|
|
32148
|
-
format,
|
|
32195
|
+
format: format || detectDateFormat(content, locale) || detectNumberFormat(content),
|
|
32149
32196
|
isFormula: false,
|
|
32150
32197
|
};
|
|
32151
32198
|
}
|
|
@@ -32206,6 +32253,18 @@ class CellPlugin extends CorePlugin {
|
|
|
32206
32253
|
}
|
|
32207
32254
|
return 0 /* CommandResult.Success */;
|
|
32208
32255
|
}
|
|
32256
|
+
checkUselessUpdateCell(cmd) {
|
|
32257
|
+
const cell = this.getters.getCell(cmd);
|
|
32258
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
32259
|
+
const hasStyle = "style" in cmd;
|
|
32260
|
+
const hasFormat = "format" in cmd;
|
|
32261
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
32262
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
32263
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
32264
|
+
return 98 /* CommandResult.NoChanges */;
|
|
32265
|
+
}
|
|
32266
|
+
return 0 /* CommandResult.Success */;
|
|
32267
|
+
}
|
|
32209
32268
|
}
|
|
32210
32269
|
class FormulaCellWithDependencies {
|
|
32211
32270
|
id;
|
|
@@ -36346,7 +36405,15 @@ class SpreadsheetRTree {
|
|
|
36346
36405
|
if (!this.rTrees[sheetId]) {
|
|
36347
36406
|
return;
|
|
36348
36407
|
}
|
|
36349
|
-
this.rTrees[sheetId].remove(item,
|
|
36408
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
36409
|
+
}
|
|
36410
|
+
rtreeItemComparer(left, right) {
|
|
36411
|
+
return (left.data == right.data &&
|
|
36412
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
36413
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
36414
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
36415
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
36416
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
36350
36417
|
}
|
|
36351
36418
|
}
|
|
36352
36419
|
/**
|
|
@@ -36424,7 +36491,7 @@ class FormulaDependencyGraph {
|
|
|
36424
36491
|
const queue = Array.from(ranges).reverse();
|
|
36425
36492
|
while (queue.length > 0) {
|
|
36426
36493
|
const range = queue.pop();
|
|
36427
|
-
visited.
|
|
36494
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
36428
36495
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
36429
36496
|
for (const positionId of impactedPositionIds) {
|
|
36430
36497
|
if (!visited.has(positionId)) {
|
|
@@ -36432,7 +36499,7 @@ class FormulaDependencyGraph {
|
|
|
36432
36499
|
}
|
|
36433
36500
|
}
|
|
36434
36501
|
}
|
|
36435
|
-
visited.
|
|
36502
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
36436
36503
|
return visited;
|
|
36437
36504
|
}
|
|
36438
36505
|
}
|
|
@@ -36563,9 +36630,9 @@ class Evaluator {
|
|
|
36563
36630
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
36564
36631
|
const cellsToCompute = new JetSet(cells);
|
|
36565
36632
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
36566
|
-
cellsToCompute.
|
|
36567
|
-
cellsToCompute.
|
|
36568
|
-
cellsToCompute.
|
|
36633
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
36634
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
36635
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
36569
36636
|
this.evaluate(cellsToCompute);
|
|
36570
36637
|
}
|
|
36571
36638
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -36579,7 +36646,7 @@ class Evaluator {
|
|
|
36579
36646
|
}
|
|
36580
36647
|
if (!content) {
|
|
36581
36648
|
// The previous content could have blocked some array formulas
|
|
36582
|
-
impactedPositionIds.
|
|
36649
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
36583
36650
|
}
|
|
36584
36651
|
}
|
|
36585
36652
|
return impactedPositionIds;
|
|
@@ -36627,7 +36694,7 @@ class Evaluator {
|
|
|
36627
36694
|
}
|
|
36628
36695
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
36629
36696
|
const cells = new JetSet(arrayFormulas);
|
|
36630
|
-
cells.
|
|
36697
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
36631
36698
|
return cells;
|
|
36632
36699
|
}
|
|
36633
36700
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -36778,7 +36845,7 @@ class Evaluator {
|
|
|
36778
36845
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
36779
36846
|
// check if formula dependencies present in the spread zone
|
|
36780
36847
|
// if so, they need to be recomputed
|
|
36781
|
-
this.nextPositionsToUpdate.
|
|
36848
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
36782
36849
|
};
|
|
36783
36850
|
}
|
|
36784
36851
|
invalidateSpreading(positionId) {
|
|
@@ -36793,8 +36860,8 @@ class Evaluator {
|
|
|
36793
36860
|
continue;
|
|
36794
36861
|
}
|
|
36795
36862
|
this.evaluatedCells.delete(child);
|
|
36796
|
-
this.nextPositionsToUpdate.
|
|
36797
|
-
this.nextPositionsToUpdate.
|
|
36863
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
36864
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
36798
36865
|
}
|
|
36799
36866
|
this.spreadingRelations.removeNode(positionId);
|
|
36800
36867
|
}
|
|
@@ -37154,7 +37221,13 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
37154
37221
|
const format = newFormat
|
|
37155
37222
|
? getItemId(newFormat, data.formats)
|
|
37156
37223
|
: exportedCellData.format;
|
|
37157
|
-
|
|
37224
|
+
let content;
|
|
37225
|
+
if (formulaCell instanceof FormulaCellWithDependencies) {
|
|
37226
|
+
content = this.getters.buildFormulaContent(exportedSheetData.id, formulaCell, formulaCell.dependencies, true);
|
|
37227
|
+
}
|
|
37228
|
+
else {
|
|
37229
|
+
content = !isExported ? newContent : exportedCellData.content;
|
|
37230
|
+
}
|
|
37158
37231
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
37159
37232
|
}
|
|
37160
37233
|
}
|
|
@@ -43673,7 +43746,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
43673
43746
|
this.replaceText(ref, this.selectionInitialStart, this.selectionEnd);
|
|
43674
43747
|
}
|
|
43675
43748
|
getZoneReference(zone) {
|
|
43676
|
-
const inputSheetId = this.getters.getCurrentEditedCell().
|
|
43749
|
+
const inputSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43677
43750
|
const sheetId = this.getters.getActiveSheetId();
|
|
43678
43751
|
const range = this.getters.getRangeFromZone(sheetId, zone);
|
|
43679
43752
|
return this.getters.getSelectionRangeString(range, inputSheetId);
|
|
@@ -43687,7 +43760,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
43687
43760
|
_fixedParts.pop();
|
|
43688
43761
|
}
|
|
43689
43762
|
const newRange = range.clone({ parts: _fixedParts });
|
|
43690
|
-
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell().
|
|
43763
|
+
return this.getters.getSelectionRangeString(newRange, this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId());
|
|
43691
43764
|
}
|
|
43692
43765
|
/**
|
|
43693
43766
|
* Replace the current selection by a new text.
|
|
@@ -43720,7 +43793,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
43720
43793
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43721
43794
|
return;
|
|
43722
43795
|
}
|
|
43723
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43796
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43724
43797
|
const XCs = this.getReferencedRanges().map((range) => this.getters.getRangeString(range, editionSheetId));
|
|
43725
43798
|
const colorsToKeep = {};
|
|
43726
43799
|
for (const xc of XCs) {
|
|
@@ -43749,7 +43822,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
43749
43822
|
if (!this.currentContent.startsWith("=") || this.mode === "inactive") {
|
|
43750
43823
|
return [];
|
|
43751
43824
|
}
|
|
43752
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43825
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43753
43826
|
const rangeColor = (rangeString) => {
|
|
43754
43827
|
const colorIndex = this.colorIndexByRange[rangeString];
|
|
43755
43828
|
return colors$1[colorIndex % colors$1.length];
|
|
@@ -43767,7 +43840,7 @@ class EditionPlugin extends UIPlugin {
|
|
|
43767
43840
|
* Return ranges currently referenced in the composer
|
|
43768
43841
|
*/
|
|
43769
43842
|
getReferencedRanges() {
|
|
43770
|
-
const editionSheetId = this.getters.getCurrentEditedCell().
|
|
43843
|
+
const editionSheetId = this.getters.getCurrentEditedCell()?.sheetId || this.getters.getActiveSheetId();
|
|
43771
43844
|
const referenceRanges = this.currentTokens
|
|
43772
43845
|
.filter((token) => token.type === "REFERENCE")
|
|
43773
43846
|
.map((token) => this.getters.getRangeFromSheetXC(editionSheetId, token.value));
|
|
@@ -45731,6 +45804,16 @@ class ImageProvider {
|
|
|
45731
45804
|
}
|
|
45732
45805
|
}
|
|
45733
45806
|
|
|
45807
|
+
class FocusableElement {
|
|
45808
|
+
focusableElement = undefined;
|
|
45809
|
+
setFocusableElement(element) {
|
|
45810
|
+
this.focusableElement = element;
|
|
45811
|
+
}
|
|
45812
|
+
focus() {
|
|
45813
|
+
this.focusableElement?.focus();
|
|
45814
|
+
}
|
|
45815
|
+
}
|
|
45816
|
+
|
|
45734
45817
|
const RIPPLE_KEY_FRAMES = [
|
|
45735
45818
|
{ transform: "scale(0)" },
|
|
45736
45819
|
{ transform: "scale(0.8)", offset: 0.33 },
|
|
@@ -47773,6 +47856,7 @@ class Spreadsheet extends owl.Component {
|
|
|
47773
47856
|
_t: Spreadsheet._t,
|
|
47774
47857
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
47775
47858
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
47859
|
+
focusableElement: new FocusableElement(),
|
|
47776
47860
|
});
|
|
47777
47861
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
47778
47862
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
@@ -47879,17 +47963,18 @@ class Spreadsheet extends owl.Component {
|
|
|
47879
47963
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47880
47964
|
this.composer.topBarFocus = "contentFocus";
|
|
47881
47965
|
this.composer.gridFocusMode = "inactive";
|
|
47882
|
-
this.setComposerContent({ selection }
|
|
47966
|
+
this.setComposerContent({ selection });
|
|
47883
47967
|
}
|
|
47884
|
-
onGridComposerContentFocused() {
|
|
47968
|
+
onGridComposerContentFocused(selection) {
|
|
47885
47969
|
if (this.model.getters.isReadonly()) {
|
|
47886
47970
|
return;
|
|
47887
47971
|
}
|
|
47888
47972
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
47889
47973
|
this.composer.topBarFocus = "inactive";
|
|
47890
47974
|
this.composer.gridFocusMode = "contentFocus";
|
|
47891
|
-
this.setComposerContent({});
|
|
47975
|
+
this.setComposerContent({ selection });
|
|
47892
47976
|
}
|
|
47977
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
47893
47978
|
onGridComposerCellFocused(content, selection) {
|
|
47894
47979
|
if (this.model.getters.isReadonly()) {
|
|
47895
47980
|
return;
|
|
@@ -49301,11 +49386,10 @@ class SelectionStreamProcessorImpl {
|
|
|
49301
49386
|
* next cluster if the given cell is outside a cluster or at the border of a cluster in the given direction.
|
|
49302
49387
|
*/
|
|
49303
49388
|
getEndOfCluster(startPosition, dim, dir) {
|
|
49304
|
-
const sheet = this.getters.getActiveSheet();
|
|
49305
49389
|
let currentPosition = startPosition;
|
|
49306
49390
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
49307
49391
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
49308
|
-
let mode = !this.
|
|
49392
|
+
let mode = !this.isEvaluatedCellEmpty(currentPosition) && !this.isEvaluatedCellEmpty(nextCellPosition)
|
|
49309
49393
|
? "endOfCluster"
|
|
49310
49394
|
: "nextCluster";
|
|
49311
49395
|
while (true) {
|
|
@@ -49315,7 +49399,7 @@ class SelectionStreamProcessorImpl {
|
|
|
49315
49399
|
currentPosition.row === nextCellPosition.row) {
|
|
49316
49400
|
break;
|
|
49317
49401
|
}
|
|
49318
|
-
const isNextCellEmpty = this.
|
|
49402
|
+
const isNextCellEmpty = this.isEvaluatedCellEmpty(nextCellPosition);
|
|
49319
49403
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
49320
49404
|
break;
|
|
49321
49405
|
}
|
|
@@ -49329,10 +49413,20 @@ class SelectionStreamProcessorImpl {
|
|
|
49329
49413
|
return dim === "cols" ? currentPosition.col : currentPosition.row;
|
|
49330
49414
|
}
|
|
49331
49415
|
/**
|
|
49332
|
-
*
|
|
49333
|
-
* check
|
|
49416
|
+
* Checks if a cell is empty (i.e. does not have a content). If the cell is part of a merge,
|
|
49417
|
+
* the check applies to the main cell of the merge.
|
|
49418
|
+
*/
|
|
49419
|
+
isCellEmpty({ col, row }) {
|
|
49420
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49421
|
+
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49422
|
+
return !(this.getters.getCorrespondingFormulaCell(position) || this.getters.getCell(position)?.content);
|
|
49423
|
+
}
|
|
49424
|
+
/**
|
|
49425
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
49426
|
+
* the check applies to the main cell of the merge.
|
|
49334
49427
|
*/
|
|
49335
|
-
|
|
49428
|
+
isEvaluatedCellEmpty({ col, row }) {
|
|
49429
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
49336
49430
|
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
49337
49431
|
const cell = this.getters.getEvaluatedCell(position);
|
|
49338
49432
|
return cell.type === CellValueType.empty;
|
|
@@ -51613,6 +51707,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
51613
51707
|
exports.tokenize = tokenize;
|
|
51614
51708
|
|
|
51615
51709
|
|
|
51616
|
-
__info__.version = '16.4.
|
|
51617
|
-
__info__.date = '2024-02-
|
|
51618
|
-
__info__.hash = '
|
|
51710
|
+
__info__.version = '16.4.23';
|
|
51711
|
+
__info__.date = '2024-02-16T14:23:29.521Z';
|
|
51712
|
+
__info__.hash = 'cb5db1a';
|