@odoo/o-spreadsheet 17.1.0-alpha.3 → 17.1.0-alpha.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 +769 -520
- package/dist/o-spreadsheet.d.ts +164 -164
- package/dist/o-spreadsheet.esm.js +769 -520
- package/dist/o-spreadsheet.iife.js +769 -520
- package/dist/o-spreadsheet.iife.min.js +299 -327
- package/dist/o_spreadsheet.xml +100 -62
- 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.1.0-alpha.
|
|
6
|
-
* @date 2023-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.0-alpha.5
|
|
6
|
+
* @date 2023-12-05T09:51:40.034Z
|
|
7
|
+
* @hash c2823eb
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
(function (exports, owl) {
|
|
@@ -228,7 +228,6 @@
|
|
|
228
228
|
const SCROLLBAR_WIDTH = 15;
|
|
229
229
|
const AUTOFILL_EDGE_LENGTH = 8;
|
|
230
230
|
const ICON_EDGE_LENGTH = 18;
|
|
231
|
-
const UNHIDE_ICON_EDGE_LENGTH = 14;
|
|
232
231
|
const MIN_CF_ICON_MARGIN = 4;
|
|
233
232
|
const MIN_CELL_TEXT_MARGIN = 4;
|
|
234
233
|
const CF_ICON_EDGE_LENGTH = 15;
|
|
@@ -692,8 +691,7 @@
|
|
|
692
691
|
*
|
|
693
692
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
694
693
|
*/
|
|
695
|
-
const
|
|
696
|
-
" ",
|
|
694
|
+
const whiteSpaceSpecialCharacters = [
|
|
697
695
|
"\t",
|
|
698
696
|
"\f",
|
|
699
697
|
"\v",
|
|
@@ -708,8 +706,7 @@
|
|
|
708
706
|
String.fromCharCode(parseInt("3000", 16)),
|
|
709
707
|
String.fromCharCode(parseInt("feff", 16)),
|
|
710
708
|
];
|
|
711
|
-
const whiteSpaceRegexp = new RegExp(
|
|
712
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
709
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
713
710
|
/**
|
|
714
711
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
715
712
|
* different newlines types by \n.
|
|
@@ -717,9 +714,9 @@
|
|
|
717
714
|
function replaceSpecialSpaces(text) {
|
|
718
715
|
if (!text)
|
|
719
716
|
return "";
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
return text;
|
|
717
|
+
if (!whiteSpaceRegexp.test(text))
|
|
718
|
+
return text;
|
|
719
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
723
720
|
}
|
|
724
721
|
/**
|
|
725
722
|
* Determine if the numbers are consecutive.
|
|
@@ -2061,6 +2058,7 @@
|
|
|
2061
2058
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2062
2059
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2063
2060
|
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2061
|
+
CommandResult["NoChanges"] = "NoChanges";
|
|
2064
2062
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
2065
2063
|
|
|
2066
2064
|
const DEFAULT_LOCALES = [
|
|
@@ -2190,12 +2188,12 @@
|
|
|
2190
2188
|
}
|
|
2191
2189
|
}
|
|
2192
2190
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2193
|
-
function normalizeString(str) {
|
|
2191
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
2194
2192
|
return str
|
|
2195
2193
|
.toLowerCase()
|
|
2196
2194
|
.normalize("NFD")
|
|
2197
2195
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2198
|
-
}
|
|
2196
|
+
});
|
|
2199
2197
|
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
2198
|
function toBoolean(value) {
|
|
2201
2199
|
switch (typeof value) {
|
|
@@ -3389,8 +3387,10 @@
|
|
|
3389
3387
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
3390
3388
|
// Same as above, but matches the exact string (nothing before or after)
|
|
3391
3389
|
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(
|
|
3390
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
3391
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
3392
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
3393
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
3394
3394
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
3395
3395
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
3396
3396
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -3420,6 +3420,9 @@
|
|
|
3420
3420
|
function isColHeader(str) {
|
|
3421
3421
|
return colHeader.test(str);
|
|
3422
3422
|
}
|
|
3423
|
+
function isRowHeader(str) {
|
|
3424
|
+
return rowHeader.test(str);
|
|
3425
|
+
}
|
|
3423
3426
|
/**
|
|
3424
3427
|
* Return true if the given xc is the reference of a single cell,
|
|
3425
3428
|
* without any specified sheet (e.g. A1)
|
|
@@ -3428,11 +3431,18 @@
|
|
|
3428
3431
|
return singleCellReference.test(xc);
|
|
3429
3432
|
}
|
|
3430
3433
|
function splitReference(ref) {
|
|
3434
|
+
if (!ref.includes("!")) {
|
|
3435
|
+
return { xc: ref };
|
|
3436
|
+
}
|
|
3431
3437
|
const parts = ref.split("!");
|
|
3432
3438
|
const xc = parts.pop();
|
|
3433
3439
|
const sheetName = getUnquotedSheetName(parts.join("!")) || undefined;
|
|
3434
3440
|
return { sheetName, xc };
|
|
3435
3441
|
}
|
|
3442
|
+
/** Return a reference SheetName!xc from the given arguments */
|
|
3443
|
+
function getFullReference(sheetName, xc) {
|
|
3444
|
+
return sheetName !== undefined ? `${getCanonicalSheetName(sheetName)}!${xc}` : xc;
|
|
3445
|
+
}
|
|
3436
3446
|
|
|
3437
3447
|
/**
|
|
3438
3448
|
* Convert from a cartesian reference to a Zone
|
|
@@ -4103,18 +4113,10 @@
|
|
|
4103
4113
|
if (isFullCol) {
|
|
4104
4114
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
4105
4115
|
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
4116
|
}
|
|
4111
4117
|
if (isFullRow) {
|
|
4112
4118
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
4113
4119
|
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
4120
|
}
|
|
4119
4121
|
return parts;
|
|
4120
4122
|
}
|
|
@@ -4356,7 +4358,7 @@
|
|
|
4356
4358
|
function getDefaultCellHeight(ctx, cell, colSize) {
|
|
4357
4359
|
if (!cell || !cell.content)
|
|
4358
4360
|
return DEFAULT_CELL_HEIGHT;
|
|
4359
|
-
const maxWidth = cell.style?.wrapping ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4361
|
+
const maxWidth = cell.style?.wrapping === "wrap" ? colSize - 2 * MIN_CELL_TEXT_MARGIN : undefined;
|
|
4360
4362
|
const numberOfLines = cell.isFormula
|
|
4361
4363
|
? 1
|
|
4362
4364
|
: splitTextToWidth(ctx, cell.content, cell.style, maxWidth).length;
|
|
@@ -4541,14 +4543,14 @@
|
|
|
4541
4543
|
switch (context.textBaseline) {
|
|
4542
4544
|
case "top":
|
|
4543
4545
|
underlineY += boxHeight - 2 * strokeWidth;
|
|
4544
|
-
strikeY += boxHeight -
|
|
4546
|
+
strikeY += boxHeight / 2 - strokeWidth;
|
|
4545
4547
|
break;
|
|
4546
4548
|
case "middle":
|
|
4547
4549
|
underlineY += boxHeight / 2 - strokeWidth;
|
|
4548
4550
|
break;
|
|
4549
4551
|
case "alphabetic":
|
|
4550
4552
|
underlineY += 2 * strokeWidth;
|
|
4551
|
-
strikeY -=
|
|
4553
|
+
strikeY -= 3 * strokeWidth;
|
|
4552
4554
|
break;
|
|
4553
4555
|
case "bottom":
|
|
4554
4556
|
underlineY = y;
|
|
@@ -4611,6 +4613,7 @@
|
|
|
4611
4613
|
const children = item.children;
|
|
4612
4614
|
const description = item.description;
|
|
4613
4615
|
const icon = item.icon;
|
|
4616
|
+
const secondaryIcon = item.secondaryIcon;
|
|
4614
4617
|
return {
|
|
4615
4618
|
id: item.id || uuidGenerator$2.uuidv4(),
|
|
4616
4619
|
name: typeof name === "function" ? name : () => name,
|
|
@@ -4629,6 +4632,7 @@
|
|
|
4629
4632
|
isReadonlyAllowed: item.isReadonlyAllowed || false,
|
|
4630
4633
|
separator: item.separator || false,
|
|
4631
4634
|
icon: typeof icon === "function" ? icon : () => icon || "",
|
|
4635
|
+
secondaryIcon: typeof secondaryIcon === "function" ? secondaryIcon : () => secondaryIcon || "",
|
|
4632
4636
|
description: typeof description === "function" ? description : () => description || "",
|
|
4633
4637
|
textColor: item.textColor,
|
|
4634
4638
|
sequence: item.sequence || 0,
|
|
@@ -6251,10 +6255,6 @@
|
|
|
6251
6255
|
|
|
6252
6256
|
.o-error-tooltip-message {
|
|
6253
6257
|
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
6258
|
}
|
|
6259
6259
|
}
|
|
6260
6260
|
`;
|
|
@@ -6662,6 +6662,9 @@
|
|
|
6662
6662
|
keyDownString += letterRegex.test(key) ? key.toUpperCase() : key;
|
|
6663
6663
|
return keyDownString;
|
|
6664
6664
|
}
|
|
6665
|
+
function isMacOS() {
|
|
6666
|
+
return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
6667
|
+
}
|
|
6665
6668
|
|
|
6666
6669
|
/**
|
|
6667
6670
|
* Return the o-spreadsheet element position relative
|
|
@@ -6984,11 +6987,9 @@
|
|
|
6984
6987
|
padding: ${MENU_VERTICAL_PADDING}px 0px;
|
|
6985
6988
|
width: ${MENU_WIDTH}px;
|
|
6986
6989
|
box-sizing: border-box !important;
|
|
6990
|
+
user-select: none;
|
|
6987
6991
|
|
|
6988
6992
|
.o-menu-item {
|
|
6989
|
-
display: flex;
|
|
6990
|
-
justify-content: space-between;
|
|
6991
|
-
align-items: center;
|
|
6992
6993
|
box-sizing: border-box;
|
|
6993
6994
|
height: ${MENU_ITEM_HEIGHT}px;
|
|
6994
6995
|
padding: ${MENU_ITEM_PADDING_VERTICAL}px ${MENU_ITEM_PADDING_HORIZONTAL}px;
|
|
@@ -6999,20 +7000,12 @@
|
|
|
6999
7000
|
min-width: 40%;
|
|
7000
7001
|
}
|
|
7001
7002
|
|
|
7002
|
-
&.o-menu-root {
|
|
7003
|
-
display: flex;
|
|
7004
|
-
justify-content: space-between;
|
|
7005
|
-
}
|
|
7006
|
-
|
|
7007
7003
|
.o-menu-item-icon {
|
|
7008
7004
|
display: inline-block;
|
|
7009
7005
|
margin: 0px 8px 0px 0px;
|
|
7010
7006
|
width: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7011
7007
|
line-height: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7012
7008
|
}
|
|
7013
|
-
.o-menu-item-root {
|
|
7014
|
-
width: 10px;
|
|
7015
|
-
}
|
|
7016
7009
|
|
|
7017
7010
|
&:not(.disabled) {
|
|
7018
7011
|
&:hover,
|
|
@@ -7355,7 +7348,7 @@
|
|
|
7355
7348
|
return result;
|
|
7356
7349
|
}
|
|
7357
7350
|
function tokenizeDebugger(chars) {
|
|
7358
|
-
if (chars.current
|
|
7351
|
+
if (chars.current === "?") {
|
|
7359
7352
|
chars.shift();
|
|
7360
7353
|
return { type: "DEBUGGER", value: "?" };
|
|
7361
7354
|
}
|
|
@@ -7366,7 +7359,7 @@
|
|
|
7366
7359
|
")": "RIGHT_PAREN",
|
|
7367
7360
|
};
|
|
7368
7361
|
function tokenizeMisc(chars) {
|
|
7369
|
-
if (chars.current
|
|
7362
|
+
if (chars.current in misc$1) {
|
|
7370
7363
|
const value = chars.shift();
|
|
7371
7364
|
const type = misc$1[value];
|
|
7372
7365
|
return { type, value };
|
|
@@ -7374,7 +7367,7 @@
|
|
|
7374
7367
|
return null;
|
|
7375
7368
|
}
|
|
7376
7369
|
function tokenizeArgsSeparator(chars, locale) {
|
|
7377
|
-
if (chars.current
|
|
7370
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
7378
7371
|
const value = chars.shift();
|
|
7379
7372
|
const type = "ARG_SEPARATOR";
|
|
7380
7373
|
return { type, value };
|
|
@@ -7399,14 +7392,13 @@
|
|
|
7399
7392
|
return null;
|
|
7400
7393
|
}
|
|
7401
7394
|
function tokenizeString(chars) {
|
|
7402
|
-
if (chars.current
|
|
7395
|
+
if (chars.current === '"') {
|
|
7403
7396
|
const startChar = chars.shift();
|
|
7404
7397
|
let letters = startChar;
|
|
7405
|
-
while (chars.current()
|
|
7406
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7398
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7407
7399
|
letters += chars.shift();
|
|
7408
7400
|
}
|
|
7409
|
-
if (chars.current
|
|
7401
|
+
if (chars.current === '"') {
|
|
7410
7402
|
letters += chars.shift();
|
|
7411
7403
|
}
|
|
7412
7404
|
return {
|
|
@@ -7433,14 +7425,14 @@
|
|
|
7433
7425
|
let result = "";
|
|
7434
7426
|
// there are two main cases to manage: either something which starts with
|
|
7435
7427
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
7436
|
-
if (chars.current
|
|
7428
|
+
if (chars.current === "'") {
|
|
7437
7429
|
let lastChar = chars.shift();
|
|
7438
7430
|
result += lastChar;
|
|
7439
|
-
while (chars.current
|
|
7431
|
+
while (chars.current) {
|
|
7440
7432
|
lastChar = chars.shift();
|
|
7441
7433
|
result += lastChar;
|
|
7442
7434
|
if (lastChar === "'") {
|
|
7443
|
-
if (chars.current
|
|
7435
|
+
if (chars.current && chars.current === "'") {
|
|
7444
7436
|
lastChar = chars.shift();
|
|
7445
7437
|
result += lastChar;
|
|
7446
7438
|
}
|
|
@@ -7456,7 +7448,7 @@
|
|
|
7456
7448
|
};
|
|
7457
7449
|
}
|
|
7458
7450
|
}
|
|
7459
|
-
while (chars.current
|
|
7451
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
7460
7452
|
result += chars.shift();
|
|
7461
7453
|
}
|
|
7462
7454
|
if (result.length) {
|
|
@@ -7471,14 +7463,14 @@
|
|
|
7471
7463
|
}
|
|
7472
7464
|
function tokenizeSpace(chars) {
|
|
7473
7465
|
let length = 0;
|
|
7474
|
-
while (chars.current
|
|
7466
|
+
while (chars.current === NEWLINE) {
|
|
7475
7467
|
length++;
|
|
7476
7468
|
chars.shift();
|
|
7477
7469
|
}
|
|
7478
7470
|
if (length) {
|
|
7479
7471
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
7480
7472
|
}
|
|
7481
|
-
while (chars.current
|
|
7473
|
+
while (chars.current === " ") {
|
|
7482
7474
|
length++;
|
|
7483
7475
|
chars.shift();
|
|
7484
7476
|
}
|
|
@@ -7497,17 +7489,20 @@
|
|
|
7497
7489
|
class TokenizingChars {
|
|
7498
7490
|
text;
|
|
7499
7491
|
currentIndex = 0;
|
|
7492
|
+
current;
|
|
7500
7493
|
constructor(text) {
|
|
7501
7494
|
this.text = text;
|
|
7502
|
-
|
|
7503
|
-
current() {
|
|
7504
|
-
return this.text[this.currentIndex];
|
|
7495
|
+
this.current = text[0];
|
|
7505
7496
|
}
|
|
7506
7497
|
shift() {
|
|
7507
|
-
|
|
7498
|
+
const current = this.current;
|
|
7499
|
+
const next = this.text[++this.currentIndex];
|
|
7500
|
+
this.current = next;
|
|
7501
|
+
return current;
|
|
7508
7502
|
}
|
|
7509
7503
|
advanceBy(length) {
|
|
7510
7504
|
this.currentIndex += length;
|
|
7505
|
+
this.current = this.text[this.currentIndex];
|
|
7511
7506
|
}
|
|
7512
7507
|
isOver() {
|
|
7513
7508
|
return this.currentIndex >= this.text.length;
|
|
@@ -11311,7 +11306,7 @@
|
|
|
11311
11306
|
) {
|
|
11312
11307
|
const _array = toMatrix(arg);
|
|
11313
11308
|
const _nbRows = toInteger(rows?.value, this.locale);
|
|
11314
|
-
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.
|
|
11309
|
+
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.locale) : _array.length;
|
|
11315
11310
|
assert(() => _nbRows >= _array[0].length, _t("The rows arguments (%s) must be greater or equal than the number of rows of the array.", _nbRows.toString()));
|
|
11316
11311
|
assert(() => _nbColumns >= _array.length, _t("The columns arguments (%s) must be greater or equal than the number of columns of the array.", _nbColumns.toString()));
|
|
11317
11312
|
return generateMatrix(_nbColumns, _nbRows, (col, row) => col >= _array.length || row >= _array[col].length ? padWith : _array[col][row]);
|
|
@@ -11800,6 +11795,10 @@
|
|
|
11800
11795
|
FORMAT_LARGE_NUMBER: FORMAT_LARGE_NUMBER
|
|
11801
11796
|
});
|
|
11802
11797
|
|
|
11798
|
+
function sum(values, locale) {
|
|
11799
|
+
return reduceNumbers(values, (acc, a) => acc + a, 0, locale);
|
|
11800
|
+
}
|
|
11801
|
+
|
|
11803
11802
|
const DEFAULT_FACTOR = 1;
|
|
11804
11803
|
const DEFAULT_MODE = 0;
|
|
11805
11804
|
const DEFAULT_PLACES = 0;
|
|
@@ -12751,7 +12750,7 @@
|
|
|
12751
12750
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
12752
12751
|
},
|
|
12753
12752
|
compute: function (...values) {
|
|
12754
|
-
return
|
|
12753
|
+
return sum(values, this.locale);
|
|
12755
12754
|
},
|
|
12756
12755
|
isExported: true,
|
|
12757
12756
|
};
|
|
@@ -12920,6 +12919,44 @@
|
|
|
12920
12919
|
const dims = args[0].length;
|
|
12921
12920
|
args.forEach((arg, i) => assert(() => arg.length === dims, _t("[[FUNCTION_NAME]] has mismatched dimensions for argument %s (%s vs %s).", i.toString(), dims.toString(), arg.length.toString())));
|
|
12922
12921
|
}
|
|
12922
|
+
function average(values, locale) {
|
|
12923
|
+
let count = 0;
|
|
12924
|
+
const sum = reduceNumbers(values, (acc, a) => {
|
|
12925
|
+
count += 1;
|
|
12926
|
+
return acc + a;
|
|
12927
|
+
}, 0, locale);
|
|
12928
|
+
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
12929
|
+
return sum / count;
|
|
12930
|
+
}
|
|
12931
|
+
function countNumbers(values, locale) {
|
|
12932
|
+
let count = 0;
|
|
12933
|
+
for (let n of values) {
|
|
12934
|
+
if (isMatrix(n)) {
|
|
12935
|
+
for (let i of n) {
|
|
12936
|
+
for (let j of i) {
|
|
12937
|
+
if (typeof j === "number") {
|
|
12938
|
+
count += 1;
|
|
12939
|
+
}
|
|
12940
|
+
}
|
|
12941
|
+
}
|
|
12942
|
+
}
|
|
12943
|
+
else if (typeof n !== "string" || isNumber(n, locale) || parseDateTime(n, locale)) {
|
|
12944
|
+
count += 1;
|
|
12945
|
+
}
|
|
12946
|
+
}
|
|
12947
|
+
return count;
|
|
12948
|
+
}
|
|
12949
|
+
function countAny(values) {
|
|
12950
|
+
return reduceAny(values, (acc, a) => (a !== undefined && a !== null ? acc + 1 : acc), 0);
|
|
12951
|
+
}
|
|
12952
|
+
function max(values, locale) {
|
|
12953
|
+
const result = reduceNumbers(values, (acc, a) => (acc < a ? a : acc), -Infinity, locale);
|
|
12954
|
+
return result === -Infinity ? 0 : result;
|
|
12955
|
+
}
|
|
12956
|
+
function min(values, locale) {
|
|
12957
|
+
const result = reduceNumbers(values, (acc, a) => (a < acc ? a : acc), Infinity, locale);
|
|
12958
|
+
return result === Infinity ? 0 : result;
|
|
12959
|
+
}
|
|
12923
12960
|
|
|
12924
12961
|
function filterAndFlatData(dataY, dataX) {
|
|
12925
12962
|
const _flatDataY = [];
|
|
@@ -13190,13 +13227,7 @@
|
|
|
13190
13227
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13191
13228
|
},
|
|
13192
13229
|
compute: function (...values) {
|
|
13193
|
-
|
|
13194
|
-
const sum = reduceNumbers(values, (acc, a) => {
|
|
13195
|
-
count += 1;
|
|
13196
|
-
return acc + a;
|
|
13197
|
-
}, 0, this.locale);
|
|
13198
|
-
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
13199
|
-
return sum / count;
|
|
13230
|
+
return average(values, this.locale);
|
|
13200
13231
|
},
|
|
13201
13232
|
isExported: true,
|
|
13202
13233
|
};
|
|
@@ -13354,24 +13385,7 @@
|
|
|
13354
13385
|
],
|
|
13355
13386
|
returns: ["NUMBER"],
|
|
13356
13387
|
compute: function (...values) {
|
|
13357
|
-
|
|
13358
|
-
for (let n of values) {
|
|
13359
|
-
if (isMatrix(n)) {
|
|
13360
|
-
for (let i of n) {
|
|
13361
|
-
for (let j of i) {
|
|
13362
|
-
if (typeof j === "number") {
|
|
13363
|
-
count += 1;
|
|
13364
|
-
}
|
|
13365
|
-
}
|
|
13366
|
-
}
|
|
13367
|
-
}
|
|
13368
|
-
else if (typeof n !== "string" ||
|
|
13369
|
-
isNumber(n, this.locale) ||
|
|
13370
|
-
parseDateTime(n, this.locale)) {
|
|
13371
|
-
count += 1;
|
|
13372
|
-
}
|
|
13373
|
-
}
|
|
13374
|
-
return count;
|
|
13388
|
+
return countNumbers(values, this.locale);
|
|
13375
13389
|
},
|
|
13376
13390
|
isExported: true,
|
|
13377
13391
|
};
|
|
@@ -13386,7 +13400,7 @@
|
|
|
13386
13400
|
],
|
|
13387
13401
|
returns: ["NUMBER"],
|
|
13388
13402
|
compute: function (...values) {
|
|
13389
|
-
return
|
|
13403
|
+
return countAny(values);
|
|
13390
13404
|
},
|
|
13391
13405
|
isExported: true,
|
|
13392
13406
|
};
|
|
@@ -13616,8 +13630,7 @@
|
|
|
13616
13630
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13617
13631
|
},
|
|
13618
13632
|
compute: function (...values) {
|
|
13619
|
-
|
|
13620
|
-
return result === -Infinity ? 0 : result;
|
|
13633
|
+
return max(values, this.locale);
|
|
13621
13634
|
},
|
|
13622
13635
|
isExported: true,
|
|
13623
13636
|
};
|
|
@@ -13704,8 +13717,7 @@
|
|
|
13704
13717
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13705
13718
|
},
|
|
13706
13719
|
compute: function (...values) {
|
|
13707
|
-
|
|
13708
|
-
return result === Infinity ? 0 : result;
|
|
13720
|
+
return min(values, this.locale);
|
|
13709
13721
|
},
|
|
13710
13722
|
isExported: true,
|
|
13711
13723
|
};
|
|
@@ -17876,6 +17888,153 @@
|
|
|
17876
17888
|
YIELDMAT: YIELDMAT
|
|
17877
17889
|
});
|
|
17878
17890
|
|
|
17891
|
+
/**
|
|
17892
|
+
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
17893
|
+
*
|
|
17894
|
+
* Eg. :
|
|
17895
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17896
|
+
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
17897
|
+
*/
|
|
17898
|
+
function loopThroughReferenceType(token) {
|
|
17899
|
+
if (token.type !== "REFERENCE")
|
|
17900
|
+
return token;
|
|
17901
|
+
const { xc, sheetName } = splitReference(token.value);
|
|
17902
|
+
const [left, right] = xc.split(":");
|
|
17903
|
+
const updatedLeft = getTokenNextReferenceType(left);
|
|
17904
|
+
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
17905
|
+
return { ...token, value: getFullReference(sheetName, updatedLeft + updatedRight) };
|
|
17906
|
+
}
|
|
17907
|
+
/**
|
|
17908
|
+
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
17909
|
+
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
17910
|
+
*
|
|
17911
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17912
|
+
*/
|
|
17913
|
+
function getTokenNextReferenceType(xc) {
|
|
17914
|
+
switch (getReferenceType(xc)) {
|
|
17915
|
+
case "none":
|
|
17916
|
+
xc = setXcToFixedReferenceType(xc, "colrow");
|
|
17917
|
+
break;
|
|
17918
|
+
case "colrow":
|
|
17919
|
+
xc = setXcToFixedReferenceType(xc, "row");
|
|
17920
|
+
break;
|
|
17921
|
+
case "row":
|
|
17922
|
+
xc = setXcToFixedReferenceType(xc, "col");
|
|
17923
|
+
break;
|
|
17924
|
+
case "col":
|
|
17925
|
+
xc = setXcToFixedReferenceType(xc, "none");
|
|
17926
|
+
break;
|
|
17927
|
+
}
|
|
17928
|
+
return xc;
|
|
17929
|
+
}
|
|
17930
|
+
/**
|
|
17931
|
+
* Returns the given XC with the given reference type. The XC string should not contain a sheet name.
|
|
17932
|
+
*/
|
|
17933
|
+
function setXcToFixedReferenceType(xc, referenceType) {
|
|
17934
|
+
if (xc.includes("!")) {
|
|
17935
|
+
throw new Error("The given XC should not contain a sheet name");
|
|
17936
|
+
}
|
|
17937
|
+
xc = xc.replace(/\$/g, "");
|
|
17938
|
+
let indexOfNumber;
|
|
17939
|
+
switch (referenceType) {
|
|
17940
|
+
case "col":
|
|
17941
|
+
return "$" + xc;
|
|
17942
|
+
case "row":
|
|
17943
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17944
|
+
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17945
|
+
case "colrow":
|
|
17946
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17947
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
17948
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
17949
|
+
return "$" + xc;
|
|
17950
|
+
}
|
|
17951
|
+
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17952
|
+
return "$" + xc;
|
|
17953
|
+
case "none":
|
|
17954
|
+
return xc;
|
|
17955
|
+
}
|
|
17956
|
+
}
|
|
17957
|
+
/**
|
|
17958
|
+
* Return the type of reference used in the given XC of a cell.
|
|
17959
|
+
* Undefined behavior if the XC have a sheet reference
|
|
17960
|
+
*/
|
|
17961
|
+
function getReferenceType(xcCell) {
|
|
17962
|
+
if (isColAndRowFixed(xcCell)) {
|
|
17963
|
+
return "colrow";
|
|
17964
|
+
}
|
|
17965
|
+
else if (isColFixed(xcCell)) {
|
|
17966
|
+
return "col";
|
|
17967
|
+
}
|
|
17968
|
+
else if (isRowFixed(xcCell)) {
|
|
17969
|
+
return "row";
|
|
17970
|
+
}
|
|
17971
|
+
return "none";
|
|
17972
|
+
}
|
|
17973
|
+
function isColFixed(xc) {
|
|
17974
|
+
return xc.startsWith("$");
|
|
17975
|
+
}
|
|
17976
|
+
function isRowFixed(xc) {
|
|
17977
|
+
return xc.includes("$", 1);
|
|
17978
|
+
}
|
|
17979
|
+
function isColAndRowFixed(xc) {
|
|
17980
|
+
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
17981
|
+
}
|
|
17982
|
+
|
|
17983
|
+
// -----------------------------------------------------------------------------
|
|
17984
|
+
// CELL
|
|
17985
|
+
// -----------------------------------------------------------------------------
|
|
17986
|
+
// NOTE: missing from Excel: "color", "filename", "parentheses", "prefix", "protect" and "width"
|
|
17987
|
+
const CELL_INFO_TYPES = ["address", "col", "contents", "format", "row", "type"];
|
|
17988
|
+
const CELL = {
|
|
17989
|
+
description: _t("Gets information about a cell."),
|
|
17990
|
+
args: [
|
|
17991
|
+
arg("info_type (string)", _t("The type of information requested. Can be one of %s", CELL_INFO_TYPES.join(", "))),
|
|
17992
|
+
arg("reference (meta)", _t("The reference to the cell.")),
|
|
17993
|
+
],
|
|
17994
|
+
returns: ["ANY"],
|
|
17995
|
+
compute: function (info, reference) {
|
|
17996
|
+
const _info = toString(info).toLowerCase();
|
|
17997
|
+
assert(() => CELL_INFO_TYPES.includes(_info), _t("The info_type should be one of %s.", CELL_INFO_TYPES.join(", ")));
|
|
17998
|
+
const sheetId = this.__originSheetId;
|
|
17999
|
+
const topLeftReference = reference.includes(":") ? reference.split(":")[0] : reference;
|
|
18000
|
+
let { sheetName, xc } = splitReference(topLeftReference);
|
|
18001
|
+
// only put the sheet name if the referenced range is in another sheet than the cell the formula is on
|
|
18002
|
+
sheetName = sheetName === this.getters.getSheetName(sheetId) ? undefined : sheetName;
|
|
18003
|
+
const fixedRef = getFullReference(sheetName, setXcToFixedReferenceType(xc, "colrow"));
|
|
18004
|
+
const range = this.getters.getRangeFromSheetXC(sheetId, fixedRef);
|
|
18005
|
+
switch (_info) {
|
|
18006
|
+
case "address":
|
|
18007
|
+
return this.getters.getRangeString(range, sheetId);
|
|
18008
|
+
case "col":
|
|
18009
|
+
return range.zone.left + 1;
|
|
18010
|
+
case "contents": {
|
|
18011
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18012
|
+
return this.getters.getEvaluatedCell(position).value;
|
|
18013
|
+
}
|
|
18014
|
+
case "format": {
|
|
18015
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18016
|
+
return this.getters.getEvaluatedCell(position).format || "";
|
|
18017
|
+
}
|
|
18018
|
+
case "row":
|
|
18019
|
+
return range.zone.top + 1;
|
|
18020
|
+
case "type": {
|
|
18021
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18022
|
+
const type = this.getters.getEvaluatedCell(position).type;
|
|
18023
|
+
if (type === CellValueType.empty) {
|
|
18024
|
+
return "b"; // blank
|
|
18025
|
+
}
|
|
18026
|
+
else if (type === CellValueType.text) {
|
|
18027
|
+
return "l"; // label
|
|
18028
|
+
}
|
|
18029
|
+
else {
|
|
18030
|
+
return "v"; // value
|
|
18031
|
+
}
|
|
18032
|
+
}
|
|
18033
|
+
}
|
|
18034
|
+
return "";
|
|
18035
|
+
},
|
|
18036
|
+
isExported: true,
|
|
18037
|
+
};
|
|
17879
18038
|
// -----------------------------------------------------------------------------
|
|
17880
18039
|
// ISERR
|
|
17881
18040
|
// -----------------------------------------------------------------------------
|
|
@@ -18031,6 +18190,7 @@
|
|
|
18031
18190
|
|
|
18032
18191
|
var info = /*#__PURE__*/Object.freeze({
|
|
18033
18192
|
__proto__: null,
|
|
18193
|
+
CELL: CELL,
|
|
18034
18194
|
ISBLANK: ISBLANK,
|
|
18035
18195
|
ISERR: ISERR,
|
|
18036
18196
|
ISERROR: ISERROR,
|
|
@@ -18322,7 +18482,7 @@
|
|
|
18322
18482
|
cellReference = rowPart + colPart;
|
|
18323
18483
|
}
|
|
18324
18484
|
if (sheet !== undefined) {
|
|
18325
|
-
return
|
|
18485
|
+
return getFullReference(toString(sheet), cellReference);
|
|
18326
18486
|
}
|
|
18327
18487
|
return cellReference;
|
|
18328
18488
|
},
|
|
@@ -18338,7 +18498,7 @@
|
|
|
18338
18498
|
],
|
|
18339
18499
|
returns: ["NUMBER"],
|
|
18340
18500
|
compute: function (cellReference) {
|
|
18341
|
-
const _cellReference = cellReference || this.__originCellXC
|
|
18501
|
+
const _cellReference = cellReference || this.__originCellXC();
|
|
18342
18502
|
assert(() => !!_cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18343
18503
|
const zone = toZone(_cellReference);
|
|
18344
18504
|
return zone.left + 1;
|
|
@@ -18505,7 +18665,7 @@
|
|
|
18505
18665
|
],
|
|
18506
18666
|
returns: ["NUMBER"],
|
|
18507
18667
|
compute: function (cellReference) {
|
|
18508
|
-
cellReference = cellReference || this.__originCellXC
|
|
18668
|
+
cellReference = cellReference || this.__originCellXC();
|
|
18509
18669
|
assert(() => !!cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18510
18670
|
const zone = toZone(cellReference);
|
|
18511
18671
|
return zone.top + 1;
|
|
@@ -23857,31 +24017,65 @@
|
|
|
23857
24017
|
`;
|
|
23858
24018
|
class FindAndReplacePanel extends owl.Component {
|
|
23859
24019
|
static template = "o-spreadsheet-FindAndReplacePanel";
|
|
23860
|
-
|
|
24020
|
+
static components = { SelectionInput };
|
|
23861
24021
|
debounceTimeoutId;
|
|
23862
|
-
|
|
24022
|
+
initialShowFormulaState = false;
|
|
24023
|
+
dataRange = "";
|
|
23863
24024
|
searchInput = owl.useRef("searchInput");
|
|
24025
|
+
replaceInput = owl.useRef("replaceInput");
|
|
23864
24026
|
get hasSearchResult() {
|
|
23865
24027
|
return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
|
|
23866
24028
|
}
|
|
23867
24029
|
get pendingSearch() {
|
|
23868
24030
|
return this.debounceTimeoutId !== undefined;
|
|
23869
24031
|
}
|
|
24032
|
+
get searchOptions() {
|
|
24033
|
+
return this.env.model.getters.getSearchOptions();
|
|
24034
|
+
}
|
|
24035
|
+
get toSearch() {
|
|
24036
|
+
return this.searchInput.el?.value || "";
|
|
24037
|
+
}
|
|
24038
|
+
get toReplace() {
|
|
24039
|
+
return this.replaceInput.el?.value || "";
|
|
24040
|
+
}
|
|
24041
|
+
get allSheetsMatchesCount() {
|
|
24042
|
+
return _t("%s in all sheets", this.env.model.getters.getAllSheetMatchesCount());
|
|
24043
|
+
}
|
|
24044
|
+
get currentSheetMatchesCount() {
|
|
24045
|
+
return _t("%(matches)s in sheet %(sheetName)s", {
|
|
24046
|
+
matches: this.env.model.getters.getActiveSheetMatchesCount(),
|
|
24047
|
+
sheetName: this.env.model.getters.getSheetName(this.env.model.getters.getActiveSheetId()),
|
|
24048
|
+
});
|
|
24049
|
+
}
|
|
24050
|
+
get specificRangeMatchesCount() {
|
|
24051
|
+
const range = this.searchOptions.specificRange;
|
|
24052
|
+
if (!range) {
|
|
24053
|
+
return "";
|
|
24054
|
+
}
|
|
24055
|
+
const { _sheetId, _zone } = range;
|
|
24056
|
+
return _t("%(matches)s in range %(range)s of sheet %(sheetName)s", {
|
|
24057
|
+
matches: this.env.model.getters.getSpecificRangeMatchesCount().toString(),
|
|
24058
|
+
range: zoneToXc(_zone),
|
|
24059
|
+
sheetName: this.env.model.getters.getSheetName(_sheetId),
|
|
24060
|
+
});
|
|
24061
|
+
}
|
|
23870
24062
|
setup() {
|
|
23871
|
-
this.
|
|
24063
|
+
this.initialShowFormulaState = this.env.model.getters.shouldShowFormulas();
|
|
23872
24064
|
owl.onMounted(() => this.searchInput.el?.focus());
|
|
23873
24065
|
owl.onWillUnmount(() => {
|
|
23874
24066
|
clearTimeout(this.debounceTimeoutId);
|
|
23875
24067
|
this.env.model.dispatch("CLEAR_SEARCH");
|
|
23876
|
-
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.
|
|
24068
|
+
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
23877
24069
|
});
|
|
23878
24070
|
owl.useEffect(() => {
|
|
23879
|
-
|
|
23880
|
-
this.searchFormulas
|
|
24071
|
+
const showFormula = this.env.model.getters.shouldShowFormulas();
|
|
24072
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
23881
24073
|
}, () => [this.env.model.getters.shouldShowFormulas()]);
|
|
23882
24074
|
}
|
|
23883
|
-
|
|
23884
|
-
this.
|
|
24075
|
+
onFocusSearch() {
|
|
24076
|
+
this.updateDataRange();
|
|
24077
|
+
}
|
|
24078
|
+
onInput() {
|
|
23885
24079
|
this.debouncedUpdateSearch();
|
|
23886
24080
|
}
|
|
23887
24081
|
onKeydownSearch(ev) {
|
|
@@ -23898,11 +24092,36 @@
|
|
|
23898
24092
|
this.replace();
|
|
23899
24093
|
}
|
|
23900
24094
|
}
|
|
23901
|
-
searchFormulas() {
|
|
24095
|
+
searchFormulas(ev) {
|
|
24096
|
+
const showFormula = ev.target.checked;
|
|
23902
24097
|
this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
|
|
23903
|
-
show:
|
|
24098
|
+
show: showFormula,
|
|
23904
24099
|
});
|
|
23905
|
-
this.updateSearch();
|
|
24100
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
24101
|
+
}
|
|
24102
|
+
searchExactMatch(ev) {
|
|
24103
|
+
const exactMatch = ev.target.checked;
|
|
24104
|
+
this.updateSearch({ exactMatch });
|
|
24105
|
+
}
|
|
24106
|
+
searchMatchCase(ev) {
|
|
24107
|
+
const matchCase = ev.target.checked;
|
|
24108
|
+
this.updateSearch({ matchCase });
|
|
24109
|
+
}
|
|
24110
|
+
changeSearchScope(ev) {
|
|
24111
|
+
const searchScope = ev.target.value;
|
|
24112
|
+
this.updateSearch({ searchScope });
|
|
24113
|
+
}
|
|
24114
|
+
onSearchRangeChanged(ranges) {
|
|
24115
|
+
this.dataRange = ranges[0];
|
|
24116
|
+
}
|
|
24117
|
+
updateDataRange() {
|
|
24118
|
+
if (!this.dataRange) {
|
|
24119
|
+
return;
|
|
24120
|
+
}
|
|
24121
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
24122
|
+
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange).rangeData;
|
|
24123
|
+
this.updateSearch({ specificRange });
|
|
24124
|
+
}
|
|
23906
24125
|
}
|
|
23907
24126
|
onSelectPreviousCell() {
|
|
23908
24127
|
this.env.model.dispatch("SELECT_SEARCH_PREVIOUS_MATCH");
|
|
@@ -23910,10 +24129,14 @@
|
|
|
23910
24129
|
onSelectNextCell() {
|
|
23911
24130
|
this.env.model.dispatch("SELECT_SEARCH_NEXT_MATCH");
|
|
23912
24131
|
}
|
|
23913
|
-
updateSearch() {
|
|
24132
|
+
updateSearch(updateSearchOptions) {
|
|
24133
|
+
const searchOptions = {
|
|
24134
|
+
...this.env.model.getters.getSearchOptions(),
|
|
24135
|
+
...updateSearchOptions,
|
|
24136
|
+
};
|
|
23914
24137
|
this.env.model.dispatch("UPDATE_SEARCH", {
|
|
23915
|
-
toSearch: this.
|
|
23916
|
-
searchOptions
|
|
24138
|
+
toSearch: this.toSearch,
|
|
24139
|
+
searchOptions,
|
|
23917
24140
|
});
|
|
23918
24141
|
}
|
|
23919
24142
|
debouncedUpdateSearch() {
|
|
@@ -23925,28 +24148,14 @@
|
|
|
23925
24148
|
}
|
|
23926
24149
|
replace() {
|
|
23927
24150
|
this.env.model.dispatch("REPLACE_SEARCH", {
|
|
23928
|
-
replaceWith: this.
|
|
24151
|
+
replaceWith: this.toReplace,
|
|
23929
24152
|
});
|
|
23930
24153
|
}
|
|
23931
24154
|
replaceAll() {
|
|
23932
24155
|
this.env.model.dispatch("REPLACE_ALL_SEARCH", {
|
|
23933
|
-
replaceWith: this.
|
|
24156
|
+
replaceWith: this.toReplace,
|
|
23934
24157
|
});
|
|
23935
24158
|
}
|
|
23936
|
-
// ---------------------------------------------------------------------------
|
|
23937
|
-
// Private
|
|
23938
|
-
// ---------------------------------------------------------------------------
|
|
23939
|
-
initialState() {
|
|
23940
|
-
return {
|
|
23941
|
-
toSearch: "",
|
|
23942
|
-
replaceWith: "",
|
|
23943
|
-
searchOptions: {
|
|
23944
|
-
matchCase: false,
|
|
23945
|
-
exactMatch: false,
|
|
23946
|
-
searchFormulas: false,
|
|
23947
|
-
},
|
|
23948
|
-
};
|
|
23949
|
-
}
|
|
23950
24159
|
}
|
|
23951
24160
|
FindAndReplacePanel.props = {
|
|
23952
24161
|
onCloseSidePanel: Function,
|
|
@@ -27092,7 +27301,7 @@
|
|
|
27092
27301
|
get cellReference() {
|
|
27093
27302
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
27094
27303
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
27095
|
-
return
|
|
27304
|
+
return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
|
|
27096
27305
|
}
|
|
27097
27306
|
get cellReferenceStyle() {
|
|
27098
27307
|
const { x: left, y: top } = this.rect;
|
|
@@ -28309,6 +28518,7 @@
|
|
|
28309
28518
|
draggerShadowThickness: 0,
|
|
28310
28519
|
delta: 0,
|
|
28311
28520
|
base: 0,
|
|
28521
|
+
position: "before",
|
|
28312
28522
|
});
|
|
28313
28523
|
_computeHandleDisplay(ev) {
|
|
28314
28524
|
const position = this._getEvOffset(ev);
|
|
@@ -28433,11 +28643,13 @@
|
|
|
28433
28643
|
this.state.draggerLinePosition = dimensions.start;
|
|
28434
28644
|
this.state.draggerShadowPosition = dimensions.start;
|
|
28435
28645
|
this.state.base = elementIndex;
|
|
28646
|
+
this.state.position = "before";
|
|
28436
28647
|
}
|
|
28437
28648
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
28438
28649
|
this.state.draggerLinePosition = dimensions.end;
|
|
28439
28650
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
28440
|
-
this.state.base = elementIndex
|
|
28651
|
+
this.state.base = elementIndex;
|
|
28652
|
+
this.state.position = "after";
|
|
28441
28653
|
}
|
|
28442
28654
|
else {
|
|
28443
28655
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -28535,22 +28747,15 @@
|
|
|
28535
28747
|
height: 10000px;
|
|
28536
28748
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28537
28749
|
}
|
|
28538
|
-
.o-unhide {
|
|
28539
|
-
width:
|
|
28540
|
-
|
|
28541
|
-
|
|
28542
|
-
overflow: hidden;
|
|
28543
|
-
border-radius: 2px;
|
|
28544
|
-
top: calc(${HEADER_HEIGHT}px / 2 - ${UNHIDE_ICON_EDGE_LENGTH}px / 2);
|
|
28750
|
+
.o-unhide-buttons {
|
|
28751
|
+
width: fit-content;
|
|
28752
|
+
gap: 5px;
|
|
28753
|
+
transform: translate(-50%, 0);
|
|
28545
28754
|
}
|
|
28546
28755
|
.o-unhide:hover {
|
|
28547
28756
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
28548
28757
|
background-color: lightgrey;
|
|
28549
28758
|
}
|
|
28550
|
-
.o-unhide > svg {
|
|
28551
|
-
position: relative;
|
|
28552
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28553
|
-
}
|
|
28554
28759
|
}
|
|
28555
28760
|
`;
|
|
28556
28761
|
AbstractResizer.props = {
|
|
@@ -28619,6 +28824,7 @@
|
|
|
28619
28824
|
dimension: "COL",
|
|
28620
28825
|
base: this.state.base,
|
|
28621
28826
|
elements,
|
|
28827
|
+
position: this.state.position,
|
|
28622
28828
|
});
|
|
28623
28829
|
if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
|
|
28624
28830
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -28660,8 +28866,8 @@
|
|
|
28660
28866
|
dimension: "COL",
|
|
28661
28867
|
});
|
|
28662
28868
|
}
|
|
28663
|
-
|
|
28664
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
28869
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
28870
|
+
return cssPropertiesToCss({ left: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28665
28871
|
}
|
|
28666
28872
|
}
|
|
28667
28873
|
css /* scss */ `
|
|
@@ -28707,18 +28913,9 @@
|
|
|
28707
28913
|
height: 1px;
|
|
28708
28914
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28709
28915
|
}
|
|
28710
|
-
.o-unhide {
|
|
28711
|
-
|
|
28712
|
-
|
|
28713
|
-
position: absolute;
|
|
28714
|
-
overflow: hidden;
|
|
28715
|
-
border-radius: 2px;
|
|
28716
|
-
left: calc(${HEADER_WIDTH}px - ${UNHIDE_ICON_EDGE_LENGTH}px - 2px);
|
|
28717
|
-
}
|
|
28718
|
-
.o-unhide > svg {
|
|
28719
|
-
position: relative;
|
|
28720
|
-
left: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28721
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28916
|
+
.o-unhide-buttons {
|
|
28917
|
+
height: fit-content;
|
|
28918
|
+
transform: translate(0, -50%);
|
|
28722
28919
|
}
|
|
28723
28920
|
.o-unhide:hover {
|
|
28724
28921
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
@@ -28792,6 +28989,7 @@
|
|
|
28792
28989
|
dimension: "ROW",
|
|
28793
28990
|
base: this.state.base,
|
|
28794
28991
|
elements,
|
|
28992
|
+
position: this.state.position,
|
|
28795
28993
|
});
|
|
28796
28994
|
if (!result.isSuccessful && result.reasons.includes("WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */)) {
|
|
28797
28995
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -28833,8 +29031,8 @@
|
|
|
28833
29031
|
elements: hiddenElements,
|
|
28834
29032
|
});
|
|
28835
29033
|
}
|
|
28836
|
-
|
|
28837
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
29034
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
29035
|
+
return cssPropertiesToCss({ top: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28838
29036
|
}
|
|
28839
29037
|
}
|
|
28840
29038
|
css /* scss */ `
|
|
@@ -28899,8 +29097,8 @@
|
|
|
28899
29097
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
28900
29098
|
}
|
|
28901
29099
|
const onMouseWheel = (ev) => {
|
|
28902
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
28903
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
29100
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
29101
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
28904
29102
|
handler(deltaX, deltaY);
|
|
28905
29103
|
};
|
|
28906
29104
|
return onMouseWheel;
|
|
@@ -29341,7 +29539,6 @@
|
|
|
29341
29539
|
owl.onMounted(() => this.focus());
|
|
29342
29540
|
this.props.exposeFocus(() => this.focus());
|
|
29343
29541
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
29344
|
-
owl.useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
29345
29542
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
29346
29543
|
this.moveCanvas(deltaX, deltaY);
|
|
29347
29544
|
this.hoveredCell.col = undefined;
|
|
@@ -29778,6 +29975,7 @@
|
|
|
29778
29975
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
29779
29976
|
const target = this.env.model.getters.getSelectedZones();
|
|
29780
29977
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
29978
|
+
const isCutOperation = this.env.model.getters.isCutOperation();
|
|
29781
29979
|
if (clipboardString === content) {
|
|
29782
29980
|
// the paste actually comes from o-spreadsheet itself
|
|
29783
29981
|
interactivePaste(this.env, target);
|
|
@@ -29785,7 +29983,7 @@
|
|
|
29785
29983
|
else {
|
|
29786
29984
|
interactivePasteFromOS(this.env, target, content);
|
|
29787
29985
|
}
|
|
29788
|
-
if (
|
|
29986
|
+
if (isCutOperation) {
|
|
29789
29987
|
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
29790
29988
|
}
|
|
29791
29989
|
}
|
|
@@ -31398,12 +31596,6 @@
|
|
|
31398
31596
|
}
|
|
31399
31597
|
function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
31400
31598
|
let { sheetName, xc } = splitReference(range);
|
|
31401
|
-
if (sheetName) {
|
|
31402
|
-
sheetName = getCanonicalSheetName(sheetName) + "!";
|
|
31403
|
-
}
|
|
31404
|
-
else {
|
|
31405
|
-
sheetName = "";
|
|
31406
|
-
}
|
|
31407
31599
|
let zone = toUnboundedZone(xc);
|
|
31408
31600
|
if (dataSetsHaveTitle && zone.bottom !== undefined && zone.right !== undefined) {
|
|
31409
31601
|
const height = zone.bottom - zone.top + 1;
|
|
@@ -31416,7 +31608,7 @@
|
|
|
31416
31608
|
}
|
|
31417
31609
|
}
|
|
31418
31610
|
const dataXC = zoneToXc(zone);
|
|
31419
|
-
return sheetName
|
|
31611
|
+
return getFullReference(sheetName, dataXC);
|
|
31420
31612
|
}
|
|
31421
31613
|
|
|
31422
31614
|
/**
|
|
@@ -33343,7 +33535,7 @@
|
|
|
33343
33535
|
SPACE: goTo(State.RightRef),
|
|
33344
33536
|
NUMBER: goTo(State.Found),
|
|
33345
33537
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
33346
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
33538
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
33347
33539
|
},
|
|
33348
33540
|
[State.RightColumnRef]: {
|
|
33349
33541
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -33354,6 +33546,7 @@
|
|
|
33354
33546
|
SPACE: goTo(State.RightRowRef),
|
|
33355
33547
|
NUMBER: goTo(State.Found),
|
|
33356
33548
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
33549
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
33357
33550
|
},
|
|
33358
33551
|
[State.Found]: {},
|
|
33359
33552
|
};
|
|
@@ -34079,6 +34272,14 @@
|
|
|
34079
34272
|
// ---------------------------------------------------------------------------
|
|
34080
34273
|
// Command Handling
|
|
34081
34274
|
// ---------------------------------------------------------------------------
|
|
34275
|
+
allowDispatch(cmd) {
|
|
34276
|
+
switch (cmd.type) {
|
|
34277
|
+
case "SET_BORDER":
|
|
34278
|
+
return this.checkBordersUnchanged(cmd);
|
|
34279
|
+
default:
|
|
34280
|
+
return "Success" /* CommandResult.Success */;
|
|
34281
|
+
}
|
|
34282
|
+
}
|
|
34082
34283
|
handle(cmd) {
|
|
34083
34284
|
switch (cmd.type) {
|
|
34084
34285
|
case "ADD_MERGE":
|
|
@@ -34498,6 +34699,14 @@
|
|
|
34498
34699
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
34499
34700
|
}
|
|
34500
34701
|
}
|
|
34702
|
+
checkBordersUnchanged(cmd) {
|
|
34703
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
34704
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
34705
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
34706
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
34707
|
+
}
|
|
34708
|
+
return "Success" /* CommandResult.Success */;
|
|
34709
|
+
}
|
|
34501
34710
|
// ---------------------------------------------------------------------------
|
|
34502
34711
|
// Import/Export
|
|
34503
34712
|
// ---------------------------------------------------------------------------
|
|
@@ -35324,7 +35533,6 @@
|
|
|
35324
35533
|
static getters = [
|
|
35325
35534
|
"zoneToXC",
|
|
35326
35535
|
"getCells",
|
|
35327
|
-
"getFormulaCellContent",
|
|
35328
35536
|
"getTranslatedCellFormula",
|
|
35329
35537
|
"getCellStyle",
|
|
35330
35538
|
"getCellById",
|
|
@@ -35353,8 +35561,9 @@
|
|
|
35353
35561
|
allowDispatch(cmd) {
|
|
35354
35562
|
switch (cmd.type) {
|
|
35355
35563
|
case "UPDATE_CELL":
|
|
35564
|
+
return this.checkCellOutOfSheet(cmd);
|
|
35356
35565
|
case "CLEAR_CELL":
|
|
35357
|
-
return this.
|
|
35566
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
35358
35567
|
default:
|
|
35359
35568
|
return "Success" /* CommandResult.Success */;
|
|
35360
35569
|
}
|
|
@@ -35523,24 +35732,18 @@
|
|
|
35523
35732
|
*/
|
|
35524
35733
|
getCellById(cellId) {
|
|
35525
35734
|
// this must be as fast as possible
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
if (cell) {
|
|
35530
|
-
return cell;
|
|
35531
|
-
}
|
|
35532
|
-
}
|
|
35533
|
-
return undefined;
|
|
35735
|
+
const position = this.getters.getCellPosition(cellId);
|
|
35736
|
+
const sheet = this.cells[position.sheetId];
|
|
35737
|
+
return sheet[cellId];
|
|
35534
35738
|
}
|
|
35535
35739
|
/*
|
|
35536
35740
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
35537
35741
|
*/
|
|
35538
35742
|
getFormulaCellContent(sheetId, compiledFormula, dependencies) {
|
|
35539
|
-
const ranges = dependencies || compiledFormula.dependencies;
|
|
35540
35743
|
let rangeIndex = 0;
|
|
35541
35744
|
return concat(compiledFormula.tokens.map((token) => {
|
|
35542
35745
|
if (token.type === "REFERENCE") {
|
|
35543
|
-
const range =
|
|
35746
|
+
const range = dependencies[rangeIndex++];
|
|
35544
35747
|
return this.getters.getRangeString(range, sheetId);
|
|
35545
35748
|
}
|
|
35546
35749
|
return token.value;
|
|
@@ -35761,13 +35964,23 @@
|
|
|
35761
35964
|
},
|
|
35762
35965
|
};
|
|
35763
35966
|
}
|
|
35764
|
-
checkCellOutOfSheet(
|
|
35967
|
+
checkCellOutOfSheet(cmd) {
|
|
35968
|
+
const { sheetId, col, row } = cmd;
|
|
35765
35969
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
35766
35970
|
if (!sheet)
|
|
35767
35971
|
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
35768
35972
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
35769
35973
|
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
|
35770
35974
|
}
|
|
35975
|
+
checkUselessClearCell(cmd) {
|
|
35976
|
+
const cell = this.getters.getCell(cmd);
|
|
35977
|
+
if (!cell)
|
|
35978
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35979
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
35980
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35981
|
+
}
|
|
35982
|
+
return "Success" /* CommandResult.Success */;
|
|
35983
|
+
}
|
|
35771
35984
|
}
|
|
35772
35985
|
class FormulaCellWithDependencies {
|
|
35773
35986
|
id;
|
|
@@ -36457,6 +36670,9 @@
|
|
|
36457
36670
|
return this.rules[sheetId].find((rule) => rule.id === id);
|
|
36458
36671
|
}
|
|
36459
36672
|
getValidationRuleForCell({ sheetId, col, row }) {
|
|
36673
|
+
if (!this.rules[sheetId]) {
|
|
36674
|
+
return undefined;
|
|
36675
|
+
}
|
|
36460
36676
|
for (const rule of this.rules[sheetId]) {
|
|
36461
36677
|
for (const range of rule.ranges) {
|
|
36462
36678
|
if (isInside(col, row, range.zone)) {
|
|
@@ -37310,7 +37526,16 @@
|
|
|
37310
37526
|
return consecutiveIndexes;
|
|
37311
37527
|
}
|
|
37312
37528
|
getAllVisibleHeaders(sheetId, dimension) {
|
|
37313
|
-
|
|
37529
|
+
const headers = range(0, this.getters.getNumberHeaders(sheetId, dimension));
|
|
37530
|
+
const foldedHeaders = [];
|
|
37531
|
+
this.getters.getHeaderGroups(sheetId, dimension).forEach((group) => {
|
|
37532
|
+
if (group.isFolded) {
|
|
37533
|
+
foldedHeaders.push(...range(group.start, group.end + 1));
|
|
37534
|
+
}
|
|
37535
|
+
});
|
|
37536
|
+
return headers.filter((i) => {
|
|
37537
|
+
return !this.hiddenHeaders[sheetId][dimension][i] && !foldedHeaders.includes(i);
|
|
37538
|
+
});
|
|
37314
37539
|
}
|
|
37315
37540
|
import(data) {
|
|
37316
37541
|
for (let sheet of data.sheets) {
|
|
@@ -37629,7 +37854,7 @@
|
|
|
37629
37854
|
const rangeString = this.getters.getRangeString(expandedRange, forSheetId);
|
|
37630
37855
|
if (this.isSingleCellOrMerge(rangeImpl.sheetId, rangeImpl.zone)) {
|
|
37631
37856
|
const { sheetName, xc } = splitReference(rangeString);
|
|
37632
|
-
return
|
|
37857
|
+
return getFullReference(sheetName, xc.split(":")[0]);
|
|
37633
37858
|
}
|
|
37634
37859
|
return rangeString;
|
|
37635
37860
|
}
|
|
@@ -39054,10 +39279,13 @@
|
|
|
39054
39279
|
// begin with the end.
|
|
39055
39280
|
rows.sort((a, b) => b - a);
|
|
39056
39281
|
for (let group of groupConsecutive(rows)) {
|
|
39282
|
+
// indexes are sorted in the descending order
|
|
39283
|
+
const from = group[group.length - 1];
|
|
39284
|
+
const to = group[0];
|
|
39057
39285
|
// Move the cells.
|
|
39058
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
39059
|
-
// Effectively delete the
|
|
39060
|
-
|
|
39286
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
39287
|
+
// Effectively delete the rows
|
|
39288
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
39061
39289
|
}
|
|
39062
39290
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
39063
39291
|
if (count) {
|
|
@@ -39079,8 +39307,6 @@
|
|
|
39079
39307
|
this.addEmptyRows(sheet, quantity);
|
|
39080
39308
|
// Move the cells.
|
|
39081
39309
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
39082
|
-
// Recompute the left-right/top-bottom.
|
|
39083
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
39084
39310
|
if (index < sheet.panes.ySplit) {
|
|
39085
39311
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
39086
39312
|
}
|
|
@@ -39181,35 +39407,20 @@
|
|
|
39181
39407
|
}
|
|
39182
39408
|
}
|
|
39183
39409
|
}
|
|
39184
|
-
updateRowsStructureOnDeletion(
|
|
39410
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
39185
39411
|
const rows = [];
|
|
39186
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39412
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
39187
39413
|
for (let i in sheet.rows) {
|
|
39188
|
-
|
|
39414
|
+
const row = Number(i);
|
|
39415
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
39189
39416
|
continue;
|
|
39190
39417
|
}
|
|
39191
39418
|
rows.push({
|
|
39192
|
-
cells: cellsQueue.
|
|
39419
|
+
cells: cellsQueue.pop(),
|
|
39193
39420
|
});
|
|
39194
39421
|
}
|
|
39195
39422
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39196
39423
|
}
|
|
39197
|
-
/**
|
|
39198
|
-
* Update the rows of the sheet after an addition:
|
|
39199
|
-
* - Rename the rows
|
|
39200
|
-
*
|
|
39201
|
-
* @param sheet Sheet on which the deletion occurs
|
|
39202
|
-
* @param addedRow Index of the added row
|
|
39203
|
-
* @param rowsToAdd Number of the rows to add
|
|
39204
|
-
*/
|
|
39205
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
39206
|
-
const rows = [];
|
|
39207
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39208
|
-
sheet.rows.forEach(() => rows.push({
|
|
39209
|
-
cells: cellsQueue.shift(),
|
|
39210
|
-
}));
|
|
39211
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39212
|
-
}
|
|
39213
39424
|
/**
|
|
39214
39425
|
* Add empty rows at the end of the rows
|
|
39215
39426
|
*
|
|
@@ -39736,6 +39947,7 @@
|
|
|
39736
39947
|
getters;
|
|
39737
39948
|
computeCell;
|
|
39738
39949
|
evalContext;
|
|
39950
|
+
rangeCache = {};
|
|
39739
39951
|
constructor(context, getters, computeCell) {
|
|
39740
39952
|
this.getters = getters;
|
|
39741
39953
|
this.computeCell = computeCell;
|
|
@@ -39758,7 +39970,8 @@
|
|
|
39758
39970
|
refFn(range, isMeta, functionName, paramNumber) {
|
|
39759
39971
|
if (isMeta) {
|
|
39760
39972
|
// Use zoneToXc of zone instead of getRangeString to avoid sending unbounded ranges
|
|
39761
|
-
|
|
39973
|
+
const sheetName = this.getters.getSheetName(range.sheetId);
|
|
39974
|
+
return { value: getFullReference(sheetName, zoneToXc(range.zone)) };
|
|
39762
39975
|
}
|
|
39763
39976
|
if (!isZoneValid(range.zone)) {
|
|
39764
39977
|
throw new InvalidReferenceError();
|
|
@@ -39783,10 +39996,13 @@
|
|
|
39783
39996
|
if (evaluatedCell === undefined) {
|
|
39784
39997
|
return { value: null, format: this.getters.getCell(position)?.format };
|
|
39785
39998
|
}
|
|
39999
|
+
if (evaluatedCell.type === CellValueType.error) {
|
|
40000
|
+
throw evaluatedCell.error;
|
|
40001
|
+
}
|
|
39786
40002
|
return evaluatedCell;
|
|
39787
40003
|
}
|
|
39788
40004
|
getEvaluatedCellIfNotEmpty(position) {
|
|
39789
|
-
const evaluatedCell = this.
|
|
40005
|
+
const evaluatedCell = this.computeCell(position);
|
|
39790
40006
|
if (evaluatedCell.type === CellValueType.empty) {
|
|
39791
40007
|
const cell = this.getters.getCell(position);
|
|
39792
40008
|
if (!cell || (!cell.isFormula && cell.content === "")) {
|
|
@@ -39795,13 +40011,6 @@
|
|
|
39795
40011
|
}
|
|
39796
40012
|
return evaluatedCell;
|
|
39797
40013
|
}
|
|
39798
|
-
getEvaluatedCell(position) {
|
|
39799
|
-
const evaluatedCell = this.computeCell(position);
|
|
39800
|
-
if (evaluatedCell.type === CellValueType.error) {
|
|
39801
|
-
throw evaluatedCell.error;
|
|
39802
|
-
}
|
|
39803
|
-
return evaluatedCell;
|
|
39804
|
-
}
|
|
39805
40014
|
/**
|
|
39806
40015
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
39807
40016
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -39821,17 +40030,33 @@
|
|
|
39821
40030
|
if (!_zone) {
|
|
39822
40031
|
return [[]];
|
|
39823
40032
|
}
|
|
40033
|
+
const { top, left, bottom, right } = zone;
|
|
40034
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
40035
|
+
if (cacheKey in this.rangeCache) {
|
|
40036
|
+
const result = this.rangeCache[cacheKey];
|
|
40037
|
+
if (result instanceof EvaluationError) {
|
|
40038
|
+
throw result;
|
|
40039
|
+
}
|
|
40040
|
+
return result;
|
|
40041
|
+
}
|
|
39824
40042
|
const height = _zone.bottom - _zone.top + 1;
|
|
39825
40043
|
const width = _zone.right - _zone.left + 1;
|
|
39826
|
-
const matrix = Array
|
|
40044
|
+
const matrix = new Array(width);
|
|
39827
40045
|
// Performance issue: nested loop is faster than a map here
|
|
39828
40046
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
40047
|
+
const colIndex = col - _zone.left;
|
|
40048
|
+
matrix[colIndex] = new Array(height);
|
|
39829
40049
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
39830
|
-
const
|
|
40050
|
+
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
|
|
40051
|
+
if (evaluatedCell?.type === CellValueType.error) {
|
|
40052
|
+
this.rangeCache[cacheKey] = evaluatedCell.error;
|
|
40053
|
+
throw evaluatedCell.error;
|
|
40054
|
+
}
|
|
39831
40055
|
const rowIndex = row - _zone.top;
|
|
39832
40056
|
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
|
39833
40057
|
}
|
|
39834
40058
|
}
|
|
40059
|
+
this.rangeCache[cacheKey] = matrix;
|
|
39835
40060
|
return matrix;
|
|
39836
40061
|
}
|
|
39837
40062
|
}
|
|
@@ -40037,6 +40262,7 @@
|
|
|
40037
40262
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
40038
40263
|
}
|
|
40039
40264
|
updateCompilationParameters() {
|
|
40265
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
40040
40266
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40041
40267
|
}
|
|
40042
40268
|
evaluateCells(positions) {
|
|
@@ -40080,6 +40306,16 @@
|
|
|
40080
40306
|
this.evaluatedCells = new Map();
|
|
40081
40307
|
this.evaluate(this.getAllCells());
|
|
40082
40308
|
}
|
|
40309
|
+
evaluateFormula(sheetId, formulaString) {
|
|
40310
|
+
const compiledFormula = compile(formulaString);
|
|
40311
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40312
|
+
this.updateCompilationParameters();
|
|
40313
|
+
const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
|
|
40314
|
+
if (isMatrix(result)) {
|
|
40315
|
+
return matrixMap(result, (cell) => cell.value);
|
|
40316
|
+
}
|
|
40317
|
+
return result.value;
|
|
40318
|
+
}
|
|
40083
40319
|
getAllCells() {
|
|
40084
40320
|
const positionIds = new JetSet();
|
|
40085
40321
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -40106,6 +40342,7 @@
|
|
|
40106
40342
|
this.nextPositionsToUpdate = cells;
|
|
40107
40343
|
let currentIteration = 0;
|
|
40108
40344
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
40345
|
+
this.updateCompilationParameters();
|
|
40109
40346
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
40110
40347
|
this.nextPositionsToUpdate.clear();
|
|
40111
40348
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -40129,7 +40366,8 @@
|
|
|
40129
40366
|
if (!this.blockedArrayFormulas.has(positionId)) {
|
|
40130
40367
|
this.invalidateSpreading(positionId);
|
|
40131
40368
|
}
|
|
40132
|
-
const
|
|
40369
|
+
const cellPosition = this.decodePosition(positionId);
|
|
40370
|
+
const cell = this.getters.getCell(cellPosition);
|
|
40133
40371
|
if (cell === undefined) {
|
|
40134
40372
|
return createEvaluatedCell("", { locale: this.getters.getLocale() });
|
|
40135
40373
|
}
|
|
@@ -40140,7 +40378,7 @@
|
|
|
40140
40378
|
}
|
|
40141
40379
|
this.cellsBeingComputed.add(cellId);
|
|
40142
40380
|
return cell.isFormula
|
|
40143
|
-
? this.computeFormulaCell(cell)
|
|
40381
|
+
? this.computeFormulaCell(cellPosition.sheetId, cell)
|
|
40144
40382
|
: evaluateLiteral(cell.content, { format: cell.format, locale: this.getters.getLocale() });
|
|
40145
40383
|
}
|
|
40146
40384
|
catch (e) {
|
|
@@ -40166,14 +40404,9 @@
|
|
|
40166
40404
|
e.message = e.message.replace("[[FUNCTION_NAME]]", __lastFnCalled);
|
|
40167
40405
|
return errorCell(e);
|
|
40168
40406
|
}
|
|
40169
|
-
computeFormulaCell(cellData) {
|
|
40407
|
+
computeFormulaCell(sheetId, cellData) {
|
|
40170
40408
|
const cellId = cellData.id;
|
|
40171
|
-
this.compilationParams
|
|
40172
|
-
// compute the value lazily for performance reasons
|
|
40173
|
-
const position = this.compilationParams[2].getters.getCellPosition(cellId);
|
|
40174
|
-
return toXC(position.col, position.row);
|
|
40175
|
-
};
|
|
40176
|
-
const formulaReturn = cellData.compiledFormula.execute(cellData.compiledFormula.dependencies, ...this.compilationParams);
|
|
40409
|
+
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, sheetId, cellId);
|
|
40177
40410
|
if (!isMatrix(formulaReturn)) {
|
|
40178
40411
|
return createEvaluatedCell(formulaReturn.value, {
|
|
40179
40412
|
format: cellData.format || formulaReturn.format,
|
|
@@ -40375,6 +40608,18 @@
|
|
|
40375
40608
|
return sheetId;
|
|
40376
40609
|
}
|
|
40377
40610
|
}
|
|
40611
|
+
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
40612
|
+
compilationParams[2].__originCellXC = lazy(() => {
|
|
40613
|
+
if (!cellId) {
|
|
40614
|
+
return undefined;
|
|
40615
|
+
}
|
|
40616
|
+
// compute the value lazily for performance reasons
|
|
40617
|
+
const position = compilationParams[2].getters.getCellPosition(cellId);
|
|
40618
|
+
return toXC(position.col, position.row);
|
|
40619
|
+
});
|
|
40620
|
+
compilationParams[2].__originSheetId = sheetId;
|
|
40621
|
+
return compiledFormula.execute(compiledFormula.dependencies, ...compilationParams);
|
|
40622
|
+
}
|
|
40378
40623
|
|
|
40379
40624
|
//#region
|
|
40380
40625
|
// ---------------------------------------------------------------------------
|
|
@@ -40469,7 +40714,6 @@
|
|
|
40469
40714
|
// of other cells depending on it, at the next iteration.
|
|
40470
40715
|
//#endregion
|
|
40471
40716
|
class EvaluationPlugin extends UIPlugin {
|
|
40472
|
-
config;
|
|
40473
40717
|
static getters = [
|
|
40474
40718
|
"evaluateFormula",
|
|
40475
40719
|
"getCorrespondingFormulaCell",
|
|
@@ -40480,15 +40724,13 @@
|
|
|
40480
40724
|
"getEvaluatedCells",
|
|
40481
40725
|
"getEvaluatedCellsInZone",
|
|
40482
40726
|
"getSpreadPositionsOf",
|
|
40727
|
+
"getArrayFormulaSpreadingOn",
|
|
40483
40728
|
];
|
|
40484
40729
|
shouldRebuildDependenciesGraph = true;
|
|
40485
40730
|
evaluator;
|
|
40486
|
-
compilationParams;
|
|
40487
40731
|
positionsToUpdate = [];
|
|
40488
40732
|
constructor(config) {
|
|
40489
40733
|
super(config);
|
|
40490
|
-
this.config = config;
|
|
40491
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40492
40734
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
40493
40735
|
}
|
|
40494
40736
|
// ---------------------------------------------------------------------------
|
|
@@ -40513,10 +40755,6 @@
|
|
|
40513
40755
|
case "EVALUATE_CELLS":
|
|
40514
40756
|
this.evaluator.evaluateAllCells();
|
|
40515
40757
|
break;
|
|
40516
|
-
case "UPDATE_LOCALE":
|
|
40517
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40518
|
-
this.evaluator.updateCompilationParameters();
|
|
40519
|
-
break;
|
|
40520
40758
|
}
|
|
40521
40759
|
}
|
|
40522
40760
|
finalize() {
|
|
@@ -40534,16 +40772,7 @@
|
|
|
40534
40772
|
// Getters
|
|
40535
40773
|
// ---------------------------------------------------------------------------
|
|
40536
40774
|
evaluateFormula(sheetId, formulaString) {
|
|
40537
|
-
|
|
40538
|
-
const ranges = [];
|
|
40539
|
-
for (let xc of compiledFormula.dependencies) {
|
|
40540
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40541
|
-
}
|
|
40542
|
-
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40543
|
-
if (isMatrix(array)) {
|
|
40544
|
-
return array.map((col) => col.map((row) => row.value));
|
|
40545
|
-
}
|
|
40546
|
-
return array.value;
|
|
40775
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
40547
40776
|
}
|
|
40548
40777
|
/**
|
|
40549
40778
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -40592,6 +40821,9 @@
|
|
|
40592
40821
|
getSpreadPositionsOf(position) {
|
|
40593
40822
|
return this.evaluator.getSpreadPositionsOf(position);
|
|
40594
40823
|
}
|
|
40824
|
+
getArrayFormulaSpreadingOn(position) {
|
|
40825
|
+
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
40826
|
+
}
|
|
40595
40827
|
// ---------------------------------------------------------------------------
|
|
40596
40828
|
// Export
|
|
40597
40829
|
// ---------------------------------------------------------------------------
|
|
@@ -40635,7 +40867,7 @@
|
|
|
40635
40867
|
else if (cell && cell.content) {
|
|
40636
40868
|
return undefined;
|
|
40637
40869
|
}
|
|
40638
|
-
const spreadingFormulaPosition = this.
|
|
40870
|
+
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
40639
40871
|
if (spreadingFormulaPosition === undefined) {
|
|
40640
40872
|
return undefined;
|
|
40641
40873
|
}
|
|
@@ -40645,9 +40877,6 @@
|
|
|
40645
40877
|
}
|
|
40646
40878
|
return undefined;
|
|
40647
40879
|
}
|
|
40648
|
-
getCompilationParameters() {
|
|
40649
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
40650
|
-
}
|
|
40651
40880
|
}
|
|
40652
40881
|
function isBadExpression(tokens) {
|
|
40653
40882
|
try {
|
|
@@ -40924,7 +41153,7 @@
|
|
|
40924
41153
|
// ---------------------------------------------------------------------------
|
|
40925
41154
|
handle(cmd) {
|
|
40926
41155
|
if (invalidateCFEvaluationCommands.has(cmd.type) ||
|
|
40927
|
-
(cmd.type === "UPDATE_CELL" && "content" in cmd)) {
|
|
41156
|
+
(cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
|
|
40928
41157
|
this.isStale = true;
|
|
40929
41158
|
}
|
|
40930
41159
|
}
|
|
@@ -41250,7 +41479,7 @@
|
|
|
41250
41479
|
handle(cmd) {
|
|
41251
41480
|
if (invalidateEvaluationCommands.has(cmd.type) ||
|
|
41252
41481
|
cmd.type === "EVALUATE_CELLS" ||
|
|
41253
|
-
(cmd.type === "UPDATE_CELL" && "content" in cmd)) {
|
|
41482
|
+
(cmd.type === "UPDATE_CELL" && ("content" in cmd || "format" in cmd))) {
|
|
41254
41483
|
this.validationResults = {};
|
|
41255
41484
|
return;
|
|
41256
41485
|
}
|
|
@@ -41788,19 +42017,21 @@
|
|
|
41788
42017
|
let col = zone.left;
|
|
41789
42018
|
let row = zone.bottom;
|
|
41790
42019
|
if (col > 0) {
|
|
41791
|
-
let
|
|
41792
|
-
while (
|
|
42020
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
42021
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
42022
|
+
this.getters.getCell(leftPosition)?.content) {
|
|
41793
42023
|
row += 1;
|
|
41794
|
-
|
|
42024
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
41795
42025
|
}
|
|
41796
42026
|
}
|
|
41797
42027
|
if (row === zone.bottom) {
|
|
41798
42028
|
col = zone.right;
|
|
41799
42029
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
41800
|
-
let
|
|
41801
|
-
while (
|
|
42030
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
42031
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
42032
|
+
this.getters.getCell(rightPosition)?.content) {
|
|
41802
42033
|
row += 1;
|
|
41803
|
-
|
|
42034
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
41804
42035
|
}
|
|
41805
42036
|
}
|
|
41806
42037
|
}
|
|
@@ -42792,6 +43023,7 @@
|
|
|
42792
43023
|
isReplayingInitialRevisions = false;
|
|
42793
43024
|
processedRevisions = new Set();
|
|
42794
43025
|
uuidGenerator = new UuidGenerator();
|
|
43026
|
+
lastLocalOperation;
|
|
42795
43027
|
/**
|
|
42796
43028
|
* Manages the collaboration between multiple users on the same spreadsheet.
|
|
42797
43029
|
* It can forward local state changes to other users to ensure they all eventually
|
|
@@ -42824,6 +43056,11 @@
|
|
|
42824
43056
|
return;
|
|
42825
43057
|
const revision = new Revision(this.uuidGenerator.uuidv4(), this.clientId, commands, rootCommand, changes, Date.now());
|
|
42826
43058
|
this.revisions.append(revision.id, revision);
|
|
43059
|
+
// REQUEST_REDO just repeats the last operation, the
|
|
43060
|
+
// last operation is still the same and should not change.
|
|
43061
|
+
if (rootCommand.type !== "REQUEST_REDO") {
|
|
43062
|
+
this.lastLocalOperation = revision;
|
|
43063
|
+
}
|
|
42827
43064
|
this.trigger("new-local-state-update", { id: revision.id });
|
|
42828
43065
|
this.sendUpdateMessage({
|
|
42829
43066
|
type: "REMOTE_REVISION",
|
|
@@ -42920,19 +43157,10 @@
|
|
|
42920
43157
|
return this.pendingMessages.length === 0;
|
|
42921
43158
|
}
|
|
42922
43159
|
/**
|
|
42923
|
-
* Get the last local revision
|
|
43160
|
+
* Get the last local revision
|
|
42924
43161
|
* */
|
|
42925
|
-
getLastLocalNonEmptyRevision(
|
|
42926
|
-
|
|
42927
|
-
for (const rev of revisions) {
|
|
42928
|
-
if (rev.rootCommand === "SNAPSHOT")
|
|
42929
|
-
return undefined;
|
|
42930
|
-
if (!rev.rootCommand || rev.rootCommand === "REMOTE")
|
|
42931
|
-
continue;
|
|
42932
|
-
if (!ignoredRootCommands.includes(rev.rootCommand?.type) && rev.commands.length)
|
|
42933
|
-
return rev;
|
|
42934
|
-
}
|
|
42935
|
-
return undefined;
|
|
43162
|
+
getLastLocalNonEmptyRevision() {
|
|
43163
|
+
return this.lastLocalOperation;
|
|
42936
43164
|
}
|
|
42937
43165
|
_move(position) {
|
|
42938
43166
|
// this method is debounced and might be called after the client
|
|
@@ -42992,7 +43220,7 @@
|
|
|
42992
43220
|
break;
|
|
42993
43221
|
case "REMOTE_REVISION":
|
|
42994
43222
|
const { clientId, commands, timestamp } = message;
|
|
42995
|
-
const revision = new Revision(message.nextRevisionId, clientId, commands,
|
|
43223
|
+
const revision = new Revision(message.nextRevisionId, clientId, commands, undefined, undefined, timestamp);
|
|
42996
43224
|
if (revision.clientId !== this.clientId) {
|
|
42997
43225
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
42998
43226
|
const pendingCommands = this.pendingMessages
|
|
@@ -43005,10 +43233,11 @@
|
|
|
43005
43233
|
}
|
|
43006
43234
|
break;
|
|
43007
43235
|
case "SNAPSHOT_CREATED": {
|
|
43008
|
-
const revision = new Revision(message.nextRevisionId, "server", [],
|
|
43236
|
+
const revision = new Revision(message.nextRevisionId, "server", [], undefined, undefined, Date.now());
|
|
43009
43237
|
this.revisions.insert(revision.id, revision, message.serverRevisionId);
|
|
43010
43238
|
this.dropPendingHistoryMessages();
|
|
43011
43239
|
this.trigger("snapshot");
|
|
43240
|
+
this.lastLocalOperation = undefined;
|
|
43012
43241
|
break;
|
|
43013
43242
|
}
|
|
43014
43243
|
}
|
|
@@ -43346,11 +43575,26 @@
|
|
|
43346
43575
|
let cellsInRow = [];
|
|
43347
43576
|
for (let col of columnsIndex) {
|
|
43348
43577
|
const position = { col, row, sheetId };
|
|
43578
|
+
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
|
43579
|
+
let cell = getters.getCell(position);
|
|
43580
|
+
const evaluatedCell = getters.getEvaluatedCell(position);
|
|
43581
|
+
if (spreader) {
|
|
43582
|
+
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
|
43583
|
+
const content = isSpreaderCopied
|
|
43584
|
+
? ""
|
|
43585
|
+
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
|
43586
|
+
cell = {
|
|
43587
|
+
id: cell?.id || "",
|
|
43588
|
+
style: cell?.style,
|
|
43589
|
+
format: evaluatedCell.format,
|
|
43590
|
+
content,
|
|
43591
|
+
isFormula: false,
|
|
43592
|
+
};
|
|
43593
|
+
}
|
|
43349
43594
|
cellsInRow.push({
|
|
43350
|
-
cell
|
|
43351
|
-
style: getters.getCellComputedStyle(position),
|
|
43352
|
-
evaluatedCell: getters.getEvaluatedCell(position),
|
|
43595
|
+
cell,
|
|
43353
43596
|
border: getters.getCellBorder(position) || undefined,
|
|
43597
|
+
evaluatedCell,
|
|
43354
43598
|
position,
|
|
43355
43599
|
});
|
|
43356
43600
|
}
|
|
@@ -43472,13 +43716,6 @@
|
|
|
43472
43716
|
});
|
|
43473
43717
|
}
|
|
43474
43718
|
this.pasteCopiedTables(target);
|
|
43475
|
-
this.cells.forEach((row) => {
|
|
43476
|
-
row.forEach((c) => {
|
|
43477
|
-
if (c.cell) {
|
|
43478
|
-
c.cell = undefined;
|
|
43479
|
-
}
|
|
43480
|
-
});
|
|
43481
|
-
});
|
|
43482
43719
|
}
|
|
43483
43720
|
/**
|
|
43484
43721
|
* The clipped zone is copied as many times as it fits in the target.
|
|
@@ -43552,7 +43789,7 @@
|
|
|
43552
43789
|
clearClippedZones() {
|
|
43553
43790
|
for (const row of this.cells) {
|
|
43554
43791
|
for (const cell of row) {
|
|
43555
|
-
if (cell
|
|
43792
|
+
if (cell?.cell) {
|
|
43556
43793
|
this.dispatch("CLEAR_CELL", cell.position);
|
|
43557
43794
|
}
|
|
43558
43795
|
}
|
|
@@ -43578,6 +43815,9 @@
|
|
|
43578
43815
|
const rowCells = this.cells[r];
|
|
43579
43816
|
for (let c = 0; c < width; c++) {
|
|
43580
43817
|
const origin = rowCells[c];
|
|
43818
|
+
if (!origin) {
|
|
43819
|
+
continue;
|
|
43820
|
+
}
|
|
43581
43821
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
43582
43822
|
// TODO: refactor this part. the "Paste merge" action is also executed with
|
|
43583
43823
|
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
@@ -43601,53 +43841,42 @@
|
|
|
43601
43841
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43602
43842
|
const { sheetId, col, row } = target;
|
|
43603
43843
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43604
|
-
if (clipboardOption?.pasteOption
|
|
43605
|
-
const
|
|
43606
|
-
const
|
|
43607
|
-
|
|
43608
|
-
|
|
43609
|
-
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43610
|
-
left: targetBorders?.left || originBorders?.left,
|
|
43611
|
-
right: targetBorders?.right || originBorders?.right,
|
|
43612
|
-
};
|
|
43613
|
-
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43844
|
+
if (clipboardOption?.pasteOption === "onlyValue") {
|
|
43845
|
+
const locale = this.getters.getLocale();
|
|
43846
|
+
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43847
|
+
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
43848
|
+
return;
|
|
43614
43849
|
}
|
|
43615
|
-
|
|
43616
|
-
|
|
43617
|
-
|
|
43618
|
-
|
|
43619
|
-
|
|
43620
|
-
|
|
43621
|
-
|
|
43622
|
-
|
|
43623
|
-
|
|
43624
|
-
|
|
43625
|
-
|
|
43626
|
-
|
|
43627
|
-
|
|
43628
|
-
|
|
43629
|
-
}
|
|
43630
|
-
|
|
43631
|
-
|
|
43632
|
-
|
|
43633
|
-
|
|
43850
|
+
const targetBorders = this.getters.getCellBorder(target);
|
|
43851
|
+
const originBorders = origin.border;
|
|
43852
|
+
const border = {
|
|
43853
|
+
top: targetBorders?.top || originBorders?.top,
|
|
43854
|
+
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43855
|
+
left: targetBorders?.left || originBorders?.left,
|
|
43856
|
+
right: targetBorders?.right || originBorders?.right,
|
|
43857
|
+
};
|
|
43858
|
+
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43859
|
+
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43860
|
+
this.dispatch("UPDATE_CELL", {
|
|
43861
|
+
...target,
|
|
43862
|
+
style: origin.cell?.style ?? null,
|
|
43863
|
+
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
|
43864
|
+
});
|
|
43865
|
+
return;
|
|
43866
|
+
}
|
|
43867
|
+
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
|
43868
|
+
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
|
43869
|
+
: origin.cell?.content;
|
|
43870
|
+
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
|
43634
43871
|
this.dispatch("UPDATE_CELL", {
|
|
43635
43872
|
...target,
|
|
43636
43873
|
content,
|
|
43637
|
-
style: origin.cell
|
|
43638
|
-
format: origin.cell
|
|
43874
|
+
style: origin.cell?.style || null,
|
|
43875
|
+
format: origin.cell?.format,
|
|
43639
43876
|
});
|
|
43640
43877
|
}
|
|
43641
43878
|
else if (targetCell) {
|
|
43642
|
-
|
|
43643
|
-
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
|
43644
|
-
}
|
|
43645
|
-
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43646
|
-
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
|
43647
|
-
}
|
|
43648
|
-
else {
|
|
43649
|
-
this.dispatch("CLEAR_CELL", target);
|
|
43650
|
-
}
|
|
43879
|
+
this.dispatch("CLEAR_CELL", target);
|
|
43651
43880
|
}
|
|
43652
43881
|
}
|
|
43653
43882
|
/**
|
|
@@ -43709,22 +43938,28 @@
|
|
|
43709
43938
|
return (this.cells
|
|
43710
43939
|
.map((cells) => {
|
|
43711
43940
|
return cells
|
|
43712
|
-
.map((c) => this.getters.shouldShowFormulas() && c
|
|
43941
|
+
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
|
43713
43942
|
? c.cell?.content || ""
|
|
43714
|
-
: c
|
|
43943
|
+
: c?.evaluatedCell?.formattedValue || "")
|
|
43715
43944
|
.join("\t");
|
|
43716
43945
|
})
|
|
43717
43946
|
.join("\n") || "\t");
|
|
43718
43947
|
}
|
|
43719
43948
|
getHTMLContent() {
|
|
43720
43949
|
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
|
43950
|
+
if (!this.cells[0][0]) {
|
|
43951
|
+
return "";
|
|
43952
|
+
}
|
|
43721
43953
|
return this.getters.getCellText(this.cells[0][0].position);
|
|
43722
43954
|
}
|
|
43723
43955
|
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
|
43724
43956
|
for (const row of this.cells) {
|
|
43725
43957
|
htmlTable += "<tr>";
|
|
43726
43958
|
for (const cell of row) {
|
|
43727
|
-
|
|
43959
|
+
if (!cell) {
|
|
43960
|
+
continue;
|
|
43961
|
+
}
|
|
43962
|
+
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
|
43728
43963
|
const cellText = this.getters.getCellText(cell.position);
|
|
43729
43964
|
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
|
43730
43965
|
}
|
|
@@ -44052,24 +44287,49 @@
|
|
|
44052
44287
|
*/
|
|
44053
44288
|
class FindAndReplacePlugin extends UIPlugin {
|
|
44054
44289
|
static layers = [3 /* LAYERS.Search */];
|
|
44055
|
-
static getters = [
|
|
44056
|
-
|
|
44290
|
+
static getters = [
|
|
44291
|
+
"getSearchMatches",
|
|
44292
|
+
"getCurrentSelectedMatchIndex",
|
|
44293
|
+
"getSearchOptions",
|
|
44294
|
+
"getAllSheetMatchesCount",
|
|
44295
|
+
"getActiveSheetMatchesCount",
|
|
44296
|
+
"getSpecificRangeMatchesCount",
|
|
44297
|
+
];
|
|
44298
|
+
allSheetsMatches = [];
|
|
44299
|
+
activeSheetMatches = [];
|
|
44300
|
+
specificRangeMatches = [];
|
|
44301
|
+
// fixme: why do we make selectedMatchIndex on top of a selected
|
|
44302
|
+
// property in the matches?
|
|
44057
44303
|
selectedMatchIndex = null;
|
|
44058
44304
|
currentSearchRegex = null;
|
|
44059
44305
|
searchOptions = {
|
|
44060
44306
|
matchCase: false,
|
|
44061
44307
|
exactMatch: false,
|
|
44062
44308
|
searchFormulas: false,
|
|
44309
|
+
searchScope: "allSheets",
|
|
44310
|
+
specificRange: undefined,
|
|
44063
44311
|
};
|
|
44064
44312
|
toSearch = "";
|
|
44065
44313
|
isSearchDirty = false;
|
|
44314
|
+
get searchMatches() {
|
|
44315
|
+
switch (this.searchOptions.searchScope) {
|
|
44316
|
+
case "allSheets":
|
|
44317
|
+
return this.allSheetsMatches;
|
|
44318
|
+
case "activeSheet":
|
|
44319
|
+
return this.activeSheetMatches;
|
|
44320
|
+
case "specificRange":
|
|
44321
|
+
return this.specificRangeMatches;
|
|
44322
|
+
}
|
|
44323
|
+
}
|
|
44066
44324
|
// ---------------------------------------------------------------------------
|
|
44067
44325
|
// Command Handling
|
|
44068
44326
|
// ---------------------------------------------------------------------------
|
|
44069
44327
|
handle(cmd) {
|
|
44070
44328
|
switch (cmd.type) {
|
|
44071
44329
|
case "UPDATE_SEARCH":
|
|
44072
|
-
|
|
44330
|
+
const rangeData = cmd.searchOptions.specificRange;
|
|
44331
|
+
const specificRange = rangeData && this.getters.getRangeFromRangeData(rangeData);
|
|
44332
|
+
this.updateSearch(cmd.toSearch, { ...cmd.searchOptions, specificRange });
|
|
44073
44333
|
break;
|
|
44074
44334
|
case "CLEAR_SEARCH":
|
|
44075
44335
|
this.clearSearch();
|
|
@@ -44099,7 +44359,9 @@
|
|
|
44099
44359
|
this.isSearchDirty = true;
|
|
44100
44360
|
break;
|
|
44101
44361
|
case "ACTIVATE_SHEET":
|
|
44102
|
-
this.
|
|
44362
|
+
if (this.searchOptions.searchScope === "activeSheet") {
|
|
44363
|
+
this.isSearchDirty = true;
|
|
44364
|
+
}
|
|
44103
44365
|
break;
|
|
44104
44366
|
}
|
|
44105
44367
|
}
|
|
@@ -44118,6 +44380,18 @@
|
|
|
44118
44380
|
getCurrentSelectedMatchIndex() {
|
|
44119
44381
|
return this.selectedMatchIndex;
|
|
44120
44382
|
}
|
|
44383
|
+
getSearchOptions() {
|
|
44384
|
+
return { ...this.searchOptions, specificRange: this.searchOptions.specificRange?.rangeData };
|
|
44385
|
+
}
|
|
44386
|
+
getAllSheetMatchesCount() {
|
|
44387
|
+
return this.allSheetsMatches.length;
|
|
44388
|
+
}
|
|
44389
|
+
getActiveSheetMatchesCount() {
|
|
44390
|
+
return this.activeSheetMatches.length;
|
|
44391
|
+
}
|
|
44392
|
+
getSpecificRangeMatchesCount() {
|
|
44393
|
+
return this.specificRangeMatches.length;
|
|
44394
|
+
}
|
|
44121
44395
|
// ---------------------------------------------------------------------------
|
|
44122
44396
|
// Search
|
|
44123
44397
|
// ---------------------------------------------------------------------------
|
|
@@ -44138,8 +44412,8 @@
|
|
|
44138
44412
|
* refresh the matches according to the current search options
|
|
44139
44413
|
*/
|
|
44140
44414
|
refreshSearch() {
|
|
44141
|
-
|
|
44142
|
-
this.
|
|
44415
|
+
this.selectedMatchIndex = null;
|
|
44416
|
+
this.findMatches();
|
|
44143
44417
|
this.selectNextCell(Direction.current);
|
|
44144
44418
|
}
|
|
44145
44419
|
/**
|
|
@@ -44154,45 +44428,65 @@
|
|
|
44154
44428
|
}
|
|
44155
44429
|
this.currentSearchRegex = RegExp(searchValue, flags);
|
|
44156
44430
|
}
|
|
44431
|
+
getSheetsInSearchOrder() {
|
|
44432
|
+
switch (this.searchOptions.searchScope) {
|
|
44433
|
+
case "allSheets":
|
|
44434
|
+
const sheetIds = this.getters.getSheetIds();
|
|
44435
|
+
const activeSheetIndex = sheetIds.findIndex((id) => id === this.getters.getActiveSheetId());
|
|
44436
|
+
return [
|
|
44437
|
+
sheetIds[activeSheetIndex],
|
|
44438
|
+
...sheetIds.slice(activeSheetIndex + 1),
|
|
44439
|
+
...sheetIds.slice(0, activeSheetIndex),
|
|
44440
|
+
];
|
|
44441
|
+
case "activeSheet":
|
|
44442
|
+
return [this.getters.getActiveSheetId()];
|
|
44443
|
+
case "specificRange":
|
|
44444
|
+
const specificRange = this.searchOptions.specificRange;
|
|
44445
|
+
if (!specificRange) {
|
|
44446
|
+
return [];
|
|
44447
|
+
}
|
|
44448
|
+
return specificRange ? [specificRange.sheetId] : [];
|
|
44449
|
+
}
|
|
44450
|
+
}
|
|
44157
44451
|
/**
|
|
44158
44452
|
* Find matches using the current regex
|
|
44159
44453
|
*/
|
|
44160
44454
|
findMatches() {
|
|
44161
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
44162
|
-
const cells = this.getters.getCells(sheetId);
|
|
44163
44455
|
const matches = [];
|
|
44164
|
-
if (this.toSearch
|
|
44165
|
-
for (const
|
|
44166
|
-
|
|
44167
|
-
|
|
44456
|
+
if (this.toSearch) {
|
|
44457
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
44458
|
+
matches.push(...this.findMatchesInSheet(sheetId));
|
|
44459
|
+
}
|
|
44460
|
+
}
|
|
44461
|
+
// set results
|
|
44462
|
+
this.allSheetsMatches = matches;
|
|
44463
|
+
this.activeSheetMatches = matches.filter((match) => match.sheetId === this.getters.getActiveSheetId());
|
|
44464
|
+
if (this.searchOptions.specificRange) {
|
|
44465
|
+
const { sheetId, zone } = this.searchOptions.specificRange;
|
|
44466
|
+
this.specificRangeMatches = matches.filter((match) => match.sheetId === sheetId && isInside(match.col, match.row, zone));
|
|
44467
|
+
}
|
|
44468
|
+
else {
|
|
44469
|
+
this.specificRangeMatches = [];
|
|
44470
|
+
}
|
|
44471
|
+
}
|
|
44472
|
+
findMatchesInSheet(sheetId) {
|
|
44473
|
+
const matches = [];
|
|
44474
|
+
const { left, right, top, bottom } = this.getters.getSheetZone(sheetId);
|
|
44475
|
+
for (let row = top; row <= bottom; row++) {
|
|
44476
|
+
for (let col = left; col <= right; col++) {
|
|
44168
44477
|
const isColHidden = this.getters.isColHidden(sheetId, col);
|
|
44169
44478
|
const isRowHidden = this.getters.isRowHidden(sheetId, row);
|
|
44170
44479
|
if (isColHidden || isRowHidden) {
|
|
44171
44480
|
continue;
|
|
44172
44481
|
}
|
|
44173
|
-
|
|
44174
|
-
|
|
44482
|
+
const cellPosition = { sheetId, col, row };
|
|
44483
|
+
if (this.currentSearchRegex?.test(this.getSearchableString(cellPosition))) {
|
|
44484
|
+
const match = { sheetId, col, row };
|
|
44175
44485
|
matches.push(match);
|
|
44176
44486
|
}
|
|
44177
|
-
for (const spreadPosition of this.getters.getSpreadPositionsOf(cellPosition)) {
|
|
44178
|
-
if (this.currentSearchRegex.test(this.getSearchableString(spreadPosition))) {
|
|
44179
|
-
const match = {
|
|
44180
|
-
col: spreadPosition.col,
|
|
44181
|
-
row: spreadPosition.row,
|
|
44182
|
-
selected: false,
|
|
44183
|
-
};
|
|
44184
|
-
matches.push(match);
|
|
44185
|
-
}
|
|
44186
|
-
}
|
|
44187
44487
|
}
|
|
44188
44488
|
}
|
|
44189
|
-
return matches
|
|
44190
|
-
}
|
|
44191
|
-
sortByRowThenColumn(a, b) {
|
|
44192
|
-
if (a.row === b.row) {
|
|
44193
|
-
return a.col - b.col;
|
|
44194
|
-
}
|
|
44195
|
-
return a.row > b.row ? 1 : -1;
|
|
44489
|
+
return matches;
|
|
44196
44490
|
}
|
|
44197
44491
|
/**
|
|
44198
44492
|
* Changes the selected search cell. Given a direction it will
|
|
@@ -44210,30 +44504,47 @@
|
|
|
44210
44504
|
}
|
|
44211
44505
|
let nextIndex;
|
|
44212
44506
|
if (this.selectedMatchIndex === null) {
|
|
44213
|
-
|
|
44507
|
+
let nextMatchIndex = -1;
|
|
44508
|
+
// if search is not available in current sheet will select in next sheet
|
|
44509
|
+
for (const sheetId of this.getSheetsInSearchOrder()) {
|
|
44510
|
+
nextMatchIndex = matches.findIndex((match) => match.sheetId === sheetId);
|
|
44511
|
+
if (nextMatchIndex !== -1) {
|
|
44512
|
+
break;
|
|
44513
|
+
}
|
|
44514
|
+
}
|
|
44515
|
+
nextIndex = nextMatchIndex;
|
|
44214
44516
|
}
|
|
44215
44517
|
else {
|
|
44216
44518
|
nextIndex = this.selectedMatchIndex + indexChange;
|
|
44217
44519
|
}
|
|
44218
|
-
//
|
|
44219
|
-
nextIndex = (
|
|
44520
|
+
// loop index value inside the array (index -1 => last index)
|
|
44521
|
+
nextIndex = (nextIndex + matches.length) % matches.length;
|
|
44220
44522
|
this.selectedMatchIndex = nextIndex;
|
|
44523
|
+
const selectedMatch = matches[nextIndex];
|
|
44524
|
+
// Switch to the sheet where the match is located
|
|
44525
|
+
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
44526
|
+
this.dispatch("ACTIVATE_SHEET", {
|
|
44527
|
+
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
44528
|
+
sheetIdTo: selectedMatch.sheetId,
|
|
44529
|
+
});
|
|
44530
|
+
}
|
|
44221
44531
|
// we want grid selection to capture the selection stream
|
|
44222
44532
|
this.selection.getBackToDefault();
|
|
44223
|
-
this.selection.selectCell(
|
|
44224
|
-
for (let index = 0; index < this.searchMatches.length; index++) {
|
|
44225
|
-
this.searchMatches[index].selected = index === this.selectedMatchIndex;
|
|
44226
|
-
}
|
|
44533
|
+
this.selection.selectCell(selectedMatch.col, selectedMatch.row);
|
|
44227
44534
|
}
|
|
44228
44535
|
clearSearch() {
|
|
44229
44536
|
this.toSearch = "";
|
|
44230
|
-
this.searchMatches = [];
|
|
44231
44537
|
this.selectedMatchIndex = null;
|
|
44232
44538
|
this.currentSearchRegex = null;
|
|
44539
|
+
this.allSheetsMatches = [];
|
|
44540
|
+
this.activeSheetMatches = [];
|
|
44541
|
+
this.specificRangeMatches = [];
|
|
44233
44542
|
this.searchOptions = {
|
|
44234
44543
|
matchCase: false,
|
|
44235
44544
|
exactMatch: false,
|
|
44236
44545
|
searchFormulas: false,
|
|
44546
|
+
searchScope: "allSheets",
|
|
44547
|
+
specificRange: undefined,
|
|
44237
44548
|
};
|
|
44238
44549
|
}
|
|
44239
44550
|
// ---------------------------------------------------------------------------
|
|
@@ -44243,9 +44554,7 @@
|
|
|
44243
44554
|
if (!this.currentSearchRegex) {
|
|
44244
44555
|
return;
|
|
44245
44556
|
}
|
|
44246
|
-
const
|
|
44247
|
-
const position = { sheetId, ...selectedMatch };
|
|
44248
|
-
const cell = this.getters.getCell(position);
|
|
44557
|
+
const cell = this.getters.getCell(selectedMatch);
|
|
44249
44558
|
if (!cell?.content) {
|
|
44250
44559
|
return;
|
|
44251
44560
|
}
|
|
@@ -44253,10 +44562,10 @@
|
|
|
44253
44562
|
return;
|
|
44254
44563
|
}
|
|
44255
44564
|
const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
|
|
44256
|
-
const toReplace = this.getSearchableString(
|
|
44565
|
+
const toReplace = this.getSearchableString(selectedMatch);
|
|
44257
44566
|
const content = toReplace.replace(replaceRegex, replaceWith);
|
|
44258
44567
|
const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
|
|
44259
|
-
this.dispatch("UPDATE_CELL", { ...
|
|
44568
|
+
this.dispatch("UPDATE_CELL", { ...selectedMatch, content: canonicalContent });
|
|
44260
44569
|
}
|
|
44261
44570
|
/**
|
|
44262
44571
|
* Replace the value of the currently selected match
|
|
@@ -44287,7 +44596,10 @@
|
|
|
44287
44596
|
drawGrid(renderingContext) {
|
|
44288
44597
|
const { ctx } = renderingContext;
|
|
44289
44598
|
const sheetId = this.getters.getActiveSheetId();
|
|
44290
|
-
for (const match of this.searchMatches) {
|
|
44599
|
+
for (const [index, match] of this.searchMatches.entries()) {
|
|
44600
|
+
if (match.sheetId !== sheetId) {
|
|
44601
|
+
continue; // Skip drawing matches from other sheets
|
|
44602
|
+
}
|
|
44291
44603
|
const merge = this.getters.getMerge({ sheetId, col: match.col, row: match.row });
|
|
44292
44604
|
const left = merge ? merge.left : match.col;
|
|
44293
44605
|
const right = merge ? merge.right : match.col;
|
|
@@ -44297,12 +44609,21 @@
|
|
|
44297
44609
|
if (width > 0 && height > 0) {
|
|
44298
44610
|
ctx.fillStyle = BACKGROUND_COLOR;
|
|
44299
44611
|
ctx.fillRect(x, y, width, height);
|
|
44300
|
-
if (
|
|
44612
|
+
if (index === this.selectedMatchIndex) {
|
|
44301
44613
|
ctx.strokeStyle = BORDER_COLOR;
|
|
44302
44614
|
ctx.strokeRect(x, y, width, height);
|
|
44303
44615
|
}
|
|
44304
44616
|
}
|
|
44305
44617
|
}
|
|
44618
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
44619
|
+
const range = this.searchOptions.specificRange;
|
|
44620
|
+
if (!range || range.sheetId !== sheetId) {
|
|
44621
|
+
return;
|
|
44622
|
+
}
|
|
44623
|
+
const { x, y, width, height } = this.getters.getVisibleRect(range.zone);
|
|
44624
|
+
ctx.strokeStyle = BORDER_COLOR;
|
|
44625
|
+
ctx.strokeRect(x, y, width, height);
|
|
44626
|
+
}
|
|
44306
44627
|
}
|
|
44307
44628
|
}
|
|
44308
44629
|
|
|
@@ -45561,6 +45882,9 @@
|
|
|
45561
45882
|
// Other
|
|
45562
45883
|
// ---------------------------------------------------------------------------
|
|
45563
45884
|
initInput(id, initialRanges, inputHasSingleRange = false) {
|
|
45885
|
+
if (this.inputs[id]) {
|
|
45886
|
+
this.unfocus();
|
|
45887
|
+
}
|
|
45564
45888
|
this.inputs[id] = new SelectionInputPlugin(this.config, initialRanges, inputHasSingleRange);
|
|
45565
45889
|
if (initialRanges.length === 0) {
|
|
45566
45890
|
const input = this.inputs[id];
|
|
@@ -46269,7 +46593,7 @@
|
|
|
46269
46593
|
* Ignore standard undo/redo revisions (that are empty)
|
|
46270
46594
|
*/
|
|
46271
46595
|
getPossibleRevisionToRepeat() {
|
|
46272
|
-
return this.session.getLastLocalNonEmptyRevision(
|
|
46596
|
+
return this.session.getLastLocalNonEmptyRevision();
|
|
46273
46597
|
}
|
|
46274
46598
|
}
|
|
46275
46599
|
|
|
@@ -46768,11 +47092,14 @@
|
|
|
46768
47092
|
}
|
|
46769
47093
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
46770
47094
|
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
|
47095
|
+
if (this.state.operation === "CUT") {
|
|
47096
|
+
this.state = undefined;
|
|
47097
|
+
}
|
|
46771
47098
|
this.lastPasteState = this.state;
|
|
46772
47099
|
if (this.paintFormatStatus === "oneOff") {
|
|
46773
47100
|
this.paintFormatStatus = "inactive";
|
|
46774
|
-
this.status = "invisible";
|
|
46775
47101
|
}
|
|
47102
|
+
this.status = "invisible";
|
|
46776
47103
|
break;
|
|
46777
47104
|
case "COPY_PASTE_CELLS_ABOVE":
|
|
46778
47105
|
{
|
|
@@ -46999,92 +47326,6 @@
|
|
|
46999
47326
|
}
|
|
47000
47327
|
}
|
|
47001
47328
|
|
|
47002
|
-
/**
|
|
47003
|
-
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
47004
|
-
*
|
|
47005
|
-
* Eg. :
|
|
47006
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47007
|
-
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
47008
|
-
*/
|
|
47009
|
-
function loopThroughReferenceType(token) {
|
|
47010
|
-
if (token.type !== "REFERENCE")
|
|
47011
|
-
return token;
|
|
47012
|
-
const { xc, sheetName } = splitReference(token.value);
|
|
47013
|
-
const [left, right] = xc.split(":");
|
|
47014
|
-
const sheetRef = sheetName ? `${getCanonicalSheetName(sheetName)}!` : "";
|
|
47015
|
-
const updatedLeft = getTokenNextReferenceType(left);
|
|
47016
|
-
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
47017
|
-
return { ...token, value: sheetRef + updatedLeft + updatedRight };
|
|
47018
|
-
}
|
|
47019
|
-
/**
|
|
47020
|
-
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
47021
|
-
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
47022
|
-
*
|
|
47023
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47024
|
-
*/
|
|
47025
|
-
function getTokenNextReferenceType(xc) {
|
|
47026
|
-
switch (getReferenceType(xc)) {
|
|
47027
|
-
case "none":
|
|
47028
|
-
xc = setXcToReferenceType(xc, "colrow");
|
|
47029
|
-
break;
|
|
47030
|
-
case "colrow":
|
|
47031
|
-
xc = setXcToReferenceType(xc, "row");
|
|
47032
|
-
break;
|
|
47033
|
-
case "row":
|
|
47034
|
-
xc = setXcToReferenceType(xc, "col");
|
|
47035
|
-
break;
|
|
47036
|
-
case "col":
|
|
47037
|
-
xc = setXcToReferenceType(xc, "none");
|
|
47038
|
-
break;
|
|
47039
|
-
}
|
|
47040
|
-
return xc;
|
|
47041
|
-
}
|
|
47042
|
-
/**
|
|
47043
|
-
* Returns the given XC with the given reference type.
|
|
47044
|
-
*/
|
|
47045
|
-
function setXcToReferenceType(xc, referenceType) {
|
|
47046
|
-
xc = xc.replace(/\$/g, "");
|
|
47047
|
-
let indexOfNumber;
|
|
47048
|
-
switch (referenceType) {
|
|
47049
|
-
case "col":
|
|
47050
|
-
return "$" + xc;
|
|
47051
|
-
case "row":
|
|
47052
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47053
|
-
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47054
|
-
case "colrow":
|
|
47055
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47056
|
-
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47057
|
-
return "$" + xc;
|
|
47058
|
-
case "none":
|
|
47059
|
-
return xc;
|
|
47060
|
-
}
|
|
47061
|
-
}
|
|
47062
|
-
/**
|
|
47063
|
-
* Return the type of reference used in the given XC of a cell.
|
|
47064
|
-
* Undefined behavior if the XC have a sheet reference
|
|
47065
|
-
*/
|
|
47066
|
-
function getReferenceType(xcCell) {
|
|
47067
|
-
if (isColAndRowFixed(xcCell)) {
|
|
47068
|
-
return "colrow";
|
|
47069
|
-
}
|
|
47070
|
-
else if (isColFixed(xcCell)) {
|
|
47071
|
-
return "col";
|
|
47072
|
-
}
|
|
47073
|
-
else if (isRowFixed(xcCell)) {
|
|
47074
|
-
return "row";
|
|
47075
|
-
}
|
|
47076
|
-
return "none";
|
|
47077
|
-
}
|
|
47078
|
-
function isColFixed(xc) {
|
|
47079
|
-
return xc.startsWith("$");
|
|
47080
|
-
}
|
|
47081
|
-
function isRowFixed(xc) {
|
|
47082
|
-
return xc.includes("$", 1);
|
|
47083
|
-
}
|
|
47084
|
-
function isColAndRowFixed(xc) {
|
|
47085
|
-
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
47086
|
-
}
|
|
47087
|
-
|
|
47088
47329
|
const CELL_DELETED_MESSAGE = _t("The cell you are trying to edit has been deleted.");
|
|
47089
47330
|
class EditionPlugin extends UIPlugin {
|
|
47090
47331
|
static getters = [
|
|
@@ -47823,6 +48064,12 @@
|
|
|
47823
48064
|
break;
|
|
47824
48065
|
case "HIDE_COLUMNS_ROWS":
|
|
47825
48066
|
case "UNHIDE_COLUMNS_ROWS":
|
|
48067
|
+
case "GROUP_HEADERS":
|
|
48068
|
+
case "UNGROUP_HEADERS":
|
|
48069
|
+
case "FOLD_HEADER_GROUP":
|
|
48070
|
+
case "UNFOLD_HEADER_GROUP":
|
|
48071
|
+
case "FOLD_ALL_HEADER_GROUPS":
|
|
48072
|
+
case "UNFOLD_ALL_HEADER_GROUPS":
|
|
47826
48073
|
this.updateHiddenRows();
|
|
47827
48074
|
break;
|
|
47828
48075
|
case "UPDATE_FILTER":
|
|
@@ -48002,32 +48249,32 @@
|
|
|
48002
48249
|
{
|
|
48003
48250
|
name: _t("Sum"),
|
|
48004
48251
|
types: [CellValueType.number],
|
|
48005
|
-
compute: (values, locale) =>
|
|
48252
|
+
compute: (values, locale) => sum([[values]], locale),
|
|
48006
48253
|
},
|
|
48007
48254
|
{
|
|
48008
48255
|
name: _t("Avg"),
|
|
48009
48256
|
types: [CellValueType.number],
|
|
48010
|
-
compute: (values, locale) =>
|
|
48257
|
+
compute: (values, locale) => average([[values]], locale),
|
|
48011
48258
|
},
|
|
48012
48259
|
{
|
|
48013
48260
|
name: _t("Min"),
|
|
48014
48261
|
types: [CellValueType.number],
|
|
48015
|
-
compute: (values, locale) =>
|
|
48262
|
+
compute: (values, locale) => min([[values]], locale),
|
|
48016
48263
|
},
|
|
48017
48264
|
{
|
|
48018
48265
|
name: _t("Max"),
|
|
48019
48266
|
types: [CellValueType.number],
|
|
48020
|
-
compute: (values, locale) =>
|
|
48267
|
+
compute: (values, locale) => max([[values]], locale),
|
|
48021
48268
|
},
|
|
48022
48269
|
{
|
|
48023
48270
|
name: _t("Count"),
|
|
48024
48271
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48025
|
-
compute: (values
|
|
48272
|
+
compute: (values) => countAny([[values]]),
|
|
48026
48273
|
},
|
|
48027
48274
|
{
|
|
48028
48275
|
name: _t("Count Numbers"),
|
|
48029
48276
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48030
|
-
compute: (values, locale) =>
|
|
48277
|
+
compute: (values, locale) => countNumbers([[values]], locale),
|
|
48031
48278
|
},
|
|
48032
48279
|
];
|
|
48033
48280
|
/**
|
|
@@ -48524,7 +48771,7 @@
|
|
|
48524
48771
|
sheetId: cmd.sheetId,
|
|
48525
48772
|
base: cmd.base,
|
|
48526
48773
|
quantity: thickness,
|
|
48527
|
-
position:
|
|
48774
|
+
position: cmd.position,
|
|
48528
48775
|
});
|
|
48529
48776
|
const isCol = cmd.dimension === "COL";
|
|
48530
48777
|
const start = cmd.elements[0];
|
|
@@ -48541,12 +48788,13 @@
|
|
|
48541
48788
|
},
|
|
48542
48789
|
];
|
|
48543
48790
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
48791
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
48544
48792
|
const pasteTarget = [
|
|
48545
48793
|
{
|
|
48546
|
-
left: isCol ?
|
|
48547
|
-
right: isCol ?
|
|
48548
|
-
top: !isCol ?
|
|
48549
|
-
bottom: !isCol ?
|
|
48794
|
+
left: isCol ? base : 0,
|
|
48795
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
48796
|
+
top: !isCol ? base : 0,
|
|
48797
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
48550
48798
|
},
|
|
48551
48799
|
];
|
|
48552
48800
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -48581,6 +48829,11 @@
|
|
|
48581
48829
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
48582
48830
|
return "WillRemoveExistingMerge" /* CommandResult.WillRemoveExistingMerge */;
|
|
48583
48831
|
}
|
|
48832
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
48833
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
48834
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
48835
|
+
return "InvalidHeaderIndex" /* CommandResult.InvalidHeaderIndex */;
|
|
48836
|
+
}
|
|
48584
48837
|
return "Success" /* CommandResult.Success */;
|
|
48585
48838
|
}
|
|
48586
48839
|
//-------------------------------------------
|
|
@@ -48758,9 +49011,6 @@
|
|
|
48758
49011
|
*/
|
|
48759
49012
|
adjustPosition(position) {
|
|
48760
49013
|
const sheetId = this.sheetId;
|
|
48761
|
-
if (!position) {
|
|
48762
|
-
position = this.getters.getSheetPosition(sheetId);
|
|
48763
|
-
}
|
|
48764
49014
|
const mainCellPosition = this.getters.getMainCellPosition({ sheetId, ...position });
|
|
48765
49015
|
const { col, row } = this.getters.getNextVisibleCellPosition(mainCellPosition);
|
|
48766
49016
|
if (isInside(col, this.boundaries.top, this.boundaries)) {
|
|
@@ -48773,56 +49023,50 @@
|
|
|
48773
49023
|
adjustPositionX(targetCol) {
|
|
48774
49024
|
const sheetId = this.sheetId;
|
|
48775
49025
|
const { end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
48776
|
-
const maxCol = this.getters.getNumberCols(sheetId);
|
|
48777
49026
|
if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
|
|
49027
|
+
const maxCol = this.getters.getNumberCols(sheetId);
|
|
48778
49028
|
let finalTarget = targetCol;
|
|
48779
|
-
while (this.getters.isColHidden(sheetId, finalTarget) &&
|
|
49029
|
+
while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget < maxCol) {
|
|
48780
49030
|
finalTarget++;
|
|
48781
49031
|
}
|
|
48782
49032
|
const finalTargetEnd = this.getters.getColDimensions(sheetId, finalTarget).end;
|
|
48783
49033
|
const startIndex = this.searchHeaderIndex("COL", finalTargetEnd - this.viewportWidth - this.offsetCorrectionX, this.boundaries.left);
|
|
48784
|
-
this.
|
|
49034
|
+
this.offsetScrollbarX =
|
|
48785
49035
|
this.getters.getColDimensions(sheetId, startIndex).end - this.offsetCorrectionX;
|
|
48786
|
-
this.offsetScrollbarX = this.offsetX;
|
|
48787
|
-
this.adjustViewportZoneX();
|
|
48788
49036
|
}
|
|
48789
49037
|
else if (this.left > targetCol) {
|
|
48790
49038
|
let finalTarget = targetCol;
|
|
48791
|
-
while (this.getters.isColHidden(sheetId, finalTarget) &&
|
|
49039
|
+
while (this.getters.isColHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
48792
49040
|
finalTarget--;
|
|
48793
49041
|
}
|
|
48794
|
-
this.
|
|
49042
|
+
this.offsetScrollbarX =
|
|
48795
49043
|
this.getters.getColDimensions(sheetId, finalTarget).start - this.offsetCorrectionX;
|
|
48796
|
-
this.offsetScrollbarX = this.offsetX;
|
|
48797
|
-
this.adjustViewportZoneX();
|
|
48798
49044
|
}
|
|
49045
|
+
this.adjustViewportZoneX();
|
|
48799
49046
|
}
|
|
48800
49047
|
adjustPositionY(targetRow) {
|
|
48801
49048
|
const sheetId = this.sheetId;
|
|
48802
49049
|
const { end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
48803
|
-
const maxRow = this.getters.getNumberRows(sheetId);
|
|
48804
49050
|
if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
|
|
49051
|
+
const maxRow = this.getters.getNumberRows(sheetId);
|
|
48805
49052
|
let finalTarget = targetRow;
|
|
48806
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) &&
|
|
49053
|
+
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget < maxRow) {
|
|
48807
49054
|
finalTarget++;
|
|
48808
49055
|
}
|
|
48809
49056
|
const finalTargetEnd = this.getters.getRowDimensions(sheetId, finalTarget).end;
|
|
48810
49057
|
const startIndex = this.searchHeaderIndex("ROW", finalTargetEnd - this.viewportHeight - this.offsetCorrectionY, this.boundaries.top);
|
|
48811
|
-
this.
|
|
49058
|
+
this.offsetScrollbarY =
|
|
48812
49059
|
this.getters.getRowDimensions(sheetId, startIndex).end - this.offsetCorrectionY;
|
|
48813
|
-
this.offsetScrollbarY = this.offsetY;
|
|
48814
|
-
this.adjustViewportZoneY();
|
|
48815
49060
|
}
|
|
48816
49061
|
else if (this.top > targetRow) {
|
|
48817
49062
|
let finalTarget = targetRow;
|
|
48818
|
-
while (this.getters.isRowHidden(sheetId, finalTarget) &&
|
|
49063
|
+
while (this.getters.isRowHidden(sheetId, finalTarget) && finalTarget > 0) {
|
|
48819
49064
|
finalTarget--;
|
|
48820
49065
|
}
|
|
48821
|
-
this.
|
|
49066
|
+
this.offsetScrollbarY =
|
|
48822
49067
|
this.getters.getRowDimensions(sheetId, finalTarget).start - this.offsetCorrectionY;
|
|
48823
|
-
this.offsetScrollbarY = this.offsetY;
|
|
48824
|
-
this.adjustViewportZoneY();
|
|
48825
49068
|
}
|
|
49069
|
+
this.adjustViewportZoneY();
|
|
48826
49070
|
}
|
|
48827
49071
|
setViewportOffset(offsetX, offsetY) {
|
|
48828
49072
|
this.setViewportOffsetX(offsetX);
|
|
@@ -48838,11 +49082,10 @@
|
|
|
48838
49082
|
* @returns Computes the absolute coordinate of a given zone inside the viewport
|
|
48839
49083
|
*/
|
|
48840
49084
|
getRect(zone) {
|
|
48841
|
-
const targetZone = intersection(zone, this
|
|
49085
|
+
const targetZone = intersection(zone, this);
|
|
48842
49086
|
if (targetZone) {
|
|
48843
|
-
const x = this.getters.getColRowOffset("COL", this.
|
|
48844
|
-
|
|
48845
|
-
const y = this.getters.getColRowOffset("ROW", this.zone.top, targetZone.top) + this.offsetCorrectionY;
|
|
49087
|
+
const x = this.getters.getColRowOffset("COL", this.left, targetZone.left) + this.offsetCorrectionX;
|
|
49088
|
+
const y = this.getters.getColRowOffset("ROW", this.top, targetZone.top) + this.offsetCorrectionY;
|
|
48846
49089
|
const width = Math.min(this.getters.getColRowOffset("COL", targetZone.left, targetZone.right + 1), this.viewportWidth);
|
|
48847
49090
|
const height = Math.min(this.getters.getColRowOffset("ROW", targetZone.top, targetZone.bottom + 1), this.viewportHeight);
|
|
48848
49091
|
return {
|
|
@@ -48852,9 +49095,7 @@
|
|
|
48852
49095
|
height,
|
|
48853
49096
|
};
|
|
48854
49097
|
}
|
|
48855
|
-
|
|
48856
|
-
return undefined;
|
|
48857
|
-
}
|
|
49098
|
+
return undefined;
|
|
48858
49099
|
}
|
|
48859
49100
|
isVisible(col, row) {
|
|
48860
49101
|
const isInside = row <= this.bottom && row >= this.top && col >= this.left && col <= this.right;
|
|
@@ -48862,7 +49103,6 @@
|
|
|
48862
49103
|
!this.getters.isColHidden(this.sheetId, col) &&
|
|
48863
49104
|
!this.getters.isRowHidden(this.sheetId, row));
|
|
48864
49105
|
}
|
|
48865
|
-
// PRIVATE
|
|
48866
49106
|
searchHeaderIndex(dimension, position, startIndex = 0) {
|
|
48867
49107
|
const sheetId = this.sheetId;
|
|
48868
49108
|
const headers = this.getters.getNumberHeaders(sheetId, dimension);
|
|
@@ -48885,9 +49125,6 @@
|
|
|
48885
49125
|
}
|
|
48886
49126
|
return -1;
|
|
48887
49127
|
}
|
|
48888
|
-
get zone() {
|
|
48889
|
-
return { left: this.left, right: this.right, top: this.top, bottom: this.bottom };
|
|
48890
|
-
}
|
|
48891
49128
|
setViewportOffsetX(offsetX) {
|
|
48892
49129
|
if (!this.canScrollHorizontally) {
|
|
48893
49130
|
return;
|
|
@@ -48912,11 +49149,6 @@
|
|
|
48912
49149
|
this.offsetScrollbarX = Math.max(0, viewportWidth - this.viewportWidth);
|
|
48913
49150
|
}
|
|
48914
49151
|
}
|
|
48915
|
-
this.left = this.getColIndex(this.offsetScrollbarX);
|
|
48916
|
-
this.right = this.getColIndex(this.offsetScrollbarX + this.viewportWidth);
|
|
48917
|
-
if (this.right === -1) {
|
|
48918
|
-
this.right = this.boundaries.right;
|
|
48919
|
-
}
|
|
48920
49152
|
this.adjustViewportZoneX();
|
|
48921
49153
|
}
|
|
48922
49154
|
/** Corrects the viewport's vertical offset based on the current structure
|
|
@@ -48929,11 +49161,6 @@
|
|
|
48929
49161
|
this.offsetScrollbarY = Math.max(0, paneHeight - this.viewportHeight);
|
|
48930
49162
|
}
|
|
48931
49163
|
}
|
|
48932
|
-
this.top = this.getRowIndex(this.offsetScrollbarY);
|
|
48933
|
-
this.bottom = this.getRowIndex(this.offsetScrollbarY + this.viewportHeight);
|
|
48934
|
-
if (this.bottom === -1) {
|
|
48935
|
-
this.bottom = this.boundaries.bottom;
|
|
48936
|
-
}
|
|
48937
49164
|
this.adjustViewportZoneY();
|
|
48938
49165
|
}
|
|
48939
49166
|
/** Updates the pane zone and snapped offset based on its horizontal
|
|
@@ -49311,7 +49538,7 @@
|
|
|
49311
49538
|
isVisibleInViewport({ sheetId, col, row }) {
|
|
49312
49539
|
return this.getSubViewports(sheetId).some((pane) => pane.isVisible(col, row));
|
|
49313
49540
|
}
|
|
49314
|
-
// =>
|
|
49541
|
+
// => returns the new offset
|
|
49315
49542
|
getEdgeScrollCol(x, previousX, startingX) {
|
|
49316
49543
|
let canEdgeScroll = false;
|
|
49317
49544
|
let direction = 0;
|
|
@@ -49626,10 +49853,13 @@
|
|
|
49626
49853
|
}
|
|
49627
49854
|
break;
|
|
49628
49855
|
case "UPDATE_CELL":
|
|
49629
|
-
if ("content" in cmd || "format" in cmd
|
|
49856
|
+
if ("content" in cmd || "format" in cmd) {
|
|
49630
49857
|
this.headerPositions = {};
|
|
49631
49858
|
this.isDirty = true;
|
|
49632
49859
|
}
|
|
49860
|
+
else {
|
|
49861
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
49862
|
+
}
|
|
49633
49863
|
break;
|
|
49634
49864
|
case "UPDATE_FILTER":
|
|
49635
49865
|
case "REMOVE_FILTER_TABLE":
|
|
@@ -51786,6 +52016,8 @@
|
|
|
51786
52016
|
*:before,
|
|
51787
52017
|
*:after {
|
|
51788
52018
|
box-sizing: content-box;
|
|
52019
|
+
/** rtl not supported ATM */
|
|
52020
|
+
direction: ltr;
|
|
51789
52021
|
}
|
|
51790
52022
|
.o-separator {
|
|
51791
52023
|
border-bottom: ${MENU_SEPARATOR_BORDER_WIDTH}px solid ${SEPARATOR_COLOR};
|
|
@@ -51942,6 +52174,7 @@
|
|
|
51942
52174
|
};
|
|
51943
52175
|
sidePanel;
|
|
51944
52176
|
composer;
|
|
52177
|
+
spreadsheetRef = owl.useRef("spreadsheet");
|
|
51945
52178
|
_focusGrid;
|
|
51946
52179
|
keyDownMapping;
|
|
51947
52180
|
isViewportTooSmall = false;
|
|
@@ -51976,6 +52209,18 @@
|
|
|
51976
52209
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
51977
52210
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
51978
52211
|
});
|
|
52212
|
+
owl.useEffect(() => {
|
|
52213
|
+
/**
|
|
52214
|
+
* Only refocus the grid if the active element is not a child of the spreadsheet
|
|
52215
|
+
* (i.e. activeElement is outside of the spreadsheetRef component)
|
|
52216
|
+
* and spreadsheet is a child of that element. Anything else means that the focus
|
|
52217
|
+
* is on an element that needs to keep it.
|
|
52218
|
+
*/
|
|
52219
|
+
if (!this.spreadsheetRef.el.contains(document.activeElement) &&
|
|
52220
|
+
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
52221
|
+
this.focusGrid();
|
|
52222
|
+
}
|
|
52223
|
+
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
51979
52224
|
owl.useExternalListener(window, "resize", () => this.render(true));
|
|
51980
52225
|
owl.useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
51981
52226
|
this.bindModelEvents();
|
|
@@ -52057,7 +52302,7 @@
|
|
|
52057
52302
|
}
|
|
52058
52303
|
focusGrid() {
|
|
52059
52304
|
if (!this._focusGrid) {
|
|
52060
|
-
|
|
52305
|
+
return;
|
|
52061
52306
|
}
|
|
52062
52307
|
this._focusGrid();
|
|
52063
52308
|
}
|
|
@@ -55450,19 +55695,22 @@
|
|
|
55450
55695
|
* Check if the given command is allowed by all the plugins and the history.
|
|
55451
55696
|
*/
|
|
55452
55697
|
checkDispatchAllowed(command) {
|
|
55453
|
-
|
|
55454
|
-
|
|
55698
|
+
const results = isCoreCommand(command)
|
|
55699
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
55700
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
55701
|
+
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
|
55702
|
+
return new DispatchResult(results.flat());
|
|
55455
55703
|
}
|
|
55456
|
-
return
|
|
55704
|
+
return DispatchResult.Success;
|
|
55457
55705
|
}
|
|
55458
55706
|
checkDispatchAllowedCoreCommand(command) {
|
|
55459
55707
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
55460
55708
|
results.push(this.range.allowDispatch(command));
|
|
55461
|
-
return
|
|
55709
|
+
return results;
|
|
55462
55710
|
}
|
|
55463
55711
|
checkDispatchAllowedLocalCommand(command) {
|
|
55464
55712
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
55465
|
-
return
|
|
55713
|
+
return results;
|
|
55466
55714
|
}
|
|
55467
55715
|
finalize() {
|
|
55468
55716
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -55757,6 +56005,7 @@
|
|
|
55757
56005
|
FigureComponent,
|
|
55758
56006
|
Menu,
|
|
55759
56007
|
SelectionInput,
|
|
56008
|
+
ValidationMessages,
|
|
55760
56009
|
};
|
|
55761
56010
|
const hooks = {
|
|
55762
56011
|
useDragAndDropListItems,
|
|
@@ -55809,9 +56058,9 @@
|
|
|
55809
56058
|
exports.tokenize = tokenize;
|
|
55810
56059
|
|
|
55811
56060
|
|
|
55812
|
-
__info__.version = "17.1.0-alpha.
|
|
55813
|
-
__info__.date = "2023-
|
|
55814
|
-
__info__.hash = "
|
|
56061
|
+
__info__.version = "17.1.0-alpha.5";
|
|
56062
|
+
__info__.date = "2023-12-05T09:51:40.034Z";
|
|
56063
|
+
__info__.hash = "c2823eb";
|
|
55815
56064
|
|
|
55816
56065
|
|
|
55817
56066
|
})(this.o_spreadsheet = this.o_spreadsheet || {}, owl);
|