@odoo/o-spreadsheet 17.0.3 → 17.0.5
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 +276 -207
- package/dist/o-spreadsheet.d.ts +16 -20
- package/dist/o-spreadsheet.esm.js +276 -207
- package/dist/o-spreadsheet.iife.js +276 -207
- package/dist/o-spreadsheet.iife.min.js +284 -286
- package/dist/o_spreadsheet.xml +7 -8
- 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 2023-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.5
|
|
6
|
+
* @date 2023-12-05T09:51:44.657Z
|
|
7
|
+
* @hash 2480a5d
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -692,8 +692,7 @@
|
|
|
692
692
|
*
|
|
693
693
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
694
694
|
*/
|
|
695
|
-
const
|
|
696
|
-
" ",
|
|
695
|
+
const whiteSpaceSpecialCharacters = [
|
|
697
696
|
"\t",
|
|
698
697
|
"\f",
|
|
699
698
|
"\v",
|
|
@@ -708,8 +707,7 @@
|
|
|
708
707
|
String.fromCharCode(parseInt("3000", 16)),
|
|
709
708
|
String.fromCharCode(parseInt("feff", 16)),
|
|
710
709
|
];
|
|
711
|
-
const whiteSpaceRegexp = new RegExp(
|
|
712
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
710
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
713
711
|
/**
|
|
714
712
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
715
713
|
* different newlines types by \n.
|
|
@@ -717,9 +715,9 @@
|
|
|
717
715
|
function replaceSpecialSpaces(text) {
|
|
718
716
|
if (!text)
|
|
719
717
|
return "";
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
return text;
|
|
718
|
+
if (!whiteSpaceRegexp.test(text))
|
|
719
|
+
return text;
|
|
720
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
723
721
|
}
|
|
724
722
|
/**
|
|
725
723
|
* Determine if the numbers are consecutive.
|
|
@@ -2061,6 +2059,7 @@
|
|
|
2061
2059
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2062
2060
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2063
2061
|
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2062
|
+
CommandResult["NoChanges"] = "NoChanges";
|
|
2064
2063
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
2065
2064
|
|
|
2066
2065
|
const DEFAULT_LOCALES = [
|
|
@@ -2190,12 +2189,12 @@
|
|
|
2190
2189
|
}
|
|
2191
2190
|
}
|
|
2192
2191
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2193
|
-
function normalizeString(str) {
|
|
2192
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
2194
2193
|
return str
|
|
2195
2194
|
.toLowerCase()
|
|
2196
2195
|
.normalize("NFD")
|
|
2197
2196
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2198
|
-
}
|
|
2197
|
+
});
|
|
2199
2198
|
const expectBooleanValueError = (value) => _t("The function [[FUNCTION_NAME]] expects a boolean value, but '%s' is a text, and cannot be coerced to a number.", value);
|
|
2200
2199
|
function toBoolean(value) {
|
|
2201
2200
|
switch (typeof value) {
|
|
@@ -3389,8 +3388,10 @@
|
|
|
3389
3388
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
3390
3389
|
// Same as above, but matches the exact string (nothing before or after)
|
|
3391
3390
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
3392
|
-
/** Reference of a column header (eg. A, AB) */
|
|
3393
|
-
const colHeader = new RegExp(
|
|
3391
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
3392
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
3393
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
3394
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
3394
3395
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
3395
3396
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
3396
3397
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -3420,6 +3421,9 @@
|
|
|
3420
3421
|
function isColHeader(str) {
|
|
3421
3422
|
return colHeader.test(str);
|
|
3422
3423
|
}
|
|
3424
|
+
function isRowHeader(str) {
|
|
3425
|
+
return rowHeader.test(str);
|
|
3426
|
+
}
|
|
3423
3427
|
/**
|
|
3424
3428
|
* Return true if the given xc is the reference of a single cell,
|
|
3425
3429
|
* without any specified sheet (e.g. A1)
|
|
@@ -4103,18 +4107,10 @@
|
|
|
4103
4107
|
if (isFullCol) {
|
|
4104
4108
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
4105
4109
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
4106
|
-
if (zone.left === zone.right) {
|
|
4107
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
4108
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
4109
|
-
}
|
|
4110
4110
|
}
|
|
4111
4111
|
if (isFullRow) {
|
|
4112
4112
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
4113
4113
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
4114
|
-
if (zone.top === zone.bottom) {
|
|
4115
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
4116
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
4117
|
-
}
|
|
4118
4114
|
}
|
|
4119
4115
|
return parts;
|
|
4120
4116
|
}
|
|
@@ -4356,7 +4352,7 @@
|
|
|
4356
4352
|
function getDefaultCellHeight(ctx, cell, colSize) {
|
|
4357
4353
|
if (!cell || !cell.content)
|
|
4358
4354
|
return DEFAULT_CELL_HEIGHT;
|
|
4359
|
-
const maxWidth = cell.style?.wrapping ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4355
|
+
const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4360
4356
|
const numberOfLines = cell.isFormula
|
|
4361
4357
|
? 1
|
|
4362
4358
|
: splitTextToWidth(ctx, cell.content, cell.style, maxWidth).length;
|
|
@@ -6251,10 +6247,6 @@
|
|
|
6251
6247
|
|
|
6252
6248
|
.o-error-tooltip-message {
|
|
6253
6249
|
overflow: hidden;
|
|
6254
|
-
display: -webkit-box; /* Limit to 3 lines */
|
|
6255
|
-
-webkit-line-clamp: 3;
|
|
6256
|
-
line-clamp: 3;
|
|
6257
|
-
-webkit-box-orient: vertical;
|
|
6258
6250
|
}
|
|
6259
6251
|
}
|
|
6260
6252
|
`;
|
|
@@ -6637,6 +6629,9 @@
|
|
|
6637
6629
|
function getOpenedMenus() {
|
|
6638
6630
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
6639
6631
|
}
|
|
6632
|
+
function isMacOS() {
|
|
6633
|
+
return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
6634
|
+
}
|
|
6640
6635
|
|
|
6641
6636
|
/**
|
|
6642
6637
|
* Return the o-spreadsheet element position relative
|
|
@@ -7330,7 +7325,7 @@
|
|
|
7330
7325
|
return result;
|
|
7331
7326
|
}
|
|
7332
7327
|
function tokenizeDebugger(chars) {
|
|
7333
|
-
if (chars.current
|
|
7328
|
+
if (chars.current === "?") {
|
|
7334
7329
|
chars.shift();
|
|
7335
7330
|
return { type: "DEBUGGER", value: "?" };
|
|
7336
7331
|
}
|
|
@@ -7341,7 +7336,7 @@
|
|
|
7341
7336
|
")": "RIGHT_PAREN",
|
|
7342
7337
|
};
|
|
7343
7338
|
function tokenizeMisc(chars) {
|
|
7344
|
-
if (chars.current
|
|
7339
|
+
if (chars.current in misc$1) {
|
|
7345
7340
|
const value = chars.shift();
|
|
7346
7341
|
const type = misc$1[value];
|
|
7347
7342
|
return { type, value };
|
|
@@ -7349,7 +7344,7 @@
|
|
|
7349
7344
|
return null;
|
|
7350
7345
|
}
|
|
7351
7346
|
function tokenizeArgsSeparator(chars, locale) {
|
|
7352
|
-
if (chars.current
|
|
7347
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
7353
7348
|
const value = chars.shift();
|
|
7354
7349
|
const type = "ARG_SEPARATOR";
|
|
7355
7350
|
return { type, value };
|
|
@@ -7374,14 +7369,13 @@
|
|
|
7374
7369
|
return null;
|
|
7375
7370
|
}
|
|
7376
7371
|
function tokenizeString(chars) {
|
|
7377
|
-
if (chars.current
|
|
7372
|
+
if (chars.current === '"') {
|
|
7378
7373
|
const startChar = chars.shift();
|
|
7379
7374
|
let letters = startChar;
|
|
7380
|
-
while (chars.current()
|
|
7381
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7375
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7382
7376
|
letters += chars.shift();
|
|
7383
7377
|
}
|
|
7384
|
-
if (chars.current
|
|
7378
|
+
if (chars.current === '"') {
|
|
7385
7379
|
letters += chars.shift();
|
|
7386
7380
|
}
|
|
7387
7381
|
return {
|
|
@@ -7408,14 +7402,14 @@
|
|
|
7408
7402
|
let result = "";
|
|
7409
7403
|
// there are two main cases to manage: either something which starts with
|
|
7410
7404
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
7411
|
-
if (chars.current
|
|
7405
|
+
if (chars.current === "'") {
|
|
7412
7406
|
let lastChar = chars.shift();
|
|
7413
7407
|
result += lastChar;
|
|
7414
|
-
while (chars.current
|
|
7408
|
+
while (chars.current) {
|
|
7415
7409
|
lastChar = chars.shift();
|
|
7416
7410
|
result += lastChar;
|
|
7417
7411
|
if (lastChar === "'") {
|
|
7418
|
-
if (chars.current
|
|
7412
|
+
if (chars.current && chars.current === "'") {
|
|
7419
7413
|
lastChar = chars.shift();
|
|
7420
7414
|
result += lastChar;
|
|
7421
7415
|
}
|
|
@@ -7431,7 +7425,7 @@
|
|
|
7431
7425
|
};
|
|
7432
7426
|
}
|
|
7433
7427
|
}
|
|
7434
|
-
while (chars.current
|
|
7428
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
7435
7429
|
result += chars.shift();
|
|
7436
7430
|
}
|
|
7437
7431
|
if (result.length) {
|
|
@@ -7446,14 +7440,14 @@
|
|
|
7446
7440
|
}
|
|
7447
7441
|
function tokenizeSpace(chars) {
|
|
7448
7442
|
let length = 0;
|
|
7449
|
-
while (chars.current
|
|
7443
|
+
while (chars.current === NEWLINE) {
|
|
7450
7444
|
length++;
|
|
7451
7445
|
chars.shift();
|
|
7452
7446
|
}
|
|
7453
7447
|
if (length) {
|
|
7454
7448
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
7455
7449
|
}
|
|
7456
|
-
while (chars.current
|
|
7450
|
+
while (chars.current === " ") {
|
|
7457
7451
|
length++;
|
|
7458
7452
|
chars.shift();
|
|
7459
7453
|
}
|
|
@@ -7472,17 +7466,20 @@
|
|
|
7472
7466
|
class TokenizingChars {
|
|
7473
7467
|
text;
|
|
7474
7468
|
currentIndex = 0;
|
|
7469
|
+
current;
|
|
7475
7470
|
constructor(text) {
|
|
7476
7471
|
this.text = text;
|
|
7477
|
-
|
|
7478
|
-
current() {
|
|
7479
|
-
return this.text[this.currentIndex];
|
|
7472
|
+
this.current = text[0];
|
|
7480
7473
|
}
|
|
7481
7474
|
shift() {
|
|
7482
|
-
|
|
7475
|
+
const current = this.current;
|
|
7476
|
+
const next = this.text[++this.currentIndex];
|
|
7477
|
+
this.current = next;
|
|
7478
|
+
return current;
|
|
7483
7479
|
}
|
|
7484
7480
|
advanceBy(length) {
|
|
7485
7481
|
this.currentIndex += length;
|
|
7482
|
+
this.current = this.text[this.currentIndex];
|
|
7486
7483
|
}
|
|
7487
7484
|
isOver() {
|
|
7488
7485
|
return this.currentIndex >= this.text.length;
|
|
@@ -28279,6 +28276,7 @@
|
|
|
28279
28276
|
draggerShadowThickness: 0,
|
|
28280
28277
|
delta: 0,
|
|
28281
28278
|
base: 0,
|
|
28279
|
+
position: "before",
|
|
28282
28280
|
});
|
|
28283
28281
|
_computeHandleDisplay(ev) {
|
|
28284
28282
|
const position = this._getEvOffset(ev);
|
|
@@ -28403,11 +28401,13 @@
|
|
|
28403
28401
|
this.state.draggerLinePosition = dimensions.start;
|
|
28404
28402
|
this.state.draggerShadowPosition = dimensions.start;
|
|
28405
28403
|
this.state.base = elementIndex;
|
|
28404
|
+
this.state.position = "before";
|
|
28406
28405
|
}
|
|
28407
28406
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
28408
28407
|
this.state.draggerLinePosition = dimensions.end;
|
|
28409
28408
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
28410
|
-
this.state.base = elementIndex
|
|
28409
|
+
this.state.base = elementIndex;
|
|
28410
|
+
this.state.position = "after";
|
|
28411
28411
|
}
|
|
28412
28412
|
else {
|
|
28413
28413
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -28589,6 +28589,7 @@
|
|
|
28589
28589
|
dimension: "COL",
|
|
28590
28590
|
base: this.state.base,
|
|
28591
28591
|
elements,
|
|
28592
|
+
position: this.state.position,
|
|
28592
28593
|
});
|
|
28593
28594
|
if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
|
|
28594
28595
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -28762,6 +28763,7 @@
|
|
|
28762
28763
|
dimension: "ROW",
|
|
28763
28764
|
base: this.state.base,
|
|
28764
28765
|
elements,
|
|
28766
|
+
position: this.state.position,
|
|
28765
28767
|
});
|
|
28766
28768
|
if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
|
|
28767
28769
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -28869,8 +28871,8 @@
|
|
|
28869
28871
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
28870
28872
|
}
|
|
28871
28873
|
const onMouseWheel = (ev) => {
|
|
28872
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
28873
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
28874
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
28875
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
28874
28876
|
handler(deltaX, deltaY);
|
|
28875
28877
|
};
|
|
28876
28878
|
return onMouseWheel;
|
|
@@ -29758,6 +29760,7 @@
|
|
|
29758
29760
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
29759
29761
|
const target = this.env.model.getters.getSelectedZones();
|
|
29760
29762
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
29763
|
+
const isCutOperation = this.env.model.getters.isCutOperation();
|
|
29761
29764
|
if (clipboardString === content) {
|
|
29762
29765
|
// the paste actually comes from o-spreadsheet itself
|
|
29763
29766
|
interactivePaste(this.env, target);
|
|
@@ -29765,7 +29768,7 @@
|
|
|
29765
29768
|
else {
|
|
29766
29769
|
interactivePasteFromOS(this.env, target, content);
|
|
29767
29770
|
}
|
|
29768
|
-
if (
|
|
29771
|
+
if (isCutOperation) {
|
|
29769
29772
|
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
29770
29773
|
}
|
|
29771
29774
|
}
|
|
@@ -33323,7 +33326,7 @@
|
|
|
33323
33326
|
SPACE: goTo(State.RightRef),
|
|
33324
33327
|
NUMBER: goTo(State.Found),
|
|
33325
33328
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
33326
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
33329
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
33327
33330
|
},
|
|
33328
33331
|
[State.RightColumnRef]: {
|
|
33329
33332
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -33334,6 +33337,7 @@
|
|
|
33334
33337
|
SPACE: goTo(State.RightRowRef),
|
|
33335
33338
|
NUMBER: goTo(State.Found),
|
|
33336
33339
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
33340
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
33337
33341
|
},
|
|
33338
33342
|
[State.Found]: {},
|
|
33339
33343
|
};
|
|
@@ -34059,6 +34063,14 @@
|
|
|
34059
34063
|
// ---------------------------------------------------------------------------
|
|
34060
34064
|
// Command Handling
|
|
34061
34065
|
// ---------------------------------------------------------------------------
|
|
34066
|
+
allowDispatch(cmd) {
|
|
34067
|
+
switch (cmd.type) {
|
|
34068
|
+
case "SET_BORDER":
|
|
34069
|
+
return this.checkBordersUnchanged(cmd);
|
|
34070
|
+
default:
|
|
34071
|
+
return "Success" /* CommandResult.Success */;
|
|
34072
|
+
}
|
|
34073
|
+
}
|
|
34062
34074
|
handle(cmd) {
|
|
34063
34075
|
switch (cmd.type) {
|
|
34064
34076
|
case "ADD_MERGE":
|
|
@@ -34478,6 +34490,14 @@
|
|
|
34478
34490
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
34479
34491
|
}
|
|
34480
34492
|
}
|
|
34493
|
+
checkBordersUnchanged(cmd) {
|
|
34494
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
34495
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
34496
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
34497
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
34498
|
+
}
|
|
34499
|
+
return "Success" /* CommandResult.Success */;
|
|
34500
|
+
}
|
|
34481
34501
|
// ---------------------------------------------------------------------------
|
|
34482
34502
|
// Import/Export
|
|
34483
34503
|
// ---------------------------------------------------------------------------
|
|
@@ -35333,8 +35353,9 @@
|
|
|
35333
35353
|
allowDispatch(cmd) {
|
|
35334
35354
|
switch (cmd.type) {
|
|
35335
35355
|
case "UPDATE_CELL":
|
|
35356
|
+
return this.checkCellOutOfSheet(cmd);
|
|
35336
35357
|
case "CLEAR_CELL":
|
|
35337
|
-
return this.
|
|
35358
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
35338
35359
|
default:
|
|
35339
35360
|
return "Success" /* CommandResult.Success */;
|
|
35340
35361
|
}
|
|
@@ -35503,14 +35524,9 @@
|
|
|
35503
35524
|
*/
|
|
35504
35525
|
getCellById(cellId) {
|
|
35505
35526
|
// this must be as fast as possible
|
|
35506
|
-
|
|
35507
|
-
|
|
35508
|
-
|
|
35509
|
-
if (cell) {
|
|
35510
|
-
return cell;
|
|
35511
|
-
}
|
|
35512
|
-
}
|
|
35513
|
-
return undefined;
|
|
35527
|
+
const position = this.getters.getCellPosition(cellId);
|
|
35528
|
+
const sheet = this.cells[position.sheetId];
|
|
35529
|
+
return sheet[cellId];
|
|
35514
35530
|
}
|
|
35515
35531
|
/*
|
|
35516
35532
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -35741,13 +35757,23 @@
|
|
|
35741
35757
|
},
|
|
35742
35758
|
};
|
|
35743
35759
|
}
|
|
35744
|
-
checkCellOutOfSheet(
|
|
35760
|
+
checkCellOutOfSheet(cmd) {
|
|
35761
|
+
const { sheetId, col, row } = cmd;
|
|
35745
35762
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
35746
35763
|
if (!sheet)
|
|
35747
35764
|
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
35748
35765
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
35749
35766
|
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
|
35750
35767
|
}
|
|
35768
|
+
checkUselessClearCell(cmd) {
|
|
35769
|
+
const cell = this.getters.getCell(cmd);
|
|
35770
|
+
if (!cell)
|
|
35771
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35772
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
35773
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35774
|
+
}
|
|
35775
|
+
return "Success" /* CommandResult.Success */;
|
|
35776
|
+
}
|
|
35751
35777
|
}
|
|
35752
35778
|
class FormulaCellWithDependencies {
|
|
35753
35779
|
id;
|
|
@@ -36437,6 +36463,9 @@
|
|
|
36437
36463
|
return this.rules[sheetId].find((rule) => rule.id === id);
|
|
36438
36464
|
}
|
|
36439
36465
|
getValidationRuleForCell({ sheetId, col, row }) {
|
|
36466
|
+
if (!this.rules[sheetId]) {
|
|
36467
|
+
return undefined;
|
|
36468
|
+
}
|
|
36440
36469
|
for (const rule of this.rules[sheetId]) {
|
|
36441
36470
|
for (const range of rule.ranges) {
|
|
36442
36471
|
if (isInside(col, row, range.zone)) {
|
|
@@ -37290,7 +37319,16 @@
|
|
|
37290
37319
|
return consecutiveIndexes;
|
|
37291
37320
|
}
|
|
37292
37321
|
getAllVisibleHeaders(sheetId, dimension) {
|
|
37293
|
-
|
|
37322
|
+
const headers = range(0, this.getters.getNumberHeaders(sheetId, dimension));
|
|
37323
|
+
const foldedHeaders = [];
|
|
37324
|
+
this.getters.getHeaderGroups(sheetId, dimension).forEach((group) => {
|
|
37325
|
+
if (group.isFolded) {
|
|
37326
|
+
foldedHeaders.push(...range(group.start, group.end + 1));
|
|
37327
|
+
}
|
|
37328
|
+
});
|
|
37329
|
+
return headers.filter((i) => {
|
|
37330
|
+
return !this.hiddenHeaders[sheetId][dimension][i] && !foldedHeaders.includes(i);
|
|
37331
|
+
});
|
|
37294
37332
|
}
|
|
37295
37333
|
import(data) {
|
|
37296
37334
|
for (let sheet of data.sheets) {
|
|
@@ -39034,10 +39072,13 @@
|
|
|
39034
39072
|
// begin with the end.
|
|
39035
39073
|
rows.sort((a, b) => b - a);
|
|
39036
39074
|
for (let group of groupConsecutive(rows)) {
|
|
39075
|
+
// indexes are sorted in the descending order
|
|
39076
|
+
const from = group[group.length - 1];
|
|
39077
|
+
const to = group[0];
|
|
39037
39078
|
// Move the cells.
|
|
39038
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
39039
|
-
// Effectively delete the
|
|
39040
|
-
|
|
39079
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
39080
|
+
// Effectively delete the rows
|
|
39081
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
39041
39082
|
}
|
|
39042
39083
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
39043
39084
|
if (count) {
|
|
@@ -39059,8 +39100,6 @@
|
|
|
39059
39100
|
this.addEmptyRows(sheet, quantity);
|
|
39060
39101
|
// Move the cells.
|
|
39061
39102
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
39062
|
-
// Recompute the left-right/top-bottom.
|
|
39063
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
39064
39103
|
if (index < sheet.panes.ySplit) {
|
|
39065
39104
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
39066
39105
|
}
|
|
@@ -39161,35 +39200,20 @@
|
|
|
39161
39200
|
}
|
|
39162
39201
|
}
|
|
39163
39202
|
}
|
|
39164
|
-
updateRowsStructureOnDeletion(
|
|
39203
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
39165
39204
|
const rows = [];
|
|
39166
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39205
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
39167
39206
|
for (let i in sheet.rows) {
|
|
39168
|
-
|
|
39207
|
+
const row = Number(i);
|
|
39208
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
39169
39209
|
continue;
|
|
39170
39210
|
}
|
|
39171
39211
|
rows.push({
|
|
39172
|
-
cells: cellsQueue.
|
|
39212
|
+
cells: cellsQueue.pop(),
|
|
39173
39213
|
});
|
|
39174
39214
|
}
|
|
39175
39215
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39176
39216
|
}
|
|
39177
|
-
/**
|
|
39178
|
-
* Update the rows of the sheet after an addition:
|
|
39179
|
-
* - Rename the rows
|
|
39180
|
-
*
|
|
39181
|
-
* @param sheet Sheet on which the deletion occurs
|
|
39182
|
-
* @param addedRow Index of the added row
|
|
39183
|
-
* @param rowsToAdd Number of the rows to add
|
|
39184
|
-
*/
|
|
39185
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
39186
|
-
const rows = [];
|
|
39187
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39188
|
-
sheet.rows.forEach(() => rows.push({
|
|
39189
|
-
cells: cellsQueue.shift(),
|
|
39190
|
-
}));
|
|
39191
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39192
|
-
}
|
|
39193
39217
|
/**
|
|
39194
39218
|
* Add empty rows at the end of the rows
|
|
39195
39219
|
*
|
|
@@ -39716,6 +39740,7 @@
|
|
|
39716
39740
|
getters;
|
|
39717
39741
|
computeCell;
|
|
39718
39742
|
evalContext;
|
|
39743
|
+
rangeCache = {};
|
|
39719
39744
|
constructor(context, getters, computeCell) {
|
|
39720
39745
|
this.getters = getters;
|
|
39721
39746
|
this.computeCell = computeCell;
|
|
@@ -39763,10 +39788,13 @@
|
|
|
39763
39788
|
if (evaluatedCell === undefined) {
|
|
39764
39789
|
return { value: null, format: this.getters.getCell(position)?.format };
|
|
39765
39790
|
}
|
|
39791
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
39792
|
+
throw evaluatedCell.error;
|
|
39793
|
+
}
|
|
39766
39794
|
return evaluatedCell;
|
|
39767
39795
|
}
|
|
39768
39796
|
getEvaluatedCellIfNotEmpty(position) {
|
|
39769
|
-
const evaluatedCell = this.
|
|
39797
|
+
const evaluatedCell = this.computeCell(position);
|
|
39770
39798
|
if (evaluatedCell.type === CellValueType.empty) {
|
|
39771
39799
|
const cell = this.getters.getCell(position);
|
|
39772
39800
|
if (!cell || (!cell.isFormula && cell.content === "")) {
|
|
@@ -39775,13 +39803,6 @@
|
|
|
39775
39803
|
}
|
|
39776
39804
|
return evaluatedCell;
|
|
39777
39805
|
}
|
|
39778
|
-
getEvaluatedCell(position) {
|
|
39779
|
-
const evaluatedCell = this.computeCell(position);
|
|
39780
|
-
if (evaluatedCell.type === CellValueType.error) {
|
|
39781
|
-
throw evaluatedCell.error;
|
|
39782
|
-
}
|
|
39783
|
-
return evaluatedCell;
|
|
39784
|
-
}
|
|
39785
39806
|
/**
|
|
39786
39807
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
39787
39808
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -39801,17 +39822,33 @@
|
|
|
39801
39822
|
if (!_zone) {
|
|
39802
39823
|
return [[]];
|
|
39803
39824
|
}
|
|
39825
|
+
const { top, left, bottom, right } = zone;
|
|
39826
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
39827
|
+
if (cacheKey in this.rangeCache) {
|
|
39828
|
+
const result = this.rangeCache[cacheKey];
|
|
39829
|
+
if (result instanceof EvaluationError) {
|
|
39830
|
+
throw result;
|
|
39831
|
+
}
|
|
39832
|
+
return result;
|
|
39833
|
+
}
|
|
39804
39834
|
const height = _zone.bottom - _zone.top + 1;
|
|
39805
39835
|
const width = _zone.right - _zone.left + 1;
|
|
39806
|
-
const matrix = Array
|
|
39836
|
+
const matrix = new Array(width);
|
|
39807
39837
|
// Performance issue: nested loop is faster than a map here
|
|
39808
39838
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
39839
|
+
const colIndex = col - _zone.left;
|
|
39840
|
+
matrix[colIndex] = new Array(height);
|
|
39809
39841
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
39810
|
-
const
|
|
39842
|
+
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
|
|
39843
|
+
if (evaluatedCell?.type === CellValueType.error) {
|
|
39844
|
+
this.rangeCache[cacheKey] = evaluatedCell.error;
|
|
39845
|
+
throw evaluatedCell.error;
|
|
39846
|
+
}
|
|
39811
39847
|
const rowIndex = row - _zone.top;
|
|
39812
39848
|
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
|
39813
39849
|
}
|
|
39814
39850
|
}
|
|
39851
|
+
this.rangeCache[cacheKey] = matrix;
|
|
39815
39852
|
return matrix;
|
|
39816
39853
|
}
|
|
39817
39854
|
}
|
|
@@ -40017,6 +40054,7 @@
|
|
|
40017
40054
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
40018
40055
|
}
|
|
40019
40056
|
updateCompilationParameters() {
|
|
40057
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
40020
40058
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40021
40059
|
}
|
|
40022
40060
|
evaluateCells(positions) {
|
|
@@ -40060,6 +40098,16 @@
|
|
|
40060
40098
|
this.evaluatedCells = new Map();
|
|
40061
40099
|
this.evaluate(this.getAllCells());
|
|
40062
40100
|
}
|
|
40101
|
+
evaluateFormula(sheetId, formulaString) {
|
|
40102
|
+
const compiledFormula = compile(formulaString);
|
|
40103
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40104
|
+
this.updateCompilationParameters();
|
|
40105
|
+
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40106
|
+
if (isMatrix(array)) {
|
|
40107
|
+
return matrixMap(array, (cell) => cell.value);
|
|
40108
|
+
}
|
|
40109
|
+
return array.value;
|
|
40110
|
+
}
|
|
40063
40111
|
getAllCells() {
|
|
40064
40112
|
const positionIds = new JetSet();
|
|
40065
40113
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -40086,6 +40134,7 @@
|
|
|
40086
40134
|
this.nextPositionsToUpdate = cells;
|
|
40087
40135
|
let currentIteration = 0;
|
|
40088
40136
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
40137
|
+
this.updateCompilationParameters();
|
|
40089
40138
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
40090
40139
|
this.nextPositionsToUpdate.clear();
|
|
40091
40140
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -40449,7 +40498,6 @@
|
|
|
40449
40498
|
// of other cells depending on it, at the next iteration.
|
|
40450
40499
|
//#endregion
|
|
40451
40500
|
class EvaluationPlugin extends UIPlugin {
|
|
40452
|
-
config;
|
|
40453
40501
|
static getters = [
|
|
40454
40502
|
"evaluateFormula",
|
|
40455
40503
|
"getCorrespondingFormulaCell",
|
|
@@ -40460,15 +40508,13 @@
|
|
|
40460
40508
|
"getEvaluatedCells",
|
|
40461
40509
|
"getEvaluatedCellsInZone",
|
|
40462
40510
|
"getSpreadPositionsOf",
|
|
40511
|
+
"getArrayFormulaSpreadingOn",
|
|
40463
40512
|
];
|
|
40464
40513
|
shouldRebuildDependenciesGraph = true;
|
|
40465
40514
|
evaluator;
|
|
40466
|
-
compilationParams;
|
|
40467
40515
|
positionsToUpdate = [];
|
|
40468
40516
|
constructor(config) {
|
|
40469
40517
|
super(config);
|
|
40470
|
-
this.config = config;
|
|
40471
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40472
40518
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
40473
40519
|
}
|
|
40474
40520
|
// ---------------------------------------------------------------------------
|
|
@@ -40493,10 +40539,6 @@
|
|
|
40493
40539
|
case "EVALUATE_CELLS":
|
|
40494
40540
|
this.evaluator.evaluateAllCells();
|
|
40495
40541
|
break;
|
|
40496
|
-
case "UPDATE_LOCALE":
|
|
40497
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40498
|
-
this.evaluator.updateCompilationParameters();
|
|
40499
|
-
break;
|
|
40500
40542
|
}
|
|
40501
40543
|
}
|
|
40502
40544
|
finalize() {
|
|
@@ -40514,16 +40556,7 @@
|
|
|
40514
40556
|
// Getters
|
|
40515
40557
|
// ---------------------------------------------------------------------------
|
|
40516
40558
|
evaluateFormula(sheetId, formulaString) {
|
|
40517
|
-
|
|
40518
|
-
const ranges = [];
|
|
40519
|
-
for (let xc of compiledFormula.dependencies) {
|
|
40520
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40521
|
-
}
|
|
40522
|
-
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40523
|
-
if (isMatrix(array)) {
|
|
40524
|
-
return array.map((col) => col.map((row) => row.value));
|
|
40525
|
-
}
|
|
40526
|
-
return array.value;
|
|
40559
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
40527
40560
|
}
|
|
40528
40561
|
/**
|
|
40529
40562
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -40572,6 +40605,9 @@
|
|
|
40572
40605
|
getSpreadPositionsOf(position) {
|
|
40573
40606
|
return this.evaluator.getSpreadPositionsOf(position);
|
|
40574
40607
|
}
|
|
40608
|
+
getArrayFormulaSpreadingOn(position) {
|
|
40609
|
+
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
40610
|
+
}
|
|
40575
40611
|
// ---------------------------------------------------------------------------
|
|
40576
40612
|
// Export
|
|
40577
40613
|
// ---------------------------------------------------------------------------
|
|
@@ -40615,7 +40651,7 @@
|
|
|
40615
40651
|
else if (cell && cell.content) {
|
|
40616
40652
|
return undefined;
|
|
40617
40653
|
}
|
|
40618
|
-
const spreadingFormulaPosition = this.
|
|
40654
|
+
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
40619
40655
|
if (spreadingFormulaPosition === undefined) {
|
|
40620
40656
|
return undefined;
|
|
40621
40657
|
}
|
|
@@ -40625,9 +40661,6 @@
|
|
|
40625
40661
|
}
|
|
40626
40662
|
return undefined;
|
|
40627
40663
|
}
|
|
40628
|
-
getCompilationParameters() {
|
|
40629
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
40630
|
-
}
|
|
40631
40664
|
}
|
|
40632
40665
|
function isBadExpression(tokens) {
|
|
40633
40666
|
try {
|
|
@@ -41768,19 +41801,21 @@
|
|
|
41768
41801
|
let col = zone.left;
|
|
41769
41802
|
let row = zone.bottom;
|
|
41770
41803
|
if (col > 0) {
|
|
41771
|
-
let
|
|
41772
|
-
while (
|
|
41804
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
41805
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
41806
|
+
this.getters.getCell(leftPosition)?.content) {
|
|
41773
41807
|
row += 1;
|
|
41774
|
-
|
|
41808
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
41775
41809
|
}
|
|
41776
41810
|
}
|
|
41777
41811
|
if (row === zone.bottom) {
|
|
41778
41812
|
col = zone.right;
|
|
41779
41813
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
41780
|
-
let
|
|
41781
|
-
while (
|
|
41814
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
41815
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
41816
|
+
this.getters.getCell(rightPosition)?.content) {
|
|
41782
41817
|
row += 1;
|
|
41783
|
-
|
|
41818
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
41784
41819
|
}
|
|
41785
41820
|
}
|
|
41786
41821
|
}
|
|
@@ -42772,6 +42807,7 @@
|
|
|
42772
42807
|
isReplayingInitialRevisions = false;
|
|
42773
42808
|
processedRevisions = new Set();
|
|
42774
42809
|
uuidGenerator = new UuidGenerator();
|
|
42810
|
+
lastLocalOperation;
|
|
42775
42811
|
/**
|
|
42776
42812
|
* Manages the collaboration between multiple users on the same spreadsheet.
|
|
42777
42813
|
* It can forward local state changes to other users to ensure they all eventually
|
|
@@ -42804,6 +42840,11 @@
|
|
|
42804
42840
|
return;
|
|
42805
42841
|
const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes, Date.now());
|
|
42806
42842
|
this.revisions.append(revision.id, revision);
|
|
42843
|
+
// REQUEST_REDO just repeats the last operation, the
|
|
42844
|
+
// last operation is still the same and should not change.
|
|
42845
|
+
if (rootCommand.type !== "REQUEST_REDO") {
|
|
42846
|
+
this.lastLocalOperation = revision;
|
|
42847
|
+
}
|
|
42807
42848
|
this.trigger("new-local-state-update", { id: revision.id });
|
|
42808
42849
|
this.sendUpdateMessage({
|
|
42809
42850
|
type: "REMOTE_REVISION",
|
|
@@ -42900,19 +42941,10 @@
|
|
|
42900
42941
|
return this.pendingMessages.length === 0;
|
|
42901
42942
|
}
|
|
42902
42943
|
/**
|
|
42903
|
-
* Get the last local revision
|
|
42944
|
+
* Get the last local revision
|
|
42904
42945
|
* */
|
|
42905
|
-
getLastLocalNonEmptyRevision(
|
|
42906
|
-
|
|
42907
|
-
for (const rev of revisions) {
|
|
42908
|
-
if (rev.rootCommand === "SNAPSHOT")
|
|
42909
|
-
return undefined;
|
|
42910
|
-
if (!rev.rootCommand || rev.rootCommand === "REMOTE")
|
|
42911
|
-
continue;
|
|
42912
|
-
if (!ignoredRootCommands.includes(rev.rootCommand?.type) && rev.commands.length)
|
|
42913
|
-
return rev;
|
|
42914
|
-
}
|
|
42915
|
-
return undefined;
|
|
42946
|
+
getLastLocalNonEmptyRevision() {
|
|
42947
|
+
return this.lastLocalOperation;
|
|
42916
42948
|
}
|
|
42917
42949
|
_move(position) {
|
|
42918
42950
|
// this method is debounced and might be called after the client
|
|
@@ -42972,7 +43004,7 @@
|
|
|
42972
43004
|
break;
|
|
42973
43005
|
case "REMOTE_REVISION":
|
|
42974
43006
|
const { clientId, commands, timestamp } = message;
|
|
42975
|
-
const revision = new Revision(message.nextRevisionId, clientId, commands,
|
|
43007
|
+
const revision = new Revision(message.nextRevisionId, clientId, commands, undefined, undefined, timestamp);
|
|
42976
43008
|
if (revision.clientId !== this.clientId) {
|
|
42977
43009
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
42978
43010
|
const pendingCommands = this.pendingMessages
|
|
@@ -42985,10 +43017,11 @@
|
|
|
42985
43017
|
}
|
|
42986
43018
|
break;
|
|
42987
43019
|
case "SNAPSHOT_CREATED": {
|
|
42988
|
-
const revision = new Revision(message.nextRevisionId, "server", [],
|
|
43020
|
+
const revision = new Revision(message.nextRevisionId, "server", [], undefined, undefined, Date.now());
|
|
42989
43021
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
42990
43022
|
this.dropPendingHistoryMessages();
|
|
42991
43023
|
this.trigger("snapshot");
|
|
43024
|
+
this.lastLocalOperation = undefined;
|
|
42992
43025
|
break;
|
|
42993
43026
|
}
|
|
42994
43027
|
}
|
|
@@ -43326,11 +43359,26 @@
|
|
|
43326
43359
|
let cellsInRow = [];
|
|
43327
43360
|
for (let col of columnsIndex) {
|
|
43328
43361
|
const position = { col, row, sheetId };
|
|
43362
|
+
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
|
43363
|
+
let cell = getters.getCell(position);
|
|
43364
|
+
const evaluatedCell = getters.getEvaluatedCell(position);
|
|
43365
|
+
if (spreader) {
|
|
43366
|
+
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
|
43367
|
+
const content = isSpreaderCopied
|
|
43368
|
+
? ""
|
|
43369
|
+
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
|
43370
|
+
cell = {
|
|
43371
|
+
id: cell?.id || "",
|
|
43372
|
+
style: cell?.style,
|
|
43373
|
+
format: evaluatedCell.format,
|
|
43374
|
+
content,
|
|
43375
|
+
isFormula: false,
|
|
43376
|
+
};
|
|
43377
|
+
}
|
|
43329
43378
|
cellsInRow.push({
|
|
43330
|
-
cell
|
|
43331
|
-
style: getters.getCellComputedStyle(position),
|
|
43332
|
-
evaluatedCell: getters.getEvaluatedCell(position),
|
|
43379
|
+
cell,
|
|
43333
43380
|
border: getters.getCellBorder(position) || undefined,
|
|
43381
|
+
evaluatedCell,
|
|
43334
43382
|
position,
|
|
43335
43383
|
});
|
|
43336
43384
|
}
|
|
@@ -43452,13 +43500,6 @@
|
|
|
43452
43500
|
});
|
|
43453
43501
|
}
|
|
43454
43502
|
this.pasteCopiedTables(target);
|
|
43455
|
-
this.cells.forEach((row) => {
|
|
43456
|
-
row.forEach((c) => {
|
|
43457
|
-
if (c.cell) {
|
|
43458
|
-
c.cell = undefined;
|
|
43459
|
-
}
|
|
43460
|
-
});
|
|
43461
|
-
});
|
|
43462
43503
|
}
|
|
43463
43504
|
/**
|
|
43464
43505
|
* The clipped zone is copied as many times as it fits in the target.
|
|
@@ -43530,7 +43571,7 @@
|
|
|
43530
43571
|
clearClippedZones() {
|
|
43531
43572
|
for (const row of this.cells) {
|
|
43532
43573
|
for (const cell of row) {
|
|
43533
|
-
if (cell
|
|
43574
|
+
if (cell?.cell) {
|
|
43534
43575
|
this.dispatch("CLEAR_CELL", cell.position);
|
|
43535
43576
|
}
|
|
43536
43577
|
}
|
|
@@ -43556,6 +43597,9 @@
|
|
|
43556
43597
|
const rowCells = this.cells[r];
|
|
43557
43598
|
for (let c = 0; c < width; c++) {
|
|
43558
43599
|
const origin = rowCells[c];
|
|
43600
|
+
if (!origin) {
|
|
43601
|
+
continue;
|
|
43602
|
+
}
|
|
43559
43603
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
43560
43604
|
// TODO: refactor this part. the "Paste merge" action is also executed with
|
|
43561
43605
|
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
@@ -43579,53 +43623,42 @@
|
|
|
43579
43623
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43580
43624
|
const { sheetId, col, row } = target;
|
|
43581
43625
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43582
|
-
if (clipboardOption?.pasteOption
|
|
43583
|
-
const
|
|
43584
|
-
const
|
|
43585
|
-
|
|
43586
|
-
|
|
43587
|
-
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43588
|
-
left: targetBorders?.left || originBorders?.left,
|
|
43589
|
-
right: targetBorders?.right || originBorders?.right,
|
|
43590
|
-
};
|
|
43591
|
-
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43626
|
+
if (clipboardOption?.pasteOption === "onlyValue") {
|
|
43627
|
+
const locale = this.getters.getLocale();
|
|
43628
|
+
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43629
|
+
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
43630
|
+
return;
|
|
43592
43631
|
}
|
|
43593
|
-
|
|
43594
|
-
|
|
43595
|
-
|
|
43596
|
-
|
|
43597
|
-
|
|
43598
|
-
|
|
43599
|
-
|
|
43600
|
-
|
|
43601
|
-
|
|
43602
|
-
|
|
43603
|
-
|
|
43604
|
-
|
|
43605
|
-
|
|
43606
|
-
|
|
43607
|
-
}
|
|
43608
|
-
|
|
43609
|
-
|
|
43610
|
-
|
|
43611
|
-
|
|
43632
|
+
const targetBorders = this.getters.getCellBorder(target);
|
|
43633
|
+
const originBorders = origin.border;
|
|
43634
|
+
const border = {
|
|
43635
|
+
top: targetBorders?.top || originBorders?.top,
|
|
43636
|
+
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43637
|
+
left: targetBorders?.left || originBorders?.left,
|
|
43638
|
+
right: targetBorders?.right || originBorders?.right,
|
|
43639
|
+
};
|
|
43640
|
+
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43641
|
+
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43642
|
+
this.dispatch("UPDATE_CELL", {
|
|
43643
|
+
...target,
|
|
43644
|
+
style: origin.cell?.style ?? null,
|
|
43645
|
+
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
|
43646
|
+
});
|
|
43647
|
+
return;
|
|
43648
|
+
}
|
|
43649
|
+
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
|
43650
|
+
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
|
43651
|
+
: origin.cell?.content;
|
|
43652
|
+
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
|
43612
43653
|
this.dispatch("UPDATE_CELL", {
|
|
43613
43654
|
...target,
|
|
43614
43655
|
content,
|
|
43615
|
-
style: origin.cell
|
|
43616
|
-
format: origin.cell
|
|
43656
|
+
style: origin.cell?.style || null,
|
|
43657
|
+
format: origin.cell?.format,
|
|
43617
43658
|
});
|
|
43618
43659
|
}
|
|
43619
43660
|
else if (targetCell) {
|
|
43620
|
-
|
|
43621
|
-
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
|
43622
|
-
}
|
|
43623
|
-
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43624
|
-
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
|
43625
|
-
}
|
|
43626
|
-
else {
|
|
43627
|
-
this.dispatch("CLEAR_CELL", target);
|
|
43628
|
-
}
|
|
43661
|
+
this.dispatch("CLEAR_CELL", target);
|
|
43629
43662
|
}
|
|
43630
43663
|
}
|
|
43631
43664
|
/**
|
|
@@ -43687,22 +43720,28 @@
|
|
|
43687
43720
|
return (this.cells
|
|
43688
43721
|
.map((cells) => {
|
|
43689
43722
|
return cells
|
|
43690
|
-
.map((c) => this.getters.shouldShowFormulas() && c
|
|
43723
|
+
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
|
43691
43724
|
? c.cell?.content || ""
|
|
43692
|
-
: c
|
|
43725
|
+
: c?.evaluatedCell?.formattedValue || "")
|
|
43693
43726
|
.join("\t");
|
|
43694
43727
|
})
|
|
43695
43728
|
.join("\n") || "\t");
|
|
43696
43729
|
}
|
|
43697
43730
|
getHTMLContent() {
|
|
43698
43731
|
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
|
43732
|
+
if (!this.cells[0][0]) {
|
|
43733
|
+
return "";
|
|
43734
|
+
}
|
|
43699
43735
|
return this.getters.getCellText(this.cells[0][0].position);
|
|
43700
43736
|
}
|
|
43701
43737
|
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
|
43702
43738
|
for (const row of this.cells) {
|
|
43703
43739
|
htmlTable += "<tr>";
|
|
43704
43740
|
for (const cell of row) {
|
|
43705
|
-
|
|
43741
|
+
if (!cell) {
|
|
43742
|
+
continue;
|
|
43743
|
+
}
|
|
43744
|
+
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
|
43706
43745
|
const cellText = this.getters.getCellText(cell.position);
|
|
43707
43746
|
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
|
43708
43747
|
}
|
|
@@ -45537,6 +45576,9 @@
|
|
|
45537
45576
|
// Other
|
|
45538
45577
|
// ---------------------------------------------------------------------------
|
|
45539
45578
|
initInput(id, initialRanges, inputHasSingleRange = false) {
|
|
45579
|
+
if (this.inputs[id]) {
|
|
45580
|
+
this.unfocus();
|
|
45581
|
+
}
|
|
45540
45582
|
this.inputs[id] = new SelectionInputPlugin(this.config, initialRanges, inputHasSingleRange);
|
|
45541
45583
|
if (initialRanges.length === 0) {
|
|
45542
45584
|
const input = this.inputs[id];
|
|
@@ -46335,7 +46377,7 @@
|
|
|
46335
46377
|
* Ignore standard undo/redo revisions (that are empty)
|
|
46336
46378
|
*/
|
|
46337
46379
|
getPossibleRevisionToRepeat() {
|
|
46338
|
-
return this.session.getLastLocalNonEmptyRevision(
|
|
46380
|
+
return this.session.getLastLocalNonEmptyRevision();
|
|
46339
46381
|
}
|
|
46340
46382
|
}
|
|
46341
46383
|
|
|
@@ -46832,11 +46874,14 @@
|
|
|
46832
46874
|
}
|
|
46833
46875
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
46834
46876
|
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
|
46877
|
+
if (this.state.operation === "CUT") {
|
|
46878
|
+
this.state = undefined;
|
|
46879
|
+
}
|
|
46835
46880
|
this.lastPasteState = this.state;
|
|
46836
46881
|
if (this.paintFormatStatus === "oneOff") {
|
|
46837
46882
|
this.paintFormatStatus = "inactive";
|
|
46838
|
-
this.status = "invisible";
|
|
46839
46883
|
}
|
|
46884
|
+
this.status = "invisible";
|
|
46840
46885
|
break;
|
|
46841
46886
|
case "COPY_PASTE_CELLS_ABOVE":
|
|
46842
46887
|
{
|
|
@@ -47117,6 +47162,10 @@
|
|
|
47117
47162
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47118
47163
|
case "colrow":
|
|
47119
47164
|
indexOfNumber = xc.search(/[0-9]/);
|
|
47165
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
47166
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
47167
|
+
return "$" + xc;
|
|
47168
|
+
}
|
|
47120
47169
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47121
47170
|
return "$" + xc;
|
|
47122
47171
|
case "none":
|
|
@@ -47887,6 +47936,12 @@
|
|
|
47887
47936
|
break;
|
|
47888
47937
|
case "HIDE_COLUMNS_ROWS":
|
|
47889
47938
|
case "UNHIDE_COLUMNS_ROWS":
|
|
47939
|
+
case "GROUP_HEADERS":
|
|
47940
|
+
case "UNGROUP_HEADERS":
|
|
47941
|
+
case "FOLD_HEADER_GROUP":
|
|
47942
|
+
case "UNFOLD_HEADER_GROUP":
|
|
47943
|
+
case "FOLD_ALL_HEADER_GROUPS":
|
|
47944
|
+
case "UNFOLD_ALL_HEADER_GROUPS":
|
|
47890
47945
|
this.updateHiddenRows();
|
|
47891
47946
|
break;
|
|
47892
47947
|
case "UPDATE_FILTER":
|
|
@@ -48588,7 +48643,7 @@
|
|
|
48588
48643
|
sheetId: cmd.sheetId,
|
|
48589
48644
|
base: cmd.base,
|
|
48590
48645
|
quantity: thickness,
|
|
48591
|
-
position:
|
|
48646
|
+
position: cmd.position,
|
|
48592
48647
|
});
|
|
48593
48648
|
const isCol = cmd.dimension === "COL";
|
|
48594
48649
|
const start = cmd.elements[0];
|
|
@@ -48605,12 +48660,13 @@
|
|
|
48605
48660
|
},
|
|
48606
48661
|
];
|
|
48607
48662
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
48663
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
48608
48664
|
const pasteTarget = [
|
|
48609
48665
|
{
|
|
48610
|
-
left: isCol ?
|
|
48611
|
-
right: isCol ?
|
|
48612
|
-
top: !isCol ?
|
|
48613
|
-
bottom: !isCol ?
|
|
48666
|
+
left: isCol ? base : 0,
|
|
48667
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
48668
|
+
top: !isCol ? base : 0,
|
|
48669
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
48614
48670
|
},
|
|
48615
48671
|
];
|
|
48616
48672
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -48645,6 +48701,11 @@
|
|
|
48645
48701
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
48646
48702
|
return "WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */;
|
|
48647
48703
|
}
|
|
48704
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
48705
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
48706
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
48707
|
+
return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
|
|
48708
|
+
}
|
|
48648
48709
|
return "Success" /* CommandResult.Success */;
|
|
48649
48710
|
}
|
|
48650
48711
|
//-------------------------------------------
|
|
@@ -49690,10 +49751,13 @@
|
|
|
49690
49751
|
}
|
|
49691
49752
|
break;
|
|
49692
49753
|
case "UPDATE_CELL":
|
|
49693
|
-
if ("content" in cmd || "format" in cmd
|
|
49754
|
+
if ("content" in cmd || "format" in cmd) {
|
|
49694
49755
|
this.headerPositions = {};
|
|
49695
49756
|
this.isDirty = true;
|
|
49696
49757
|
}
|
|
49758
|
+
else {
|
|
49759
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
49760
|
+
}
|
|
49697
49761
|
break;
|
|
49698
49762
|
case "UPDATE_FILTER":
|
|
49699
49763
|
case "REMOVE_FILTER_TABLE":
|
|
@@ -51850,6 +51914,8 @@
|
|
|
51850
51914
|
*:before,
|
|
51851
51915
|
*:after {
|
|
51852
51916
|
box-sizing: content-box;
|
|
51917
|
+
/** rtl not supported ATM */
|
|
51918
|
+
direction: ltr;
|
|
51853
51919
|
}
|
|
51854
51920
|
.o-separator {
|
|
51855
51921
|
border-bottom: ${MENU_SEPARATOR_BORDER_WIDTH}px solid ${SEPARATOR_COLOR};
|
|
@@ -55560,19 +55626,22 @@
|
|
|
55560
55626
|
* Check if the given command is allowed by all the plugins and the history.
|
|
55561
55627
|
*/
|
|
55562
55628
|
checkDispatchAllowed(command) {
|
|
55563
|
-
|
|
55564
|
-
|
|
55629
|
+
const results = isCoreCommand(command)
|
|
55630
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
55631
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
55632
|
+
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
|
55633
|
+
return new DispatchResult(results.flat());
|
|
55565
55634
|
}
|
|
55566
|
-
return
|
|
55635
|
+
return DispatchResult.Success;
|
|
55567
55636
|
}
|
|
55568
55637
|
checkDispatchAllowedCoreCommand(command) {
|
|
55569
55638
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
55570
55639
|
results.push(this.range.allowDispatch(command));
|
|
55571
|
-
return
|
|
55640
|
+
return results;
|
|
55572
55641
|
}
|
|
55573
55642
|
checkDispatchAllowedLocalCommand(command) {
|
|
55574
55643
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
55575
|
-
return
|
|
55644
|
+
return results;
|
|
55576
55645
|
}
|
|
55577
55646
|
finalize() {
|
|
55578
55647
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -55919,9 +55988,9 @@
|
|
|
55919
55988
|
exports.tokenize = tokenize;
|
|
55920
55989
|
|
|
55921
55990
|
|
|
55922
|
-
__info__.version = "17.0.
|
|
55923
|
-
__info__.date = "2023-
|
|
55924
|
-
__info__.hash = "
|
|
55991
|
+
__info__.version = "17.0.5";
|
|
55992
|
+
__info__.date = "2023-12-05T09:51:44.657Z";
|
|
55993
|
+
__info__.hash = "2480a5d";
|
|
55925
55994
|
|
|
55926
55995
|
|
|
55927
55996
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|