@odoo/o-spreadsheet 16.1.33 → 16.1.36
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 +257 -153
- package/dist/o-spreadsheet.d.ts +72 -51
- package/dist/o-spreadsheet.esm.js +257 -153
- package/dist/o-spreadsheet.iife.js +257 -153
- package/dist/o-spreadsheet.iife.min.js +105 -112
- package/dist/o_spreadsheet.xml +14 -32
- package/package.json +1 -1
|
@@ -207,7 +207,7 @@ const TOPBAR_HEIGHT = 63;
|
|
|
207
207
|
const BOTTOMBAR_HEIGHT = 36;
|
|
208
208
|
const DEFAULT_CELL_WIDTH = 96;
|
|
209
209
|
const DEFAULT_CELL_HEIGHT = 23;
|
|
210
|
-
const SCROLLBAR_WIDTH
|
|
210
|
+
const SCROLLBAR_WIDTH = 15;
|
|
211
211
|
const AUTOFILL_EDGE_LENGTH = 8;
|
|
212
212
|
const ICON_EDGE_LENGTH = 18;
|
|
213
213
|
const UNHIDE_ICON_EDGE_LENGTH = 14;
|
|
@@ -1676,6 +1676,9 @@ function parseFormat(formatString) {
|
|
|
1676
1676
|
function formatValue(value, format) {
|
|
1677
1677
|
switch (typeof value) {
|
|
1678
1678
|
case "string":
|
|
1679
|
+
if (value.includes('\\"')) {
|
|
1680
|
+
return value.replace(/\\"/g, '"');
|
|
1681
|
+
}
|
|
1679
1682
|
return value;
|
|
1680
1683
|
case "boolean":
|
|
1681
1684
|
return value ? "TRUE" : "FALSE";
|
|
@@ -3878,14 +3881,8 @@ function createDataSets(getters, dataSetsString, sheetId, dataSetsHaveTitle) {
|
|
|
3878
3881
|
: undefined));
|
|
3879
3882
|
}
|
|
3880
3883
|
}
|
|
3881
|
-
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
3882
|
-
// A single cell. If it's only the title, the dataset is not added.
|
|
3883
|
-
if (!dataSetsHaveTitle) {
|
|
3884
|
-
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
3885
|
-
}
|
|
3886
|
-
}
|
|
3887
3884
|
else {
|
|
3888
|
-
/* 1 row or 1 column */
|
|
3885
|
+
/* 1 cell, 1 row or 1 column */
|
|
3889
3886
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
3890
3887
|
? {
|
|
3891
3888
|
top: zone.top,
|
|
@@ -3935,8 +3932,10 @@ function toExcelDataset(getters, ds) {
|
|
|
3935
3932
|
}
|
|
3936
3933
|
const dataRange = ds.dataRange.clone({ zone: dataZone });
|
|
3937
3934
|
return {
|
|
3938
|
-
label: ds.labelCell
|
|
3939
|
-
|
|
3935
|
+
label: ds.labelCell
|
|
3936
|
+
? getters.getRangeString(ds.labelCell, "forceSheetReference", true)
|
|
3937
|
+
: undefined,
|
|
3938
|
+
range: getters.getRangeString(dataRange, "forceSheetReference", true),
|
|
3940
3939
|
};
|
|
3941
3940
|
}
|
|
3942
3941
|
/**
|
|
@@ -4433,6 +4432,9 @@ class BarChart extends AbstractChart {
|
|
|
4433
4432
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
4434
4433
|
return {
|
|
4435
4434
|
...this.getDefinition(),
|
|
4435
|
+
labelRange: this.labelRange
|
|
4436
|
+
? this.getters.getRangeString(this.labelRange, this.sheetId, true)
|
|
4437
|
+
: undefined,
|
|
4436
4438
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
4437
4439
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
4438
4440
|
dataSets,
|
|
@@ -4991,6 +4993,9 @@ class LineChart extends AbstractChart {
|
|
|
4991
4993
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
4992
4994
|
return {
|
|
4993
4995
|
...this.getDefinition(),
|
|
4996
|
+
labelRange: this.labelRange
|
|
4997
|
+
? this.getters.getRangeString(this.labelRange, this.sheetId, true)
|
|
4998
|
+
: undefined,
|
|
4994
4999
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
4995
5000
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
4996
5001
|
dataSets,
|
|
@@ -5254,6 +5259,9 @@ class PieChart extends AbstractChart {
|
|
|
5254
5259
|
.filter((ds) => ds.range !== ""); // && range !== INCORRECT_RANGE_STRING ? show incorrect #ref ?
|
|
5255
5260
|
return {
|
|
5256
5261
|
...this.getDefinition(),
|
|
5262
|
+
labelRange: this.labelRange
|
|
5263
|
+
? this.getters.getRangeString(this.labelRange, this.sheetId, true)
|
|
5264
|
+
: undefined,
|
|
5257
5265
|
backgroundColor: toXlsxHexColor(this.background || BACKGROUND_CHART_COLOR),
|
|
5258
5266
|
fontColor: toXlsxHexColor(chartFontColor(this.background)),
|
|
5259
5267
|
verticalAxisPosition: "left",
|
|
@@ -7259,6 +7267,12 @@ const INSERT_LINK = (env) => {
|
|
|
7259
7267
|
let { col, row } = env.model.getters.getActivePosition();
|
|
7260
7268
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
7261
7269
|
};
|
|
7270
|
+
const INSERT_LINK_NAME = (env) => {
|
|
7271
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
7272
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
7273
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
7274
|
+
return cell && cell.link ? _lt("Edit link") : _lt("Insert link");
|
|
7275
|
+
};
|
|
7262
7276
|
//------------------------------------------------------------------------------
|
|
7263
7277
|
// Filters action
|
|
7264
7278
|
//------------------------------------------------------------------------------
|
|
@@ -7396,7 +7410,7 @@ cellMenuRegistry
|
|
|
7396
7410
|
action: DELETE_CELL_SHIFT_LEFT,
|
|
7397
7411
|
})
|
|
7398
7412
|
.add("insert_link", {
|
|
7399
|
-
name:
|
|
7413
|
+
name: INSERT_LINK_NAME,
|
|
7400
7414
|
separator: true,
|
|
7401
7415
|
sequence: 150,
|
|
7402
7416
|
action: INSERT_LINK,
|
|
@@ -16555,9 +16569,6 @@ class EditionPlugin extends UIPlugin {
|
|
|
16555
16569
|
break;
|
|
16556
16570
|
}
|
|
16557
16571
|
}
|
|
16558
|
-
unsubscribe() {
|
|
16559
|
-
this.mode = "inactive";
|
|
16560
|
-
}
|
|
16561
16572
|
// ---------------------------------------------------------------------------
|
|
16562
16573
|
// Getters
|
|
16563
16574
|
// ---------------------------------------------------------------------------
|
|
@@ -17450,13 +17461,12 @@ class Composer extends owl.Component {
|
|
|
17450
17461
|
setup() {
|
|
17451
17462
|
owl.onMounted(() => {
|
|
17452
17463
|
const el = this.composerRef.el;
|
|
17464
|
+
if (this.props.isDefaultFocus) {
|
|
17465
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
17466
|
+
}
|
|
17453
17467
|
this.contentHelper.updateEl(el);
|
|
17454
17468
|
this.processContent();
|
|
17455
17469
|
});
|
|
17456
|
-
owl.onWillUnmount(() => {
|
|
17457
|
-
var _a, _b;
|
|
17458
|
-
(_b = (_a = this.props).onComposerUnmounted) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
17459
|
-
});
|
|
17460
17470
|
owl.onPatched(() => {
|
|
17461
17471
|
if (!this.isKeyStillDown) {
|
|
17462
17472
|
this.processContent();
|
|
@@ -17467,7 +17477,8 @@ class Composer extends owl.Component {
|
|
|
17467
17477
|
// Handlers
|
|
17468
17478
|
// ---------------------------------------------------------------------------
|
|
17469
17479
|
processArrowKeys(ev) {
|
|
17470
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
17480
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
17481
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
17471
17482
|
this.functionDescriptionState.showDescription = false;
|
|
17472
17483
|
// Prevent the default content editable behavior which moves the cursor
|
|
17473
17484
|
ev.preventDefault();
|
|
@@ -17508,21 +17519,23 @@ class Composer extends owl.Component {
|
|
|
17508
17519
|
var _a;
|
|
17509
17520
|
ev.preventDefault();
|
|
17510
17521
|
ev.stopPropagation();
|
|
17511
|
-
if (this.
|
|
17512
|
-
|
|
17513
|
-
|
|
17514
|
-
|
|
17515
|
-
|
|
17522
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
17523
|
+
if (this.autoCompleteState.showProvider) {
|
|
17524
|
+
const autoCompleteValue = (_a = this.autoCompleteState.values[this.autoCompleteState.selectedIndex]) === null || _a === void 0 ? void 0 : _a.text;
|
|
17525
|
+
if (autoCompleteValue) {
|
|
17526
|
+
this.autoComplete(autoCompleteValue);
|
|
17527
|
+
return;
|
|
17528
|
+
}
|
|
17516
17529
|
}
|
|
17517
|
-
|
|
17518
|
-
|
|
17519
|
-
|
|
17520
|
-
|
|
17521
|
-
|
|
17522
|
-
|
|
17530
|
+
else {
|
|
17531
|
+
// when completing with tab, if there is no value to complete, the active cell will be moved to the right.
|
|
17532
|
+
// we can't let the model think that it is for a ref selection.
|
|
17533
|
+
// todo: check if this can be removed someday
|
|
17534
|
+
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
17535
|
+
}
|
|
17536
|
+
this.env.model.dispatch("STOP_EDITION");
|
|
17523
17537
|
}
|
|
17524
17538
|
const direction = ev.shiftKey ? "left" : "right";
|
|
17525
|
-
this.env.model.dispatch("STOP_EDITION");
|
|
17526
17539
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
17527
17540
|
}
|
|
17528
17541
|
processEnterKey(ev) {
|
|
@@ -17555,6 +17568,9 @@ class Composer extends owl.Component {
|
|
|
17555
17568
|
this.compositionActive = false;
|
|
17556
17569
|
}
|
|
17557
17570
|
onKeydown(ev) {
|
|
17571
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
17572
|
+
return;
|
|
17573
|
+
}
|
|
17558
17574
|
let handler = this.keyMapping[ev.key];
|
|
17559
17575
|
if (handler) {
|
|
17560
17576
|
handler.call(this, ev);
|
|
@@ -17565,23 +17581,46 @@ class Composer extends owl.Component {
|
|
|
17565
17581
|
}
|
|
17566
17582
|
}
|
|
17567
17583
|
updateCursorIfNeeded() {
|
|
17568
|
-
|
|
17584
|
+
const moveCursor = !this.env.model.getters.isSelectingForComposer() &&
|
|
17585
|
+
!(this.env.model.getters.getEditionMode() === "inactive");
|
|
17586
|
+
if (moveCursor) {
|
|
17569
17587
|
const { start, end } = this.contentHelper.getCurrentSelection();
|
|
17570
17588
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", { start, end });
|
|
17571
17589
|
this.isKeyStillDown = true;
|
|
17572
17590
|
}
|
|
17573
17591
|
}
|
|
17592
|
+
onPaste(ev) {
|
|
17593
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
17594
|
+
ev.stopPropagation();
|
|
17595
|
+
}
|
|
17596
|
+
}
|
|
17574
17597
|
/*
|
|
17575
17598
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
17576
17599
|
* */
|
|
17577
|
-
onInput() {
|
|
17578
|
-
|
|
17600
|
+
onInput(ev) {
|
|
17601
|
+
var _a, _b;
|
|
17602
|
+
if (!this.shouldProcessInputEvents) {
|
|
17579
17603
|
return;
|
|
17580
17604
|
}
|
|
17605
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
17606
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
17607
|
+
return;
|
|
17608
|
+
}
|
|
17609
|
+
ev.stopPropagation();
|
|
17610
|
+
let content;
|
|
17611
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
17612
|
+
content = ev.data || "";
|
|
17613
|
+
}
|
|
17614
|
+
else {
|
|
17615
|
+
const el = this.composerRef.el;
|
|
17616
|
+
content = el.childNodes.length ? el.textContent : "";
|
|
17617
|
+
}
|
|
17618
|
+
if (this.props.focus === "inactive") {
|
|
17619
|
+
return (_b = (_a = this.props).onComposerCellFocused) === null || _b === void 0 ? void 0 : _b.call(_a, content);
|
|
17620
|
+
}
|
|
17581
17621
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
17582
|
-
const el = this.composerRef.el;
|
|
17583
17622
|
this.env.model.dispatch("SET_CURRENT_CONTENT", {
|
|
17584
|
-
content
|
|
17623
|
+
content,
|
|
17585
17624
|
selection: this.contentHelper.getCurrentSelection(),
|
|
17586
17625
|
});
|
|
17587
17626
|
}
|
|
@@ -17641,9 +17680,8 @@ class Composer extends owl.Component {
|
|
|
17641
17680
|
}
|
|
17642
17681
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
17643
17682
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
17644
|
-
|
|
17645
|
-
|
|
17646
|
-
}
|
|
17683
|
+
this.props.onComposerContentFocused();
|
|
17684
|
+
if (this.props.focus === "inactive") ;
|
|
17647
17685
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
17648
17686
|
this.processTokenAtCursor();
|
|
17649
17687
|
}
|
|
@@ -17660,6 +17698,7 @@ class Composer extends owl.Component {
|
|
|
17660
17698
|
this.contentHelper.removeAll(); // removes the content of the composer, to be added just after
|
|
17661
17699
|
this.shouldProcessInputEvents = false;
|
|
17662
17700
|
if (this.props.focus !== "inactive") {
|
|
17701
|
+
this.contentHelper.el.focus();
|
|
17663
17702
|
this.contentHelper.selectRange(0, 0); // move the cursor inside the composer at 0 0.
|
|
17664
17703
|
}
|
|
17665
17704
|
const content = this.getContent();
|
|
@@ -17826,18 +17865,18 @@ Composer.template = "o-spreadsheet-Composer";
|
|
|
17826
17865
|
Composer.components = { TextValueProvider, FunctionDescriptionProvider };
|
|
17827
17866
|
Composer.defaultProps = {
|
|
17828
17867
|
inputStyle: "",
|
|
17868
|
+
isDefaultFocus: false,
|
|
17829
17869
|
};
|
|
17830
17870
|
Composer.props = {
|
|
17831
17871
|
inputStyle: { type: String, optional: true },
|
|
17832
17872
|
rect: { type: Object, optional: true },
|
|
17833
17873
|
delimitation: { type: Object, optional: true },
|
|
17834
17874
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
17835
|
-
|
|
17875
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
17836
17876
|
onComposerContentFocused: Function,
|
|
17877
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
17837
17878
|
};
|
|
17838
17879
|
|
|
17839
|
-
const SCROLLBAR_WIDTH = 14;
|
|
17840
|
-
const SCROLLBAR_HIGHT = 15;
|
|
17841
17880
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
17842
17881
|
css /* scss */ `
|
|
17843
17882
|
div.o-grid-composer {
|
|
@@ -17852,35 +17891,52 @@ css /* scss */ `
|
|
|
17852
17891
|
* It also applies the style of the cell to the composer input.
|
|
17853
17892
|
*/
|
|
17854
17893
|
class GridComposer extends owl.Component {
|
|
17894
|
+
constructor() {
|
|
17895
|
+
super(...arguments);
|
|
17896
|
+
this.rect = undefined;
|
|
17897
|
+
this.isEditing = false;
|
|
17898
|
+
}
|
|
17899
|
+
get defaultRect() {
|
|
17900
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
17901
|
+
}
|
|
17855
17902
|
setup() {
|
|
17856
|
-
|
|
17857
|
-
|
|
17858
|
-
|
|
17859
|
-
|
|
17860
|
-
|
|
17861
|
-
|
|
17862
|
-
|
|
17863
|
-
|
|
17864
|
-
|
|
17865
|
-
|
|
17866
|
-
|
|
17867
|
-
|
|
17868
|
-
|
|
17869
|
-
const maxWidth = el.parentElement.clientWidth - this.rect.x - SCROLLBAR_WIDTH;
|
|
17870
|
-
el.style.maxWidth = (maxWidth + "px");
|
|
17871
|
-
this.composerState.rect = {
|
|
17872
|
-
x: this.rect.x,
|
|
17873
|
-
y: this.rect.y,
|
|
17874
|
-
width: el.clientWidth,
|
|
17875
|
-
height: el.clientHeight,
|
|
17876
|
-
};
|
|
17877
|
-
this.composerState.delimitation = {
|
|
17878
|
-
width: el.parentElement.clientWidth,
|
|
17879
|
-
height: el.parentElement.clientHeight,
|
|
17880
|
-
};
|
|
17903
|
+
owl.onWillUpdateProps(() => {
|
|
17904
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
17905
|
+
if (this.isEditing !== isEditing) {
|
|
17906
|
+
this.isEditing = isEditing;
|
|
17907
|
+
if (!isEditing) {
|
|
17908
|
+
this.rect = undefined;
|
|
17909
|
+
this.env.focusableElement.focus();
|
|
17910
|
+
return;
|
|
17911
|
+
}
|
|
17912
|
+
const position = this.env.model.getters.getActivePosition();
|
|
17913
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
17914
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
17915
|
+
}
|
|
17881
17916
|
});
|
|
17882
17917
|
}
|
|
17918
|
+
get composerProps() {
|
|
17919
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
17920
|
+
return {
|
|
17921
|
+
rect: this.rect && { ...this.rect },
|
|
17922
|
+
delimitation: {
|
|
17923
|
+
width,
|
|
17924
|
+
height,
|
|
17925
|
+
},
|
|
17926
|
+
inputStyle: this.composerStyle,
|
|
17927
|
+
focus: this.props.focus,
|
|
17928
|
+
isDefaultFocus: true,
|
|
17929
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
17930
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
17931
|
+
};
|
|
17932
|
+
}
|
|
17883
17933
|
get containerStyle() {
|
|
17934
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
17935
|
+
return `
|
|
17936
|
+
position: absolute;
|
|
17937
|
+
z-index: -1000;
|
|
17938
|
+
`;
|
|
17939
|
+
}
|
|
17884
17940
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
17885
17941
|
const cell = this.env.model.getters.getActiveCell();
|
|
17886
17942
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -17900,12 +17956,18 @@ class GridComposer extends owl.Component {
|
|
|
17900
17956
|
if (!isFormula) {
|
|
17901
17957
|
textAlign = style.align || cell.defaultAlign;
|
|
17902
17958
|
}
|
|
17959
|
+
const sheetDimensions = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
17960
|
+
const maxWidth = sheetDimensions.width - this.rect.x;
|
|
17961
|
+
const maxHeight = sheetDimensions.height - this.rect.y;
|
|
17903
17962
|
return `
|
|
17904
17963
|
left: ${left - 1}px;
|
|
17905
17964
|
top: ${top}px;
|
|
17906
17965
|
min-width: ${width + 2}px;
|
|
17907
17966
|
min-height: ${height + 1}px;
|
|
17908
17967
|
|
|
17968
|
+
max-width: ${maxWidth}px;
|
|
17969
|
+
max-height: ${maxHeight}px;
|
|
17970
|
+
|
|
17909
17971
|
background: ${background};
|
|
17910
17972
|
color: ${color};
|
|
17911
17973
|
|
|
@@ -17929,8 +17991,8 @@ GridComposer.template = "o-spreadsheet-GridComposer";
|
|
|
17929
17991
|
GridComposer.components = { Composer };
|
|
17930
17992
|
GridComposer.props = {
|
|
17931
17993
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
17932
|
-
onComposerUnmounted: Function,
|
|
17933
17994
|
onComposerContentFocused: Function,
|
|
17995
|
+
onComposerCellFocused: Function,
|
|
17934
17996
|
};
|
|
17935
17997
|
|
|
17936
17998
|
const CSS$2 = css /* scss */ `
|
|
@@ -22692,7 +22754,6 @@ class GridOverlay extends owl.Component {
|
|
|
22692
22754
|
this.props.onCellDoubleClicked(col, row);
|
|
22693
22755
|
}
|
|
22694
22756
|
onContextMenu(ev) {
|
|
22695
|
-
ev.preventDefault();
|
|
22696
22757
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
22697
22758
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
22698
22759
|
}
|
|
@@ -23626,8 +23687,8 @@ css /* scss */ `
|
|
|
23626
23687
|
&.corner {
|
|
23627
23688
|
right: 0px;
|
|
23628
23689
|
bottom: 0px;
|
|
23629
|
-
height: ${SCROLLBAR_WIDTH
|
|
23630
|
-
width: ${SCROLLBAR_WIDTH
|
|
23690
|
+
height: ${SCROLLBAR_WIDTH}px;
|
|
23691
|
+
width: ${SCROLLBAR_WIDTH}px;
|
|
23631
23692
|
border-top: 1px solid #e2e3e3;
|
|
23632
23693
|
border-left: 1px solid #e2e3e3;
|
|
23633
23694
|
}
|
|
@@ -23700,7 +23761,7 @@ class HorizontalScrollBar extends owl.Component {
|
|
|
23700
23761
|
return {
|
|
23701
23762
|
left: `${this.props.leftOffset + x}px`,
|
|
23702
23763
|
bottom: "0px",
|
|
23703
|
-
height: `${SCROLLBAR_WIDTH
|
|
23764
|
+
height: `${SCROLLBAR_WIDTH}px`,
|
|
23704
23765
|
right: `0px`,
|
|
23705
23766
|
};
|
|
23706
23767
|
}
|
|
@@ -23745,7 +23806,7 @@ class VerticalScrollBar extends owl.Component {
|
|
|
23745
23806
|
return {
|
|
23746
23807
|
top: `${this.props.topOffset + y}px`,
|
|
23747
23808
|
right: "0px",
|
|
23748
|
-
width: `${SCROLLBAR_WIDTH
|
|
23809
|
+
width: `${SCROLLBAR_WIDTH}px`,
|
|
23749
23810
|
bottom: `0px`,
|
|
23750
23811
|
};
|
|
23751
23812
|
}
|
|
@@ -23919,17 +23980,16 @@ class Grid extends owl.Component {
|
|
|
23919
23980
|
menuItems: [],
|
|
23920
23981
|
});
|
|
23921
23982
|
this.gridRef = owl.useRef("grid");
|
|
23922
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
23923
23983
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
23924
23984
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
23925
23985
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
23926
23986
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
23927
23987
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
23928
23988
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
23929
|
-
owl.onMounted(() => this.
|
|
23930
|
-
this.props.exposeFocus(() => this.
|
|
23989
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
23990
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
23931
23991
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
23932
|
-
owl.useEffect(() => this.
|
|
23992
|
+
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
23933
23993
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
23934
23994
|
this.moveCanvas(deltaX, deltaY);
|
|
23935
23995
|
this.hoveredCell.col = undefined;
|
|
@@ -23944,21 +24004,20 @@ class Grid extends owl.Component {
|
|
|
23944
24004
|
return `
|
|
23945
24005
|
top: ${HEADER_HEIGHT}px;
|
|
23946
24006
|
left: ${HEADER_WIDTH}px;
|
|
23947
|
-
height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH
|
|
23948
|
-
width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH
|
|
24007
|
+
height: calc(100% - ${HEADER_HEIGHT + SCROLLBAR_WIDTH}px);
|
|
24008
|
+
width: calc(100% - ${HEADER_WIDTH + SCROLLBAR_WIDTH}px);
|
|
23949
24009
|
`;
|
|
23950
24010
|
}
|
|
23951
24011
|
onClosePopover() {
|
|
23952
24012
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
23953
24013
|
this.closeOpenedPopover();
|
|
23954
24014
|
}
|
|
23955
|
-
this.
|
|
24015
|
+
this.focusDefaultElement();
|
|
23956
24016
|
}
|
|
23957
|
-
|
|
23958
|
-
var _a;
|
|
24017
|
+
focusDefaultElement() {
|
|
23959
24018
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
23960
24019
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
23961
|
-
|
|
24020
|
+
this.env.focusableElement.focus();
|
|
23962
24021
|
}
|
|
23963
24022
|
}
|
|
23964
24023
|
get gridEl() {
|
|
@@ -24103,19 +24162,6 @@ class Grid extends owl.Component {
|
|
|
24103
24162
|
return;
|
|
24104
24163
|
}
|
|
24105
24164
|
}
|
|
24106
|
-
onInput(ev) {
|
|
24107
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
24108
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
24109
|
-
return;
|
|
24110
|
-
}
|
|
24111
|
-
if (ev.data) {
|
|
24112
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
24113
|
-
// character
|
|
24114
|
-
ev.preventDefault();
|
|
24115
|
-
ev.stopPropagation();
|
|
24116
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
24117
|
-
}
|
|
24118
|
-
}
|
|
24119
24165
|
// ---------------------------------------------------------------------------
|
|
24120
24166
|
// Context Menu
|
|
24121
24167
|
// ---------------------------------------------------------------------------
|
|
@@ -24212,7 +24258,7 @@ class Grid extends owl.Component {
|
|
|
24212
24258
|
}
|
|
24213
24259
|
closeMenu() {
|
|
24214
24260
|
this.menuState.isOpen = false;
|
|
24215
|
-
this.
|
|
24261
|
+
this.focusDefaultElement();
|
|
24216
24262
|
}
|
|
24217
24263
|
}
|
|
24218
24264
|
Grid.template = "o-spreadsheet-Grid";
|
|
@@ -27525,7 +27571,7 @@ function normalizeV9(formula) {
|
|
|
27525
27571
|
* a breaking change is made in the way the state is handled, and an upgrade
|
|
27526
27572
|
* function should be defined
|
|
27527
27573
|
*/
|
|
27528
|
-
const CURRENT_VERSION = 12;
|
|
27574
|
+
const CURRENT_VERSION = 12.5;
|
|
27529
27575
|
const INITIAL_SHEET_ID = "Sheet1";
|
|
27530
27576
|
/**
|
|
27531
27577
|
* This function tries to load anything that could look like a valid
|
|
@@ -27791,6 +27837,31 @@ const MIGRATIONS = [
|
|
|
27791
27837
|
return data;
|
|
27792
27838
|
},
|
|
27793
27839
|
},
|
|
27840
|
+
{
|
|
27841
|
+
description: "Fix datafilter duplication",
|
|
27842
|
+
from: 12,
|
|
27843
|
+
to: 12.5,
|
|
27844
|
+
applyMigration(data) {
|
|
27845
|
+
for (let sheet of data.sheets || []) {
|
|
27846
|
+
let knownDataFilterZones = [];
|
|
27847
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
27848
|
+
const zone = toZone(filterTable.range);
|
|
27849
|
+
// See commit message for the details
|
|
27850
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
27851
|
+
if (intersectZoneIndex !== -1) {
|
|
27852
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
27853
|
+
}
|
|
27854
|
+
else {
|
|
27855
|
+
knownDataFilterZones.push(zone);
|
|
27856
|
+
}
|
|
27857
|
+
}
|
|
27858
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
27859
|
+
range: zoneToXc(zone),
|
|
27860
|
+
}));
|
|
27861
|
+
}
|
|
27862
|
+
return data;
|
|
27863
|
+
},
|
|
27864
|
+
},
|
|
27794
27865
|
];
|
|
27795
27866
|
/**
|
|
27796
27867
|
* This function is used to repair faulty data independently of the migration.
|
|
@@ -28555,9 +28626,9 @@ class CellPlugin extends CorePlugin {
|
|
|
28555
28626
|
allowDispatch(cmd) {
|
|
28556
28627
|
switch (cmd.type) {
|
|
28557
28628
|
case "UPDATE_CELL":
|
|
28558
|
-
return this.
|
|
28629
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
28559
28630
|
case "CLEAR_CELL":
|
|
28560
|
-
return this.checkValidations(cmd, this.
|
|
28631
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
28561
28632
|
default:
|
|
28562
28633
|
return 0 /* CommandResult.Success */;
|
|
28563
28634
|
}
|
|
@@ -28723,13 +28794,13 @@ class CellPlugin extends CorePlugin {
|
|
|
28723
28794
|
/*
|
|
28724
28795
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
28725
28796
|
*/
|
|
28726
|
-
buildFormulaContent(sheetId, cell, dependencies) {
|
|
28797
|
+
buildFormulaContent(sheetId, cell, dependencies, useFixedZone = false) {
|
|
28727
28798
|
const ranges = dependencies || cell.dependencies;
|
|
28728
28799
|
let rangeIndex = 0;
|
|
28729
28800
|
return concat(cell.compiledFormula.tokens.map((token) => {
|
|
28730
28801
|
if (token.type === "REFERENCE") {
|
|
28731
28802
|
const range = ranges[rangeIndex++];
|
|
28732
|
-
return this.getters.getRangeString(range, sheetId);
|
|
28803
|
+
return this.getters.getRangeString(range, sheetId, useFixedZone);
|
|
28733
28804
|
}
|
|
28734
28805
|
return token.value;
|
|
28735
28806
|
}));
|
|
@@ -28976,6 +29047,18 @@ class CellPlugin extends CorePlugin {
|
|
|
28976
29047
|
}
|
|
28977
29048
|
return 0 /* CommandResult.Success */;
|
|
28978
29049
|
}
|
|
29050
|
+
checkUselessUpdateCell(cmd) {
|
|
29051
|
+
const cell = this.getters.getCell(cmd);
|
|
29052
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
29053
|
+
const hasStyle = "style" in cmd;
|
|
29054
|
+
const hasFormat = "format" in cmd;
|
|
29055
|
+
if ((!hasContent || (cell === null || cell === void 0 ? void 0 : cell.content) === cmd.content) &&
|
|
29056
|
+
(!hasStyle || deepEquals(cell === null || cell === void 0 ? void 0 : cell.style, cmd.style)) &&
|
|
29057
|
+
(!hasFormat || (cell === null || cell === void 0 ? void 0 : cell.format) === cmd.format)) {
|
|
29058
|
+
return 89 /* CommandResult.NoChanges */;
|
|
29059
|
+
}
|
|
29060
|
+
return 0 /* CommandResult.Success */;
|
|
29061
|
+
}
|
|
28979
29062
|
}
|
|
28980
29063
|
CellPlugin.getters = [
|
|
28981
29064
|
"zoneToXC",
|
|
@@ -29302,7 +29385,13 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
29302
29385
|
}
|
|
29303
29386
|
}
|
|
29304
29387
|
exportForExcel(data) {
|
|
29305
|
-
|
|
29388
|
+
if (data.sheets) {
|
|
29389
|
+
for (let sheet of data.sheets) {
|
|
29390
|
+
if (this.cfRules[sheet.id]) {
|
|
29391
|
+
sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
|
|
29392
|
+
}
|
|
29393
|
+
}
|
|
29394
|
+
}
|
|
29306
29395
|
}
|
|
29307
29396
|
// ---------------------------------------------------------------------------
|
|
29308
29397
|
// Getters
|
|
@@ -29352,11 +29441,11 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
29352
29441
|
// ---------------------------------------------------------------------------
|
|
29353
29442
|
// Private
|
|
29354
29443
|
// ---------------------------------------------------------------------------
|
|
29355
|
-
mapToConditionalFormat(sheetId, cf) {
|
|
29444
|
+
mapToConditionalFormat(sheetId, cf, options = { useFixedReference: false }) {
|
|
29356
29445
|
return {
|
|
29357
29446
|
...cf,
|
|
29358
29447
|
ranges: cf.ranges.map((range) => {
|
|
29359
|
-
return this.getters.getRangeString(range, sheetId);
|
|
29448
|
+
return this.getters.getRangeString(range, sheetId, options.useFixedReference);
|
|
29360
29449
|
}),
|
|
29361
29450
|
};
|
|
29362
29451
|
}
|
|
@@ -31267,8 +31356,9 @@ class RangeAdapter {
|
|
|
31267
31356
|
*
|
|
31268
31357
|
* @param range the range (received from getRangeFromXC or getRangeFromZone)
|
|
31269
31358
|
* @param forSheetId the id of the sheet where the range string is supposed to be used.
|
|
31359
|
+
* @param [useFixedZone=false] if true, the range will be returned with fixed row and column
|
|
31270
31360
|
*/
|
|
31271
|
-
getRangeString(range, forSheetId) {
|
|
31361
|
+
getRangeString(range, forSheetId, useFixedZone = false) {
|
|
31272
31362
|
if (!range) {
|
|
31273
31363
|
return INCORRECT_RANGE_STRING;
|
|
31274
31364
|
}
|
|
@@ -31295,7 +31385,7 @@ class RangeAdapter {
|
|
|
31295
31385
|
if (prefixSheet && !sheetName) {
|
|
31296
31386
|
return INCORRECT_RANGE_STRING;
|
|
31297
31387
|
}
|
|
31298
|
-
let rangeString = this.getRangePartString(rangeImpl, 0);
|
|
31388
|
+
let rangeString = this.getRangePartString(rangeImpl, 0, useFixedZone);
|
|
31299
31389
|
if (rangeImpl.parts && rangeImpl.parts.length === 2) {
|
|
31300
31390
|
// this if converts A2:A2 into A2 except if any part of the original range had fixed row or column (with $)
|
|
31301
31391
|
if (rangeImpl.zone.top !== rangeImpl.zone.bottom ||
|
|
@@ -31305,7 +31395,7 @@ class RangeAdapter {
|
|
|
31305
31395
|
rangeImpl.parts[1].rowFixed ||
|
|
31306
31396
|
rangeImpl.parts[1].colFixed) {
|
|
31307
31397
|
rangeString += ":";
|
|
31308
|
-
rangeString += this.getRangePartString(rangeImpl, 1);
|
|
31398
|
+
rangeString += this.getRangePartString(rangeImpl, 1, useFixedZone);
|
|
31309
31399
|
}
|
|
31310
31400
|
}
|
|
31311
31401
|
return `${prefixSheet ? sheetName + "!" : ""}${rangeString}`;
|
|
@@ -31335,14 +31425,14 @@ class RangeAdapter {
|
|
|
31335
31425
|
/**
|
|
31336
31426
|
* Get a Xc string that represent a part of a range
|
|
31337
31427
|
*/
|
|
31338
|
-
getRangePartString(range, part) {
|
|
31428
|
+
getRangePartString(range, part, useFixedZone = false) {
|
|
31339
31429
|
var _a, _b;
|
|
31340
31430
|
const colFixed = range.parts && ((_a = range.parts[part]) === null || _a === void 0 ? void 0 : _a.colFixed) ? "$" : "";
|
|
31341
31431
|
const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
|
|
31342
31432
|
const rowFixed = range.parts && ((_b = range.parts[part]) === null || _b === void 0 ? void 0 : _b.rowFixed) ? "$" : "";
|
|
31343
31433
|
const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
|
|
31344
31434
|
let str = "";
|
|
31345
|
-
if (range.isFullCol) {
|
|
31435
|
+
if (range.isFullCol && !useFixedZone) {
|
|
31346
31436
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
31347
31437
|
str = colFixed + col + rowFixed + row;
|
|
31348
31438
|
}
|
|
@@ -31350,7 +31440,7 @@ class RangeAdapter {
|
|
|
31350
31440
|
str = colFixed + col;
|
|
31351
31441
|
}
|
|
31352
31442
|
}
|
|
31353
|
-
else if (range.isFullRow) {
|
|
31443
|
+
else if (range.isFullRow && !useFixedZone) {
|
|
31354
31444
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
31355
31445
|
str = colFixed + col + rowFixed + row;
|
|
31356
31446
|
}
|
|
@@ -32725,6 +32815,10 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32725
32815
|
if (cell.format !== evaluatedCell.format) {
|
|
32726
32816
|
exportedCellData.computedFormat = evaluatedCell.format;
|
|
32727
32817
|
}
|
|
32818
|
+
// if there is a formula but no dependencies (maybe because the cell is in error), no need to recompute the formula text
|
|
32819
|
+
if (cell.isFormula && cell.dependencies.length) {
|
|
32820
|
+
exportedCellData.content = this.getters.buildFormulaContent(sheet.id, cell, cell.dependencies, true);
|
|
32821
|
+
}
|
|
32728
32822
|
}
|
|
32729
32823
|
}
|
|
32730
32824
|
}
|
|
@@ -34585,8 +34679,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
34585
34679
|
let row = zone.bottom;
|
|
34586
34680
|
if (col > 0) {
|
|
34587
34681
|
let leftPosition = { sheetId, col: col - 1, row };
|
|
34588
|
-
while (this.getters.
|
|
34589
|
-
((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
|
|
34682
|
+
while ((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content) {
|
|
34590
34683
|
row += 1;
|
|
34591
34684
|
leftPosition = { sheetId, col: col - 1, row };
|
|
34592
34685
|
}
|
|
@@ -34595,8 +34688,7 @@ class AutofillPlugin extends UIPlugin {
|
|
|
34595
34688
|
col = zone.right;
|
|
34596
34689
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
34597
34690
|
let rightPosition = { sheetId, col: col + 1, row };
|
|
34598
|
-
while (this.getters.
|
|
34599
|
-
((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
|
|
34691
|
+
while ((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content) {
|
|
34600
34692
|
row += 1;
|
|
34601
34693
|
rightPosition = { sheetId, col: col + 1, row };
|
|
34602
34694
|
}
|
|
@@ -36288,9 +36380,6 @@ class SelectionInputPlugin extends UIPlugin {
|
|
|
36288
36380
|
}
|
|
36289
36381
|
}
|
|
36290
36382
|
}
|
|
36291
|
-
unsubscribe() {
|
|
36292
|
-
this.unfocus();
|
|
36293
|
-
}
|
|
36294
36383
|
// ---------------------------------------------------------------------------
|
|
36295
36384
|
// Getters || only callable by the parent
|
|
36296
36385
|
// ---------------------------------------------------------------------------
|
|
@@ -36497,9 +36586,9 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
36497
36586
|
break;
|
|
36498
36587
|
case "FOCUS_RANGE":
|
|
36499
36588
|
case "CHANGE_RANGE":
|
|
36500
|
-
|
|
36501
|
-
|
|
36502
|
-
|
|
36589
|
+
const input = this.inputs[cmd.id];
|
|
36590
|
+
const range = input.ranges.find((range) => range.id === cmd.rangeId);
|
|
36591
|
+
if (range) {
|
|
36503
36592
|
const sheetId = this.getters.getActiveSheetId();
|
|
36504
36593
|
const zone = this.getters.getRangeFromSheetXC(sheetId, (range === null || range === void 0 ? void 0 : range.xc) || "A1").zone;
|
|
36505
36594
|
this.selection.capture(input, { cell: { col: zone.left, row: zone.top }, zone }, { handleEvent: input.handleEvent.bind(input) });
|
|
@@ -36509,9 +36598,6 @@ class SelectionInputsManagerPlugin extends UIPlugin {
|
|
|
36509
36598
|
}
|
|
36510
36599
|
(_a = this.currentInput) === null || _a === void 0 ? void 0 : _a.handle(cmd);
|
|
36511
36600
|
}
|
|
36512
|
-
unsubscribe() {
|
|
36513
|
-
this.unfocus();
|
|
36514
|
-
}
|
|
36515
36601
|
// ---------------------------------------------------------------------------
|
|
36516
36602
|
// Getters
|
|
36517
36603
|
// ---------------------------------------------------------------------------
|
|
@@ -39582,6 +39668,19 @@ class ImageProvider {
|
|
|
39582
39668
|
}
|
|
39583
39669
|
}
|
|
39584
39670
|
|
|
39671
|
+
class FocusableElement {
|
|
39672
|
+
constructor() {
|
|
39673
|
+
this.focusableElement = undefined;
|
|
39674
|
+
}
|
|
39675
|
+
setFocusableElement(element) {
|
|
39676
|
+
this.focusableElement = element;
|
|
39677
|
+
}
|
|
39678
|
+
focus() {
|
|
39679
|
+
var _a;
|
|
39680
|
+
(_a = this.focusableElement) === null || _a === void 0 ? void 0 : _a.focus();
|
|
39681
|
+
}
|
|
39682
|
+
}
|
|
39683
|
+
|
|
39585
39684
|
// -----------------------------------------------------------------------------
|
|
39586
39685
|
// SpreadSheet
|
|
39587
39686
|
// -----------------------------------------------------------------------------
|
|
@@ -40825,8 +40924,8 @@ css /* scss */ `
|
|
|
40825
40924
|
&.corner {
|
|
40826
40925
|
right: 0px;
|
|
40827
40926
|
bottom: 0px;
|
|
40828
|
-
height: ${SCROLLBAR_WIDTH
|
|
40829
|
-
width: ${SCROLLBAR_WIDTH
|
|
40927
|
+
height: ${SCROLLBAR_WIDTH}px;
|
|
40928
|
+
width: ${SCROLLBAR_WIDTH}px;
|
|
40830
40929
|
border-top: 1px solid #e2e3e3;
|
|
40831
40930
|
border-left: 1px solid #e2e3e3;
|
|
40832
40931
|
}
|
|
@@ -40873,6 +40972,7 @@ class Spreadsheet extends owl.Component {
|
|
|
40873
40972
|
toggleSidePanel: this.toggleSidePanel.bind(this),
|
|
40874
40973
|
_t: Spreadsheet._t,
|
|
40875
40974
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
40975
|
+
focusableElement: new FocusableElement(),
|
|
40876
40976
|
});
|
|
40877
40977
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
40878
40978
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
@@ -40971,17 +41071,18 @@ class Spreadsheet extends owl.Component {
|
|
|
40971
41071
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
40972
41072
|
this.composer.topBarFocus = "contentFocus";
|
|
40973
41073
|
this.composer.gridFocusMode = "inactive";
|
|
40974
|
-
this.setComposerContent({ selection }
|
|
41074
|
+
this.setComposerContent({ selection });
|
|
40975
41075
|
}
|
|
40976
|
-
onGridComposerContentFocused() {
|
|
41076
|
+
onGridComposerContentFocused(selection) {
|
|
40977
41077
|
if (this.model.getters.isReadonly()) {
|
|
40978
41078
|
return;
|
|
40979
41079
|
}
|
|
40980
41080
|
this.model.dispatch("UNFOCUS_SELECTION_INPUT");
|
|
40981
41081
|
this.composer.topBarFocus = "inactive";
|
|
40982
41082
|
this.composer.gridFocusMode = "contentFocus";
|
|
40983
|
-
this.setComposerContent({});
|
|
41083
|
+
this.setComposerContent({ selection });
|
|
40984
41084
|
}
|
|
41085
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
40985
41086
|
onGridComposerCellFocused(content, selection) {
|
|
40986
41087
|
if (this.model.getters.isReadonly()) {
|
|
40987
41088
|
return;
|
|
@@ -41962,18 +42063,17 @@ class EventStream {
|
|
|
41962
42063
|
if (this.observers.find((sub) => sub.owner === owner)) {
|
|
41963
42064
|
throw new Error("You are already subscribed forever");
|
|
41964
42065
|
}
|
|
41965
|
-
if ((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) {
|
|
42066
|
+
if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) && this.mainSubscription.owner !== owner) {
|
|
41966
42067
|
(_c = (_b = this.mainSubscription.callbacks).release) === null || _c === void 0 ? void 0 : _c.call(_b);
|
|
41967
42068
|
}
|
|
41968
42069
|
this.mainSubscription = { owner, callbacks };
|
|
41969
42070
|
}
|
|
41970
42071
|
release(owner) {
|
|
41971
|
-
var _a
|
|
42072
|
+
var _a;
|
|
41972
42073
|
if (((_a = this.mainSubscription) === null || _a === void 0 ? void 0 : _a.owner) !== owner ||
|
|
41973
42074
|
this.observers.find((sub) => sub.owner === owner)) {
|
|
41974
42075
|
return;
|
|
41975
42076
|
}
|
|
41976
|
-
(_d = (_b = this.mainSubscription) === null || _b === void 0 ? void 0 : (_c = _b.callbacks).release) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
41977
42077
|
this.mainSubscription = this.defaultSubscription;
|
|
41978
42078
|
}
|
|
41979
42079
|
/**
|
|
@@ -42441,11 +42541,10 @@ class SelectionStreamProcessor {
|
|
|
42441
42541
|
* next cluster if the given cell is outside a cluster or at the border of a cluster in the given direction.
|
|
42442
42542
|
*/
|
|
42443
42543
|
getEndOfCluster(startPosition, dim, dir) {
|
|
42444
|
-
const sheet = this.getters.getActiveSheet();
|
|
42445
42544
|
let currentPosition = startPosition;
|
|
42446
42545
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
42447
42546
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
42448
|
-
let mode = !this.
|
|
42547
|
+
let mode = !this.isEvaluatedCellEmpty(currentPosition) && !this.isEvaluatedCellEmpty(nextCellPosition)
|
|
42449
42548
|
? "endOfCluster"
|
|
42450
42549
|
: "nextCluster";
|
|
42451
42550
|
while (true) {
|
|
@@ -42455,7 +42554,7 @@ class SelectionStreamProcessor {
|
|
|
42455
42554
|
currentPosition.row === nextCellPosition.row) {
|
|
42456
42555
|
break;
|
|
42457
42556
|
}
|
|
42458
|
-
const isNextCellEmpty = this.
|
|
42557
|
+
const isNextCellEmpty = this.isEvaluatedCellEmpty(nextCellPosition);
|
|
42459
42558
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
42460
42559
|
break;
|
|
42461
42560
|
}
|
|
@@ -42469,14 +42568,25 @@ class SelectionStreamProcessor {
|
|
|
42469
42568
|
return dim === "cols" ? currentPosition.col : currentPosition.row;
|
|
42470
42569
|
}
|
|
42471
42570
|
/**
|
|
42472
|
-
* Check if a cell is empty
|
|
42473
|
-
* check
|
|
42571
|
+
* Check if a cell evaluated value is empty. If the cell is part of a merge,
|
|
42572
|
+
* the check applies to the main cell of the merge.
|
|
42474
42573
|
*/
|
|
42475
|
-
|
|
42574
|
+
isEvaluatedCellEmpty({ col, row }) {
|
|
42575
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
42476
42576
|
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
42477
42577
|
const cell = this.getters.getEvaluatedCell(position);
|
|
42478
42578
|
return cell.type === CellValueType.empty;
|
|
42479
42579
|
}
|
|
42580
|
+
/**
|
|
42581
|
+
* Checks if a cell is empty (i.e. does not have a content). If the cell is part of a merge,
|
|
42582
|
+
* the check applies to the main cell of the merge.
|
|
42583
|
+
*/
|
|
42584
|
+
isCellEmpty({ col, row }) {
|
|
42585
|
+
var _a;
|
|
42586
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
42587
|
+
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
42588
|
+
return !((_a = this.getters.getCell(position)) === null || _a === void 0 ? void 0 : _a.content);
|
|
42589
|
+
}
|
|
42480
42590
|
/** Computes the next cell position in the given direction by crossing through merges and skipping hidden cells.
|
|
42481
42591
|
*
|
|
42482
42592
|
* This has the same behaviour as getNextAvailablePosition() for certain arguments, but use this method instead
|
|
@@ -42955,12 +43065,7 @@ function addFormula(cell) {
|
|
|
42955
43065
|
attrs.push(["t", "str"]);
|
|
42956
43066
|
cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
|
|
42957
43067
|
}
|
|
42958
|
-
node = escapeXml /*xml*/
|
|
42959
|
-
<f>
|
|
42960
|
-
${XlsxFormula}
|
|
42961
|
-
</f>
|
|
42962
|
-
${cycle}
|
|
42963
|
-
`;
|
|
43068
|
+
node = escapeXml /*xml*/ `<f> ${XlsxFormula} </f> ${cycle}`;
|
|
42964
43069
|
return { attrs, node };
|
|
42965
43070
|
}
|
|
42966
43071
|
else {
|
|
@@ -43701,11 +43806,10 @@ function addRows(construct, data, sheet) {
|
|
|
43701
43806
|
({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader));
|
|
43702
43807
|
}
|
|
43703
43808
|
attributes.push(...additionalAttrs);
|
|
43704
|
-
|
|
43705
|
-
|
|
43706
|
-
|
|
43707
|
-
|
|
43708
|
-
`);
|
|
43809
|
+
// prettier-ignore
|
|
43810
|
+
cellNodes.push(escapeXml /*xml*/ `<c ${formatAttributes(attributes)}>
|
|
43811
|
+
${cellNode}
|
|
43812
|
+
</c>`);
|
|
43709
43813
|
}
|
|
43710
43814
|
}
|
|
43711
43815
|
if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden) {
|
|
@@ -44462,7 +44566,7 @@ const SPREADSHEET_DIMENSIONS = {
|
|
|
44462
44566
|
BOTTOMBAR_HEIGHT,
|
|
44463
44567
|
DEFAULT_CELL_WIDTH,
|
|
44464
44568
|
DEFAULT_CELL_HEIGHT,
|
|
44465
|
-
SCROLLBAR_WIDTH
|
|
44569
|
+
SCROLLBAR_WIDTH,
|
|
44466
44570
|
};
|
|
44467
44571
|
const registries = {
|
|
44468
44572
|
autofillModifiersRegistry,
|
|
@@ -44577,6 +44681,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
44577
44681
|
exports.tokenize = tokenize;
|
|
44578
44682
|
|
|
44579
44683
|
|
|
44580
|
-
__info__.version = '16.1.
|
|
44581
|
-
__info__.date = '2024-
|
|
44582
|
-
__info__.hash = '
|
|
44684
|
+
__info__.version = '16.1.36';
|
|
44685
|
+
__info__.date = '2024-02-16T14:16:11.082Z';
|
|
44686
|
+
__info__.hash = 'ad5301c';
|