@odoo/o-spreadsheet 17.0.9 → 17.0.12
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 +363 -232
- package/dist/o-spreadsheet.d.ts +39 -18
- package/dist/o-spreadsheet.esm.js +363 -232
- package/dist/o-spreadsheet.iife.js +363 -232
- package/dist/o-spreadsheet.iife.min.js +262 -268
- package/dist/o_spreadsheet.xml +19 -36
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.0.
|
|
6
|
-
* @date 2024-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.12
|
|
6
|
+
* @date 2024-02-16T14:24:02.984Z
|
|
7
|
+
* @hash 8fa2bab
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -551,8 +551,8 @@
|
|
|
551
551
|
* If the given item does not exist in the dictionary, it creates one with a new id.
|
|
552
552
|
*/
|
|
553
553
|
function getItemId(item, itemsDic) {
|
|
554
|
-
for (
|
|
555
|
-
if (deepEquals(
|
|
554
|
+
for (const key in itemsDic) {
|
|
555
|
+
if (deepEquals(itemsDic[key], item)) {
|
|
556
556
|
return parseInt(key, 10);
|
|
557
557
|
}
|
|
558
558
|
}
|
|
@@ -651,11 +651,13 @@
|
|
|
651
651
|
if (typeof o1 !== "object")
|
|
652
652
|
return o1 === o2;
|
|
653
653
|
// Objects can have different keys if the values are undefined
|
|
654
|
-
const
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
654
|
+
for (const key in o2) {
|
|
655
|
+
if (!(key in o1) && o2[key] !== undefined) {
|
|
656
|
+
return false;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
for (const key in o1) {
|
|
660
|
+
if (typeof o1[key] !== typeof o2[key])
|
|
659
661
|
return false;
|
|
660
662
|
if (typeof o1[key] === "object") {
|
|
661
663
|
if (!deepEquals(o1[key], o2[key]))
|
|
@@ -725,18 +727,18 @@
|
|
|
725
727
|
return true;
|
|
726
728
|
}
|
|
727
729
|
class JetSet extends Set {
|
|
728
|
-
|
|
730
|
+
addMany(iterable) {
|
|
729
731
|
for (const element of iterable) {
|
|
730
732
|
super.add(element);
|
|
731
733
|
}
|
|
732
734
|
return this;
|
|
733
735
|
}
|
|
734
|
-
|
|
735
|
-
let
|
|
736
|
+
deleteMany(iterable) {
|
|
737
|
+
let wasDeleted = false;
|
|
736
738
|
for (const element of iterable) {
|
|
737
|
-
|
|
739
|
+
wasDeleted ||= super.delete(element);
|
|
738
740
|
}
|
|
739
|
-
return
|
|
741
|
+
return wasDeleted;
|
|
740
742
|
}
|
|
741
743
|
}
|
|
742
744
|
/**
|
|
@@ -1995,7 +1997,7 @@
|
|
|
1995
1997
|
* Static helper which returns a successful DispatchResult
|
|
1996
1998
|
*/
|
|
1997
1999
|
static get Success() {
|
|
1998
|
-
return
|
|
2000
|
+
return SUCCESS;
|
|
1999
2001
|
}
|
|
2000
2002
|
get isSuccessful() {
|
|
2001
2003
|
return this.reasons.length === 0;
|
|
@@ -2008,6 +2010,7 @@
|
|
|
2008
2010
|
return this.reasons.includes(reason);
|
|
2009
2011
|
}
|
|
2010
2012
|
}
|
|
2013
|
+
const SUCCESS = new DispatchResult();
|
|
2011
2014
|
exports.CommandResult = void 0;
|
|
2012
2015
|
(function (CommandResult) {
|
|
2013
2016
|
CommandResult["Success"] = "Success";
|
|
@@ -2889,6 +2892,9 @@
|
|
|
2889
2892
|
function formatValue(value, { format, locale }) {
|
|
2890
2893
|
switch (typeof value) {
|
|
2891
2894
|
case "string":
|
|
2895
|
+
if (value.includes('\\"')) {
|
|
2896
|
+
return value.replace(/\\"/g, '"');
|
|
2897
|
+
}
|
|
2892
2898
|
return value;
|
|
2893
2899
|
case "boolean":
|
|
2894
2900
|
return value ? "TRUE" : "FALSE";
|
|
@@ -4933,14 +4939,8 @@
|
|
|
4933
4939
|
: undefined));
|
|
4934
4940
|
}
|
|
4935
4941
|
}
|
|
4936
|
-
else if (zone.left === zone.right && zone.top === zone.bottom) {
|
|
4937
|
-
// A single cell. If it's only the title, the dataset is not added.
|
|
4938
|
-
if (!dataSetsHaveTitle) {
|
|
4939
|
-
dataSets.push(createDataSet(getters, dataSetSheetId, zone, undefined));
|
|
4940
|
-
}
|
|
4941
|
-
}
|
|
4942
4942
|
else {
|
|
4943
|
-
/* 1 row or 1 column */
|
|
4943
|
+
/* 1 cell, 1 row or 1 column */
|
|
4944
4944
|
dataSets.push(createDataSet(getters, dataSetSheetId, zone, dataSetsHaveTitle
|
|
4945
4945
|
? {
|
|
4946
4946
|
top: zone.top,
|
|
@@ -4989,8 +4989,10 @@
|
|
|
4989
4989
|
}
|
|
4990
4990
|
const dataRange = ds.dataRange.clone({ zone: dataZone });
|
|
4991
4991
|
return {
|
|
4992
|
-
label: ds.labelCell
|
|
4993
|
-
|
|
4992
|
+
label: ds.labelCell
|
|
4993
|
+
? getters.getRangeString(ds.labelCell, "forceSheetReference", { useFixedReference: true })
|
|
4994
|
+
: undefined,
|
|
4995
|
+
range: getters.getRangeString(dataRange, "forceSheetReference", { useFixedReference: true }),
|
|
4994
4996
|
};
|
|
4995
4997
|
}
|
|
4996
4998
|
function toExcelLabelRange(getters, labelRange, shouldRemoveFirstLabel) {
|
|
@@ -5003,7 +5005,7 @@
|
|
|
5003
5005
|
zone.top = zone.top + 1;
|
|
5004
5006
|
}
|
|
5005
5007
|
const range = labelRange.clone({ zone });
|
|
5006
|
-
return getters.getRangeString(range, "forceSheetReference");
|
|
5008
|
+
return getters.getRangeString(range, "forceSheetReference", { useFixedReference: true });
|
|
5007
5009
|
}
|
|
5008
5010
|
/**
|
|
5009
5011
|
* Transform a chart definition which supports dataSets (dataSets and LabelRange)
|
|
@@ -7384,7 +7386,7 @@
|
|
|
7384
7386
|
while (!chars.isOver()) {
|
|
7385
7387
|
let token = tokenizeSpace(chars) ||
|
|
7386
7388
|
tokenizeArgsSeparator(chars, locale) ||
|
|
7387
|
-
|
|
7389
|
+
tokenizeParenthesis(chars) ||
|
|
7388
7390
|
tokenizeOperator(chars) ||
|
|
7389
7391
|
tokenizeString(chars) ||
|
|
7390
7392
|
tokenizeDebugger(chars) ||
|
|
@@ -7405,15 +7407,14 @@
|
|
|
7405
7407
|
}
|
|
7406
7408
|
return null;
|
|
7407
7409
|
}
|
|
7408
|
-
const
|
|
7409
|
-
"(": "LEFT_PAREN",
|
|
7410
|
-
")": "RIGHT_PAREN",
|
|
7410
|
+
const parenthesis = {
|
|
7411
|
+
"(": { type: "LEFT_PAREN", value: "(" },
|
|
7412
|
+
")": { type: "RIGHT_PAREN", value: ")" },
|
|
7411
7413
|
};
|
|
7412
|
-
function
|
|
7413
|
-
if (chars.current
|
|
7414
|
+
function tokenizeParenthesis(chars) {
|
|
7415
|
+
if (chars.current === "(" || chars.current === ")") {
|
|
7414
7416
|
const value = chars.shift();
|
|
7415
|
-
|
|
7416
|
-
return { type, value };
|
|
7417
|
+
return parenthesis[value];
|
|
7417
7418
|
}
|
|
7418
7419
|
return null;
|
|
7419
7420
|
}
|
|
@@ -7434,7 +7435,12 @@
|
|
|
7434
7435
|
}
|
|
7435
7436
|
return null;
|
|
7436
7437
|
}
|
|
7438
|
+
const FIRST_POSSIBLE_NUMBER_CHARS = new Set("0123456789");
|
|
7437
7439
|
function tokenizeNumber(chars, locale) {
|
|
7440
|
+
if (!FIRST_POSSIBLE_NUMBER_CHARS.has(chars.current) &&
|
|
7441
|
+
chars.current !== locale.decimalSeparator) {
|
|
7442
|
+
return null;
|
|
7443
|
+
}
|
|
7438
7444
|
const match = chars.remaining().match(getFormulaNumberRegex(locale.decimalSeparator));
|
|
7439
7445
|
if (match) {
|
|
7440
7446
|
chars.advanceBy(match[0].length);
|
|
@@ -7459,7 +7465,7 @@
|
|
|
7459
7465
|
}
|
|
7460
7466
|
return null;
|
|
7461
7467
|
}
|
|
7462
|
-
const separatorRegexp =
|
|
7468
|
+
const separatorRegexp = /^[\w\.!\$]+/;
|
|
7463
7469
|
/**
|
|
7464
7470
|
* A "Symbol" is just basically any word-like element that can appear in a
|
|
7465
7471
|
* formula, which is not a string. So:
|
|
@@ -7499,8 +7505,11 @@
|
|
|
7499
7505
|
};
|
|
7500
7506
|
}
|
|
7501
7507
|
}
|
|
7502
|
-
|
|
7503
|
-
|
|
7508
|
+
const match = chars.remaining().match(separatorRegexp);
|
|
7509
|
+
if (match) {
|
|
7510
|
+
const value = match[0];
|
|
7511
|
+
result += value;
|
|
7512
|
+
chars.advanceBy(value.length);
|
|
7504
7513
|
}
|
|
7505
7514
|
if (result.length) {
|
|
7506
7515
|
const value = result;
|
|
@@ -7562,7 +7571,10 @@
|
|
|
7562
7571
|
return this.text.substring(this.currentIndex);
|
|
7563
7572
|
}
|
|
7564
7573
|
currentStartsWith(str) {
|
|
7565
|
-
|
|
7574
|
+
if (this.current !== str[0]) {
|
|
7575
|
+
return false;
|
|
7576
|
+
}
|
|
7577
|
+
for (let j = 1; j < str.length; j++) {
|
|
7566
7578
|
if (this.text[this.currentIndex + j] !== str[j]) {
|
|
7567
7579
|
return false;
|
|
7568
7580
|
}
|
|
@@ -7589,6 +7601,9 @@
|
|
|
7589
7601
|
if (locale.formulaArgSeparator === locale.decimalSeparator) {
|
|
7590
7602
|
return false;
|
|
7591
7603
|
}
|
|
7604
|
+
if (locale.thousandsSeparator === locale.decimalSeparator) {
|
|
7605
|
+
return false;
|
|
7606
|
+
}
|
|
7592
7607
|
try {
|
|
7593
7608
|
formatValue(1, { locale, format: "#,##0.00" });
|
|
7594
7609
|
formatValue(1, { locale, format: locale.dateFormat });
|
|
@@ -7679,7 +7694,7 @@
|
|
|
7679
7694
|
if (locale.decimalSeparator === "." || !isNumber(content, locale)) {
|
|
7680
7695
|
return content;
|
|
7681
7696
|
}
|
|
7682
|
-
return content.replace(locale.decimalSeparator, ".");
|
|
7697
|
+
return content.replace(locale.thousandsSeparator, "").replace(locale.decimalSeparator, ".");
|
|
7683
7698
|
}
|
|
7684
7699
|
/**
|
|
7685
7700
|
* Change a content string from the given locale to its canonical form (en_US locale). Also convert date string.
|
|
@@ -8593,7 +8608,7 @@
|
|
|
8593
8608
|
return undefined;
|
|
8594
8609
|
const dataSets = this.dataSets
|
|
8595
8610
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
8596
|
-
.filter((ds) => ds.range !== ""
|
|
8611
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
8597
8612
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
8598
8613
|
return {
|
|
8599
8614
|
...this.getDefinition(),
|
|
@@ -9171,7 +9186,7 @@
|
|
|
9171
9186
|
return undefined;
|
|
9172
9187
|
const dataSets = this.dataSets
|
|
9173
9188
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
9174
|
-
.filter((ds) => ds.range !== ""
|
|
9189
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
9175
9190
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
9176
9191
|
return {
|
|
9177
9192
|
...this.getDefinition(),
|
|
@@ -9477,7 +9492,7 @@
|
|
|
9477
9492
|
return undefined;
|
|
9478
9493
|
const dataSets = this.dataSets
|
|
9479
9494
|
.map((ds) => toExcelDataset(this.getters, ds))
|
|
9480
|
-
.filter((ds) => ds.range !== ""
|
|
9495
|
+
.filter((ds) => ds.range !== "" && ds.range !== INCORRECT_RANGE_STRING);
|
|
9481
9496
|
const labelRange = toExcelLabelRange(this.getters, this.labelRange, shouldRemoveFirstLabel(this.labelRange, this.dataSets[0], this.dataSetsHaveTitle));
|
|
9482
9497
|
return {
|
|
9483
9498
|
...this.getDefinition(),
|
|
@@ -10751,6 +10766,12 @@
|
|
|
10751
10766
|
let { col, row } = env.model.getters.getActivePosition();
|
|
10752
10767
|
env.model.dispatch("OPEN_CELL_POPOVER", { col, row, popoverType: "LinkEditor" });
|
|
10753
10768
|
};
|
|
10769
|
+
const INSERT_LINK_NAME = (env) => {
|
|
10770
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
10771
|
+
const { col, row } = env.model.getters.getActivePosition();
|
|
10772
|
+
const cell = env.model.getters.getEvaluatedCell({ sheetId, col, row });
|
|
10773
|
+
return cell && cell.link ? _t("Edit link") : _t("Insert link");
|
|
10774
|
+
};
|
|
10754
10775
|
//------------------------------------------------------------------------------
|
|
10755
10776
|
// Filters action
|
|
10756
10777
|
//------------------------------------------------------------------------------
|
|
@@ -19782,7 +19803,7 @@
|
|
|
19782
19803
|
})
|
|
19783
19804
|
.add("insert_link", {
|
|
19784
19805
|
...insertLink,
|
|
19785
|
-
name:
|
|
19806
|
+
name: INSERT_LINK_NAME,
|
|
19786
19807
|
sequence: 150,
|
|
19787
19808
|
separator: true,
|
|
19788
19809
|
});
|
|
@@ -19920,19 +19941,20 @@
|
|
|
19920
19941
|
const formatNumberCurrency = createFormatActionSpec({
|
|
19921
19942
|
name: _t("Currency"),
|
|
19922
19943
|
descriptionValue: 1000.12,
|
|
19923
|
-
format: (env) => env.model.config.defaultCurrencyFormat,
|
|
19944
|
+
format: (env) => env.model.config.defaultCurrencyFormat ?? DEFAULT_CURRENCY_FORMAT,
|
|
19924
19945
|
});
|
|
19925
19946
|
const formatNumberCurrencyRounded = {
|
|
19926
19947
|
...createFormatActionSpec({
|
|
19927
19948
|
name: _t("Currency rounded"),
|
|
19928
19949
|
descriptionValue: 1000,
|
|
19929
|
-
format: (env) => roundFormat(env.model.config.defaultCurrencyFormat),
|
|
19950
|
+
format: (env) => roundFormat(env.model.config.defaultCurrencyFormat ?? DEFAULT_CURRENCY_FORMAT),
|
|
19930
19951
|
}),
|
|
19931
19952
|
isVisible: (env) => {
|
|
19932
19953
|
const currencyFormat = env.model.config.defaultCurrencyFormat;
|
|
19933
|
-
return currencyFormat !== roundFormat(currencyFormat);
|
|
19954
|
+
return currencyFormat !== roundFormat(currencyFormat ?? DEFAULT_CURRENCY_FORMAT);
|
|
19934
19955
|
},
|
|
19935
19956
|
};
|
|
19957
|
+
const DEFAULT_CURRENCY_FORMAT = "[$$]#,##0.00";
|
|
19936
19958
|
const EXAMPLE_DATE = parseLiteral("2023/09/26 10:43:00 PM", DEFAULT_LOCALE);
|
|
19937
19959
|
const formatCustomCurrency = {
|
|
19938
19960
|
name: _t("Custom currency"),
|
|
@@ -26034,6 +26056,17 @@
|
|
|
26034
26056
|
`;
|
|
26035
26057
|
class TextValueProvider extends owl.Component {
|
|
26036
26058
|
static template = "o-spreadsheet-TextValueProvider";
|
|
26059
|
+
autoCompleteListRef = owl.useRef("autoCompleteList");
|
|
26060
|
+
setup() {
|
|
26061
|
+
owl.useEffect(() => {
|
|
26062
|
+
const selectedIndex = this.props.selectedIndex;
|
|
26063
|
+
if (selectedIndex === undefined) {
|
|
26064
|
+
return;
|
|
26065
|
+
}
|
|
26066
|
+
const selectedElement = this.autoCompleteListRef.el?.children[selectedIndex];
|
|
26067
|
+
selectedElement?.scrollIntoView?.({ block: "nearest" });
|
|
26068
|
+
}, () => [this.props.selectedIndex, this.autoCompleteListRef.el]);
|
|
26069
|
+
}
|
|
26037
26070
|
}
|
|
26038
26071
|
TextValueProvider.props = {
|
|
26039
26072
|
values: Array,
|
|
@@ -26485,6 +26518,7 @@
|
|
|
26485
26518
|
position: absolute;
|
|
26486
26519
|
margin: 1px 4px;
|
|
26487
26520
|
pointer-events: none;
|
|
26521
|
+
overflow: auto;
|
|
26488
26522
|
|
|
26489
26523
|
.o-semi-bold {
|
|
26490
26524
|
/** FIXME: to remove in favor of Bootstrap
|
|
@@ -26500,6 +26534,7 @@
|
|
|
26500
26534
|
static components = { TextValueProvider, FunctionDescriptionProvider };
|
|
26501
26535
|
static defaultProps = {
|
|
26502
26536
|
inputStyle: "",
|
|
26537
|
+
isDefaultFocus: false,
|
|
26503
26538
|
};
|
|
26504
26539
|
composerRef = owl.useRef("o_composer");
|
|
26505
26540
|
contentHelper = new ContentEditableHelper(this.composerRef.el);
|
|
@@ -26530,7 +26565,10 @@
|
|
|
26530
26565
|
if (this.props.delimitation && this.props.rect) {
|
|
26531
26566
|
const { x: cellX, y: cellY, height: cellHeight } = this.props.rect;
|
|
26532
26567
|
const remainingHeight = this.props.delimitation.height - (cellY + cellHeight);
|
|
26568
|
+
assistantStyle["max-height"] = `${remainingHeight}px`;
|
|
26533
26569
|
if (cellY > remainingHeight) {
|
|
26570
|
+
const availableSpaceAbove = cellY;
|
|
26571
|
+
assistantStyle["max-height"] = `${availableSpaceAbove}px`;
|
|
26534
26572
|
// render top
|
|
26535
26573
|
// We compensate 2 px of margin on the assistant style + 1px for design reasons
|
|
26536
26574
|
assistantStyle.top = `-3px`;
|
|
@@ -26556,7 +26594,6 @@
|
|
|
26556
26594
|
F2: () => console.warn("Not implemented"),
|
|
26557
26595
|
F4: this.processF4Key,
|
|
26558
26596
|
Tab: (ev) => this.processTabKey(ev),
|
|
26559
|
-
" ": (ev) => this.processSpaceKey(ev),
|
|
26560
26597
|
};
|
|
26561
26598
|
keyCodeMapping = {
|
|
26562
26599
|
NumpadDecimal: this.processNumpadDecimal,
|
|
@@ -26564,12 +26601,12 @@
|
|
|
26564
26601
|
setup() {
|
|
26565
26602
|
owl.onMounted(() => {
|
|
26566
26603
|
const el = this.composerRef.el;
|
|
26604
|
+
if (this.props.isDefaultFocus) {
|
|
26605
|
+
this.env.focusableElement.setFocusableElement(el);
|
|
26606
|
+
}
|
|
26567
26607
|
this.contentHelper.updateEl(el);
|
|
26568
26608
|
this.processTokenAtCursor();
|
|
26569
26609
|
});
|
|
26570
|
-
owl.onWillUnmount(() => {
|
|
26571
|
-
this.props.onComposerUnmounted?.();
|
|
26572
|
-
});
|
|
26573
26610
|
owl.useEffect(() => {
|
|
26574
26611
|
this.processContent();
|
|
26575
26612
|
});
|
|
@@ -26578,7 +26615,8 @@
|
|
|
26578
26615
|
// Handlers
|
|
26579
26616
|
// ---------------------------------------------------------------------------
|
|
26580
26617
|
processArrowKeys(ev) {
|
|
26581
|
-
if (this.env.model.getters.isSelectingForComposer()
|
|
26618
|
+
if (this.env.model.getters.isSelectingForComposer() ||
|
|
26619
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26582
26620
|
this.functionDescriptionState.showDescription = false;
|
|
26583
26621
|
// Prevent the default content editable behavior which moves the cursor
|
|
26584
26622
|
ev.preventDefault();
|
|
@@ -26621,26 +26659,20 @@
|
|
|
26621
26659
|
processTabKey(ev) {
|
|
26622
26660
|
ev.preventDefault();
|
|
26623
26661
|
ev.stopPropagation();
|
|
26624
|
-
|
|
26625
|
-
|
|
26626
|
-
|
|
26627
|
-
|
|
26628
|
-
|
|
26629
|
-
|
|
26662
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
26663
|
+
const state = this.autoCompleteState;
|
|
26664
|
+
if (state.showProvider && state.selectedIndex !== undefined) {
|
|
26665
|
+
const autoCompleteValue = this.autoCompleteState.values[state.selectedIndex]?.text;
|
|
26666
|
+
if (autoCompleteValue) {
|
|
26667
|
+
this.autoComplete(autoCompleteValue);
|
|
26668
|
+
return;
|
|
26669
|
+
}
|
|
26630
26670
|
}
|
|
26671
|
+
interactiveStopEdition(this.env);
|
|
26631
26672
|
}
|
|
26632
26673
|
const direction = ev.shiftKey ? "left" : "right";
|
|
26633
|
-
interactiveStopEdition(this.env);
|
|
26634
26674
|
this.env.model.selection.moveAnchorCell(direction, 1);
|
|
26635
26675
|
}
|
|
26636
|
-
processSpaceKey(ev) {
|
|
26637
|
-
if (ev.ctrlKey) {
|
|
26638
|
-
ev.preventDefault();
|
|
26639
|
-
ev.stopPropagation();
|
|
26640
|
-
this.showFunctionAutocomplete("");
|
|
26641
|
-
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
26642
|
-
}
|
|
26643
|
-
}
|
|
26644
26676
|
processEnterKey(ev) {
|
|
26645
26677
|
ev.preventDefault();
|
|
26646
26678
|
ev.stopPropagation();
|
|
@@ -26693,6 +26725,9 @@
|
|
|
26693
26725
|
this.compositionActive = false;
|
|
26694
26726
|
}
|
|
26695
26727
|
onKeydown(ev) {
|
|
26728
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
26729
|
+
return;
|
|
26730
|
+
}
|
|
26696
26731
|
let handler = this.keyMapping[ev.key] || this.keyCodeMapping[ev.code];
|
|
26697
26732
|
if (handler) {
|
|
26698
26733
|
handler.call(this, ev);
|
|
@@ -26701,14 +26736,33 @@
|
|
|
26701
26736
|
ev.stopPropagation();
|
|
26702
26737
|
}
|
|
26703
26738
|
}
|
|
26739
|
+
onPaste(ev) {
|
|
26740
|
+
if (this.env.model.getters.getEditionMode() !== "inactive") {
|
|
26741
|
+
ev.stopPropagation();
|
|
26742
|
+
}
|
|
26743
|
+
}
|
|
26704
26744
|
/*
|
|
26705
26745
|
* Triggered automatically by the content-editable between the keydown and key up
|
|
26706
26746
|
* */
|
|
26707
26747
|
onInput(ev) {
|
|
26708
|
-
if (
|
|
26748
|
+
if (!this.shouldProcessInputEvents) {
|
|
26749
|
+
return;
|
|
26750
|
+
}
|
|
26751
|
+
if (ev.inputType === "insertFromPaste" &&
|
|
26752
|
+
this.env.model.getters.getEditionMode() === "inactive") {
|
|
26709
26753
|
return;
|
|
26710
26754
|
}
|
|
26711
|
-
|
|
26755
|
+
ev.stopPropagation();
|
|
26756
|
+
let content;
|
|
26757
|
+
if (this.env.model.getters.getEditionMode() === "inactive") {
|
|
26758
|
+
content = ev.data || "";
|
|
26759
|
+
}
|
|
26760
|
+
else {
|
|
26761
|
+
content = this.contentHelper.getText();
|
|
26762
|
+
}
|
|
26763
|
+
if (this.props.focus === "inactive") {
|
|
26764
|
+
return this.props.onComposerCellFocused?.(content);
|
|
26765
|
+
}
|
|
26712
26766
|
let selection = this.contentHelper.getCurrentSelection();
|
|
26713
26767
|
if (ev.inputType === "insertParagraph") {
|
|
26714
26768
|
const start = Math.min(selection.start, selection.end);
|
|
@@ -26790,9 +26844,8 @@
|
|
|
26790
26844
|
}
|
|
26791
26845
|
const newSelection = this.contentHelper.getCurrentSelection();
|
|
26792
26846
|
this.env.model.dispatch("STOP_COMPOSER_RANGE_SELECTION");
|
|
26793
|
-
|
|
26794
|
-
|
|
26795
|
-
}
|
|
26847
|
+
this.props.onComposerContentFocused();
|
|
26848
|
+
if (this.props.focus === "inactive") ;
|
|
26796
26849
|
this.env.model.dispatch("CHANGE_COMPOSER_CURSOR_SELECTION", newSelection);
|
|
26797
26850
|
this.processTokenAtCursor();
|
|
26798
26851
|
}
|
|
@@ -26959,7 +27012,7 @@
|
|
|
26959
27012
|
const highlights = this.env.model.getters.getHighlights();
|
|
26960
27013
|
const refSheet = sheetName
|
|
26961
27014
|
? this.env.model.getters.getSheetIdByName(sheetName)
|
|
26962
|
-
: this.env.model.getters.getCurrentEditedCell()
|
|
27015
|
+
: this.env.model.getters.getCurrentEditedCell()?.sheetId;
|
|
26963
27016
|
const highlight = highlights.find((highlight) => {
|
|
26964
27017
|
if (highlight.sheetId !== refSheet)
|
|
26965
27018
|
return false;
|
|
@@ -27052,12 +27105,13 @@
|
|
|
27052
27105
|
}
|
|
27053
27106
|
}
|
|
27054
27107
|
Composer.props = {
|
|
27055
|
-
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27056
|
-
onComposerContentFocused: Function,
|
|
27057
27108
|
inputStyle: { type: String, optional: true },
|
|
27058
27109
|
rect: { type: Object, optional: true },
|
|
27059
27110
|
delimitation: { type: Object, optional: true },
|
|
27060
|
-
|
|
27111
|
+
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27112
|
+
onComposerCellFocused: { type: Function, optional: true },
|
|
27113
|
+
onComposerContentFocused: Function,
|
|
27114
|
+
isDefaultFocus: { type: Boolean, optional: true },
|
|
27061
27115
|
};
|
|
27062
27116
|
|
|
27063
27117
|
const COMPOSER_BORDER_WIDTH = 3 * 0.4 * window.devicePixelRatio || 1;
|
|
@@ -27091,51 +27145,25 @@
|
|
|
27091
27145
|
class GridComposer extends owl.Component {
|
|
27092
27146
|
static template = "o-spreadsheet-GridComposer";
|
|
27093
27147
|
static components = { Composer };
|
|
27094
|
-
|
|
27095
|
-
|
|
27096
|
-
rect;
|
|
27148
|
+
rect = this.defaultRect;
|
|
27149
|
+
isEditing = false;
|
|
27097
27150
|
isCellReferenceVisible;
|
|
27098
|
-
|
|
27151
|
+
get defaultRect() {
|
|
27152
|
+
return { x: 0, y: 0, width: 0, height: 0 };
|
|
27153
|
+
}
|
|
27099
27154
|
setup() {
|
|
27100
|
-
this.gridComposerRef = owl.useRef("gridComposer");
|
|
27101
|
-
this.composerState = owl.useState({
|
|
27102
|
-
rect: undefined,
|
|
27103
|
-
delimitation: undefined,
|
|
27104
|
-
});
|
|
27105
|
-
const { sheetId, col, row } = this.env.model.getters.getActivePosition();
|
|
27106
|
-
this.zone = this.env.model.getters.expandZone(sheetId, positionToZone({ col, row }));
|
|
27107
|
-
this.rect = this.env.model.getters.getVisibleRect(this.zone);
|
|
27108
|
-
this.isCellReferenceVisible = false;
|
|
27109
|
-
owl.onMounted(() => {
|
|
27110
|
-
const el = this.gridComposerRef.el;
|
|
27111
|
-
this.composerState.rect = {
|
|
27112
|
-
x: this.rect.x,
|
|
27113
|
-
y: this.rect.y,
|
|
27114
|
-
width: el.clientWidth,
|
|
27115
|
-
height: el.clientHeight,
|
|
27116
|
-
};
|
|
27117
|
-
this.composerState.delimitation = {
|
|
27118
|
-
width: this.props.gridDims.width,
|
|
27119
|
-
height: this.props.gridDims.height,
|
|
27120
|
-
};
|
|
27121
|
-
});
|
|
27122
27155
|
owl.onWillUpdateProps(() => {
|
|
27123
|
-
|
|
27124
|
-
|
|
27125
|
-
}
|
|
27126
|
-
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27127
|
-
const zone = this.env.model.getters.getSelectedZone();
|
|
27128
|
-
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
27129
|
-
if (!deepEquals(rect, this.rect) ||
|
|
27130
|
-
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
27131
|
-
this.isCellReferenceVisible = true;
|
|
27132
|
-
}
|
|
27156
|
+
this.updateComponentPosition();
|
|
27157
|
+
this.updateCellReferenceVisibility();
|
|
27133
27158
|
});
|
|
27134
27159
|
}
|
|
27135
27160
|
get shouldDisplayCellReference() {
|
|
27136
27161
|
return this.isCellReferenceVisible;
|
|
27137
27162
|
}
|
|
27138
27163
|
get cellReference() {
|
|
27164
|
+
if (!this.env.model.getters.getCurrentEditedCell()) {
|
|
27165
|
+
return "";
|
|
27166
|
+
}
|
|
27139
27167
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
27140
27168
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
27141
27169
|
return `${prefixSheet ? getCanonicalSheetName(this.env.model.getters.getSheetName(sheetId)) + "!" : ""}${toXC(col, row)}`;
|
|
@@ -27147,7 +27175,27 @@
|
|
|
27147
27175
|
top: `${top - GRID_CELL_REFERENCE_TOP_OFFSET}px`,
|
|
27148
27176
|
});
|
|
27149
27177
|
}
|
|
27178
|
+
get composerProps() {
|
|
27179
|
+
const { width, height } = this.env.model.getters.getSheetViewDimensionWithHeaders();
|
|
27180
|
+
return {
|
|
27181
|
+
rect: { ...this.rect },
|
|
27182
|
+
delimitation: {
|
|
27183
|
+
width,
|
|
27184
|
+
height,
|
|
27185
|
+
},
|
|
27186
|
+
focus: this.props.focus,
|
|
27187
|
+
isDefaultFocus: true,
|
|
27188
|
+
onComposerContentFocused: this.props.onComposerContentFocused,
|
|
27189
|
+
onComposerCellFocused: this.props.onComposerCellFocused,
|
|
27190
|
+
};
|
|
27191
|
+
}
|
|
27150
27192
|
get containerStyle() {
|
|
27193
|
+
if (this.env.model.getters.getEditionMode() === "inactive" || !this.rect) {
|
|
27194
|
+
return `
|
|
27195
|
+
position: absolute;
|
|
27196
|
+
z-index: -1000;
|
|
27197
|
+
`;
|
|
27198
|
+
}
|
|
27151
27199
|
const isFormula = this.env.model.getters.getCurrentContent().startsWith("=");
|
|
27152
27200
|
const cell = this.env.model.getters.getActiveCell();
|
|
27153
27201
|
const position = this.env.model.getters.getActivePosition();
|
|
@@ -27167,6 +27215,8 @@
|
|
|
27167
27215
|
if (!isFormula) {
|
|
27168
27216
|
textAlign = style.align || cell.defaultAlign;
|
|
27169
27217
|
}
|
|
27218
|
+
const maxHeight = this.props.gridDims.height - this.rect.y;
|
|
27219
|
+
const maxWidth = this.props.gridDims.width - this.rect.x;
|
|
27170
27220
|
/**
|
|
27171
27221
|
* min-size is on the container, not the composer element, because we want to have the same size as the cell by default,
|
|
27172
27222
|
* including all the paddings/margins of the composer
|
|
@@ -27178,6 +27228,8 @@
|
|
|
27178
27228
|
top: `${top}px`,
|
|
27179
27229
|
"min-width": `${width + 1}px`,
|
|
27180
27230
|
"min-height": `${height + 1}px`,
|
|
27231
|
+
"max-width": `${maxWidth}px`,
|
|
27232
|
+
"max-height": `${maxHeight}px`,
|
|
27181
27233
|
background,
|
|
27182
27234
|
color,
|
|
27183
27235
|
"font-size": `${fontSizeInPixels(fontSize)}px`,
|
|
@@ -27187,20 +27239,38 @@
|
|
|
27187
27239
|
"text-align": textAlign,
|
|
27188
27240
|
});
|
|
27189
27241
|
}
|
|
27190
|
-
|
|
27191
|
-
const
|
|
27192
|
-
|
|
27193
|
-
|
|
27194
|
-
|
|
27195
|
-
|
|
27196
|
-
|
|
27242
|
+
updateComponentPosition() {
|
|
27243
|
+
const isEditing = this.env.model.getters.getEditionMode() !== "inactive";
|
|
27244
|
+
if (this.isEditing !== isEditing) {
|
|
27245
|
+
this.isEditing = isEditing;
|
|
27246
|
+
if (!isEditing) {
|
|
27247
|
+
this.rect = this.defaultRect;
|
|
27248
|
+
this.env.focusableElement.focus();
|
|
27249
|
+
return;
|
|
27250
|
+
}
|
|
27251
|
+
const position = this.env.model.getters.getActivePosition();
|
|
27252
|
+
const zone = this.env.model.getters.expandZone(position.sheetId, positionToZone(position));
|
|
27253
|
+
this.rect = this.env.model.getters.getVisibleRect(zone);
|
|
27254
|
+
}
|
|
27255
|
+
}
|
|
27256
|
+
updateCellReferenceVisibility() {
|
|
27257
|
+
if (this.isCellReferenceVisible || this.env.model.getters.getEditionMode() === "inactive") {
|
|
27258
|
+
return;
|
|
27259
|
+
}
|
|
27260
|
+
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
27261
|
+
const zone = this.env.model.getters.getSelectedZone();
|
|
27262
|
+
const rect = this.env.model.getters.getVisibleRect(zone);
|
|
27263
|
+
if (!deepEquals(rect, this.rect) ||
|
|
27264
|
+
sheetId !== this.env.model.getters.getCurrentEditedCell().sheetId) {
|
|
27265
|
+
this.isCellReferenceVisible = true;
|
|
27266
|
+
}
|
|
27197
27267
|
}
|
|
27198
27268
|
}
|
|
27199
27269
|
GridComposer.props = {
|
|
27200
27270
|
focus: { validate: (value) => ["inactive", "cellFocus", "contentFocus"].includes(value) },
|
|
27201
|
-
onComposerUnmounted: Function,
|
|
27202
27271
|
onComposerContentFocused: Function,
|
|
27203
27272
|
gridDims: Object,
|
|
27273
|
+
onComposerCellFocused: Function,
|
|
27204
27274
|
};
|
|
27205
27275
|
|
|
27206
27276
|
const CSS$1 = css /* scss */ `
|
|
@@ -28291,7 +28361,6 @@
|
|
|
28291
28361
|
this.props.onCellDoubleClicked(col, row);
|
|
28292
28362
|
}
|
|
28293
28363
|
onContextMenu(ev) {
|
|
28294
|
-
ev.preventDefault();
|
|
28295
28364
|
const [col, row] = this.getCartesianCoordinates(ev);
|
|
28296
28365
|
this.props.onCellRightClicked(col, row, { x: ev.clientX, y: ev.clientY });
|
|
28297
28366
|
}
|
|
@@ -29352,6 +29421,7 @@
|
|
|
29352
29421
|
GROUP_HEADERS: groupHeadersMenuRegistry,
|
|
29353
29422
|
UNGROUP_HEADERS: unGroupHeadersMenuRegistry,
|
|
29354
29423
|
};
|
|
29424
|
+
const MODIFIER_KEYS = ["Shift", "Control", "Alt", "Meta"];
|
|
29355
29425
|
// -----------------------------------------------------------------------------
|
|
29356
29426
|
// JS
|
|
29357
29427
|
// -----------------------------------------------------------------------------
|
|
@@ -29375,7 +29445,6 @@
|
|
|
29375
29445
|
HEADER_WIDTH = HEADER_WIDTH;
|
|
29376
29446
|
menuState;
|
|
29377
29447
|
gridRef;
|
|
29378
|
-
hiddenInput;
|
|
29379
29448
|
onMouseWheel;
|
|
29380
29449
|
canvasPosition;
|
|
29381
29450
|
hoveredCell;
|
|
@@ -29386,17 +29455,16 @@
|
|
|
29386
29455
|
menuItems: [],
|
|
29387
29456
|
});
|
|
29388
29457
|
this.gridRef = owl.useRef("grid");
|
|
29389
|
-
this.hiddenInput = owl.useRef("hiddenInput");
|
|
29390
29458
|
this.canvasPosition = useAbsoluteBoundingRect(this.gridRef);
|
|
29391
29459
|
this.hoveredCell = owl.useState({ col: undefined, row: undefined });
|
|
29392
29460
|
owl.useChildSubEnv({ getPopoverContainerRect: () => this.getGridRect() });
|
|
29393
29461
|
owl.useExternalListener(document.body, "cut", this.copy.bind(this, true));
|
|
29394
29462
|
owl.useExternalListener(document.body, "copy", this.copy.bind(this, false));
|
|
29395
29463
|
owl.useExternalListener(document.body, "paste", this.paste);
|
|
29396
|
-
owl.onMounted(() => this.
|
|
29397
|
-
this.props.exposeFocus(() => this.
|
|
29464
|
+
owl.onMounted(() => this.focusDefaultElement());
|
|
29465
|
+
this.props.exposeFocus(() => this.focusDefaultElement());
|
|
29398
29466
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
29399
|
-
owl.useEffect(() => this.
|
|
29467
|
+
owl.useEffect(() => this.focusDefaultElement(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
29400
29468
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
29401
29469
|
this.moveCanvas(deltaX, deltaY);
|
|
29402
29470
|
this.hoveredCell.col = undefined;
|
|
@@ -29419,7 +29487,7 @@
|
|
|
29419
29487
|
if (this.env.model.getters.hasOpenedPopover()) {
|
|
29420
29488
|
this.closeOpenedPopover();
|
|
29421
29489
|
}
|
|
29422
|
-
this.
|
|
29490
|
+
this.focusDefaultElement();
|
|
29423
29491
|
}
|
|
29424
29492
|
// this map will handle most of the actions that should happen on key down. The arrow keys are managed in the key
|
|
29425
29493
|
// down itself
|
|
@@ -29598,10 +29666,10 @@
|
|
|
29598
29666
|
"ALT+SHIFT+ARROWUP": () => this.processHeaderGroupingKey("up"),
|
|
29599
29667
|
"ALT+SHIFT+ARROWDOWN": () => this.processHeaderGroupingKey("down"),
|
|
29600
29668
|
};
|
|
29601
|
-
|
|
29669
|
+
focusDefaultElement() {
|
|
29602
29670
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
29603
29671
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
29604
|
-
this.
|
|
29672
|
+
this.env.focusableElement.focus();
|
|
29605
29673
|
}
|
|
29606
29674
|
}
|
|
29607
29675
|
get gridEl() {
|
|
@@ -29724,16 +29792,15 @@
|
|
|
29724
29792
|
}
|
|
29725
29793
|
}
|
|
29726
29794
|
onKeydown(ev) {
|
|
29727
|
-
const eventKey = ev.key.toUpperCase();
|
|
29728
29795
|
let keyDownString = "";
|
|
29729
|
-
if (
|
|
29730
|
-
|
|
29731
|
-
|
|
29732
|
-
|
|
29733
|
-
|
|
29734
|
-
|
|
29735
|
-
|
|
29736
|
-
|
|
29796
|
+
if (!MODIFIER_KEYS.includes(ev.key)) {
|
|
29797
|
+
if (isCtrlKey(ev))
|
|
29798
|
+
keyDownString += "CTRL+";
|
|
29799
|
+
if (ev.altKey)
|
|
29800
|
+
keyDownString += "ALT+";
|
|
29801
|
+
if (ev.shiftKey)
|
|
29802
|
+
keyDownString += "SHIFT+";
|
|
29803
|
+
}
|
|
29737
29804
|
keyDownString += ev.key.toUpperCase();
|
|
29738
29805
|
let handler = this.keyDownMapping[keyDownString];
|
|
29739
29806
|
if (handler) {
|
|
@@ -29747,19 +29814,6 @@
|
|
|
29747
29814
|
return;
|
|
29748
29815
|
}
|
|
29749
29816
|
}
|
|
29750
|
-
onInput(ev) {
|
|
29751
|
-
// the user meant to paste in the sheet, not open the composer with the pasted content
|
|
29752
|
-
if (!ev.isComposing && ev.inputType === "insertFromPaste") {
|
|
29753
|
-
return;
|
|
29754
|
-
}
|
|
29755
|
-
if (ev.data) {
|
|
29756
|
-
// if the user types a character on the grid, it means he wants to start composing the selected cell with that
|
|
29757
|
-
// character
|
|
29758
|
-
ev.preventDefault();
|
|
29759
|
-
ev.stopPropagation();
|
|
29760
|
-
this.props.onGridComposerCellFocused(ev.data);
|
|
29761
|
-
}
|
|
29762
|
-
}
|
|
29763
29817
|
// ---------------------------------------------------------------------------
|
|
29764
29818
|
// Context Menu
|
|
29765
29819
|
// ---------------------------------------------------------------------------
|
|
@@ -29874,7 +29928,7 @@
|
|
|
29874
29928
|
}
|
|
29875
29929
|
closeMenu() {
|
|
29876
29930
|
this.menuState.isOpen = false;
|
|
29877
|
-
this.
|
|
29931
|
+
this.focusDefaultElement();
|
|
29878
29932
|
}
|
|
29879
29933
|
processHeaderGroupingKey(direction) {
|
|
29880
29934
|
if (this.env.model.getters.getSelectedZones().length !== 1) {
|
|
@@ -33769,6 +33823,31 @@
|
|
|
33769
33823
|
return data;
|
|
33770
33824
|
},
|
|
33771
33825
|
},
|
|
33826
|
+
{
|
|
33827
|
+
description: "Fix datafilter duplication",
|
|
33828
|
+
from: 12,
|
|
33829
|
+
to: 12.5,
|
|
33830
|
+
applyMigration(data) {
|
|
33831
|
+
for (let sheet of data.sheets || []) {
|
|
33832
|
+
let knownDataFilterZones = [];
|
|
33833
|
+
for (let filterTable of sheet.filterTables || []) {
|
|
33834
|
+
const zone = toZone(filterTable.range);
|
|
33835
|
+
// See commit message for the details
|
|
33836
|
+
const intersectZoneIndex = knownDataFilterZones.findIndex((knownZone) => overlap(knownZone, zone));
|
|
33837
|
+
if (intersectZoneIndex !== -1) {
|
|
33838
|
+
knownDataFilterZones[intersectZoneIndex] = zone;
|
|
33839
|
+
}
|
|
33840
|
+
else {
|
|
33841
|
+
knownDataFilterZones.push(zone);
|
|
33842
|
+
}
|
|
33843
|
+
}
|
|
33844
|
+
sheet.filterTables = knownDataFilterZones.map((zone) => ({
|
|
33845
|
+
range: zoneToXc(zone),
|
|
33846
|
+
}));
|
|
33847
|
+
}
|
|
33848
|
+
return data;
|
|
33849
|
+
},
|
|
33850
|
+
},
|
|
33772
33851
|
{
|
|
33773
33852
|
description: "Change Border description structure",
|
|
33774
33853
|
from: 12,
|
|
@@ -34608,22 +34687,7 @@
|
|
|
34608
34687
|
}
|
|
34609
34688
|
}
|
|
34610
34689
|
export(data) {
|
|
34611
|
-
// Borders
|
|
34612
|
-
let borderId = 0;
|
|
34613
34690
|
const borders = {};
|
|
34614
|
-
/**
|
|
34615
|
-
* Get the id of the given border. If the border does not exist, it creates
|
|
34616
|
-
* one.
|
|
34617
|
-
*/
|
|
34618
|
-
function getBorderId(border) {
|
|
34619
|
-
for (let [key, value] of Object.entries(borders)) {
|
|
34620
|
-
if (deepEquals(value, border)) {
|
|
34621
|
-
return parseInt(key, 10);
|
|
34622
|
-
}
|
|
34623
|
-
}
|
|
34624
|
-
borders[++borderId] = border;
|
|
34625
|
-
return borderId;
|
|
34626
|
-
}
|
|
34627
34691
|
for (let sheet of data.sheets) {
|
|
34628
34692
|
for (let col = 0; col < sheet.colNumber; col++) {
|
|
34629
34693
|
for (let row = 0; row < sheet.rowNumber; row++) {
|
|
@@ -34631,7 +34695,7 @@
|
|
|
34631
34695
|
if (border) {
|
|
34632
34696
|
const xc = toXC(col, row);
|
|
34633
34697
|
const cell = sheet.cells[xc];
|
|
34634
|
-
const borderId =
|
|
34698
|
+
const borderId = getItemId(border, borders);
|
|
34635
34699
|
if (cell) {
|
|
34636
34700
|
cell.border = borderId;
|
|
34637
34701
|
}
|
|
@@ -35436,9 +35500,9 @@
|
|
|
35436
35500
|
allowDispatch(cmd) {
|
|
35437
35501
|
switch (cmd.type) {
|
|
35438
35502
|
case "UPDATE_CELL":
|
|
35439
|
-
return this.
|
|
35503
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
35440
35504
|
case "CLEAR_CELL":
|
|
35441
|
-
return this.checkValidations(cmd, this.
|
|
35505
|
+
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
35442
35506
|
default:
|
|
35443
35507
|
return "Success" /* CommandResult.Success */;
|
|
35444
35508
|
}
|
|
@@ -35588,8 +35652,8 @@
|
|
|
35588
35652
|
}
|
|
35589
35653
|
removeDefaultStyleValues(style) {
|
|
35590
35654
|
const cleanedStyle = { ...style };
|
|
35591
|
-
for (const
|
|
35592
|
-
if (cleanedStyle[property] ===
|
|
35655
|
+
for (const property in DEFAULT_STYLE) {
|
|
35656
|
+
if (cleanedStyle[property] === DEFAULT_STYLE[property]) {
|
|
35593
35657
|
delete cleanedStyle[property];
|
|
35594
35658
|
}
|
|
35595
35659
|
}
|
|
@@ -35614,13 +35678,13 @@
|
|
|
35614
35678
|
/*
|
|
35615
35679
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
35616
35680
|
*/
|
|
35617
|
-
getFormulaCellContent(sheetId, compiledFormula, dependencies) {
|
|
35681
|
+
getFormulaCellContent(sheetId, compiledFormula, dependencies, useFixedReference = false) {
|
|
35618
35682
|
const ranges = dependencies || compiledFormula.dependencies;
|
|
35619
35683
|
let rangeIndex = 0;
|
|
35620
35684
|
return concat(compiledFormula.tokens.map((token) => {
|
|
35621
35685
|
if (token.type === "REFERENCE") {
|
|
35622
35686
|
const range = ranges[rangeIndex++];
|
|
35623
|
-
return this.getters.getRangeString(range, sheetId);
|
|
35687
|
+
return this.getters.getRangeString(range, sheetId, { useFixedReference });
|
|
35624
35688
|
}
|
|
35625
35689
|
return token.value;
|
|
35626
35690
|
}));
|
|
@@ -35746,10 +35810,7 @@
|
|
|
35746
35810
|
else {
|
|
35747
35811
|
style = before ? before.style : undefined;
|
|
35748
35812
|
}
|
|
35749
|
-
const
|
|
35750
|
-
let format = ("format" in after ? after.format : before && before.format) ||
|
|
35751
|
-
detectDateFormat(afterContent, locale) ||
|
|
35752
|
-
detectNumberFormat(afterContent);
|
|
35813
|
+
const format = "format" in after ? after.format : before && before.format;
|
|
35753
35814
|
/* Read the following IF as:
|
|
35754
35815
|
* we need to remove the cell if it is completely empty, but we can know if it completely empty if:
|
|
35755
35816
|
* - the command says the new content is empty and has no border/format/style
|
|
@@ -35790,12 +35851,11 @@
|
|
|
35790
35851
|
}
|
|
35791
35852
|
createLiteralCell(id, content, format, style) {
|
|
35792
35853
|
const locale = this.getters.getLocale();
|
|
35793
|
-
content = parseLiteral(content, locale).toString();
|
|
35794
35854
|
return {
|
|
35795
35855
|
id,
|
|
35796
|
-
content,
|
|
35856
|
+
content: parseLiteral(content, locale).toString(),
|
|
35797
35857
|
style,
|
|
35798
|
-
format,
|
|
35858
|
+
format: format || detectDateFormat(content, locale) || detectNumberFormat(content),
|
|
35799
35859
|
isFormula: false,
|
|
35800
35860
|
};
|
|
35801
35861
|
}
|
|
@@ -35821,8 +35881,11 @@
|
|
|
35821
35881
|
* being a computed property to rebuild the dependencies XC.
|
|
35822
35882
|
*/
|
|
35823
35883
|
createFormulaCellWithDependencies(id, compiledFormula, format, style, sheetId) {
|
|
35824
|
-
const dependencies =
|
|
35825
|
-
|
|
35884
|
+
const dependencies = [];
|
|
35885
|
+
for (const xc of compiledFormula.dependencies) {
|
|
35886
|
+
dependencies.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
35887
|
+
}
|
|
35888
|
+
return new FormulaCellWithDependencies(id, compiledFormula, format, style, dependencies, sheetId, this.getters.getRangeString);
|
|
35826
35889
|
}
|
|
35827
35890
|
createErrorFormula(id, content, format, style, error) {
|
|
35828
35891
|
return {
|
|
@@ -35857,6 +35920,18 @@
|
|
|
35857
35920
|
}
|
|
35858
35921
|
return "Success" /* CommandResult.Success */;
|
|
35859
35922
|
}
|
|
35923
|
+
checkUselessUpdateCell(cmd) {
|
|
35924
|
+
const cell = this.getters.getCell(cmd);
|
|
35925
|
+
const hasContent = "content" in cmd || "formula" in cmd;
|
|
35926
|
+
const hasStyle = "style" in cmd;
|
|
35927
|
+
const hasFormat = "format" in cmd;
|
|
35928
|
+
if ((!hasContent || cell?.content === cmd.content) &&
|
|
35929
|
+
(!hasStyle || deepEquals(cell?.style, cmd.style)) &&
|
|
35930
|
+
(!hasFormat || cell?.format === cmd.format)) {
|
|
35931
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35932
|
+
}
|
|
35933
|
+
return "Success" /* CommandResult.Success */;
|
|
35934
|
+
}
|
|
35860
35935
|
}
|
|
35861
35936
|
class FormulaCellWithDependencies {
|
|
35862
35937
|
id;
|
|
@@ -35876,7 +35951,7 @@
|
|
|
35876
35951
|
const tokens = compiledFormula.tokens.map((token) => {
|
|
35877
35952
|
if (token.type === "REFERENCE") {
|
|
35878
35953
|
const index = rangeIndex++;
|
|
35879
|
-
return new RangeReferenceToken(
|
|
35954
|
+
return new RangeReferenceToken(dependencies, index, this.sheetId, this.getRangeString);
|
|
35880
35955
|
}
|
|
35881
35956
|
return token;
|
|
35882
35957
|
});
|
|
@@ -35889,15 +35964,34 @@
|
|
|
35889
35964
|
get content() {
|
|
35890
35965
|
return concat(this.compiledFormula.tokens.map((token) => token.value));
|
|
35891
35966
|
}
|
|
35967
|
+
get contentWithFixedReferences() {
|
|
35968
|
+
let rangeIndex = 0;
|
|
35969
|
+
return concat(this.compiledFormula.tokens.map((token) => {
|
|
35970
|
+
if (token.type === "REFERENCE") {
|
|
35971
|
+
const index = rangeIndex++;
|
|
35972
|
+
return this.getRangeString(this.compiledFormula.dependencies[index], this.sheetId, {
|
|
35973
|
+
useFixedReference: true,
|
|
35974
|
+
});
|
|
35975
|
+
}
|
|
35976
|
+
return token.value;
|
|
35977
|
+
}));
|
|
35978
|
+
}
|
|
35892
35979
|
}
|
|
35893
35980
|
class RangeReferenceToken {
|
|
35894
|
-
|
|
35981
|
+
ranges;
|
|
35982
|
+
rangeIndex;
|
|
35983
|
+
sheetId;
|
|
35984
|
+
getRangeString;
|
|
35895
35985
|
type = "REFERENCE";
|
|
35896
|
-
constructor(
|
|
35897
|
-
this.
|
|
35986
|
+
constructor(ranges, rangeIndex, sheetId, getRangeString) {
|
|
35987
|
+
this.ranges = ranges;
|
|
35988
|
+
this.rangeIndex = rangeIndex;
|
|
35989
|
+
this.sheetId = sheetId;
|
|
35990
|
+
this.getRangeString = getRangeString;
|
|
35898
35991
|
}
|
|
35899
35992
|
get value() {
|
|
35900
|
-
|
|
35993
|
+
const range = this.ranges[this.rangeIndex];
|
|
35994
|
+
return this.getRangeString(range, this.sheetId);
|
|
35901
35995
|
}
|
|
35902
35996
|
}
|
|
35903
35997
|
|
|
@@ -36193,7 +36287,13 @@
|
|
|
36193
36287
|
}
|
|
36194
36288
|
}
|
|
36195
36289
|
exportForExcel(data) {
|
|
36196
|
-
|
|
36290
|
+
if (data.sheets) {
|
|
36291
|
+
for (let sheet of data.sheets) {
|
|
36292
|
+
if (this.cfRules[sheet.id]) {
|
|
36293
|
+
sheet.conditionalFormats = this.cfRules[sheet.id].map((rule) => this.mapToConditionalFormat(sheet.id, rule, { useFixedReference: true }));
|
|
36294
|
+
}
|
|
36295
|
+
}
|
|
36296
|
+
}
|
|
36197
36297
|
}
|
|
36198
36298
|
// ---------------------------------------------------------------------------
|
|
36199
36299
|
// Getters
|
|
@@ -36258,11 +36358,11 @@
|
|
|
36258
36358
|
// ---------------------------------------------------------------------------
|
|
36259
36359
|
// Private
|
|
36260
36360
|
// ---------------------------------------------------------------------------
|
|
36261
|
-
mapToConditionalFormat(sheetId, cf) {
|
|
36361
|
+
mapToConditionalFormat(sheetId, cf, { useFixedReference } = { useFixedReference: false }) {
|
|
36262
36362
|
return {
|
|
36263
36363
|
...cf,
|
|
36264
36364
|
ranges: cf.ranges.map((range) => {
|
|
36265
|
-
return this.getters.getRangeString(range, sheetId);
|
|
36365
|
+
return this.getters.getRangeString(range, sheetId, { useFixedReference });
|
|
36266
36366
|
}),
|
|
36267
36367
|
};
|
|
36268
36368
|
}
|
|
@@ -38330,8 +38430,10 @@
|
|
|
38330
38430
|
*
|
|
38331
38431
|
* @param range the range (received from getRangeFromXC or getRangeFromZone)
|
|
38332
38432
|
* @param forSheetId the id of the sheet where the range string is supposed to be used.
|
|
38433
|
+
* @param options
|
|
38434
|
+
* @param options.useFixedReference if true, the range will be returned with fixed row and column
|
|
38333
38435
|
*/
|
|
38334
|
-
getRangeString(range, forSheetId) {
|
|
38436
|
+
getRangeString(range, forSheetId, options = { useFixedReference: false }) {
|
|
38335
38437
|
if (!range) {
|
|
38336
38438
|
return INCORRECT_RANGE_STRING;
|
|
38337
38439
|
}
|
|
@@ -38358,7 +38460,7 @@
|
|
|
38358
38460
|
if (prefixSheet && !sheetName) {
|
|
38359
38461
|
return INCORRECT_RANGE_STRING;
|
|
38360
38462
|
}
|
|
38361
|
-
let rangeString = this.getRangePartString(rangeImpl, 0);
|
|
38463
|
+
let rangeString = this.getRangePartString(rangeImpl, 0, options);
|
|
38362
38464
|
if (rangeImpl.parts && rangeImpl.parts.length === 2) {
|
|
38363
38465
|
// this if converts A2:A2 into A2 except if any part of the original range had fixed row or column (with $)
|
|
38364
38466
|
if (rangeImpl.zone.top !== rangeImpl.zone.bottom ||
|
|
@@ -38368,7 +38470,7 @@
|
|
|
38368
38470
|
rangeImpl.parts[1].rowFixed ||
|
|
38369
38471
|
rangeImpl.parts[1].colFixed) {
|
|
38370
38472
|
rangeString += ":";
|
|
38371
|
-
rangeString += this.getRangePartString(rangeImpl, 1);
|
|
38473
|
+
rangeString += this.getRangePartString(rangeImpl, 1, options);
|
|
38372
38474
|
}
|
|
38373
38475
|
}
|
|
38374
38476
|
return `${prefixSheet ? sheetName + "!" : ""}${rangeString}`;
|
|
@@ -38409,13 +38511,13 @@
|
|
|
38409
38511
|
/**
|
|
38410
38512
|
* Get a Xc string that represent a part of a range
|
|
38411
38513
|
*/
|
|
38412
|
-
getRangePartString(range, part) {
|
|
38514
|
+
getRangePartString(range, part, options = { useFixedReference: false }) {
|
|
38413
38515
|
const colFixed = range.parts && range.parts[part]?.colFixed ? "$" : "";
|
|
38414
38516
|
const col = part === 0 ? numberToLetters(range.zone.left) : numberToLetters(range.zone.right);
|
|
38415
38517
|
const rowFixed = range.parts && range.parts[part]?.rowFixed ? "$" : "";
|
|
38416
38518
|
const row = part === 0 ? String(range.zone.top + 1) : String(range.zone.bottom + 1);
|
|
38417
38519
|
let str = "";
|
|
38418
|
-
if (range.isFullCol) {
|
|
38520
|
+
if (range.isFullCol && !options.useFixedReference) {
|
|
38419
38521
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
38420
38522
|
str = colFixed + col + rowFixed + row;
|
|
38421
38523
|
}
|
|
@@ -38423,7 +38525,7 @@
|
|
|
38423
38525
|
str = colFixed + col;
|
|
38424
38526
|
}
|
|
38425
38527
|
}
|
|
38426
|
-
else if (range.isFullRow) {
|
|
38528
|
+
else if (range.isFullRow && !options.useFixedReference) {
|
|
38427
38529
|
if (part === 0 && range.unboundedZone.hasHeader) {
|
|
38428
38530
|
str = colFixed + col + rowFixed + row;
|
|
38429
38531
|
}
|
|
@@ -40625,7 +40727,15 @@
|
|
|
40625
40727
|
if (!this.rTrees[sheetId]) {
|
|
40626
40728
|
return;
|
|
40627
40729
|
}
|
|
40628
|
-
this.rTrees[sheetId].remove(item,
|
|
40730
|
+
this.rTrees[sheetId].remove(item, this.rtreeItemComparer);
|
|
40731
|
+
}
|
|
40732
|
+
rtreeItemComparer(left, right) {
|
|
40733
|
+
return (left.data == right.data &&
|
|
40734
|
+
left.boundingBox.sheetId === right.boundingBox.sheetId &&
|
|
40735
|
+
left.boundingBox?.zone.left === right.boundingBox.zone.left &&
|
|
40736
|
+
left.boundingBox?.zone.top === right.boundingBox.zone.top &&
|
|
40737
|
+
left.boundingBox?.zone.right === right.boundingBox.zone.right &&
|
|
40738
|
+
left.boundingBox?.zone.bottom === right.boundingBox.zone.bottom);
|
|
40629
40739
|
}
|
|
40630
40740
|
}
|
|
40631
40741
|
/**
|
|
@@ -40703,7 +40813,7 @@
|
|
|
40703
40813
|
const queue = Array.from(ranges).reverse();
|
|
40704
40814
|
while (queue.length > 0) {
|
|
40705
40815
|
const range = queue.pop();
|
|
40706
|
-
visited.
|
|
40816
|
+
visited.addMany(this.encoder.encodeBoundingBox(range));
|
|
40707
40817
|
const impactedPositionIds = this.rTree.search(range).map((dep) => dep.data);
|
|
40708
40818
|
for (const positionId of impactedPositionIds) {
|
|
40709
40819
|
if (!visited.has(positionId)) {
|
|
@@ -40711,7 +40821,7 @@
|
|
|
40711
40821
|
}
|
|
40712
40822
|
}
|
|
40713
40823
|
}
|
|
40714
|
-
visited.
|
|
40824
|
+
visited.deleteMany(ranges.flatMap((r) => this.encoder.encodeBoundingBox(r)));
|
|
40715
40825
|
return visited;
|
|
40716
40826
|
}
|
|
40717
40827
|
}
|
|
@@ -40849,9 +40959,9 @@
|
|
|
40849
40959
|
const cells = positions.map((p) => this.encoder.encode(p));
|
|
40850
40960
|
const cellsToCompute = new JetSet(cells);
|
|
40851
40961
|
const arrayFormulasPositionIds = this.getArrayFormulasImpactedByChangesOf(cells);
|
|
40852
|
-
cellsToCompute.
|
|
40853
|
-
cellsToCompute.
|
|
40854
|
-
cellsToCompute.
|
|
40962
|
+
cellsToCompute.addMany(this.getCellsDependingOn(cells));
|
|
40963
|
+
cellsToCompute.addMany(arrayFormulasPositionIds);
|
|
40964
|
+
cellsToCompute.addMany(this.getCellsDependingOn(arrayFormulasPositionIds));
|
|
40855
40965
|
this.evaluate(cellsToCompute);
|
|
40856
40966
|
}
|
|
40857
40967
|
getArrayFormulasImpactedByChangesOf(positionIds) {
|
|
@@ -40865,7 +40975,7 @@
|
|
|
40865
40975
|
}
|
|
40866
40976
|
if (!content) {
|
|
40867
40977
|
// The previous content could have blocked some array formulas
|
|
40868
|
-
impactedPositionIds.
|
|
40978
|
+
impactedPositionIds.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(positionId));
|
|
40869
40979
|
}
|
|
40870
40980
|
}
|
|
40871
40981
|
return impactedPositionIds;
|
|
@@ -40914,7 +41024,7 @@
|
|
|
40914
41024
|
}
|
|
40915
41025
|
const arrayFormulas = this.spreadingRelations.getFormulaPositionsSpreadingOn(positionId);
|
|
40916
41026
|
const cells = new JetSet(arrayFormulas);
|
|
40917
|
-
cells.
|
|
41027
|
+
cells.addMany(this.getCellsDependingOn(arrayFormulas));
|
|
40918
41028
|
return cells;
|
|
40919
41029
|
}
|
|
40920
41030
|
nextPositionsToUpdate = new JetSet();
|
|
@@ -41063,7 +41173,7 @@
|
|
|
41063
41173
|
this.setEvaluatedCell(positionId, evaluatedCell);
|
|
41064
41174
|
// check if formula dependencies present in the spread zone
|
|
41065
41175
|
// if so, they need to be recomputed
|
|
41066
|
-
this.nextPositionsToUpdate.
|
|
41176
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([positionId]));
|
|
41067
41177
|
};
|
|
41068
41178
|
}
|
|
41069
41179
|
invalidateSpreading(positionId) {
|
|
@@ -41078,8 +41188,8 @@
|
|
|
41078
41188
|
continue;
|
|
41079
41189
|
}
|
|
41080
41190
|
this.evaluatedCells.delete(child);
|
|
41081
|
-
this.nextPositionsToUpdate.
|
|
41082
|
-
this.nextPositionsToUpdate.
|
|
41191
|
+
this.nextPositionsToUpdate.addMany(this.getCellsDependingOn([child]));
|
|
41192
|
+
this.nextPositionsToUpdate.addMany(this.getArrayFormulasBlockedByOrSpreadingOn(child));
|
|
41083
41193
|
}
|
|
41084
41194
|
this.spreadingRelations.removeNode(positionId);
|
|
41085
41195
|
}
|
|
@@ -41428,7 +41538,13 @@
|
|
|
41428
41538
|
const format = newFormat
|
|
41429
41539
|
? getItemId(newFormat, data.formats)
|
|
41430
41540
|
: exportedCellData.format;
|
|
41431
|
-
|
|
41541
|
+
let content;
|
|
41542
|
+
if (formulaCell instanceof FormulaCellWithDependencies) {
|
|
41543
|
+
content = this.getters.getFormulaCellContent(exportedSheetData.id, formulaCell.compiledFormula, formulaCell.compiledFormula.dependencies, true);
|
|
41544
|
+
}
|
|
41545
|
+
else {
|
|
41546
|
+
content = !isExported ? newContent : exportedCellData.content;
|
|
41547
|
+
}
|
|
41432
41548
|
exportedSheetData.cells[xc] = { ...exportedCellData, value, isFormula, content, format };
|
|
41433
41549
|
}
|
|
41434
41550
|
}
|
|
@@ -50744,6 +50860,16 @@
|
|
|
50744
50860
|
}
|
|
50745
50861
|
}
|
|
50746
50862
|
|
|
50863
|
+
class FocusableElement {
|
|
50864
|
+
focusableElement = undefined;
|
|
50865
|
+
setFocusableElement(element) {
|
|
50866
|
+
this.focusableElement = element;
|
|
50867
|
+
}
|
|
50868
|
+
focus() {
|
|
50869
|
+
this.focusableElement?.focus();
|
|
50870
|
+
}
|
|
50871
|
+
}
|
|
50872
|
+
|
|
50747
50873
|
const RIPPLE_KEY_FRAMES = [
|
|
50748
50874
|
{ transform: "scale(0)" },
|
|
50749
50875
|
{ transform: "scale(0.8)", offset: 0.33 },
|
|
@@ -52900,6 +53026,7 @@
|
|
|
52900
53026
|
toggleSidePanel: this.toggleSidePanel.bind(this),
|
|
52901
53027
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
52902
53028
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
53029
|
+
focusableElement: new FocusableElement(),
|
|
52903
53030
|
});
|
|
52904
53031
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
52905
53032
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
@@ -53006,16 +53133,17 @@
|
|
|
53006
53133
|
}
|
|
53007
53134
|
this.composer.topBarFocus = "contentFocus";
|
|
53008
53135
|
this.composer.gridFocusMode = "inactive";
|
|
53009
|
-
this.setComposerContent({ selection }
|
|
53136
|
+
this.setComposerContent({ selection });
|
|
53010
53137
|
}
|
|
53011
|
-
onGridComposerContentFocused() {
|
|
53138
|
+
onGridComposerContentFocused(selection) {
|
|
53012
53139
|
if (this.model.getters.isReadonly()) {
|
|
53013
53140
|
return;
|
|
53014
53141
|
}
|
|
53015
53142
|
this.composer.topBarFocus = "inactive";
|
|
53016
53143
|
this.composer.gridFocusMode = "contentFocus";
|
|
53017
|
-
this.setComposerContent({});
|
|
53144
|
+
this.setComposerContent({ selection });
|
|
53018
53145
|
}
|
|
53146
|
+
// TODO: either both are defined or none of them. change those args to an object
|
|
53019
53147
|
onGridComposerCellFocused(content, selection) {
|
|
53020
53148
|
if (this.model.getters.isReadonly()) {
|
|
53021
53149
|
return;
|
|
@@ -54441,11 +54569,10 @@
|
|
|
54441
54569
|
* next cluster if the given cell is outside a cluster or at the border of a cluster in the given direction.
|
|
54442
54570
|
*/
|
|
54443
54571
|
getEndOfCluster(startPosition, dim, dir) {
|
|
54444
|
-
const sheet = this.getters.getActiveSheet();
|
|
54445
54572
|
let currentPosition = startPosition;
|
|
54446
54573
|
// If both the current cell and the next cell are not empty, we want to go to the end of the cluster
|
|
54447
54574
|
const nextCellPosition = this.getNextCellPosition(startPosition, dim, dir);
|
|
54448
|
-
let mode = !this.
|
|
54575
|
+
let mode = !this.isEvaluatedCellEmpty(currentPosition) && !this.isEvaluatedCellEmpty(nextCellPosition)
|
|
54449
54576
|
? "endOfCluster"
|
|
54450
54577
|
: "nextCluster";
|
|
54451
54578
|
while (true) {
|
|
@@ -54455,7 +54582,7 @@
|
|
|
54455
54582
|
currentPosition.row === nextCellPosition.row) {
|
|
54456
54583
|
break;
|
|
54457
54584
|
}
|
|
54458
|
-
const isNextCellEmpty = this.
|
|
54585
|
+
const isNextCellEmpty = this.isEvaluatedCellEmpty(nextCellPosition);
|
|
54459
54586
|
if (mode === "endOfCluster" && isNextCellEmpty) {
|
|
54460
54587
|
break;
|
|
54461
54588
|
}
|
|
@@ -54469,10 +54596,20 @@
|
|
|
54469
54596
|
return dim === "cols" ? currentPosition.col : currentPosition.row;
|
|
54470
54597
|
}
|
|
54471
54598
|
/**
|
|
54472
|
-
*
|
|
54473
|
-
* check
|
|
54599
|
+
* Checks if a cell is empty (i.e. does not have a content). If the cell is part of a merge,
|
|
54600
|
+
* the check applies to the main cell of the merge.
|
|
54474
54601
|
*/
|
|
54475
|
-
isCellEmpty({ col, row }
|
|
54602
|
+
isCellEmpty({ col, row }) {
|
|
54603
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
54604
|
+
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
54605
|
+
return !(this.getters.getCorrespondingFormulaCell(position) || this.getters.getCell(position)?.content);
|
|
54606
|
+
}
|
|
54607
|
+
/**
|
|
54608
|
+
* Checks if a cell evaluated value is empty. If the cell is part of a merge,
|
|
54609
|
+
* the check applies to the main cell of the merge.
|
|
54610
|
+
*/
|
|
54611
|
+
isEvaluatedCellEmpty({ col, row }) {
|
|
54612
|
+
const sheetId = this.getters.getActiveSheetId();
|
|
54476
54613
|
const position = this.getters.getMainCellPosition({ sheetId, col, row });
|
|
54477
54614
|
const cell = this.getters.getEvaluatedCell(position);
|
|
54478
54615
|
return cell.type === CellValueType.empty;
|
|
@@ -54950,12 +55087,7 @@
|
|
|
54950
55087
|
attrs.push(["t", "str"]);
|
|
54951
55088
|
cycle = escapeXml /*xml*/ `<v>${cell.value}</v>`;
|
|
54952
55089
|
}
|
|
54953
|
-
node = escapeXml /*xml*/
|
|
54954
|
-
<f>
|
|
54955
|
-
${XlsxFormula}
|
|
54956
|
-
</f>
|
|
54957
|
-
${cycle}
|
|
54958
|
-
`;
|
|
55090
|
+
node = escapeXml /*xml*/ `<f>${XlsxFormula}</f>${cycle}`;
|
|
54959
55091
|
return { attrs, node };
|
|
54960
55092
|
}
|
|
54961
55093
|
function addContent(content, sharedStrings, forceString = false) {
|
|
@@ -55774,11 +55906,10 @@
|
|
|
55774
55906
|
({ attrs: additionalAttrs, node: cellNode } = addContent(cell.content, construct.sharedStrings, isTableHeader));
|
|
55775
55907
|
}
|
|
55776
55908
|
attributes.push(...additionalAttrs);
|
|
55777
|
-
|
|
55778
|
-
|
|
55779
|
-
|
|
55780
|
-
|
|
55781
|
-
`);
|
|
55909
|
+
// prettier-ignore
|
|
55910
|
+
cellNodes.push(escapeXml /*xml*/ `<c ${formatAttributes(attributes)}>
|
|
55911
|
+
${cellNode}
|
|
55912
|
+
</c>`);
|
|
55782
55913
|
}
|
|
55783
55914
|
}
|
|
55784
55915
|
if (cellNodes.length || row.size !== DEFAULT_CELL_HEIGHT || row.isHidden) {
|
|
@@ -56374,7 +56505,6 @@
|
|
|
56374
56505
|
...config,
|
|
56375
56506
|
mode: config.mode || "normal",
|
|
56376
56507
|
custom: config.custom || {},
|
|
56377
|
-
defaultCurrencyFormat: config.defaultCurrencyFormat || "[$$]#,##0.00",
|
|
56378
56508
|
external: this.setupExternalConfig(config.external || {}),
|
|
56379
56509
|
transportService,
|
|
56380
56510
|
client,
|
|
@@ -56412,6 +56542,7 @@
|
|
|
56412
56542
|
custom: this.config.custom,
|
|
56413
56543
|
uiActions: this.config,
|
|
56414
56544
|
session: this.session,
|
|
56545
|
+
defaultCurrencyFormat: this.config.defaultCurrencyFormat,
|
|
56415
56546
|
};
|
|
56416
56547
|
}
|
|
56417
56548
|
// ---------------------------------------------------------------------------
|
|
@@ -56784,9 +56915,9 @@
|
|
|
56784
56915
|
exports.tokenize = tokenize;
|
|
56785
56916
|
|
|
56786
56917
|
|
|
56787
|
-
__info__.version = "17.0.
|
|
56788
|
-
__info__.date = "2024-
|
|
56789
|
-
__info__.hash = "
|
|
56918
|
+
__info__.version = "17.0.12";
|
|
56919
|
+
__info__.date = "2024-02-16T14:24:02.984Z";
|
|
56920
|
+
__info__.hash = "8fa2bab";
|
|
56790
56921
|
|
|
56791
56922
|
|
|
56792
56923
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|