@odoo/o-spreadsheet 17.1.0-alpha.3 → 17.1.0-alpha.4
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 +655 -420
- package/dist/o-spreadsheet.d.ts +148 -138
- package/dist/o-spreadsheet.esm.js +655 -420
- package/dist/o-spreadsheet.iife.js +655 -420
- package/dist/o-spreadsheet.iife.min.js +294 -320
- package/dist/o_spreadsheet.xml +99 -61
- 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-11-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.1.0-alpha.4
|
|
6
|
+
* @date 2023-11-24T13:12:24.882Z
|
|
7
|
+
* @hash 255821b
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import { Component, useRef, onMounted, useEffect, onWillPatch, useState, onWillUpdateProps, onPatched, useComponent, useExternalListener, onWillUnmount, onWillStart, xml, useChildSubEnv, useSubEnv, markRaw } from '@odoo/owl';
|
|
@@ -227,7 +227,6 @@ const DEFAULT_CELL_HEIGHT = 23;
|
|
|
227
227
|
const SCROLLBAR_WIDTH = 15;
|
|
228
228
|
const AUTOFILL_EDGE_LENGTH = 8;
|
|
229
229
|
const ICON_EDGE_LENGTH = 18;
|
|
230
|
-
const UNHIDE_ICON_EDGE_LENGTH = 14;
|
|
231
230
|
const MIN_CF_ICON_MARGIN = 4;
|
|
232
231
|
const MIN_CELL_TEXT_MARGIN = 4;
|
|
233
232
|
const CF_ICON_EDGE_LENGTH = 15;
|
|
@@ -691,8 +690,7 @@ function removeFalsyAttributes(obj) {
|
|
|
691
690
|
*
|
|
692
691
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
693
692
|
*/
|
|
694
|
-
const
|
|
695
|
-
" ",
|
|
693
|
+
const whiteSpaceSpecialCharacters = [
|
|
696
694
|
"\t",
|
|
697
695
|
"\f",
|
|
698
696
|
"\v",
|
|
@@ -707,8 +705,7 @@ const whiteSpaceCharacters = [
|
|
|
707
705
|
String.fromCharCode(parseInt("3000", 16)),
|
|
708
706
|
String.fromCharCode(parseInt("feff", 16)),
|
|
709
707
|
];
|
|
710
|
-
const whiteSpaceRegexp = new RegExp(
|
|
711
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
708
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
712
709
|
/**
|
|
713
710
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
714
711
|
* different newlines types by \n.
|
|
@@ -716,9 +713,9 @@ const newLineRegex = /\r\n|\r|\n/g;
|
|
|
716
713
|
function replaceSpecialSpaces(text) {
|
|
717
714
|
if (!text)
|
|
718
715
|
return "";
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
return text;
|
|
716
|
+
if (!whiteSpaceRegexp.test(text))
|
|
717
|
+
return text;
|
|
718
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
722
719
|
}
|
|
723
720
|
/**
|
|
724
721
|
* Determine if the numbers are consecutive.
|
|
@@ -2060,6 +2057,7 @@ var CommandResult;
|
|
|
2060
2057
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2061
2058
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2062
2059
|
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2060
|
+
CommandResult["NoChanges"] = "NoChanges";
|
|
2063
2061
|
})(CommandResult || (CommandResult = {}));
|
|
2064
2062
|
|
|
2065
2063
|
const DEFAULT_LOCALES = [
|
|
@@ -2189,12 +2187,12 @@ function toString(value) {
|
|
|
2189
2187
|
}
|
|
2190
2188
|
}
|
|
2191
2189
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2192
|
-
function normalizeString(str) {
|
|
2190
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
2193
2191
|
return str
|
|
2194
2192
|
.toLowerCase()
|
|
2195
2193
|
.normalize("NFD")
|
|
2196
2194
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2197
|
-
}
|
|
2195
|
+
});
|
|
2198
2196
|
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);
|
|
2199
2197
|
function toBoolean(value) {
|
|
2200
2198
|
switch (typeof value) {
|
|
@@ -3427,11 +3425,18 @@ function isSingleCellReference(xc) {
|
|
|
3427
3425
|
return singleCellReference.test(xc);
|
|
3428
3426
|
}
|
|
3429
3427
|
function splitReference(ref) {
|
|
3428
|
+
if (!ref.includes("!")) {
|
|
3429
|
+
return { xc: ref };
|
|
3430
|
+
}
|
|
3430
3431
|
const parts = ref.split("!");
|
|
3431
3432
|
const xc = parts.pop();
|
|
3432
3433
|
const sheetName = getUnquotedSheetName(parts.join("!")) || undefined;
|
|
3433
3434
|
return { sheetName, xc };
|
|
3434
3435
|
}
|
|
3436
|
+
/** Return a reference SheetName!xc from the given arguments */
|
|
3437
|
+
function getFullReference(sheetName, xc) {
|
|
3438
|
+
return sheetName !== undefined ? `${getCanonicalSheetName(sheetName)}!${xc}` : xc;
|
|
3439
|
+
}
|
|
3435
3440
|
|
|
3436
3441
|
/**
|
|
3437
3442
|
* Convert from a cartesian reference to a Zone
|
|
@@ -4540,14 +4545,14 @@ function drawDecoratedText(context, text, position, underline = false, strikethr
|
|
|
4540
4545
|
switch (context.textBaseline) {
|
|
4541
4546
|
case "top":
|
|
4542
4547
|
underlineY += boxHeight - 2 * strokeWidth;
|
|
4543
|
-
strikeY += boxHeight -
|
|
4548
|
+
strikeY += boxHeight / 2 - strokeWidth;
|
|
4544
4549
|
break;
|
|
4545
4550
|
case "middle":
|
|
4546
4551
|
underlineY += boxHeight / 2 - strokeWidth;
|
|
4547
4552
|
break;
|
|
4548
4553
|
case "alphabetic":
|
|
4549
4554
|
underlineY += 2 * strokeWidth;
|
|
4550
|
-
strikeY -=
|
|
4555
|
+
strikeY -= 3 * strokeWidth;
|
|
4551
4556
|
break;
|
|
4552
4557
|
case "bottom":
|
|
4553
4558
|
underlineY = y;
|
|
@@ -4610,6 +4615,7 @@ function createAction(item) {
|
|
|
4610
4615
|
const children = item.children;
|
|
4611
4616
|
const description = item.description;
|
|
4612
4617
|
const icon = item.icon;
|
|
4618
|
+
const secondaryIcon = item.secondaryIcon;
|
|
4613
4619
|
return {
|
|
4614
4620
|
id: item.id || uuidGenerator$2.uuidv4(),
|
|
4615
4621
|
name: typeof name === "function" ? name : () => name,
|
|
@@ -4628,6 +4634,7 @@ function createAction(item) {
|
|
|
4628
4634
|
isReadonlyAllowed: item.isReadonlyAllowed || false,
|
|
4629
4635
|
separator: item.separator || false,
|
|
4630
4636
|
icon: typeof icon === "function" ? icon : () => icon || "",
|
|
4637
|
+
secondaryIcon: typeof secondaryIcon === "function" ? secondaryIcon : () => secondaryIcon || "",
|
|
4631
4638
|
description: typeof description === "function" ? description : () => description || "",
|
|
4632
4639
|
textColor: item.textColor,
|
|
4633
4640
|
sequence: item.sequence || 0,
|
|
@@ -6983,11 +6990,9 @@ css /* scss */ `
|
|
|
6983
6990
|
padding: ${MENU_VERTICAL_PADDING}px 0px;
|
|
6984
6991
|
width: ${MENU_WIDTH}px;
|
|
6985
6992
|
box-sizing: border-box !important;
|
|
6993
|
+
user-select: none;
|
|
6986
6994
|
|
|
6987
6995
|
.o-menu-item {
|
|
6988
|
-
display: flex;
|
|
6989
|
-
justify-content: space-between;
|
|
6990
|
-
align-items: center;
|
|
6991
6996
|
box-sizing: border-box;
|
|
6992
6997
|
height: ${MENU_ITEM_HEIGHT}px;
|
|
6993
6998
|
padding: ${MENU_ITEM_PADDING_VERTICAL}px ${MENU_ITEM_PADDING_HORIZONTAL}px;
|
|
@@ -6998,20 +7003,12 @@ css /* scss */ `
|
|
|
6998
7003
|
min-width: 40%;
|
|
6999
7004
|
}
|
|
7000
7005
|
|
|
7001
|
-
&.o-menu-root {
|
|
7002
|
-
display: flex;
|
|
7003
|
-
justify-content: space-between;
|
|
7004
|
-
}
|
|
7005
|
-
|
|
7006
7006
|
.o-menu-item-icon {
|
|
7007
7007
|
display: inline-block;
|
|
7008
7008
|
margin: 0px 8px 0px 0px;
|
|
7009
7009
|
width: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7010
7010
|
line-height: ${MENU_ITEM_HEIGHT - 2 * MENU_ITEM_PADDING_VERTICAL}px;
|
|
7011
7011
|
}
|
|
7012
|
-
.o-menu-item-root {
|
|
7013
|
-
width: 10px;
|
|
7014
|
-
}
|
|
7015
7012
|
|
|
7016
7013
|
&:not(.disabled) {
|
|
7017
7014
|
&:hover,
|
|
@@ -7354,7 +7351,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
7354
7351
|
return result;
|
|
7355
7352
|
}
|
|
7356
7353
|
function tokenizeDebugger(chars) {
|
|
7357
|
-
if (chars.current
|
|
7354
|
+
if (chars.current === "?") {
|
|
7358
7355
|
chars.shift();
|
|
7359
7356
|
return { type: "DEBUGGER", value: "?" };
|
|
7360
7357
|
}
|
|
@@ -7365,7 +7362,7 @@ const misc$1 = {
|
|
|
7365
7362
|
")": "RIGHT_PAREN",
|
|
7366
7363
|
};
|
|
7367
7364
|
function tokenizeMisc(chars) {
|
|
7368
|
-
if (chars.current
|
|
7365
|
+
if (chars.current in misc$1) {
|
|
7369
7366
|
const value = chars.shift();
|
|
7370
7367
|
const type = misc$1[value];
|
|
7371
7368
|
return { type, value };
|
|
@@ -7373,7 +7370,7 @@ function tokenizeMisc(chars) {
|
|
|
7373
7370
|
return null;
|
|
7374
7371
|
}
|
|
7375
7372
|
function tokenizeArgsSeparator(chars, locale) {
|
|
7376
|
-
if (chars.current
|
|
7373
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
7377
7374
|
const value = chars.shift();
|
|
7378
7375
|
const type = "ARG_SEPARATOR";
|
|
7379
7376
|
return { type, value };
|
|
@@ -7398,14 +7395,13 @@ function tokenizeNumber(chars, locale) {
|
|
|
7398
7395
|
return null;
|
|
7399
7396
|
}
|
|
7400
7397
|
function tokenizeString(chars) {
|
|
7401
|
-
if (chars.current
|
|
7398
|
+
if (chars.current === '"') {
|
|
7402
7399
|
const startChar = chars.shift();
|
|
7403
7400
|
let letters = startChar;
|
|
7404
|
-
while (chars.current()
|
|
7405
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7401
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7406
7402
|
letters += chars.shift();
|
|
7407
7403
|
}
|
|
7408
|
-
if (chars.current
|
|
7404
|
+
if (chars.current === '"') {
|
|
7409
7405
|
letters += chars.shift();
|
|
7410
7406
|
}
|
|
7411
7407
|
return {
|
|
@@ -7432,14 +7428,14 @@ function tokenizeSymbol(chars) {
|
|
|
7432
7428
|
let result = "";
|
|
7433
7429
|
// there are two main cases to manage: either something which starts with
|
|
7434
7430
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
7435
|
-
if (chars.current
|
|
7431
|
+
if (chars.current === "'") {
|
|
7436
7432
|
let lastChar = chars.shift();
|
|
7437
7433
|
result += lastChar;
|
|
7438
|
-
while (chars.current
|
|
7434
|
+
while (chars.current) {
|
|
7439
7435
|
lastChar = chars.shift();
|
|
7440
7436
|
result += lastChar;
|
|
7441
7437
|
if (lastChar === "'") {
|
|
7442
|
-
if (chars.current
|
|
7438
|
+
if (chars.current && chars.current === "'") {
|
|
7443
7439
|
lastChar = chars.shift();
|
|
7444
7440
|
result += lastChar;
|
|
7445
7441
|
}
|
|
@@ -7455,7 +7451,7 @@ function tokenizeSymbol(chars) {
|
|
|
7455
7451
|
};
|
|
7456
7452
|
}
|
|
7457
7453
|
}
|
|
7458
|
-
while (chars.current
|
|
7454
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
7459
7455
|
result += chars.shift();
|
|
7460
7456
|
}
|
|
7461
7457
|
if (result.length) {
|
|
@@ -7470,14 +7466,14 @@ function tokenizeSymbol(chars) {
|
|
|
7470
7466
|
}
|
|
7471
7467
|
function tokenizeSpace(chars) {
|
|
7472
7468
|
let length = 0;
|
|
7473
|
-
while (chars.current
|
|
7469
|
+
while (chars.current === NEWLINE) {
|
|
7474
7470
|
length++;
|
|
7475
7471
|
chars.shift();
|
|
7476
7472
|
}
|
|
7477
7473
|
if (length) {
|
|
7478
7474
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
7479
7475
|
}
|
|
7480
|
-
while (chars.current
|
|
7476
|
+
while (chars.current === " ") {
|
|
7481
7477
|
length++;
|
|
7482
7478
|
chars.shift();
|
|
7483
7479
|
}
|
|
@@ -7496,17 +7492,20 @@ function tokenizeInvalidRange(chars) {
|
|
|
7496
7492
|
class TokenizingChars {
|
|
7497
7493
|
text;
|
|
7498
7494
|
currentIndex = 0;
|
|
7495
|
+
current;
|
|
7499
7496
|
constructor(text) {
|
|
7500
7497
|
this.text = text;
|
|
7501
|
-
|
|
7502
|
-
current() {
|
|
7503
|
-
return this.text[this.currentIndex];
|
|
7498
|
+
this.current = text[0];
|
|
7504
7499
|
}
|
|
7505
7500
|
shift() {
|
|
7506
|
-
|
|
7501
|
+
const current = this.current;
|
|
7502
|
+
const next = this.text[++this.currentIndex];
|
|
7503
|
+
this.current = next;
|
|
7504
|
+
return current;
|
|
7507
7505
|
}
|
|
7508
7506
|
advanceBy(length) {
|
|
7509
7507
|
this.currentIndex += length;
|
|
7508
|
+
this.current = this.text[this.currentIndex];
|
|
7510
7509
|
}
|
|
7511
7510
|
isOver() {
|
|
7512
7511
|
return this.currentIndex >= this.text.length;
|
|
@@ -11310,7 +11309,7 @@ const EXPAND = {
|
|
|
11310
11309
|
) {
|
|
11311
11310
|
const _array = toMatrix(arg);
|
|
11312
11311
|
const _nbRows = toInteger(rows?.value, this.locale);
|
|
11313
|
-
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.
|
|
11312
|
+
const _nbColumns = columns !== undefined ? toInteger(columns.value, this.locale) : _array.length;
|
|
11314
11313
|
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()));
|
|
11315
11314
|
assert(() => _nbColumns >= _array.length, _t("The columns arguments (%s) must be greater or equal than the number of columns of the array.", _nbColumns.toString()));
|
|
11316
11315
|
return generateMatrix(_nbColumns, _nbRows, (col, row) => col >= _array.length || row >= _array[col].length ? padWith : _array[col][row]);
|
|
@@ -11799,6 +11798,10 @@ var misc = /*#__PURE__*/Object.freeze({
|
|
|
11799
11798
|
FORMAT_LARGE_NUMBER: FORMAT_LARGE_NUMBER
|
|
11800
11799
|
});
|
|
11801
11800
|
|
|
11801
|
+
function sum(values, locale) {
|
|
11802
|
+
return reduceNumbers(values, (acc, a) => acc + a, 0, locale);
|
|
11803
|
+
}
|
|
11804
|
+
|
|
11802
11805
|
const DEFAULT_FACTOR = 1;
|
|
11803
11806
|
const DEFAULT_MODE = 0;
|
|
11804
11807
|
const DEFAULT_PLACES = 0;
|
|
@@ -12750,7 +12753,7 @@ const SUM = {
|
|
|
12750
12753
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
12751
12754
|
},
|
|
12752
12755
|
compute: function (...values) {
|
|
12753
|
-
return
|
|
12756
|
+
return sum(values, this.locale);
|
|
12754
12757
|
},
|
|
12755
12758
|
isExported: true,
|
|
12756
12759
|
};
|
|
@@ -12919,6 +12922,44 @@ function assertSameNumberOfElements(...args) {
|
|
|
12919
12922
|
const dims = args[0].length;
|
|
12920
12923
|
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())));
|
|
12921
12924
|
}
|
|
12925
|
+
function average(values, locale) {
|
|
12926
|
+
let count = 0;
|
|
12927
|
+
const sum = reduceNumbers(values, (acc, a) => {
|
|
12928
|
+
count += 1;
|
|
12929
|
+
return acc + a;
|
|
12930
|
+
}, 0, locale);
|
|
12931
|
+
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
12932
|
+
return sum / count;
|
|
12933
|
+
}
|
|
12934
|
+
function countNumbers(values, locale) {
|
|
12935
|
+
let count = 0;
|
|
12936
|
+
for (let n of values) {
|
|
12937
|
+
if (isMatrix(n)) {
|
|
12938
|
+
for (let i of n) {
|
|
12939
|
+
for (let j of i) {
|
|
12940
|
+
if (typeof j === "number") {
|
|
12941
|
+
count += 1;
|
|
12942
|
+
}
|
|
12943
|
+
}
|
|
12944
|
+
}
|
|
12945
|
+
}
|
|
12946
|
+
else if (typeof n !== "string" || isNumber(n, locale) || parseDateTime(n, locale)) {
|
|
12947
|
+
count += 1;
|
|
12948
|
+
}
|
|
12949
|
+
}
|
|
12950
|
+
return count;
|
|
12951
|
+
}
|
|
12952
|
+
function countAny(values) {
|
|
12953
|
+
return reduceAny(values, (acc, a) => (a !== undefined && a !== null ? acc + 1 : acc), 0);
|
|
12954
|
+
}
|
|
12955
|
+
function max(values, locale) {
|
|
12956
|
+
const result = reduceNumbers(values, (acc, a) => (acc < a ? a : acc), -Infinity, locale);
|
|
12957
|
+
return result === -Infinity ? 0 : result;
|
|
12958
|
+
}
|
|
12959
|
+
function min(values, locale) {
|
|
12960
|
+
const result = reduceNumbers(values, (acc, a) => (a < acc ? a : acc), Infinity, locale);
|
|
12961
|
+
return result === Infinity ? 0 : result;
|
|
12962
|
+
}
|
|
12922
12963
|
|
|
12923
12964
|
function filterAndFlatData(dataY, dataX) {
|
|
12924
12965
|
const _flatDataY = [];
|
|
@@ -13189,13 +13230,7 @@ const AVERAGE = {
|
|
|
13189
13230
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13190
13231
|
},
|
|
13191
13232
|
compute: function (...values) {
|
|
13192
|
-
|
|
13193
|
-
const sum = reduceNumbers(values, (acc, a) => {
|
|
13194
|
-
count += 1;
|
|
13195
|
-
return acc + a;
|
|
13196
|
-
}, 0, this.locale);
|
|
13197
|
-
assert(() => count !== 0, _t("Evaluation of function [[FUNCTION_NAME]] caused a divide by zero error."));
|
|
13198
|
-
return sum / count;
|
|
13233
|
+
return average(values, this.locale);
|
|
13199
13234
|
},
|
|
13200
13235
|
isExported: true,
|
|
13201
13236
|
};
|
|
@@ -13353,24 +13388,7 @@ const COUNT = {
|
|
|
13353
13388
|
],
|
|
13354
13389
|
returns: ["NUMBER"],
|
|
13355
13390
|
compute: function (...values) {
|
|
13356
|
-
|
|
13357
|
-
for (let n of values) {
|
|
13358
|
-
if (isMatrix(n)) {
|
|
13359
|
-
for (let i of n) {
|
|
13360
|
-
for (let j of i) {
|
|
13361
|
-
if (typeof j === "number") {
|
|
13362
|
-
count += 1;
|
|
13363
|
-
}
|
|
13364
|
-
}
|
|
13365
|
-
}
|
|
13366
|
-
}
|
|
13367
|
-
else if (typeof n !== "string" ||
|
|
13368
|
-
isNumber(n, this.locale) ||
|
|
13369
|
-
parseDateTime(n, this.locale)) {
|
|
13370
|
-
count += 1;
|
|
13371
|
-
}
|
|
13372
|
-
}
|
|
13373
|
-
return count;
|
|
13391
|
+
return countNumbers(values, this.locale);
|
|
13374
13392
|
},
|
|
13375
13393
|
isExported: true,
|
|
13376
13394
|
};
|
|
@@ -13385,7 +13403,7 @@ const COUNTA = {
|
|
|
13385
13403
|
],
|
|
13386
13404
|
returns: ["NUMBER"],
|
|
13387
13405
|
compute: function (...values) {
|
|
13388
|
-
return
|
|
13406
|
+
return countAny(values);
|
|
13389
13407
|
},
|
|
13390
13408
|
isExported: true,
|
|
13391
13409
|
};
|
|
@@ -13615,8 +13633,7 @@ const MAX = {
|
|
|
13615
13633
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13616
13634
|
},
|
|
13617
13635
|
compute: function (...values) {
|
|
13618
|
-
|
|
13619
|
-
return result === -Infinity ? 0 : result;
|
|
13636
|
+
return max(values, this.locale);
|
|
13620
13637
|
},
|
|
13621
13638
|
isExported: true,
|
|
13622
13639
|
};
|
|
@@ -13703,8 +13720,7 @@ const MIN = {
|
|
|
13703
13720
|
return isMatrix(value1) ? value1[0][0]?.format : value1?.format;
|
|
13704
13721
|
},
|
|
13705
13722
|
compute: function (...values) {
|
|
13706
|
-
|
|
13707
|
-
return result === Infinity ? 0 : result;
|
|
13723
|
+
return min(values, this.locale);
|
|
13708
13724
|
},
|
|
13709
13725
|
isExported: true,
|
|
13710
13726
|
};
|
|
@@ -17875,6 +17891,149 @@ var financial = /*#__PURE__*/Object.freeze({
|
|
|
17875
17891
|
YIELDMAT: YIELDMAT
|
|
17876
17892
|
});
|
|
17877
17893
|
|
|
17894
|
+
/**
|
|
17895
|
+
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
17896
|
+
*
|
|
17897
|
+
* Eg. :
|
|
17898
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17899
|
+
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
17900
|
+
*/
|
|
17901
|
+
function loopThroughReferenceType(token) {
|
|
17902
|
+
if (token.type !== "REFERENCE")
|
|
17903
|
+
return token;
|
|
17904
|
+
const { xc, sheetName } = splitReference(token.value);
|
|
17905
|
+
const [left, right] = xc.split(":");
|
|
17906
|
+
const updatedLeft = getTokenNextReferenceType(left);
|
|
17907
|
+
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
17908
|
+
return { ...token, value: getFullReference(sheetName, updatedLeft + updatedRight) };
|
|
17909
|
+
}
|
|
17910
|
+
/**
|
|
17911
|
+
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
17912
|
+
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
17913
|
+
*
|
|
17914
|
+
* A1 => $A$1 => A$1 => $A1 => A1
|
|
17915
|
+
*/
|
|
17916
|
+
function getTokenNextReferenceType(xc) {
|
|
17917
|
+
switch (getReferenceType(xc)) {
|
|
17918
|
+
case "none":
|
|
17919
|
+
xc = setXcToFixedReferenceType(xc, "colrow");
|
|
17920
|
+
break;
|
|
17921
|
+
case "colrow":
|
|
17922
|
+
xc = setXcToFixedReferenceType(xc, "row");
|
|
17923
|
+
break;
|
|
17924
|
+
case "row":
|
|
17925
|
+
xc = setXcToFixedReferenceType(xc, "col");
|
|
17926
|
+
break;
|
|
17927
|
+
case "col":
|
|
17928
|
+
xc = setXcToFixedReferenceType(xc, "none");
|
|
17929
|
+
break;
|
|
17930
|
+
}
|
|
17931
|
+
return xc;
|
|
17932
|
+
}
|
|
17933
|
+
/**
|
|
17934
|
+
* Returns the given XC with the given reference type. The XC string should not contain a sheet name.
|
|
17935
|
+
*/
|
|
17936
|
+
function setXcToFixedReferenceType(xc, referenceType) {
|
|
17937
|
+
if (xc.includes("!")) {
|
|
17938
|
+
throw new Error("The given XC should not contain a sheet name");
|
|
17939
|
+
}
|
|
17940
|
+
xc = xc.replace(/\$/g, "");
|
|
17941
|
+
let indexOfNumber;
|
|
17942
|
+
switch (referenceType) {
|
|
17943
|
+
case "col":
|
|
17944
|
+
return "$" + xc;
|
|
17945
|
+
case "row":
|
|
17946
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17947
|
+
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17948
|
+
case "colrow":
|
|
17949
|
+
indexOfNumber = xc.search(/[0-9]/);
|
|
17950
|
+
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
17951
|
+
return "$" + xc;
|
|
17952
|
+
case "none":
|
|
17953
|
+
return xc;
|
|
17954
|
+
}
|
|
17955
|
+
}
|
|
17956
|
+
/**
|
|
17957
|
+
* Return the type of reference used in the given XC of a cell.
|
|
17958
|
+
* Undefined behavior if the XC have a sheet reference
|
|
17959
|
+
*/
|
|
17960
|
+
function getReferenceType(xcCell) {
|
|
17961
|
+
if (isColAndRowFixed(xcCell)) {
|
|
17962
|
+
return "colrow";
|
|
17963
|
+
}
|
|
17964
|
+
else if (isColFixed(xcCell)) {
|
|
17965
|
+
return "col";
|
|
17966
|
+
}
|
|
17967
|
+
else if (isRowFixed(xcCell)) {
|
|
17968
|
+
return "row";
|
|
17969
|
+
}
|
|
17970
|
+
return "none";
|
|
17971
|
+
}
|
|
17972
|
+
function isColFixed(xc) {
|
|
17973
|
+
return xc.startsWith("$");
|
|
17974
|
+
}
|
|
17975
|
+
function isRowFixed(xc) {
|
|
17976
|
+
return xc.includes("$", 1);
|
|
17977
|
+
}
|
|
17978
|
+
function isColAndRowFixed(xc) {
|
|
17979
|
+
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
17980
|
+
}
|
|
17981
|
+
|
|
17982
|
+
// -----------------------------------------------------------------------------
|
|
17983
|
+
// CELL
|
|
17984
|
+
// -----------------------------------------------------------------------------
|
|
17985
|
+
// NOTE: missing from Excel: "color", "filename", "parentheses", "prefix", "protect" and "width"
|
|
17986
|
+
const CELL_INFO_TYPES = ["address", "col", "contents", "format", "row", "type"];
|
|
17987
|
+
const CELL = {
|
|
17988
|
+
description: _t("Gets information about a cell."),
|
|
17989
|
+
args: [
|
|
17990
|
+
arg("info_type (string)", _t("The type of information requested. Can be one of %s", CELL_INFO_TYPES.join(", "))),
|
|
17991
|
+
arg("reference (meta)", _t("The reference to the cell.")),
|
|
17992
|
+
],
|
|
17993
|
+
returns: ["ANY"],
|
|
17994
|
+
compute: function (info, reference) {
|
|
17995
|
+
const _info = toString(info).toLowerCase();
|
|
17996
|
+
assert(() => CELL_INFO_TYPES.includes(_info), _t("The info_type should be one of %s.", CELL_INFO_TYPES.join(", ")));
|
|
17997
|
+
const sheetId = this.__originSheetId;
|
|
17998
|
+
const topLeftReference = reference.includes(":") ? reference.split(":")[0] : reference;
|
|
17999
|
+
let { sheetName, xc } = splitReference(topLeftReference);
|
|
18000
|
+
// only put the sheet name if the referenced range is in another sheet than the cell the formula is on
|
|
18001
|
+
sheetName = sheetName === this.getters.getSheetName(sheetId) ? undefined : sheetName;
|
|
18002
|
+
const fixedRef = getFullReference(sheetName, setXcToFixedReferenceType(xc, "colrow"));
|
|
18003
|
+
const range = this.getters.getRangeFromSheetXC(sheetId, fixedRef);
|
|
18004
|
+
switch (_info) {
|
|
18005
|
+
case "address":
|
|
18006
|
+
return this.getters.getRangeString(range, sheetId);
|
|
18007
|
+
case "col":
|
|
18008
|
+
return range.zone.left + 1;
|
|
18009
|
+
case "contents": {
|
|
18010
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18011
|
+
return this.getters.getEvaluatedCell(position).value;
|
|
18012
|
+
}
|
|
18013
|
+
case "format": {
|
|
18014
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18015
|
+
return this.getters.getEvaluatedCell(position).format || "";
|
|
18016
|
+
}
|
|
18017
|
+
case "row":
|
|
18018
|
+
return range.zone.top + 1;
|
|
18019
|
+
case "type": {
|
|
18020
|
+
const position = { sheetId: range.sheetId, col: range.zone.left, row: range.zone.top };
|
|
18021
|
+
const type = this.getters.getEvaluatedCell(position).type;
|
|
18022
|
+
if (type === CellValueType.empty) {
|
|
18023
|
+
return "b"; // blank
|
|
18024
|
+
}
|
|
18025
|
+
else if (type === CellValueType.text) {
|
|
18026
|
+
return "l"; // label
|
|
18027
|
+
}
|
|
18028
|
+
else {
|
|
18029
|
+
return "v"; // value
|
|
18030
|
+
}
|
|
18031
|
+
}
|
|
18032
|
+
}
|
|
18033
|
+
return "";
|
|
18034
|
+
},
|
|
18035
|
+
isExported: true,
|
|
18036
|
+
};
|
|
17878
18037
|
// -----------------------------------------------------------------------------
|
|
17879
18038
|
// ISERR
|
|
17880
18039
|
// -----------------------------------------------------------------------------
|
|
@@ -18030,6 +18189,7 @@ const NA = {
|
|
|
18030
18189
|
|
|
18031
18190
|
var info = /*#__PURE__*/Object.freeze({
|
|
18032
18191
|
__proto__: null,
|
|
18192
|
+
CELL: CELL,
|
|
18033
18193
|
ISBLANK: ISBLANK,
|
|
18034
18194
|
ISERR: ISERR,
|
|
18035
18195
|
ISERROR: ISERROR,
|
|
@@ -18321,7 +18481,7 @@ const ADDRESS = {
|
|
|
18321
18481
|
cellReference = rowPart + colPart;
|
|
18322
18482
|
}
|
|
18323
18483
|
if (sheet !== undefined) {
|
|
18324
|
-
return
|
|
18484
|
+
return getFullReference(toString(sheet), cellReference);
|
|
18325
18485
|
}
|
|
18326
18486
|
return cellReference;
|
|
18327
18487
|
},
|
|
@@ -18337,7 +18497,7 @@ const COLUMN = {
|
|
|
18337
18497
|
],
|
|
18338
18498
|
returns: ["NUMBER"],
|
|
18339
18499
|
compute: function (cellReference) {
|
|
18340
|
-
const _cellReference = cellReference || this.__originCellXC
|
|
18500
|
+
const _cellReference = cellReference || this.__originCellXC();
|
|
18341
18501
|
assert(() => !!_cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18342
18502
|
const zone = toZone(_cellReference);
|
|
18343
18503
|
return zone.left + 1;
|
|
@@ -18504,7 +18664,7 @@ const ROW = {
|
|
|
18504
18664
|
],
|
|
18505
18665
|
returns: ["NUMBER"],
|
|
18506
18666
|
compute: function (cellReference) {
|
|
18507
|
-
cellReference = cellReference || this.__originCellXC
|
|
18667
|
+
cellReference = cellReference || this.__originCellXC();
|
|
18508
18668
|
assert(() => !!cellReference, "In this context, the function [[FUNCTION_NAME]] needs to have a cell or range in parameter.");
|
|
18509
18669
|
const zone = toZone(cellReference);
|
|
18510
18670
|
return zone.top + 1;
|
|
@@ -23856,31 +24016,65 @@ css /* scss */ `
|
|
|
23856
24016
|
`;
|
|
23857
24017
|
class FindAndReplacePanel extends Component {
|
|
23858
24018
|
static template = "o-spreadsheet-FindAndReplacePanel";
|
|
23859
|
-
|
|
24019
|
+
static components = { SelectionInput };
|
|
23860
24020
|
debounceTimeoutId;
|
|
23861
|
-
|
|
24021
|
+
initialShowFormulaState = false;
|
|
24022
|
+
dataRange = "";
|
|
23862
24023
|
searchInput = useRef("searchInput");
|
|
24024
|
+
replaceInput = useRef("replaceInput");
|
|
23863
24025
|
get hasSearchResult() {
|
|
23864
24026
|
return this.env.model.getters.getCurrentSelectedMatchIndex() !== null;
|
|
23865
24027
|
}
|
|
23866
24028
|
get pendingSearch() {
|
|
23867
24029
|
return this.debounceTimeoutId !== undefined;
|
|
23868
24030
|
}
|
|
24031
|
+
get searchOptions() {
|
|
24032
|
+
return this.env.model.getters.getSearchOptions();
|
|
24033
|
+
}
|
|
24034
|
+
get toSearch() {
|
|
24035
|
+
return this.searchInput.el?.value || "";
|
|
24036
|
+
}
|
|
24037
|
+
get toReplace() {
|
|
24038
|
+
return this.replaceInput.el?.value || "";
|
|
24039
|
+
}
|
|
24040
|
+
get allSheetsMatchesCount() {
|
|
24041
|
+
return _t("%s in all sheets", this.env.model.getters.getAllSheetMatchesCount());
|
|
24042
|
+
}
|
|
24043
|
+
get currentSheetMatchesCount() {
|
|
24044
|
+
return _t("%(matches)s in sheet %(sheetName)s", {
|
|
24045
|
+
matches: this.env.model.getters.getActiveSheetMatchesCount(),
|
|
24046
|
+
sheetName: this.env.model.getters.getSheetName(this.env.model.getters.getActiveSheetId()),
|
|
24047
|
+
});
|
|
24048
|
+
}
|
|
24049
|
+
get specificRangeMatchesCount() {
|
|
24050
|
+
const range = this.searchOptions.specificRange;
|
|
24051
|
+
if (!range) {
|
|
24052
|
+
return "";
|
|
24053
|
+
}
|
|
24054
|
+
const { _sheetId, _zone } = range;
|
|
24055
|
+
return _t("%(matches)s in range %(range)s of sheet %(sheetName)s", {
|
|
24056
|
+
matches: this.env.model.getters.getSpecificRangeMatchesCount().toString(),
|
|
24057
|
+
range: zoneToXc(_zone),
|
|
24058
|
+
sheetName: this.env.model.getters.getSheetName(_sheetId),
|
|
24059
|
+
});
|
|
24060
|
+
}
|
|
23869
24061
|
setup() {
|
|
23870
|
-
this.
|
|
24062
|
+
this.initialShowFormulaState = this.env.model.getters.shouldShowFormulas();
|
|
23871
24063
|
onMounted(() => this.searchInput.el?.focus());
|
|
23872
24064
|
onWillUnmount(() => {
|
|
23873
24065
|
clearTimeout(this.debounceTimeoutId);
|
|
23874
24066
|
this.env.model.dispatch("CLEAR_SEARCH");
|
|
23875
|
-
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.
|
|
24067
|
+
this.env.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
23876
24068
|
});
|
|
23877
24069
|
useEffect(() => {
|
|
23878
|
-
|
|
23879
|
-
this.searchFormulas
|
|
24070
|
+
const showFormula = this.env.model.getters.shouldShowFormulas();
|
|
24071
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
23880
24072
|
}, () => [this.env.model.getters.shouldShowFormulas()]);
|
|
23881
24073
|
}
|
|
23882
|
-
|
|
23883
|
-
this.
|
|
24074
|
+
onFocusSearch() {
|
|
24075
|
+
this.updateDataRange();
|
|
24076
|
+
}
|
|
24077
|
+
onInput() {
|
|
23884
24078
|
this.debouncedUpdateSearch();
|
|
23885
24079
|
}
|
|
23886
24080
|
onKeydownSearch(ev) {
|
|
@@ -23897,11 +24091,36 @@ class FindAndReplacePanel extends Component {
|
|
|
23897
24091
|
this.replace();
|
|
23898
24092
|
}
|
|
23899
24093
|
}
|
|
23900
|
-
searchFormulas() {
|
|
24094
|
+
searchFormulas(ev) {
|
|
24095
|
+
const showFormula = ev.target.checked;
|
|
23901
24096
|
this.env.model.dispatch("SET_FORMULA_VISIBILITY", {
|
|
23902
|
-
show:
|
|
24097
|
+
show: showFormula,
|
|
23903
24098
|
});
|
|
23904
|
-
this.updateSearch();
|
|
24099
|
+
this.updateSearch({ searchFormulas: showFormula });
|
|
24100
|
+
}
|
|
24101
|
+
searchExactMatch(ev) {
|
|
24102
|
+
const exactMatch = ev.target.checked;
|
|
24103
|
+
this.updateSearch({ exactMatch });
|
|
24104
|
+
}
|
|
24105
|
+
searchMatchCase(ev) {
|
|
24106
|
+
const matchCase = ev.target.checked;
|
|
24107
|
+
this.updateSearch({ matchCase });
|
|
24108
|
+
}
|
|
24109
|
+
changeSearchScope(ev) {
|
|
24110
|
+
const searchScope = ev.target.value;
|
|
24111
|
+
this.updateSearch({ searchScope });
|
|
24112
|
+
}
|
|
24113
|
+
onSearchRangeChanged(ranges) {
|
|
24114
|
+
this.dataRange = ranges[0];
|
|
24115
|
+
}
|
|
24116
|
+
updateDataRange() {
|
|
24117
|
+
if (!this.dataRange) {
|
|
24118
|
+
return;
|
|
24119
|
+
}
|
|
24120
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
24121
|
+
const specificRange = this.env.model.getters.getRangeFromSheetXC(this.env.model.getters.getActiveSheetId(), this.dataRange).rangeData;
|
|
24122
|
+
this.updateSearch({ specificRange });
|
|
24123
|
+
}
|
|
23905
24124
|
}
|
|
23906
24125
|
onSelectPreviousCell() {
|
|
23907
24126
|
this.env.model.dispatch("SELECT_SEARCH_PREVIOUS_MATCH");
|
|
@@ -23909,10 +24128,14 @@ class FindAndReplacePanel extends Component {
|
|
|
23909
24128
|
onSelectNextCell() {
|
|
23910
24129
|
this.env.model.dispatch("SELECT_SEARCH_NEXT_MATCH");
|
|
23911
24130
|
}
|
|
23912
|
-
updateSearch() {
|
|
24131
|
+
updateSearch(updateSearchOptions) {
|
|
24132
|
+
const searchOptions = {
|
|
24133
|
+
...this.env.model.getters.getSearchOptions(),
|
|
24134
|
+
...updateSearchOptions,
|
|
24135
|
+
};
|
|
23913
24136
|
this.env.model.dispatch("UPDATE_SEARCH", {
|
|
23914
|
-
toSearch: this.
|
|
23915
|
-
searchOptions
|
|
24137
|
+
toSearch: this.toSearch,
|
|
24138
|
+
searchOptions,
|
|
23916
24139
|
});
|
|
23917
24140
|
}
|
|
23918
24141
|
debouncedUpdateSearch() {
|
|
@@ -23924,28 +24147,14 @@ class FindAndReplacePanel extends Component {
|
|
|
23924
24147
|
}
|
|
23925
24148
|
replace() {
|
|
23926
24149
|
this.env.model.dispatch("REPLACE_SEARCH", {
|
|
23927
|
-
replaceWith: this.
|
|
24150
|
+
replaceWith: this.toReplace,
|
|
23928
24151
|
});
|
|
23929
24152
|
}
|
|
23930
24153
|
replaceAll() {
|
|
23931
24154
|
this.env.model.dispatch("REPLACE_ALL_SEARCH", {
|
|
23932
|
-
replaceWith: this.
|
|
24155
|
+
replaceWith: this.toReplace,
|
|
23933
24156
|
});
|
|
23934
24157
|
}
|
|
23935
|
-
// ---------------------------------------------------------------------------
|
|
23936
|
-
// Private
|
|
23937
|
-
// ---------------------------------------------------------------------------
|
|
23938
|
-
initialState() {
|
|
23939
|
-
return {
|
|
23940
|
-
toSearch: "",
|
|
23941
|
-
replaceWith: "",
|
|
23942
|
-
searchOptions: {
|
|
23943
|
-
matchCase: false,
|
|
23944
|
-
exactMatch: false,
|
|
23945
|
-
searchFormulas: false,
|
|
23946
|
-
},
|
|
23947
|
-
};
|
|
23948
|
-
}
|
|
23949
24158
|
}
|
|
23950
24159
|
FindAndReplacePanel.props = {
|
|
23951
24160
|
onCloseSidePanel: Function,
|
|
@@ -27091,7 +27300,7 @@ class GridComposer extends Component {
|
|
|
27091
27300
|
get cellReference() {
|
|
27092
27301
|
const { col, row, sheetId } = this.env.model.getters.getCurrentEditedCell();
|
|
27093
27302
|
const prefixSheet = sheetId !== this.env.model.getters.getActiveSheetId();
|
|
27094
|
-
return
|
|
27303
|
+
return getFullReference(prefixSheet ? this.env.model.getters.getSheetName(sheetId) : undefined, toXC(col, row));
|
|
27095
27304
|
}
|
|
27096
27305
|
get cellReferenceStyle() {
|
|
27097
27306
|
const { x: left, y: top } = this.rect;
|
|
@@ -28534,22 +28743,15 @@ css /* scss */ `
|
|
|
28534
28743
|
height: 10000px;
|
|
28535
28744
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28536
28745
|
}
|
|
28537
|
-
.o-unhide {
|
|
28538
|
-
width:
|
|
28539
|
-
|
|
28540
|
-
|
|
28541
|
-
overflow: hidden;
|
|
28542
|
-
border-radius: 2px;
|
|
28543
|
-
top: calc(${HEADER_HEIGHT}px / 2 - ${UNHIDE_ICON_EDGE_LENGTH}px / 2);
|
|
28746
|
+
.o-unhide-buttons {
|
|
28747
|
+
width: fit-content;
|
|
28748
|
+
gap: 5px;
|
|
28749
|
+
transform: translate(-50%, 0);
|
|
28544
28750
|
}
|
|
28545
28751
|
.o-unhide:hover {
|
|
28546
28752
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
28547
28753
|
background-color: lightgrey;
|
|
28548
28754
|
}
|
|
28549
|
-
.o-unhide > svg {
|
|
28550
|
-
position: relative;
|
|
28551
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28552
|
-
}
|
|
28553
28755
|
}
|
|
28554
28756
|
`;
|
|
28555
28757
|
AbstractResizer.props = {
|
|
@@ -28659,8 +28861,8 @@ class ColResizer extends AbstractResizer {
|
|
|
28659
28861
|
dimension: "COL",
|
|
28660
28862
|
});
|
|
28661
28863
|
}
|
|
28662
|
-
|
|
28663
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
28864
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
28865
|
+
return cssPropertiesToCss({ left: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28664
28866
|
}
|
|
28665
28867
|
}
|
|
28666
28868
|
css /* scss */ `
|
|
@@ -28706,18 +28908,9 @@ css /* scss */ `
|
|
|
28706
28908
|
height: 1px;
|
|
28707
28909
|
background-color: ${SELECTION_BORDER_COLOR};
|
|
28708
28910
|
}
|
|
28709
|
-
.o-unhide {
|
|
28710
|
-
|
|
28711
|
-
|
|
28712
|
-
position: absolute;
|
|
28713
|
-
overflow: hidden;
|
|
28714
|
-
border-radius: 2px;
|
|
28715
|
-
left: calc(${HEADER_WIDTH}px - ${UNHIDE_ICON_EDGE_LENGTH}px - 2px);
|
|
28716
|
-
}
|
|
28717
|
-
.o-unhide > svg {
|
|
28718
|
-
position: relative;
|
|
28719
|
-
left: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28720
|
-
top: calc(${UNHIDE_ICON_EDGE_LENGTH}px / 2 - ${ICON_EDGE_LENGTH}px / 2);
|
|
28911
|
+
.o-unhide-buttons {
|
|
28912
|
+
height: fit-content;
|
|
28913
|
+
transform: translate(0, -50%);
|
|
28721
28914
|
}
|
|
28722
28915
|
.o-unhide:hover {
|
|
28723
28916
|
z-index: ${ComponentsImportance.Grid + 1};
|
|
@@ -28832,8 +29025,8 @@ class RowResizer extends AbstractResizer {
|
|
|
28832
29025
|
elements: hiddenElements,
|
|
28833
29026
|
});
|
|
28834
29027
|
}
|
|
28835
|
-
|
|
28836
|
-
return this._getDimensionsInViewport(hiddenIndex).start;
|
|
29028
|
+
getUnhideButtonStyle(hiddenIndex) {
|
|
29029
|
+
return cssPropertiesToCss({ top: this._getDimensionsInViewport(hiddenIndex).start + "px" });
|
|
28837
29030
|
}
|
|
28838
29031
|
}
|
|
28839
29032
|
css /* scss */ `
|
|
@@ -29340,7 +29533,6 @@ class Grid extends Component {
|
|
|
29340
29533
|
onMounted(() => this.focus());
|
|
29341
29534
|
this.props.exposeFocus(() => this.focus());
|
|
29342
29535
|
useGridDrawing("canvas", this.env.model, () => this.env.model.getters.getSheetViewDimensionWithHeaders());
|
|
29343
|
-
useEffect(() => this.focus(), () => [this.env.model.getters.getActiveSheetId()]);
|
|
29344
29536
|
this.onMouseWheel = useWheelHandler((deltaX, deltaY) => {
|
|
29345
29537
|
this.moveCanvas(deltaX, deltaY);
|
|
29346
29538
|
this.hoveredCell.col = undefined;
|
|
@@ -29777,6 +29969,7 @@ class Grid extends Component {
|
|
|
29777
29969
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
29778
29970
|
const target = this.env.model.getters.getSelectedZones();
|
|
29779
29971
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
29972
|
+
const isCutOperation = this.env.model.getters.isCutOperation();
|
|
29780
29973
|
if (clipboardString === content) {
|
|
29781
29974
|
// the paste actually comes from o-spreadsheet itself
|
|
29782
29975
|
interactivePaste(this.env, target);
|
|
@@ -29784,7 +29977,7 @@ class Grid extends Component {
|
|
|
29784
29977
|
else {
|
|
29785
29978
|
interactivePasteFromOS(this.env, target, content);
|
|
29786
29979
|
}
|
|
29787
|
-
if (
|
|
29980
|
+
if (isCutOperation) {
|
|
29788
29981
|
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
29789
29982
|
}
|
|
29790
29983
|
}
|
|
@@ -31397,12 +31590,6 @@ function convertChartData(chartData) {
|
|
|
31397
31590
|
}
|
|
31398
31591
|
function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
31399
31592
|
let { sheetName, xc } = splitReference(range);
|
|
31400
|
-
if (sheetName) {
|
|
31401
|
-
sheetName = getCanonicalSheetName(sheetName) + "!";
|
|
31402
|
-
}
|
|
31403
|
-
else {
|
|
31404
|
-
sheetName = "";
|
|
31405
|
-
}
|
|
31406
31593
|
let zone = toUnboundedZone(xc);
|
|
31407
31594
|
if (dataSetsHaveTitle && zone.bottom !== undefined && zone.right !== undefined) {
|
|
31408
31595
|
const height = zone.bottom - zone.top + 1;
|
|
@@ -31415,7 +31602,7 @@ function convertExcelRangeToSheetXC(range, dataSetsHaveTitle) {
|
|
|
31415
31602
|
}
|
|
31416
31603
|
}
|
|
31417
31604
|
const dataXC = zoneToXc(zone);
|
|
31418
|
-
return sheetName
|
|
31605
|
+
return getFullReference(sheetName, dataXC);
|
|
31419
31606
|
}
|
|
31420
31607
|
|
|
31421
31608
|
/**
|
|
@@ -34078,6 +34265,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
34078
34265
|
// ---------------------------------------------------------------------------
|
|
34079
34266
|
// Command Handling
|
|
34080
34267
|
// ---------------------------------------------------------------------------
|
|
34268
|
+
allowDispatch(cmd) {
|
|
34269
|
+
switch (cmd.type) {
|
|
34270
|
+
case "SET_BORDER":
|
|
34271
|
+
return this.checkBordersUnchanged(cmd);
|
|
34272
|
+
default:
|
|
34273
|
+
return "Success" /* CommandResult.Success */;
|
|
34274
|
+
}
|
|
34275
|
+
}
|
|
34081
34276
|
handle(cmd) {
|
|
34082
34277
|
switch (cmd.type) {
|
|
34083
34278
|
case "ADD_MERGE":
|
|
@@ -34497,6 +34692,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
34497
34692
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
34498
34693
|
}
|
|
34499
34694
|
}
|
|
34695
|
+
checkBordersUnchanged(cmd) {
|
|
34696
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
34697
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
34698
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
34699
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
34700
|
+
}
|
|
34701
|
+
return "Success" /* CommandResult.Success */;
|
|
34702
|
+
}
|
|
34500
34703
|
// ---------------------------------------------------------------------------
|
|
34501
34704
|
// Import/Export
|
|
34502
34705
|
// ---------------------------------------------------------------------------
|
|
@@ -35323,7 +35526,6 @@ class CellPlugin extends CorePlugin {
|
|
|
35323
35526
|
static getters = [
|
|
35324
35527
|
"zoneToXC",
|
|
35325
35528
|
"getCells",
|
|
35326
|
-
"getFormulaCellContent",
|
|
35327
35529
|
"getTranslatedCellFormula",
|
|
35328
35530
|
"getCellStyle",
|
|
35329
35531
|
"getCellById",
|
|
@@ -35352,8 +35554,9 @@ class CellPlugin extends CorePlugin {
|
|
|
35352
35554
|
allowDispatch(cmd) {
|
|
35353
35555
|
switch (cmd.type) {
|
|
35354
35556
|
case "UPDATE_CELL":
|
|
35557
|
+
return this.checkCellOutOfSheet(cmd);
|
|
35355
35558
|
case "CLEAR_CELL":
|
|
35356
|
-
return this.
|
|
35559
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
35357
35560
|
default:
|
|
35358
35561
|
return "Success" /* CommandResult.Success */;
|
|
35359
35562
|
}
|
|
@@ -35522,24 +35725,18 @@ class CellPlugin extends CorePlugin {
|
|
|
35522
35725
|
*/
|
|
35523
35726
|
getCellById(cellId) {
|
|
35524
35727
|
// this must be as fast as possible
|
|
35525
|
-
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
if (cell) {
|
|
35529
|
-
return cell;
|
|
35530
|
-
}
|
|
35531
|
-
}
|
|
35532
|
-
return undefined;
|
|
35728
|
+
const position = this.getters.getCellPosition(cellId);
|
|
35729
|
+
const sheet = this.cells[position.sheetId];
|
|
35730
|
+
return sheet[cellId];
|
|
35533
35731
|
}
|
|
35534
35732
|
/*
|
|
35535
35733
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
35536
35734
|
*/
|
|
35537
35735
|
getFormulaCellContent(sheetId, compiledFormula, dependencies) {
|
|
35538
|
-
const ranges = dependencies || compiledFormula.dependencies;
|
|
35539
35736
|
let rangeIndex = 0;
|
|
35540
35737
|
return concat(compiledFormula.tokens.map((token) => {
|
|
35541
35738
|
if (token.type === "REFERENCE") {
|
|
35542
|
-
const range =
|
|
35739
|
+
const range = dependencies[rangeIndex++];
|
|
35543
35740
|
return this.getters.getRangeString(range, sheetId);
|
|
35544
35741
|
}
|
|
35545
35742
|
return token.value;
|
|
@@ -35760,13 +35957,23 @@ class CellPlugin extends CorePlugin {
|
|
|
35760
35957
|
},
|
|
35761
35958
|
};
|
|
35762
35959
|
}
|
|
35763
|
-
checkCellOutOfSheet(
|
|
35960
|
+
checkCellOutOfSheet(cmd) {
|
|
35961
|
+
const { sheetId, col, row } = cmd;
|
|
35764
35962
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
35765
35963
|
if (!sheet)
|
|
35766
35964
|
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
35767
35965
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
35768
35966
|
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
|
35769
35967
|
}
|
|
35968
|
+
checkUselessClearCell(cmd) {
|
|
35969
|
+
const cell = this.getters.getCell(cmd);
|
|
35970
|
+
if (!cell)
|
|
35971
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35972
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
35973
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35974
|
+
}
|
|
35975
|
+
return "Success" /* CommandResult.Success */;
|
|
35976
|
+
}
|
|
35770
35977
|
}
|
|
35771
35978
|
class FormulaCellWithDependencies {
|
|
35772
35979
|
id;
|
|
@@ -36456,6 +36663,9 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
36456
36663
|
return this.rules[sheetId].find((rule) => rule.id === id);
|
|
36457
36664
|
}
|
|
36458
36665
|
getValidationRuleForCell({ sheetId, col, row }) {
|
|
36666
|
+
if (!this.rules[sheetId]) {
|
|
36667
|
+
return undefined;
|
|
36668
|
+
}
|
|
36459
36669
|
for (const rule of this.rules[sheetId]) {
|
|
36460
36670
|
for (const range of rule.ranges) {
|
|
36461
36671
|
if (isInside(col, row, range.zone)) {
|
|
@@ -37628,7 +37838,7 @@ class MergePlugin extends CorePlugin {
|
|
|
37628
37838
|
const rangeString = this.getters.getRangeString(expandedRange, forSheetId);
|
|
37629
37839
|
if (this.isSingleCellOrMerge(rangeImpl.sheetId, rangeImpl.zone)) {
|
|
37630
37840
|
const { sheetName, xc } = splitReference(rangeString);
|
|
37631
|
-
return
|
|
37841
|
+
return getFullReference(sheetName, xc.split(":")[0]);
|
|
37632
37842
|
}
|
|
37633
37843
|
return rangeString;
|
|
37634
37844
|
}
|
|
@@ -39053,10 +39263,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
39053
39263
|
// begin with the end.
|
|
39054
39264
|
rows.sort((a, b) => b - a);
|
|
39055
39265
|
for (let group of groupConsecutive(rows)) {
|
|
39266
|
+
// indexes are sorted in the descending order
|
|
39267
|
+
const from = group[group.length - 1];
|
|
39268
|
+
const to = group[0];
|
|
39056
39269
|
// Move the cells.
|
|
39057
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
39058
|
-
// Effectively delete the
|
|
39059
|
-
|
|
39270
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
39271
|
+
// Effectively delete the rows
|
|
39272
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
39060
39273
|
}
|
|
39061
39274
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
39062
39275
|
if (count) {
|
|
@@ -39078,8 +39291,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
39078
39291
|
this.addEmptyRows(sheet, quantity);
|
|
39079
39292
|
// Move the cells.
|
|
39080
39293
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
39081
|
-
// Recompute the left-right/top-bottom.
|
|
39082
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
39083
39294
|
if (index < sheet.panes.ySplit) {
|
|
39084
39295
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
39085
39296
|
}
|
|
@@ -39180,35 +39391,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
39180
39391
|
}
|
|
39181
39392
|
}
|
|
39182
39393
|
}
|
|
39183
|
-
updateRowsStructureOnDeletion(
|
|
39394
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
39184
39395
|
const rows = [];
|
|
39185
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39396
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
39186
39397
|
for (let i in sheet.rows) {
|
|
39187
|
-
|
|
39398
|
+
const row = Number(i);
|
|
39399
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
39188
39400
|
continue;
|
|
39189
39401
|
}
|
|
39190
39402
|
rows.push({
|
|
39191
|
-
cells: cellsQueue.
|
|
39403
|
+
cells: cellsQueue.pop(),
|
|
39192
39404
|
});
|
|
39193
39405
|
}
|
|
39194
39406
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39195
39407
|
}
|
|
39196
|
-
/**
|
|
39197
|
-
* Update the rows of the sheet after an addition:
|
|
39198
|
-
* - Rename the rows
|
|
39199
|
-
*
|
|
39200
|
-
* @param sheet Sheet on which the deletion occurs
|
|
39201
|
-
* @param addedRow Index of the added row
|
|
39202
|
-
* @param rowsToAdd Number of the rows to add
|
|
39203
|
-
*/
|
|
39204
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
39205
|
-
const rows = [];
|
|
39206
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39207
|
-
sheet.rows.forEach(() => rows.push({
|
|
39208
|
-
cells: cellsQueue.shift(),
|
|
39209
|
-
}));
|
|
39210
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39211
|
-
}
|
|
39212
39408
|
/**
|
|
39213
39409
|
* Add empty rows at the end of the rows
|
|
39214
39410
|
*
|
|
@@ -39735,6 +39931,7 @@ class CompilationParametersBuilder {
|
|
|
39735
39931
|
getters;
|
|
39736
39932
|
computeCell;
|
|
39737
39933
|
evalContext;
|
|
39934
|
+
rangeCache = {};
|
|
39738
39935
|
constructor(context, getters, computeCell) {
|
|
39739
39936
|
this.getters = getters;
|
|
39740
39937
|
this.computeCell = computeCell;
|
|
@@ -39757,7 +39954,8 @@ class CompilationParametersBuilder {
|
|
|
39757
39954
|
refFn(range, isMeta, functionName, paramNumber) {
|
|
39758
39955
|
if (isMeta) {
|
|
39759
39956
|
// Use zoneToXc of zone instead of getRangeString to avoid sending unbounded ranges
|
|
39760
|
-
|
|
39957
|
+
const sheetName = this.getters.getSheetName(range.sheetId);
|
|
39958
|
+
return { value: getFullReference(sheetName, zoneToXc(range.zone)) };
|
|
39761
39959
|
}
|
|
39762
39960
|
if (!isZoneValid(range.zone)) {
|
|
39763
39961
|
throw new InvalidReferenceError();
|
|
@@ -39820,17 +40018,24 @@ class CompilationParametersBuilder {
|
|
|
39820
40018
|
if (!_zone) {
|
|
39821
40019
|
return [[]];
|
|
39822
40020
|
}
|
|
40021
|
+
const { top, left, bottom, right } = zone;
|
|
40022
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
40023
|
+
if (cacheKey in this.rangeCache) {
|
|
40024
|
+
return this.rangeCache[cacheKey];
|
|
40025
|
+
}
|
|
39823
40026
|
const height = _zone.bottom - _zone.top + 1;
|
|
39824
40027
|
const width = _zone.right - _zone.left + 1;
|
|
39825
|
-
const matrix = Array
|
|
40028
|
+
const matrix = new Array(width);
|
|
39826
40029
|
// Performance issue: nested loop is faster than a map here
|
|
39827
40030
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
40031
|
+
const colIndex = col - _zone.left;
|
|
40032
|
+
matrix[colIndex] = new Array(height);
|
|
39828
40033
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
39829
|
-
const colIndex = col - _zone.left;
|
|
39830
40034
|
const rowIndex = row - _zone.top;
|
|
39831
40035
|
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
|
39832
40036
|
}
|
|
39833
40037
|
}
|
|
40038
|
+
this.rangeCache[cacheKey] = matrix;
|
|
39834
40039
|
return matrix;
|
|
39835
40040
|
}
|
|
39836
40041
|
}
|
|
@@ -40036,6 +40241,7 @@ class Evaluator {
|
|
|
40036
40241
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
40037
40242
|
}
|
|
40038
40243
|
updateCompilationParameters() {
|
|
40244
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
40039
40245
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40040
40246
|
}
|
|
40041
40247
|
evaluateCells(positions) {
|
|
@@ -40079,6 +40285,16 @@ class Evaluator {
|
|
|
40079
40285
|
this.evaluatedCells = new Map();
|
|
40080
40286
|
this.evaluate(this.getAllCells());
|
|
40081
40287
|
}
|
|
40288
|
+
evaluateFormula(sheetId, formulaString) {
|
|
40289
|
+
const compiledFormula = compile(formulaString);
|
|
40290
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40291
|
+
this.updateCompilationParameters();
|
|
40292
|
+
const result = updateEvalContextAndExecute({ ...compiledFormula, dependencies: ranges }, this.compilationParams, sheetId);
|
|
40293
|
+
if (isMatrix(result)) {
|
|
40294
|
+
return matrixMap(result, (cell) => cell.value);
|
|
40295
|
+
}
|
|
40296
|
+
return result.value;
|
|
40297
|
+
}
|
|
40082
40298
|
getAllCells() {
|
|
40083
40299
|
const positionIds = new JetSet();
|
|
40084
40300
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -40105,6 +40321,7 @@ class Evaluator {
|
|
|
40105
40321
|
this.nextPositionsToUpdate = cells;
|
|
40106
40322
|
let currentIteration = 0;
|
|
40107
40323
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
40324
|
+
this.updateCompilationParameters();
|
|
40108
40325
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
40109
40326
|
this.nextPositionsToUpdate.clear();
|
|
40110
40327
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -40128,7 +40345,8 @@ class Evaluator {
|
|
|
40128
40345
|
if (!this.blockedArrayFormulas.has(positionId)) {
|
|
40129
40346
|
this.invalidateSpreading(positionId);
|
|
40130
40347
|
}
|
|
40131
|
-
const
|
|
40348
|
+
const cellPosition = this.decodePosition(positionId);
|
|
40349
|
+
const cell = this.getters.getCell(cellPosition);
|
|
40132
40350
|
if (cell === undefined) {
|
|
40133
40351
|
return createEvaluatedCell("", { locale: this.getters.getLocale() });
|
|
40134
40352
|
}
|
|
@@ -40139,7 +40357,7 @@ class Evaluator {
|
|
|
40139
40357
|
}
|
|
40140
40358
|
this.cellsBeingComputed.add(cellId);
|
|
40141
40359
|
return cell.isFormula
|
|
40142
|
-
? this.computeFormulaCell(cell)
|
|
40360
|
+
? this.computeFormulaCell(cellPosition.sheetId, cell)
|
|
40143
40361
|
: evaluateLiteral(cell.content, { format: cell.format, locale: this.getters.getLocale() });
|
|
40144
40362
|
}
|
|
40145
40363
|
catch (e) {
|
|
@@ -40165,14 +40383,9 @@ class Evaluator {
|
|
|
40165
40383
|
e.message = e.message.replace("[[FUNCTION_NAME]]", __lastFnCalled);
|
|
40166
40384
|
return errorCell(e);
|
|
40167
40385
|
}
|
|
40168
|
-
computeFormulaCell(cellData) {
|
|
40386
|
+
computeFormulaCell(sheetId, cellData) {
|
|
40169
40387
|
const cellId = cellData.id;
|
|
40170
|
-
this.compilationParams
|
|
40171
|
-
// compute the value lazily for performance reasons
|
|
40172
|
-
const position = this.compilationParams[2].getters.getCellPosition(cellId);
|
|
40173
|
-
return toXC(position.col, position.row);
|
|
40174
|
-
};
|
|
40175
|
-
const formulaReturn = cellData.compiledFormula.execute(cellData.compiledFormula.dependencies, ...this.compilationParams);
|
|
40388
|
+
const formulaReturn = updateEvalContextAndExecute(cellData.compiledFormula, this.compilationParams, sheetId, cellId);
|
|
40176
40389
|
if (!isMatrix(formulaReturn)) {
|
|
40177
40390
|
return createEvaluatedCell(formulaReturn.value, {
|
|
40178
40391
|
format: cellData.format || formulaReturn.format,
|
|
@@ -40374,6 +40587,18 @@ class PositionBitsEncoder {
|
|
|
40374
40587
|
return sheetId;
|
|
40375
40588
|
}
|
|
40376
40589
|
}
|
|
40590
|
+
function updateEvalContextAndExecute(compiledFormula, compilationParams, sheetId, cellId) {
|
|
40591
|
+
compilationParams[2].__originCellXC = lazy(() => {
|
|
40592
|
+
if (!cellId) {
|
|
40593
|
+
return undefined;
|
|
40594
|
+
}
|
|
40595
|
+
// compute the value lazily for performance reasons
|
|
40596
|
+
const position = compilationParams[2].getters.getCellPosition(cellId);
|
|
40597
|
+
return toXC(position.col, position.row);
|
|
40598
|
+
});
|
|
40599
|
+
compilationParams[2].__originSheetId = sheetId;
|
|
40600
|
+
return compiledFormula.execute(compiledFormula.dependencies, ...compilationParams);
|
|
40601
|
+
}
|
|
40377
40602
|
|
|
40378
40603
|
//#region
|
|
40379
40604
|
// ---------------------------------------------------------------------------
|
|
@@ -40468,7 +40693,6 @@ class PositionBitsEncoder {
|
|
|
40468
40693
|
// of other cells depending on it, at the next iteration.
|
|
40469
40694
|
//#endregion
|
|
40470
40695
|
class EvaluationPlugin extends UIPlugin {
|
|
40471
|
-
config;
|
|
40472
40696
|
static getters = [
|
|
40473
40697
|
"evaluateFormula",
|
|
40474
40698
|
"getCorrespondingFormulaCell",
|
|
@@ -40479,15 +40703,13 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40479
40703
|
"getEvaluatedCells",
|
|
40480
40704
|
"getEvaluatedCellsInZone",
|
|
40481
40705
|
"getSpreadPositionsOf",
|
|
40706
|
+
"getArrayFormulaSpreadingOn",
|
|
40482
40707
|
];
|
|
40483
40708
|
shouldRebuildDependenciesGraph = true;
|
|
40484
40709
|
evaluator;
|
|
40485
|
-
compilationParams;
|
|
40486
40710
|
positionsToUpdate = [];
|
|
40487
40711
|
constructor(config) {
|
|
40488
40712
|
super(config);
|
|
40489
|
-
this.config = config;
|
|
40490
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40491
40713
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
40492
40714
|
}
|
|
40493
40715
|
// ---------------------------------------------------------------------------
|
|
@@ -40512,10 +40734,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40512
40734
|
case "EVALUATE_CELLS":
|
|
40513
40735
|
this.evaluator.evaluateAllCells();
|
|
40514
40736
|
break;
|
|
40515
|
-
case "UPDATE_LOCALE":
|
|
40516
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40517
|
-
this.evaluator.updateCompilationParameters();
|
|
40518
|
-
break;
|
|
40519
40737
|
}
|
|
40520
40738
|
}
|
|
40521
40739
|
finalize() {
|
|
@@ -40533,16 +40751,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40533
40751
|
// Getters
|
|
40534
40752
|
// ---------------------------------------------------------------------------
|
|
40535
40753
|
evaluateFormula(sheetId, formulaString) {
|
|
40536
|
-
|
|
40537
|
-
const ranges = [];
|
|
40538
|
-
for (let xc of compiledFormula.dependencies) {
|
|
40539
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40540
|
-
}
|
|
40541
|
-
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40542
|
-
if (isMatrix(array)) {
|
|
40543
|
-
return array.map((col) => col.map((row) => row.value));
|
|
40544
|
-
}
|
|
40545
|
-
return array.value;
|
|
40754
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
40546
40755
|
}
|
|
40547
40756
|
/**
|
|
40548
40757
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -40591,6 +40800,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40591
40800
|
getSpreadPositionsOf(position) {
|
|
40592
40801
|
return this.evaluator.getSpreadPositionsOf(position);
|
|
40593
40802
|
}
|
|
40803
|
+
getArrayFormulaSpreadingOn(position) {
|
|
40804
|
+
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
40805
|
+
}
|
|
40594
40806
|
// ---------------------------------------------------------------------------
|
|
40595
40807
|
// Export
|
|
40596
40808
|
// ---------------------------------------------------------------------------
|
|
@@ -40634,7 +40846,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40634
40846
|
else if (cell && cell.content) {
|
|
40635
40847
|
return undefined;
|
|
40636
40848
|
}
|
|
40637
|
-
const spreadingFormulaPosition = this.
|
|
40849
|
+
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
40638
40850
|
if (spreadingFormulaPosition === undefined) {
|
|
40639
40851
|
return undefined;
|
|
40640
40852
|
}
|
|
@@ -40644,9 +40856,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40644
40856
|
}
|
|
40645
40857
|
return undefined;
|
|
40646
40858
|
}
|
|
40647
|
-
getCompilationParameters() {
|
|
40648
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
40649
|
-
}
|
|
40650
40859
|
}
|
|
40651
40860
|
function isBadExpression(tokens) {
|
|
40652
40861
|
try {
|
|
@@ -43345,11 +43554,26 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43345
43554
|
let cellsInRow = [];
|
|
43346
43555
|
for (let col of columnsIndex) {
|
|
43347
43556
|
const position = { col, row, sheetId };
|
|
43557
|
+
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
|
43558
|
+
let cell = getters.getCell(position);
|
|
43559
|
+
const evaluatedCell = getters.getEvaluatedCell(position);
|
|
43560
|
+
if (spreader) {
|
|
43561
|
+
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
|
43562
|
+
const content = isSpreaderCopied
|
|
43563
|
+
? ""
|
|
43564
|
+
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
|
43565
|
+
cell = {
|
|
43566
|
+
id: cell?.id || "",
|
|
43567
|
+
style: cell?.style,
|
|
43568
|
+
format: evaluatedCell.format,
|
|
43569
|
+
content,
|
|
43570
|
+
isFormula: false,
|
|
43571
|
+
};
|
|
43572
|
+
}
|
|
43348
43573
|
cellsInRow.push({
|
|
43349
|
-
cell
|
|
43350
|
-
style: getters.getCellComputedStyle(position),
|
|
43351
|
-
evaluatedCell: getters.getEvaluatedCell(position),
|
|
43574
|
+
cell,
|
|
43352
43575
|
border: getters.getCellBorder(position) || undefined,
|
|
43576
|
+
evaluatedCell,
|
|
43353
43577
|
position,
|
|
43354
43578
|
});
|
|
43355
43579
|
}
|
|
@@ -43471,13 +43695,6 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43471
43695
|
});
|
|
43472
43696
|
}
|
|
43473
43697
|
this.pasteCopiedTables(target);
|
|
43474
|
-
this.cells.forEach((row) => {
|
|
43475
|
-
row.forEach((c) => {
|
|
43476
|
-
if (c.cell) {
|
|
43477
|
-
c.cell = undefined;
|
|
43478
|
-
}
|
|
43479
|
-
});
|
|
43480
|
-
});
|
|
43481
43698
|
}
|
|
43482
43699
|
/**
|
|
43483
43700
|
* The clipped zone is copied as many times as it fits in the target.
|
|
@@ -43551,7 +43768,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43551
43768
|
clearClippedZones() {
|
|
43552
43769
|
for (const row of this.cells) {
|
|
43553
43770
|
for (const cell of row) {
|
|
43554
|
-
if (cell
|
|
43771
|
+
if (cell?.cell) {
|
|
43555
43772
|
this.dispatch("CLEAR_CELL", cell.position);
|
|
43556
43773
|
}
|
|
43557
43774
|
}
|
|
@@ -43577,6 +43794,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43577
43794
|
const rowCells = this.cells[r];
|
|
43578
43795
|
for (let c = 0; c < width; c++) {
|
|
43579
43796
|
const origin = rowCells[c];
|
|
43797
|
+
if (!origin) {
|
|
43798
|
+
continue;
|
|
43799
|
+
}
|
|
43580
43800
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
43581
43801
|
// TODO: refactor this part. the "Paste merge" action is also executed with
|
|
43582
43802
|
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
@@ -43600,53 +43820,42 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43600
43820
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43601
43821
|
const { sheetId, col, row } = target;
|
|
43602
43822
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43603
|
-
if (clipboardOption?.pasteOption
|
|
43604
|
-
const
|
|
43605
|
-
const
|
|
43606
|
-
|
|
43607
|
-
|
|
43608
|
-
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43609
|
-
left: targetBorders?.left || originBorders?.left,
|
|
43610
|
-
right: targetBorders?.right || originBorders?.right,
|
|
43611
|
-
};
|
|
43612
|
-
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43823
|
+
if (clipboardOption?.pasteOption === "onlyValue") {
|
|
43824
|
+
const locale = this.getters.getLocale();
|
|
43825
|
+
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43826
|
+
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
43827
|
+
return;
|
|
43613
43828
|
}
|
|
43614
|
-
|
|
43615
|
-
|
|
43616
|
-
|
|
43617
|
-
|
|
43618
|
-
|
|
43619
|
-
|
|
43620
|
-
|
|
43621
|
-
|
|
43622
|
-
|
|
43623
|
-
|
|
43624
|
-
|
|
43625
|
-
|
|
43626
|
-
|
|
43627
|
-
|
|
43628
|
-
}
|
|
43629
|
-
|
|
43630
|
-
|
|
43631
|
-
|
|
43632
|
-
|
|
43829
|
+
const targetBorders = this.getters.getCellBorder(target);
|
|
43830
|
+
const originBorders = origin.border;
|
|
43831
|
+
const border = {
|
|
43832
|
+
top: targetBorders?.top || originBorders?.top,
|
|
43833
|
+
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43834
|
+
left: targetBorders?.left || originBorders?.left,
|
|
43835
|
+
right: targetBorders?.right || originBorders?.right,
|
|
43836
|
+
};
|
|
43837
|
+
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43838
|
+
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43839
|
+
this.dispatch("UPDATE_CELL", {
|
|
43840
|
+
...target,
|
|
43841
|
+
style: origin.cell?.style ?? null,
|
|
43842
|
+
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
|
43843
|
+
});
|
|
43844
|
+
return;
|
|
43845
|
+
}
|
|
43846
|
+
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
|
43847
|
+
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
|
43848
|
+
: origin.cell?.content;
|
|
43849
|
+
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
|
43633
43850
|
this.dispatch("UPDATE_CELL", {
|
|
43634
43851
|
...target,
|
|
43635
43852
|
content,
|
|
43636
|
-
style: origin.cell
|
|
43637
|
-
format: origin.cell
|
|
43853
|
+
style: origin.cell?.style || null,
|
|
43854
|
+
format: origin.cell?.format,
|
|
43638
43855
|
});
|
|
43639
43856
|
}
|
|
43640
43857
|
else if (targetCell) {
|
|
43641
|
-
|
|
43642
|
-
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
|
43643
|
-
}
|
|
43644
|
-
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43645
|
-
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
|
43646
|
-
}
|
|
43647
|
-
else {
|
|
43648
|
-
this.dispatch("CLEAR_CELL", target);
|
|
43649
|
-
}
|
|
43858
|
+
this.dispatch("CLEAR_CELL", target);
|
|
43650
43859
|
}
|
|
43651
43860
|
}
|
|
43652
43861
|
/**
|
|
@@ -43708,22 +43917,28 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43708
43917
|
return (this.cells
|
|
43709
43918
|
.map((cells) => {
|
|
43710
43919
|
return cells
|
|
43711
|
-
.map((c) => this.getters.shouldShowFormulas() && c
|
|
43920
|
+
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
|
43712
43921
|
? c.cell?.content || ""
|
|
43713
|
-
: c
|
|
43922
|
+
: c?.evaluatedCell?.formattedValue || "")
|
|
43714
43923
|
.join("\t");
|
|
43715
43924
|
})
|
|
43716
43925
|
.join("\n") || "\t");
|
|
43717
43926
|
}
|
|
43718
43927
|
getHTMLContent() {
|
|
43719
43928
|
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
|
43929
|
+
if (!this.cells[0][0]) {
|
|
43930
|
+
return "";
|
|
43931
|
+
}
|
|
43720
43932
|
return this.getters.getCellText(this.cells[0][0].position);
|
|
43721
43933
|
}
|
|
43722
43934
|
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
|
43723
43935
|
for (const row of this.cells) {
|
|
43724
43936
|
htmlTable += "<tr>";
|
|
43725
43937
|
for (const cell of row) {
|
|
43726
|
-
|
|
43938
|
+
if (!cell) {
|
|
43939
|
+
continue;
|
|
43940
|
+
}
|
|
43941
|
+
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
|
43727
43942
|
const cellText = this.getters.getCellText(cell.position);
|
|
43728
43943
|
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
|
43729
43944
|
}
|
|
@@ -44051,24 +44266,49 @@ var Direction;
|
|
|
44051
44266
|
*/
|
|
44052
44267
|
class FindAndReplacePlugin extends UIPlugin {
|
|
44053
44268
|
static layers = [3 /* LAYERS.Search */];
|
|
44054
|
-
static getters = [
|
|
44055
|
-
|
|
44269
|
+
static getters = [
|
|
44270
|
+
"getSearchMatches",
|
|
44271
|
+
"getCurrentSelectedMatchIndex",
|
|
44272
|
+
"getSearchOptions",
|
|
44273
|
+
"getAllSheetMatchesCount",
|
|
44274
|
+
"getActiveSheetMatchesCount",
|
|
44275
|
+
"getSpecificRangeMatchesCount",
|
|
44276
|
+
];
|
|
44277
|
+
allSheetsMatches = [];
|
|
44278
|
+
activeSheetMatches = [];
|
|
44279
|
+
specificRangeMatches = [];
|
|
44280
|
+
// fixme: why do we make selectedMatchIndex on top of a selected
|
|
44281
|
+
// property in the matches?
|
|
44056
44282
|
selectedMatchIndex = null;
|
|
44057
44283
|
currentSearchRegex = null;
|
|
44058
44284
|
searchOptions = {
|
|
44059
44285
|
matchCase: false,
|
|
44060
44286
|
exactMatch: false,
|
|
44061
44287
|
searchFormulas: false,
|
|
44288
|
+
searchScope: "allSheets",
|
|
44289
|
+
specificRange: undefined,
|
|
44062
44290
|
};
|
|
44063
44291
|
toSearch = "";
|
|
44064
44292
|
isSearchDirty = false;
|
|
44293
|
+
get searchMatches() {
|
|
44294
|
+
switch (this.searchOptions.searchScope) {
|
|
44295
|
+
case "allSheets":
|
|
44296
|
+
return this.allSheetsMatches;
|
|
44297
|
+
case "activeSheet":
|
|
44298
|
+
return this.activeSheetMatches;
|
|
44299
|
+
case "specificRange":
|
|
44300
|
+
return this.specificRangeMatches;
|
|
44301
|
+
}
|
|
44302
|
+
}
|
|
44065
44303
|
// ---------------------------------------------------------------------------
|
|
44066
44304
|
// Command Handling
|
|
44067
44305
|
// ---------------------------------------------------------------------------
|
|
44068
44306
|
handle(cmd) {
|
|
44069
44307
|
switch (cmd.type) {
|
|
44070
44308
|
case "UPDATE_SEARCH":
|
|
44071
|
-
|
|
44309
|
+
const rangeData = cmd.searchOptions.specificRange;
|
|
44310
|
+
const specificRange = rangeData && this.getters.getRangeFromRangeData(rangeData);
|
|
44311
|
+
this.updateSearch(cmd.toSearch, { ...cmd.searchOptions, specificRange });
|
|
44072
44312
|
break;
|
|
44073
44313
|
case "CLEAR_SEARCH":
|
|
44074
44314
|
this.clearSearch();
|
|
@@ -44098,7 +44338,9 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44098
44338
|
this.isSearchDirty = true;
|
|
44099
44339
|
break;
|
|
44100
44340
|
case "ACTIVATE_SHEET":
|
|
44101
|
-
this.
|
|
44341
|
+
if (this.searchOptions.searchScope === "activeSheet") {
|
|
44342
|
+
this.isSearchDirty = true;
|
|
44343
|
+
}
|
|
44102
44344
|
break;
|
|
44103
44345
|
}
|
|
44104
44346
|
}
|
|
@@ -44117,6 +44359,18 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44117
44359
|
getCurrentSelectedMatchIndex() {
|
|
44118
44360
|
return this.selectedMatchIndex;
|
|
44119
44361
|
}
|
|
44362
|
+
getSearchOptions() {
|
|
44363
|
+
return { ...this.searchOptions, specificRange: this.searchOptions.specificRange?.rangeData };
|
|
44364
|
+
}
|
|
44365
|
+
getAllSheetMatchesCount() {
|
|
44366
|
+
return this.allSheetsMatches.length;
|
|
44367
|
+
}
|
|
44368
|
+
getActiveSheetMatchesCount() {
|
|
44369
|
+
return this.activeSheetMatches.length;
|
|
44370
|
+
}
|
|
44371
|
+
getSpecificRangeMatchesCount() {
|
|
44372
|
+
return this.specificRangeMatches.length;
|
|
44373
|
+
}
|
|
44120
44374
|
// ---------------------------------------------------------------------------
|
|
44121
44375
|
// Search
|
|
44122
44376
|
// ---------------------------------------------------------------------------
|
|
@@ -44137,8 +44391,8 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44137
44391
|
* refresh the matches according to the current search options
|
|
44138
44392
|
*/
|
|
44139
44393
|
refreshSearch() {
|
|
44140
|
-
|
|
44141
|
-
this.
|
|
44394
|
+
this.selectedMatchIndex = null;
|
|
44395
|
+
this.findMatches();
|
|
44142
44396
|
this.selectNextCell(Direction.current);
|
|
44143
44397
|
}
|
|
44144
44398
|
/**
|
|
@@ -44153,45 +44407,65 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44153
44407
|
}
|
|
44154
44408
|
this.currentSearchRegex = RegExp(searchValue, flags);
|
|
44155
44409
|
}
|
|
44410
|
+
getSheetsInSearchOrder() {
|
|
44411
|
+
switch (this.searchOptions.searchScope) {
|
|
44412
|
+
case "allSheets":
|
|
44413
|
+
const sheetIds = this.getters.getSheetIds();
|
|
44414
|
+
const activeSheetIndex = sheetIds.findIndex((id) => id === this.getters.getActiveSheetId());
|
|
44415
|
+
return [
|
|
44416
|
+
sheetIds[activeSheetIndex],
|
|
44417
|
+
...sheetIds.slice(activeSheetIndex + 1),
|
|
44418
|
+
...sheetIds.slice(0, activeSheetIndex),
|
|
44419
|
+
];
|
|
44420
|
+
case "activeSheet":
|
|
44421
|
+
return [this.getters.getActiveSheetId()];
|
|
44422
|
+
case "specificRange":
|
|
44423
|
+
const specificRange = this.searchOptions.specificRange;
|
|
44424
|
+
if (!specificRange) {
|
|
44425
|
+
return [];
|
|
44426
|
+
}
|
|
44427
|
+
return specificRange ? [specificRange.sheetId] : [];
|
|
44428
|
+
}
|
|
44429
|
+
}
|
|
44156
44430
|
/**
|
|
44157
44431
|
* Find matches using the current regex
|
|
44158
44432
|
*/
|
|
44159
44433
|
findMatches() {
|
|
44160
|
-
const sheetId = this.getters.getActiveSheetId();
|
|
44161
|
-
const cells = this.getters.getCells(sheetId);
|
|
44162
44434
|
const matches = [];
|
|
44163
|
-
if (this.toSearch
|
|
44164
|
-
for (const
|
|
44165
|
-
|
|
44166
|
-
|
|
44435
|
+
if (this.toSearch) {
|
|
44436
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
44437
|
+
matches.push(...this.findMatchesInSheet(sheetId));
|
|
44438
|
+
}
|
|
44439
|
+
}
|
|
44440
|
+
// set results
|
|
44441
|
+
this.allSheetsMatches = matches;
|
|
44442
|
+
this.activeSheetMatches = matches.filter((match) => match.sheetId === this.getters.getActiveSheetId());
|
|
44443
|
+
if (this.searchOptions.specificRange) {
|
|
44444
|
+
const { sheetId, zone } = this.searchOptions.specificRange;
|
|
44445
|
+
this.specificRangeMatches = matches.filter((match) => match.sheetId === sheetId && isInside(match.col, match.row, zone));
|
|
44446
|
+
}
|
|
44447
|
+
else {
|
|
44448
|
+
this.specificRangeMatches = [];
|
|
44449
|
+
}
|
|
44450
|
+
}
|
|
44451
|
+
findMatchesInSheet(sheetId) {
|
|
44452
|
+
const matches = [];
|
|
44453
|
+
const { left, right, top, bottom } = this.getters.getSheetZone(sheetId);
|
|
44454
|
+
for (let row = top; row <= bottom; row++) {
|
|
44455
|
+
for (let col = left; col <= right; col++) {
|
|
44167
44456
|
const isColHidden = this.getters.isColHidden(sheetId, col);
|
|
44168
44457
|
const isRowHidden = this.getters.isRowHidden(sheetId, row);
|
|
44169
44458
|
if (isColHidden || isRowHidden) {
|
|
44170
44459
|
continue;
|
|
44171
44460
|
}
|
|
44172
|
-
|
|
44173
|
-
|
|
44461
|
+
const cellPosition = { sheetId, col, row };
|
|
44462
|
+
if (this.currentSearchRegex?.test(this.getSearchableString(cellPosition))) {
|
|
44463
|
+
const match = { sheetId, col, row };
|
|
44174
44464
|
matches.push(match);
|
|
44175
44465
|
}
|
|
44176
|
-
for (const spreadPosition of this.getters.getSpreadPositionsOf(cellPosition)) {
|
|
44177
|
-
if (this.currentSearchRegex.test(this.getSearchableString(spreadPosition))) {
|
|
44178
|
-
const match = {
|
|
44179
|
-
col: spreadPosition.col,
|
|
44180
|
-
row: spreadPosition.row,
|
|
44181
|
-
selected: false,
|
|
44182
|
-
};
|
|
44183
|
-
matches.push(match);
|
|
44184
|
-
}
|
|
44185
|
-
}
|
|
44186
44466
|
}
|
|
44187
44467
|
}
|
|
44188
|
-
return matches
|
|
44189
|
-
}
|
|
44190
|
-
sortByRowThenColumn(a, b) {
|
|
44191
|
-
if (a.row === b.row) {
|
|
44192
|
-
return a.col - b.col;
|
|
44193
|
-
}
|
|
44194
|
-
return a.row > b.row ? 1 : -1;
|
|
44468
|
+
return matches;
|
|
44195
44469
|
}
|
|
44196
44470
|
/**
|
|
44197
44471
|
* Changes the selected search cell. Given a direction it will
|
|
@@ -44209,30 +44483,47 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44209
44483
|
}
|
|
44210
44484
|
let nextIndex;
|
|
44211
44485
|
if (this.selectedMatchIndex === null) {
|
|
44212
|
-
|
|
44486
|
+
let nextMatchIndex = -1;
|
|
44487
|
+
// if search is not available in current sheet will select in next sheet
|
|
44488
|
+
for (const sheetId of this.getSheetsInSearchOrder()) {
|
|
44489
|
+
nextMatchIndex = matches.findIndex((match) => match.sheetId === sheetId);
|
|
44490
|
+
if (nextMatchIndex !== -1) {
|
|
44491
|
+
break;
|
|
44492
|
+
}
|
|
44493
|
+
}
|
|
44494
|
+
nextIndex = nextMatchIndex;
|
|
44213
44495
|
}
|
|
44214
44496
|
else {
|
|
44215
44497
|
nextIndex = this.selectedMatchIndex + indexChange;
|
|
44216
44498
|
}
|
|
44217
|
-
//
|
|
44218
|
-
nextIndex = (
|
|
44499
|
+
// loop index value inside the array (index -1 => last index)
|
|
44500
|
+
nextIndex = (nextIndex + matches.length) % matches.length;
|
|
44219
44501
|
this.selectedMatchIndex = nextIndex;
|
|
44502
|
+
const selectedMatch = matches[nextIndex];
|
|
44503
|
+
// Switch to the sheet where the match is located
|
|
44504
|
+
if (this.getters.getActiveSheetId() !== selectedMatch.sheetId) {
|
|
44505
|
+
this.dispatch("ACTIVATE_SHEET", {
|
|
44506
|
+
sheetIdFrom: this.getters.getActiveSheetId(),
|
|
44507
|
+
sheetIdTo: selectedMatch.sheetId,
|
|
44508
|
+
});
|
|
44509
|
+
}
|
|
44220
44510
|
// we want grid selection to capture the selection stream
|
|
44221
44511
|
this.selection.getBackToDefault();
|
|
44222
|
-
this.selection.selectCell(
|
|
44223
|
-
for (let index = 0; index < this.searchMatches.length; index++) {
|
|
44224
|
-
this.searchMatches[index].selected = index === this.selectedMatchIndex;
|
|
44225
|
-
}
|
|
44512
|
+
this.selection.selectCell(selectedMatch.col, selectedMatch.row);
|
|
44226
44513
|
}
|
|
44227
44514
|
clearSearch() {
|
|
44228
44515
|
this.toSearch = "";
|
|
44229
|
-
this.searchMatches = [];
|
|
44230
44516
|
this.selectedMatchIndex = null;
|
|
44231
44517
|
this.currentSearchRegex = null;
|
|
44518
|
+
this.allSheetsMatches = [];
|
|
44519
|
+
this.activeSheetMatches = [];
|
|
44520
|
+
this.specificRangeMatches = [];
|
|
44232
44521
|
this.searchOptions = {
|
|
44233
44522
|
matchCase: false,
|
|
44234
44523
|
exactMatch: false,
|
|
44235
44524
|
searchFormulas: false,
|
|
44525
|
+
searchScope: "allSheets",
|
|
44526
|
+
specificRange: undefined,
|
|
44236
44527
|
};
|
|
44237
44528
|
}
|
|
44238
44529
|
// ---------------------------------------------------------------------------
|
|
@@ -44242,9 +44533,7 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44242
44533
|
if (!this.currentSearchRegex) {
|
|
44243
44534
|
return;
|
|
44244
44535
|
}
|
|
44245
|
-
const
|
|
44246
|
-
const position = { sheetId, ...selectedMatch };
|
|
44247
|
-
const cell = this.getters.getCell(position);
|
|
44536
|
+
const cell = this.getters.getCell(selectedMatch);
|
|
44248
44537
|
if (!cell?.content) {
|
|
44249
44538
|
return;
|
|
44250
44539
|
}
|
|
@@ -44252,10 +44541,10 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44252
44541
|
return;
|
|
44253
44542
|
}
|
|
44254
44543
|
const replaceRegex = new RegExp(this.currentSearchRegex.source, this.currentSearchRegex.flags + "g");
|
|
44255
|
-
const toReplace = this.getSearchableString(
|
|
44544
|
+
const toReplace = this.getSearchableString(selectedMatch);
|
|
44256
44545
|
const content = toReplace.replace(replaceRegex, replaceWith);
|
|
44257
44546
|
const canonicalContent = canonicalizeNumberContent(content, this.getters.getLocale());
|
|
44258
|
-
this.dispatch("UPDATE_CELL", { ...
|
|
44547
|
+
this.dispatch("UPDATE_CELL", { ...selectedMatch, content: canonicalContent });
|
|
44259
44548
|
}
|
|
44260
44549
|
/**
|
|
44261
44550
|
* Replace the value of the currently selected match
|
|
@@ -44286,7 +44575,10 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44286
44575
|
drawGrid(renderingContext) {
|
|
44287
44576
|
const { ctx } = renderingContext;
|
|
44288
44577
|
const sheetId = this.getters.getActiveSheetId();
|
|
44289
|
-
for (const match of this.searchMatches) {
|
|
44578
|
+
for (const [index, match] of this.searchMatches.entries()) {
|
|
44579
|
+
if (match.sheetId !== sheetId) {
|
|
44580
|
+
continue; // Skip drawing matches from other sheets
|
|
44581
|
+
}
|
|
44290
44582
|
const merge = this.getters.getMerge({ sheetId, col: match.col, row: match.row });
|
|
44291
44583
|
const left = merge ? merge.left : match.col;
|
|
44292
44584
|
const right = merge ? merge.right : match.col;
|
|
@@ -44296,12 +44588,21 @@ class FindAndReplacePlugin extends UIPlugin {
|
|
|
44296
44588
|
if (width > 0 && height > 0) {
|
|
44297
44589
|
ctx.fillStyle = BACKGROUND_COLOR;
|
|
44298
44590
|
ctx.fillRect(x, y, width, height);
|
|
44299
|
-
if (
|
|
44591
|
+
if (index === this.selectedMatchIndex) {
|
|
44300
44592
|
ctx.strokeStyle = BORDER_COLOR;
|
|
44301
44593
|
ctx.strokeRect(x, y, width, height);
|
|
44302
44594
|
}
|
|
44303
44595
|
}
|
|
44304
44596
|
}
|
|
44597
|
+
if (this.searchOptions.searchScope === "specificRange") {
|
|
44598
|
+
const range = this.searchOptions.specificRange;
|
|
44599
|
+
if (!range || range.sheetId !== sheetId) {
|
|
44600
|
+
return;
|
|
44601
|
+
}
|
|
44602
|
+
const { x, y, width, height } = this.getters.getVisibleRect(range.zone);
|
|
44603
|
+
ctx.strokeStyle = BORDER_COLOR;
|
|
44604
|
+
ctx.strokeRect(x, y, width, height);
|
|
44605
|
+
}
|
|
44305
44606
|
}
|
|
44306
44607
|
}
|
|
44307
44608
|
|
|
@@ -46767,11 +47068,14 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
46767
47068
|
}
|
|
46768
47069
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
46769
47070
|
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
|
47071
|
+
if (this.state.operation === "CUT") {
|
|
47072
|
+
this.state = undefined;
|
|
47073
|
+
}
|
|
46770
47074
|
this.lastPasteState = this.state;
|
|
46771
47075
|
if (this.paintFormatStatus === "oneOff") {
|
|
46772
47076
|
this.paintFormatStatus = "inactive";
|
|
46773
|
-
this.status = "invisible";
|
|
46774
47077
|
}
|
|
47078
|
+
this.status = "invisible";
|
|
46775
47079
|
break;
|
|
46776
47080
|
case "COPY_PASTE_CELLS_ABOVE":
|
|
46777
47081
|
{
|
|
@@ -46998,92 +47302,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
46998
47302
|
}
|
|
46999
47303
|
}
|
|
47000
47304
|
|
|
47001
|
-
/**
|
|
47002
|
-
* Change the reference types inside the given token, if the token represent a range or a cell
|
|
47003
|
-
*
|
|
47004
|
-
* Eg. :
|
|
47005
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47006
|
-
* A1:$B$1 => $A$1:B$1 => A$1:$B1 => $A1:B1 => A1:$B$1
|
|
47007
|
-
*/
|
|
47008
|
-
function loopThroughReferenceType(token) {
|
|
47009
|
-
if (token.type !== "REFERENCE")
|
|
47010
|
-
return token;
|
|
47011
|
-
const { xc, sheetName } = splitReference(token.value);
|
|
47012
|
-
const [left, right] = xc.split(":");
|
|
47013
|
-
const sheetRef = sheetName ? `${getCanonicalSheetName(sheetName)}!` : "";
|
|
47014
|
-
const updatedLeft = getTokenNextReferenceType(left);
|
|
47015
|
-
const updatedRight = right ? `:${getTokenNextReferenceType(right)}` : "";
|
|
47016
|
-
return { ...token, value: sheetRef + updatedLeft + updatedRight };
|
|
47017
|
-
}
|
|
47018
|
-
/**
|
|
47019
|
-
* Get a new token with a changed type of reference from the given cell token symbol.
|
|
47020
|
-
* Undefined behavior if given a token other than a cell or if the Xc contains a sheet reference
|
|
47021
|
-
*
|
|
47022
|
-
* A1 => $A$1 => A$1 => $A1 => A1
|
|
47023
|
-
*/
|
|
47024
|
-
function getTokenNextReferenceType(xc) {
|
|
47025
|
-
switch (getReferenceType(xc)) {
|
|
47026
|
-
case "none":
|
|
47027
|
-
xc = setXcToReferenceType(xc, "colrow");
|
|
47028
|
-
break;
|
|
47029
|
-
case "colrow":
|
|
47030
|
-
xc = setXcToReferenceType(xc, "row");
|
|
47031
|
-
break;
|
|
47032
|
-
case "row":
|
|
47033
|
-
xc = setXcToReferenceType(xc, "col");
|
|
47034
|
-
break;
|
|
47035
|
-
case "col":
|
|
47036
|
-
xc = setXcToReferenceType(xc, "none");
|
|
47037
|
-
break;
|
|
47038
|
-
}
|
|
47039
|
-
return xc;
|
|
47040
|
-
}
|
|
47041
|
-
/**
|
|
47042
|
-
* Returns the given XC with the given reference type.
|
|
47043
|
-
*/
|
|
47044
|
-
function setXcToReferenceType(xc, referenceType) {
|
|
47045
|
-
xc = xc.replace(/\$/g, "");
|
|
47046
|
-
let indexOfNumber;
|
|
47047
|
-
switch (referenceType) {
|
|
47048
|
-
case "col":
|
|
47049
|
-
return "$" + xc;
|
|
47050
|
-
case "row":
|
|
47051
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47052
|
-
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47053
|
-
case "colrow":
|
|
47054
|
-
indexOfNumber = xc.search(/[0-9]/);
|
|
47055
|
-
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
47056
|
-
return "$" + xc;
|
|
47057
|
-
case "none":
|
|
47058
|
-
return xc;
|
|
47059
|
-
}
|
|
47060
|
-
}
|
|
47061
|
-
/**
|
|
47062
|
-
* Return the type of reference used in the given XC of a cell.
|
|
47063
|
-
* Undefined behavior if the XC have a sheet reference
|
|
47064
|
-
*/
|
|
47065
|
-
function getReferenceType(xcCell) {
|
|
47066
|
-
if (isColAndRowFixed(xcCell)) {
|
|
47067
|
-
return "colrow";
|
|
47068
|
-
}
|
|
47069
|
-
else if (isColFixed(xcCell)) {
|
|
47070
|
-
return "col";
|
|
47071
|
-
}
|
|
47072
|
-
else if (isRowFixed(xcCell)) {
|
|
47073
|
-
return "row";
|
|
47074
|
-
}
|
|
47075
|
-
return "none";
|
|
47076
|
-
}
|
|
47077
|
-
function isColFixed(xc) {
|
|
47078
|
-
return xc.startsWith("$");
|
|
47079
|
-
}
|
|
47080
|
-
function isRowFixed(xc) {
|
|
47081
|
-
return xc.includes("$", 1);
|
|
47082
|
-
}
|
|
47083
|
-
function isColAndRowFixed(xc) {
|
|
47084
|
-
return xc.startsWith("$") && xc.length > 1 && xc.slice(1).includes("$");
|
|
47085
|
-
}
|
|
47086
|
-
|
|
47087
47305
|
const CELL_DELETED_MESSAGE = _t("The cell you are trying to edit has been deleted.");
|
|
47088
47306
|
class EditionPlugin extends UIPlugin {
|
|
47089
47307
|
static getters = [
|
|
@@ -48001,32 +48219,32 @@ const selectionStatisticFunctions = [
|
|
|
48001
48219
|
{
|
|
48002
48220
|
name: _t("Sum"),
|
|
48003
48221
|
types: [CellValueType.number],
|
|
48004
|
-
compute: (values, locale) =>
|
|
48222
|
+
compute: (values, locale) => sum([[values]], locale),
|
|
48005
48223
|
},
|
|
48006
48224
|
{
|
|
48007
48225
|
name: _t("Avg"),
|
|
48008
48226
|
types: [CellValueType.number],
|
|
48009
|
-
compute: (values, locale) =>
|
|
48227
|
+
compute: (values, locale) => average([[values]], locale),
|
|
48010
48228
|
},
|
|
48011
48229
|
{
|
|
48012
48230
|
name: _t("Min"),
|
|
48013
48231
|
types: [CellValueType.number],
|
|
48014
|
-
compute: (values, locale) =>
|
|
48232
|
+
compute: (values, locale) => min([[values]], locale),
|
|
48015
48233
|
},
|
|
48016
48234
|
{
|
|
48017
48235
|
name: _t("Max"),
|
|
48018
48236
|
types: [CellValueType.number],
|
|
48019
|
-
compute: (values, locale) =>
|
|
48237
|
+
compute: (values, locale) => max([[values]], locale),
|
|
48020
48238
|
},
|
|
48021
48239
|
{
|
|
48022
48240
|
name: _t("Count"),
|
|
48023
48241
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48024
|
-
compute: (values
|
|
48242
|
+
compute: (values) => countAny([[values]]),
|
|
48025
48243
|
},
|
|
48026
48244
|
{
|
|
48027
48245
|
name: _t("Count Numbers"),
|
|
48028
48246
|
types: [CellValueType.number, CellValueType.text, CellValueType.boolean, CellValueType.error],
|
|
48029
|
-
compute: (values, locale) =>
|
|
48247
|
+
compute: (values, locale) => countNumbers([[values]], locale),
|
|
48030
48248
|
},
|
|
48031
48249
|
];
|
|
48032
48250
|
/**
|
|
@@ -51941,6 +52159,7 @@ class Spreadsheet extends Component {
|
|
|
51941
52159
|
};
|
|
51942
52160
|
sidePanel;
|
|
51943
52161
|
composer;
|
|
52162
|
+
spreadsheetRef = useRef("spreadsheet");
|
|
51944
52163
|
_focusGrid;
|
|
51945
52164
|
keyDownMapping;
|
|
51946
52165
|
isViewportTooSmall = false;
|
|
@@ -51975,6 +52194,18 @@ class Spreadsheet extends Component {
|
|
|
51975
52194
|
clipboard: this.env.clipboard || instantiateClipboard(),
|
|
51976
52195
|
startCellEdition: (content) => this.onGridComposerCellFocused(content),
|
|
51977
52196
|
});
|
|
52197
|
+
useEffect(() => {
|
|
52198
|
+
/**
|
|
52199
|
+
* Only refocus the grid if the active element is not a child of the spreadsheet
|
|
52200
|
+
* (i.e. activeElement is outside of the spreadsheetRef component)
|
|
52201
|
+
* and spreadsheet is a child of that element. Anything else means that the focus
|
|
52202
|
+
* is on an element that needs to keep it.
|
|
52203
|
+
*/
|
|
52204
|
+
if (!this.spreadsheetRef.el.contains(document.activeElement) &&
|
|
52205
|
+
document.activeElement?.contains(this.spreadsheetRef.el)) {
|
|
52206
|
+
this.focusGrid();
|
|
52207
|
+
}
|
|
52208
|
+
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
51978
52209
|
useExternalListener(window, "resize", () => this.render(true));
|
|
51979
52210
|
useExternalListener(window, "beforeunload", this.unbindModelEvents.bind(this));
|
|
51980
52211
|
this.bindModelEvents();
|
|
@@ -52056,7 +52287,7 @@ class Spreadsheet extends Component {
|
|
|
52056
52287
|
}
|
|
52057
52288
|
focusGrid() {
|
|
52058
52289
|
if (!this._focusGrid) {
|
|
52059
|
-
|
|
52290
|
+
return;
|
|
52060
52291
|
}
|
|
52061
52292
|
this._focusGrid();
|
|
52062
52293
|
}
|
|
@@ -55449,19 +55680,22 @@ class Model extends EventBus {
|
|
|
55449
55680
|
* Check if the given command is allowed by all the plugins and the history.
|
|
55450
55681
|
*/
|
|
55451
55682
|
checkDispatchAllowed(command) {
|
|
55452
|
-
|
|
55453
|
-
|
|
55683
|
+
const results = isCoreCommand(command)
|
|
55684
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
55685
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
55686
|
+
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
|
55687
|
+
return new DispatchResult(results.flat());
|
|
55454
55688
|
}
|
|
55455
|
-
return
|
|
55689
|
+
return DispatchResult.Success;
|
|
55456
55690
|
}
|
|
55457
55691
|
checkDispatchAllowedCoreCommand(command) {
|
|
55458
55692
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
55459
55693
|
results.push(this.range.allowDispatch(command));
|
|
55460
|
-
return
|
|
55694
|
+
return results;
|
|
55461
55695
|
}
|
|
55462
55696
|
checkDispatchAllowedLocalCommand(command) {
|
|
55463
55697
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
55464
|
-
return
|
|
55698
|
+
return results;
|
|
55465
55699
|
}
|
|
55466
55700
|
finalize() {
|
|
55467
55701
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -55756,6 +55990,7 @@ const components = {
|
|
|
55756
55990
|
FigureComponent,
|
|
55757
55991
|
Menu,
|
|
55758
55992
|
SelectionInput,
|
|
55993
|
+
ValidationMessages,
|
|
55759
55994
|
};
|
|
55760
55995
|
const hooks = {
|
|
55761
55996
|
useDragAndDropListItems,
|
|
@@ -55773,6 +56008,6 @@ const constants = {
|
|
|
55773
56008
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
55774
56009
|
|
|
55775
56010
|
|
|
55776
|
-
__info__.version = "17.1.0-alpha.
|
|
55777
|
-
__info__.date = "2023-11-
|
|
55778
|
-
__info__.hash = "
|
|
56011
|
+
__info__.version = "17.1.0-alpha.4";
|
|
56012
|
+
__info__.date = "2023-11-24T13:12:24.882Z";
|
|
56013
|
+
__info__.hash = "255821b";
|