@odoo/o-spreadsheet 17.0.3 → 17.0.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 +181 -152
- package/dist/o-spreadsheet.d.ts +9 -16
- package/dist/o-spreadsheet.esm.js +181 -152
- package/dist/o-spreadsheet.iife.js +181 -152
- package/dist/o-spreadsheet.iife.min.js +121 -121
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 17.0.
|
|
6
|
-
* @date 2023-11-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 17.0.4
|
|
6
|
+
* @date 2023-11-24T13:13:42.575Z
|
|
7
|
+
* @hash 7346d0a
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -693,8 +693,7 @@ function removeFalsyAttributes(obj) {
|
|
|
693
693
|
*
|
|
694
694
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
695
695
|
*/
|
|
696
|
-
const
|
|
697
|
-
" ",
|
|
696
|
+
const whiteSpaceSpecialCharacters = [
|
|
698
697
|
"\t",
|
|
699
698
|
"\f",
|
|
700
699
|
"\v",
|
|
@@ -709,8 +708,7 @@ const whiteSpaceCharacters = [
|
|
|
709
708
|
String.fromCharCode(parseInt("3000", 16)),
|
|
710
709
|
String.fromCharCode(parseInt("feff", 16)),
|
|
711
710
|
];
|
|
712
|
-
const whiteSpaceRegexp = new RegExp(
|
|
713
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
711
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
714
712
|
/**
|
|
715
713
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
716
714
|
* different newlines types by \n.
|
|
@@ -718,9 +716,9 @@ const newLineRegex = /\r\n|\r|\n/g;
|
|
|
718
716
|
function replaceSpecialSpaces(text) {
|
|
719
717
|
if (!text)
|
|
720
718
|
return "";
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
return text;
|
|
719
|
+
if (!whiteSpaceRegexp.test(text))
|
|
720
|
+
return text;
|
|
721
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
724
722
|
}
|
|
725
723
|
/**
|
|
726
724
|
* Determine if the numbers are consecutive.
|
|
@@ -2062,6 +2060,7 @@ exports.CommandResult = void 0;
|
|
|
2062
2060
|
CommandResult["InvalidNumberOfCriterionValues"] = "InvalidNumberOfCriterionValues";
|
|
2063
2061
|
CommandResult["BlockingValidationRule"] = "BlockingValidationRule";
|
|
2064
2062
|
CommandResult["InvalidCopyPasteSelection"] = "InvalidCopyPasteSelection";
|
|
2063
|
+
CommandResult["NoChanges"] = "NoChanges";
|
|
2065
2064
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
2066
2065
|
|
|
2067
2066
|
const DEFAULT_LOCALES = [
|
|
@@ -2191,12 +2190,12 @@ function toString(value) {
|
|
|
2191
2190
|
}
|
|
2192
2191
|
}
|
|
2193
2192
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
2194
|
-
function normalizeString(str) {
|
|
2193
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
2195
2194
|
return str
|
|
2196
2195
|
.toLowerCase()
|
|
2197
2196
|
.normalize("NFD")
|
|
2198
2197
|
.replace(/[\u0300-\u036f]/g, "");
|
|
2199
|
-
}
|
|
2198
|
+
});
|
|
2200
2199
|
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);
|
|
2201
2200
|
function toBoolean(value) {
|
|
2202
2201
|
switch (typeof value) {
|
|
@@ -7331,7 +7330,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
7331
7330
|
return result;
|
|
7332
7331
|
}
|
|
7333
7332
|
function tokenizeDebugger(chars) {
|
|
7334
|
-
if (chars.current
|
|
7333
|
+
if (chars.current === "?") {
|
|
7335
7334
|
chars.shift();
|
|
7336
7335
|
return { type: "DEBUGGER", value: "?" };
|
|
7337
7336
|
}
|
|
@@ -7342,7 +7341,7 @@ const misc$1 = {
|
|
|
7342
7341
|
")": "RIGHT_PAREN",
|
|
7343
7342
|
};
|
|
7344
7343
|
function tokenizeMisc(chars) {
|
|
7345
|
-
if (chars.current
|
|
7344
|
+
if (chars.current in misc$1) {
|
|
7346
7345
|
const value = chars.shift();
|
|
7347
7346
|
const type = misc$1[value];
|
|
7348
7347
|
return { type, value };
|
|
@@ -7350,7 +7349,7 @@ function tokenizeMisc(chars) {
|
|
|
7350
7349
|
return null;
|
|
7351
7350
|
}
|
|
7352
7351
|
function tokenizeArgsSeparator(chars, locale) {
|
|
7353
|
-
if (chars.current
|
|
7352
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
7354
7353
|
const value = chars.shift();
|
|
7355
7354
|
const type = "ARG_SEPARATOR";
|
|
7356
7355
|
return { type, value };
|
|
@@ -7375,14 +7374,13 @@ function tokenizeNumber(chars, locale) {
|
|
|
7375
7374
|
return null;
|
|
7376
7375
|
}
|
|
7377
7376
|
function tokenizeString(chars) {
|
|
7378
|
-
if (chars.current
|
|
7377
|
+
if (chars.current === '"') {
|
|
7379
7378
|
const startChar = chars.shift();
|
|
7380
7379
|
let letters = startChar;
|
|
7381
|
-
while (chars.current()
|
|
7382
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7380
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
7383
7381
|
letters += chars.shift();
|
|
7384
7382
|
}
|
|
7385
|
-
if (chars.current
|
|
7383
|
+
if (chars.current === '"') {
|
|
7386
7384
|
letters += chars.shift();
|
|
7387
7385
|
}
|
|
7388
7386
|
return {
|
|
@@ -7409,14 +7407,14 @@ function tokenizeSymbol(chars) {
|
|
|
7409
7407
|
let result = "";
|
|
7410
7408
|
// there are two main cases to manage: either something which starts with
|
|
7411
7409
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
7412
|
-
if (chars.current
|
|
7410
|
+
if (chars.current === "'") {
|
|
7413
7411
|
let lastChar = chars.shift();
|
|
7414
7412
|
result += lastChar;
|
|
7415
|
-
while (chars.current
|
|
7413
|
+
while (chars.current) {
|
|
7416
7414
|
lastChar = chars.shift();
|
|
7417
7415
|
result += lastChar;
|
|
7418
7416
|
if (lastChar === "'") {
|
|
7419
|
-
if (chars.current
|
|
7417
|
+
if (chars.current && chars.current === "'") {
|
|
7420
7418
|
lastChar = chars.shift();
|
|
7421
7419
|
result += lastChar;
|
|
7422
7420
|
}
|
|
@@ -7432,7 +7430,7 @@ function tokenizeSymbol(chars) {
|
|
|
7432
7430
|
};
|
|
7433
7431
|
}
|
|
7434
7432
|
}
|
|
7435
|
-
while (chars.current
|
|
7433
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
7436
7434
|
result += chars.shift();
|
|
7437
7435
|
}
|
|
7438
7436
|
if (result.length) {
|
|
@@ -7447,14 +7445,14 @@ function tokenizeSymbol(chars) {
|
|
|
7447
7445
|
}
|
|
7448
7446
|
function tokenizeSpace(chars) {
|
|
7449
7447
|
let length = 0;
|
|
7450
|
-
while (chars.current
|
|
7448
|
+
while (chars.current === NEWLINE) {
|
|
7451
7449
|
length++;
|
|
7452
7450
|
chars.shift();
|
|
7453
7451
|
}
|
|
7454
7452
|
if (length) {
|
|
7455
7453
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
7456
7454
|
}
|
|
7457
|
-
while (chars.current
|
|
7455
|
+
while (chars.current === " ") {
|
|
7458
7456
|
length++;
|
|
7459
7457
|
chars.shift();
|
|
7460
7458
|
}
|
|
@@ -7473,17 +7471,20 @@ function tokenizeInvalidRange(chars) {
|
|
|
7473
7471
|
class TokenizingChars {
|
|
7474
7472
|
text;
|
|
7475
7473
|
currentIndex = 0;
|
|
7474
|
+
current;
|
|
7476
7475
|
constructor(text) {
|
|
7477
7476
|
this.text = text;
|
|
7478
|
-
|
|
7479
|
-
current() {
|
|
7480
|
-
return this.text[this.currentIndex];
|
|
7477
|
+
this.current = text[0];
|
|
7481
7478
|
}
|
|
7482
7479
|
shift() {
|
|
7483
|
-
|
|
7480
|
+
const current = this.current;
|
|
7481
|
+
const next = this.text[++this.currentIndex];
|
|
7482
|
+
this.current = next;
|
|
7483
|
+
return current;
|
|
7484
7484
|
}
|
|
7485
7485
|
advanceBy(length) {
|
|
7486
7486
|
this.currentIndex += length;
|
|
7487
|
+
this.current = this.text[this.currentIndex];
|
|
7487
7488
|
}
|
|
7488
7489
|
isOver() {
|
|
7489
7490
|
return this.currentIndex >= this.text.length;
|
|
@@ -29759,6 +29760,7 @@ class Grid extends owl.Component {
|
|
|
29759
29760
|
const content = clipboardData.getData(ClipboardMIMEType.PlainText);
|
|
29760
29761
|
const target = this.env.model.getters.getSelectedZones();
|
|
29761
29762
|
const clipboardString = this.env.model.getters.getClipboardTextContent();
|
|
29763
|
+
const isCutOperation = this.env.model.getters.isCutOperation();
|
|
29762
29764
|
if (clipboardString === content) {
|
|
29763
29765
|
// the paste actually comes from o-spreadsheet itself
|
|
29764
29766
|
interactivePaste(this.env, target);
|
|
@@ -29766,7 +29768,7 @@ class Grid extends owl.Component {
|
|
|
29766
29768
|
else {
|
|
29767
29769
|
interactivePasteFromOS(this.env, target, content);
|
|
29768
29770
|
}
|
|
29769
|
-
if (
|
|
29771
|
+
if (isCutOperation) {
|
|
29770
29772
|
await this.env.clipboard.write({ [ClipboardMIMEType.PlainText]: "" });
|
|
29771
29773
|
}
|
|
29772
29774
|
}
|
|
@@ -34060,6 +34062,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
34060
34062
|
// ---------------------------------------------------------------------------
|
|
34061
34063
|
// Command Handling
|
|
34062
34064
|
// ---------------------------------------------------------------------------
|
|
34065
|
+
allowDispatch(cmd) {
|
|
34066
|
+
switch (cmd.type) {
|
|
34067
|
+
case "SET_BORDER":
|
|
34068
|
+
return this.checkBordersUnchanged(cmd);
|
|
34069
|
+
default:
|
|
34070
|
+
return "Success" /* CommandResult.Success */;
|
|
34071
|
+
}
|
|
34072
|
+
}
|
|
34063
34073
|
handle(cmd) {
|
|
34064
34074
|
switch (cmd.type) {
|
|
34065
34075
|
case "ADD_MERGE":
|
|
@@ -34479,6 +34489,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
34479
34489
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
34480
34490
|
}
|
|
34481
34491
|
}
|
|
34492
|
+
checkBordersUnchanged(cmd) {
|
|
34493
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
34494
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
34495
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
34496
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
34497
|
+
}
|
|
34498
|
+
return "Success" /* CommandResult.Success */;
|
|
34499
|
+
}
|
|
34482
34500
|
// ---------------------------------------------------------------------------
|
|
34483
34501
|
// Import/Export
|
|
34484
34502
|
// ---------------------------------------------------------------------------
|
|
@@ -35334,8 +35352,9 @@ class CellPlugin extends CorePlugin {
|
|
|
35334
35352
|
allowDispatch(cmd) {
|
|
35335
35353
|
switch (cmd.type) {
|
|
35336
35354
|
case "UPDATE_CELL":
|
|
35355
|
+
return this.checkCellOutOfSheet(cmd);
|
|
35337
35356
|
case "CLEAR_CELL":
|
|
35338
|
-
return this.
|
|
35357
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
35339
35358
|
default:
|
|
35340
35359
|
return "Success" /* CommandResult.Success */;
|
|
35341
35360
|
}
|
|
@@ -35504,14 +35523,9 @@ class CellPlugin extends CorePlugin {
|
|
|
35504
35523
|
*/
|
|
35505
35524
|
getCellById(cellId) {
|
|
35506
35525
|
// this must be as fast as possible
|
|
35507
|
-
|
|
35508
|
-
|
|
35509
|
-
|
|
35510
|
-
if (cell) {
|
|
35511
|
-
return cell;
|
|
35512
|
-
}
|
|
35513
|
-
}
|
|
35514
|
-
return undefined;
|
|
35526
|
+
const position = this.getters.getCellPosition(cellId);
|
|
35527
|
+
const sheet = this.cells[position.sheetId];
|
|
35528
|
+
return sheet[cellId];
|
|
35515
35529
|
}
|
|
35516
35530
|
/*
|
|
35517
35531
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -35742,13 +35756,23 @@ class CellPlugin extends CorePlugin {
|
|
|
35742
35756
|
},
|
|
35743
35757
|
};
|
|
35744
35758
|
}
|
|
35745
|
-
checkCellOutOfSheet(
|
|
35759
|
+
checkCellOutOfSheet(cmd) {
|
|
35760
|
+
const { sheetId, col, row } = cmd;
|
|
35746
35761
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
35747
35762
|
if (!sheet)
|
|
35748
35763
|
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
35749
35764
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
35750
35765
|
return isInside(col, row, sheetZone) ? "Success" /* CommandResult.Success */ : "TargetOutOfSheet" /* CommandResult.TargetOutOfSheet */;
|
|
35751
35766
|
}
|
|
35767
|
+
checkUselessClearCell(cmd) {
|
|
35768
|
+
const cell = this.getters.getCell(cmd);
|
|
35769
|
+
if (!cell)
|
|
35770
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35771
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
35772
|
+
return "NoChanges" /* CommandResult.NoChanges */;
|
|
35773
|
+
}
|
|
35774
|
+
return "Success" /* CommandResult.Success */;
|
|
35775
|
+
}
|
|
35752
35776
|
}
|
|
35753
35777
|
class FormulaCellWithDependencies {
|
|
35754
35778
|
id;
|
|
@@ -36438,6 +36462,9 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
36438
36462
|
return this.rules[sheetId].find((rule) => rule.id === id);
|
|
36439
36463
|
}
|
|
36440
36464
|
getValidationRuleForCell({ sheetId, col, row }) {
|
|
36465
|
+
if (!this.rules[sheetId]) {
|
|
36466
|
+
return undefined;
|
|
36467
|
+
}
|
|
36441
36468
|
for (const rule of this.rules[sheetId]) {
|
|
36442
36469
|
for (const range of rule.ranges) {
|
|
36443
36470
|
if (isInside(col, row, range.zone)) {
|
|
@@ -39035,10 +39062,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
39035
39062
|
// begin with the end.
|
|
39036
39063
|
rows.sort((a, b) => b - a);
|
|
39037
39064
|
for (let group of groupConsecutive(rows)) {
|
|
39065
|
+
// indexes are sorted in the descending order
|
|
39066
|
+
const from = group[group.length - 1];
|
|
39067
|
+
const to = group[0];
|
|
39038
39068
|
// Move the cells.
|
|
39039
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
39040
|
-
// Effectively delete the
|
|
39041
|
-
|
|
39069
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
39070
|
+
// Effectively delete the rows
|
|
39071
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
39042
39072
|
}
|
|
39043
39073
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
39044
39074
|
if (count) {
|
|
@@ -39060,8 +39090,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
39060
39090
|
this.addEmptyRows(sheet, quantity);
|
|
39061
39091
|
// Move the cells.
|
|
39062
39092
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
39063
|
-
// Recompute the left-right/top-bottom.
|
|
39064
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
39065
39093
|
if (index < sheet.panes.ySplit) {
|
|
39066
39094
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
39067
39095
|
}
|
|
@@ -39162,35 +39190,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
39162
39190
|
}
|
|
39163
39191
|
}
|
|
39164
39192
|
}
|
|
39165
|
-
updateRowsStructureOnDeletion(
|
|
39193
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
39166
39194
|
const rows = [];
|
|
39167
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39195
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
39168
39196
|
for (let i in sheet.rows) {
|
|
39169
|
-
|
|
39197
|
+
const row = Number(i);
|
|
39198
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
39170
39199
|
continue;
|
|
39171
39200
|
}
|
|
39172
39201
|
rows.push({
|
|
39173
|
-
cells: cellsQueue.
|
|
39202
|
+
cells: cellsQueue.pop(),
|
|
39174
39203
|
});
|
|
39175
39204
|
}
|
|
39176
39205
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39177
39206
|
}
|
|
39178
|
-
/**
|
|
39179
|
-
* Update the rows of the sheet after an addition:
|
|
39180
|
-
* - Rename the rows
|
|
39181
|
-
*
|
|
39182
|
-
* @param sheet Sheet on which the deletion occurs
|
|
39183
|
-
* @param addedRow Index of the added row
|
|
39184
|
-
* @param rowsToAdd Number of the rows to add
|
|
39185
|
-
*/
|
|
39186
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
39187
|
-
const rows = [];
|
|
39188
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
39189
|
-
sheet.rows.forEach(() => rows.push({
|
|
39190
|
-
cells: cellsQueue.shift(),
|
|
39191
|
-
}));
|
|
39192
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
39193
|
-
}
|
|
39194
39207
|
/**
|
|
39195
39208
|
* Add empty rows at the end of the rows
|
|
39196
39209
|
*
|
|
@@ -39717,6 +39730,7 @@ class CompilationParametersBuilder {
|
|
|
39717
39730
|
getters;
|
|
39718
39731
|
computeCell;
|
|
39719
39732
|
evalContext;
|
|
39733
|
+
rangeCache = {};
|
|
39720
39734
|
constructor(context, getters, computeCell) {
|
|
39721
39735
|
this.getters = getters;
|
|
39722
39736
|
this.computeCell = computeCell;
|
|
@@ -39802,17 +39816,24 @@ class CompilationParametersBuilder {
|
|
|
39802
39816
|
if (!_zone) {
|
|
39803
39817
|
return [[]];
|
|
39804
39818
|
}
|
|
39819
|
+
const { top, left, bottom, right } = zone;
|
|
39820
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
39821
|
+
if (cacheKey in this.rangeCache) {
|
|
39822
|
+
return this.rangeCache[cacheKey];
|
|
39823
|
+
}
|
|
39805
39824
|
const height = _zone.bottom - _zone.top + 1;
|
|
39806
39825
|
const width = _zone.right - _zone.left + 1;
|
|
39807
|
-
const matrix = Array
|
|
39826
|
+
const matrix = new Array(width);
|
|
39808
39827
|
// Performance issue: nested loop is faster than a map here
|
|
39809
39828
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
39829
|
+
const colIndex = col - _zone.left;
|
|
39830
|
+
matrix[colIndex] = new Array(height);
|
|
39810
39831
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
39811
|
-
const colIndex = col - _zone.left;
|
|
39812
39832
|
const rowIndex = row - _zone.top;
|
|
39813
39833
|
matrix[colIndex][rowIndex] = this.readCell({ sheetId, col, row });
|
|
39814
39834
|
}
|
|
39815
39835
|
}
|
|
39836
|
+
this.rangeCache[cacheKey] = matrix;
|
|
39816
39837
|
return matrix;
|
|
39817
39838
|
}
|
|
39818
39839
|
}
|
|
@@ -40018,6 +40039,7 @@ class Evaluator {
|
|
|
40018
40039
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
40019
40040
|
}
|
|
40020
40041
|
updateCompilationParameters() {
|
|
40042
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
40021
40043
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
40022
40044
|
}
|
|
40023
40045
|
evaluateCells(positions) {
|
|
@@ -40061,6 +40083,16 @@ class Evaluator {
|
|
|
40061
40083
|
this.evaluatedCells = new Map();
|
|
40062
40084
|
this.evaluate(this.getAllCells());
|
|
40063
40085
|
}
|
|
40086
|
+
evaluateFormula(sheetId, formulaString) {
|
|
40087
|
+
const compiledFormula = compile(formulaString);
|
|
40088
|
+
const ranges = compiledFormula.dependencies.map((xc) => this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40089
|
+
this.updateCompilationParameters();
|
|
40090
|
+
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40091
|
+
if (isMatrix(array)) {
|
|
40092
|
+
return matrixMap(array, (cell) => cell.value);
|
|
40093
|
+
}
|
|
40094
|
+
return array.value;
|
|
40095
|
+
}
|
|
40064
40096
|
getAllCells() {
|
|
40065
40097
|
const positionIds = new JetSet();
|
|
40066
40098
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -40087,6 +40119,7 @@ class Evaluator {
|
|
|
40087
40119
|
this.nextPositionsToUpdate = cells;
|
|
40088
40120
|
let currentIteration = 0;
|
|
40089
40121
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
40122
|
+
this.updateCompilationParameters();
|
|
40090
40123
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
40091
40124
|
this.nextPositionsToUpdate.clear();
|
|
40092
40125
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -40450,7 +40483,6 @@ class PositionBitsEncoder {
|
|
|
40450
40483
|
// of other cells depending on it, at the next iteration.
|
|
40451
40484
|
//#endregion
|
|
40452
40485
|
class EvaluationPlugin extends UIPlugin {
|
|
40453
|
-
config;
|
|
40454
40486
|
static getters = [
|
|
40455
40487
|
"evaluateFormula",
|
|
40456
40488
|
"getCorrespondingFormulaCell",
|
|
@@ -40461,15 +40493,13 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40461
40493
|
"getEvaluatedCells",
|
|
40462
40494
|
"getEvaluatedCellsInZone",
|
|
40463
40495
|
"getSpreadPositionsOf",
|
|
40496
|
+
"getArrayFormulaSpreadingOn",
|
|
40464
40497
|
];
|
|
40465
40498
|
shouldRebuildDependenciesGraph = true;
|
|
40466
40499
|
evaluator;
|
|
40467
|
-
compilationParams;
|
|
40468
40500
|
positionsToUpdate = [];
|
|
40469
40501
|
constructor(config) {
|
|
40470
40502
|
super(config);
|
|
40471
|
-
this.config = config;
|
|
40472
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40473
40503
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
40474
40504
|
}
|
|
40475
40505
|
// ---------------------------------------------------------------------------
|
|
@@ -40494,10 +40524,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40494
40524
|
case "EVALUATE_CELLS":
|
|
40495
40525
|
this.evaluator.evaluateAllCells();
|
|
40496
40526
|
break;
|
|
40497
|
-
case "UPDATE_LOCALE":
|
|
40498
|
-
this.compilationParams = this.getCompilationParameters();
|
|
40499
|
-
this.evaluator.updateCompilationParameters();
|
|
40500
|
-
break;
|
|
40501
40527
|
}
|
|
40502
40528
|
}
|
|
40503
40529
|
finalize() {
|
|
@@ -40515,16 +40541,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40515
40541
|
// Getters
|
|
40516
40542
|
// ---------------------------------------------------------------------------
|
|
40517
40543
|
evaluateFormula(sheetId, formulaString) {
|
|
40518
|
-
|
|
40519
|
-
const ranges = [];
|
|
40520
|
-
for (let xc of compiledFormula.dependencies) {
|
|
40521
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
40522
|
-
}
|
|
40523
|
-
const array = compiledFormula.execute(ranges, ...this.compilationParams);
|
|
40524
|
-
if (isMatrix(array)) {
|
|
40525
|
-
return array.map((col) => col.map((row) => row.value));
|
|
40526
|
-
}
|
|
40527
|
-
return array.value;
|
|
40544
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
40528
40545
|
}
|
|
40529
40546
|
/**
|
|
40530
40547
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -40573,6 +40590,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40573
40590
|
getSpreadPositionsOf(position) {
|
|
40574
40591
|
return this.evaluator.getSpreadPositionsOf(position);
|
|
40575
40592
|
}
|
|
40593
|
+
getArrayFormulaSpreadingOn(position) {
|
|
40594
|
+
return this.evaluator.getArrayFormulaSpreadingOn(position);
|
|
40595
|
+
}
|
|
40576
40596
|
// ---------------------------------------------------------------------------
|
|
40577
40597
|
// Export
|
|
40578
40598
|
// ---------------------------------------------------------------------------
|
|
@@ -40616,7 +40636,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40616
40636
|
else if (cell && cell.content) {
|
|
40617
40637
|
return undefined;
|
|
40618
40638
|
}
|
|
40619
|
-
const spreadingFormulaPosition = this.
|
|
40639
|
+
const spreadingFormulaPosition = this.getArrayFormulaSpreadingOn(position);
|
|
40620
40640
|
if (spreadingFormulaPosition === undefined) {
|
|
40621
40641
|
return undefined;
|
|
40622
40642
|
}
|
|
@@ -40626,9 +40646,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
40626
40646
|
}
|
|
40627
40647
|
return undefined;
|
|
40628
40648
|
}
|
|
40629
|
-
getCompilationParameters() {
|
|
40630
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
40631
|
-
}
|
|
40632
40649
|
}
|
|
40633
40650
|
function isBadExpression(tokens) {
|
|
40634
40651
|
try {
|
|
@@ -43327,11 +43344,26 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43327
43344
|
let cellsInRow = [];
|
|
43328
43345
|
for (let col of columnsIndex) {
|
|
43329
43346
|
const position = { col, row, sheetId };
|
|
43347
|
+
const spreader = getters.getArrayFormulaSpreadingOn(position);
|
|
43348
|
+
let cell = getters.getCell(position);
|
|
43349
|
+
const evaluatedCell = getters.getEvaluatedCell(position);
|
|
43350
|
+
if (spreader) {
|
|
43351
|
+
const isSpreaderCopied = rowsIndex.includes(spreader.row) && columnsIndex.includes(spreader.col);
|
|
43352
|
+
const content = isSpreaderCopied
|
|
43353
|
+
? ""
|
|
43354
|
+
: formatValue(evaluatedCell.value, { locale: getters.getLocale() });
|
|
43355
|
+
cell = {
|
|
43356
|
+
id: cell?.id || "",
|
|
43357
|
+
style: cell?.style,
|
|
43358
|
+
format: evaluatedCell.format,
|
|
43359
|
+
content,
|
|
43360
|
+
isFormula: false,
|
|
43361
|
+
};
|
|
43362
|
+
}
|
|
43330
43363
|
cellsInRow.push({
|
|
43331
|
-
cell
|
|
43332
|
-
style: getters.getCellComputedStyle(position),
|
|
43333
|
-
evaluatedCell: getters.getEvaluatedCell(position),
|
|
43364
|
+
cell,
|
|
43334
43365
|
border: getters.getCellBorder(position) || undefined,
|
|
43366
|
+
evaluatedCell,
|
|
43335
43367
|
position,
|
|
43336
43368
|
});
|
|
43337
43369
|
}
|
|
@@ -43453,13 +43485,6 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43453
43485
|
});
|
|
43454
43486
|
}
|
|
43455
43487
|
this.pasteCopiedTables(target);
|
|
43456
|
-
this.cells.forEach((row) => {
|
|
43457
|
-
row.forEach((c) => {
|
|
43458
|
-
if (c.cell) {
|
|
43459
|
-
c.cell = undefined;
|
|
43460
|
-
}
|
|
43461
|
-
});
|
|
43462
|
-
});
|
|
43463
43488
|
}
|
|
43464
43489
|
/**
|
|
43465
43490
|
* The clipped zone is copied as many times as it fits in the target.
|
|
@@ -43531,7 +43556,7 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43531
43556
|
clearClippedZones() {
|
|
43532
43557
|
for (const row of this.cells) {
|
|
43533
43558
|
for (const cell of row) {
|
|
43534
|
-
if (cell
|
|
43559
|
+
if (cell?.cell) {
|
|
43535
43560
|
this.dispatch("CLEAR_CELL", cell.position);
|
|
43536
43561
|
}
|
|
43537
43562
|
}
|
|
@@ -43557,6 +43582,9 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43557
43582
|
const rowCells = this.cells[r];
|
|
43558
43583
|
for (let c = 0; c < width; c++) {
|
|
43559
43584
|
const origin = rowCells[c];
|
|
43585
|
+
if (!origin) {
|
|
43586
|
+
continue;
|
|
43587
|
+
}
|
|
43560
43588
|
const position = { col: col + c, row: row + r, sheetId: sheetId };
|
|
43561
43589
|
// TODO: refactor this part. the "Paste merge" action is also executed with
|
|
43562
43590
|
// MOVE_RANGES in pasteFromCut. Adding a condition on the operation type here
|
|
@@ -43580,53 +43608,42 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43580
43608
|
pasteCell(origin, target, operation, clipboardOption) {
|
|
43581
43609
|
const { sheetId, col, row } = target;
|
|
43582
43610
|
const targetCell = this.getters.getEvaluatedCell(target);
|
|
43583
|
-
if (clipboardOption?.pasteOption
|
|
43584
|
-
const
|
|
43585
|
-
const
|
|
43586
|
-
|
|
43587
|
-
|
|
43588
|
-
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43589
|
-
left: targetBorders?.left || originBorders?.left,
|
|
43590
|
-
right: targetBorders?.right || originBorders?.right,
|
|
43591
|
-
};
|
|
43592
|
-
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43611
|
+
if (clipboardOption?.pasteOption === "onlyValue") {
|
|
43612
|
+
const locale = this.getters.getLocale();
|
|
43613
|
+
const content = formatValue(origin.evaluatedCell.value, { locale });
|
|
43614
|
+
this.dispatch("UPDATE_CELL", { ...target, content });
|
|
43615
|
+
return;
|
|
43593
43616
|
}
|
|
43594
|
-
|
|
43595
|
-
|
|
43596
|
-
|
|
43597
|
-
|
|
43598
|
-
|
|
43599
|
-
|
|
43600
|
-
|
|
43601
|
-
|
|
43602
|
-
|
|
43603
|
-
|
|
43604
|
-
|
|
43605
|
-
|
|
43606
|
-
|
|
43607
|
-
|
|
43608
|
-
}
|
|
43609
|
-
|
|
43610
|
-
|
|
43611
|
-
|
|
43612
|
-
|
|
43617
|
+
const targetBorders = this.getters.getCellBorder(target);
|
|
43618
|
+
const originBorders = origin.border;
|
|
43619
|
+
const border = {
|
|
43620
|
+
top: targetBorders?.top || originBorders?.top,
|
|
43621
|
+
bottom: targetBorders?.bottom || originBorders?.bottom,
|
|
43622
|
+
left: targetBorders?.left || originBorders?.left,
|
|
43623
|
+
right: targetBorders?.right || originBorders?.right,
|
|
43624
|
+
};
|
|
43625
|
+
this.dispatch("SET_BORDER", { sheetId, col, row, border });
|
|
43626
|
+
if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43627
|
+
this.dispatch("UPDATE_CELL", {
|
|
43628
|
+
...target,
|
|
43629
|
+
style: origin.cell?.style ?? null,
|
|
43630
|
+
format: origin.cell?.format ?? origin.evaluatedCell.format ?? targetCell.format,
|
|
43631
|
+
});
|
|
43632
|
+
return;
|
|
43633
|
+
}
|
|
43634
|
+
const content = origin.cell && origin.cell.isFormula && operation === "COPY"
|
|
43635
|
+
? this.getters.getTranslatedCellFormula(sheetId, col - origin.position.col, row - origin.position.row, origin.cell.compiledFormula)
|
|
43636
|
+
: origin.cell?.content;
|
|
43637
|
+
if (content !== "" || origin.cell?.format || origin.cell?.style) {
|
|
43613
43638
|
this.dispatch("UPDATE_CELL", {
|
|
43614
43639
|
...target,
|
|
43615
43640
|
content,
|
|
43616
|
-
style: origin.cell
|
|
43617
|
-
format: origin.cell
|
|
43641
|
+
style: origin.cell?.style || null,
|
|
43642
|
+
format: origin.cell?.format,
|
|
43618
43643
|
});
|
|
43619
43644
|
}
|
|
43620
43645
|
else if (targetCell) {
|
|
43621
|
-
|
|
43622
|
-
this.dispatch("UPDATE_CELL", { ...target, content: "" });
|
|
43623
|
-
}
|
|
43624
|
-
else if (clipboardOption?.pasteOption === "onlyFormat") {
|
|
43625
|
-
this.dispatch("UPDATE_CELL", { ...target, style: null, format: "" });
|
|
43626
|
-
}
|
|
43627
|
-
else {
|
|
43628
|
-
this.dispatch("CLEAR_CELL", target);
|
|
43629
|
-
}
|
|
43646
|
+
this.dispatch("CLEAR_CELL", target);
|
|
43630
43647
|
}
|
|
43631
43648
|
}
|
|
43632
43649
|
/**
|
|
@@ -43688,22 +43705,28 @@ class ClipboardCellsState extends ClipboardCellsAbstractState {
|
|
|
43688
43705
|
return (this.cells
|
|
43689
43706
|
.map((cells) => {
|
|
43690
43707
|
return cells
|
|
43691
|
-
.map((c) => this.getters.shouldShowFormulas() && c
|
|
43708
|
+
.map((c) => this.getters.shouldShowFormulas() && c?.cell?.isFormula
|
|
43692
43709
|
? c.cell?.content || ""
|
|
43693
|
-
: c
|
|
43710
|
+
: c?.evaluatedCell?.formattedValue || "")
|
|
43694
43711
|
.join("\t");
|
|
43695
43712
|
})
|
|
43696
43713
|
.join("\n") || "\t");
|
|
43697
43714
|
}
|
|
43698
43715
|
getHTMLContent() {
|
|
43699
43716
|
if (this.cells.length === 1 && this.cells[0].length === 1) {
|
|
43717
|
+
if (!this.cells[0][0]) {
|
|
43718
|
+
return "";
|
|
43719
|
+
}
|
|
43700
43720
|
return this.getters.getCellText(this.cells[0][0].position);
|
|
43701
43721
|
}
|
|
43702
43722
|
let htmlTable = '<table border="1" style="border-collapse:collapse">';
|
|
43703
43723
|
for (const row of this.cells) {
|
|
43704
43724
|
htmlTable += "<tr>";
|
|
43705
43725
|
for (const cell of row) {
|
|
43706
|
-
|
|
43726
|
+
if (!cell) {
|
|
43727
|
+
continue;
|
|
43728
|
+
}
|
|
43729
|
+
const cssStyle = cssPropertiesToCss(cellStyleToCss(this.getters.getCellComputedStyle(cell.position)));
|
|
43707
43730
|
const cellText = this.getters.getCellText(cell.position);
|
|
43708
43731
|
htmlTable += `<td style="${cssStyle}">` + xmlEscape(cellText) + "</td>";
|
|
43709
43732
|
}
|
|
@@ -46833,11 +46856,14 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
46833
46856
|
}
|
|
46834
46857
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
46835
46858
|
this.state.paste(cmd.target, { pasteOption, shouldPasteCF: true, selectTarget: true });
|
|
46859
|
+
if (this.state.operation === "CUT") {
|
|
46860
|
+
this.state = undefined;
|
|
46861
|
+
}
|
|
46836
46862
|
this.lastPasteState = this.state;
|
|
46837
46863
|
if (this.paintFormatStatus === "oneOff") {
|
|
46838
46864
|
this.paintFormatStatus = "inactive";
|
|
46839
|
-
this.status = "invisible";
|
|
46840
46865
|
}
|
|
46866
|
+
this.status = "invisible";
|
|
46841
46867
|
break;
|
|
46842
46868
|
case "COPY_PASTE_CELLS_ABOVE":
|
|
46843
46869
|
{
|
|
@@ -55561,19 +55587,22 @@ class Model extends EventBus {
|
|
|
55561
55587
|
* Check if the given command is allowed by all the plugins and the history.
|
|
55562
55588
|
*/
|
|
55563
55589
|
checkDispatchAllowed(command) {
|
|
55564
|
-
|
|
55565
|
-
|
|
55590
|
+
const results = isCoreCommand(command)
|
|
55591
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
55592
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
55593
|
+
if (results.some((r) => r !== "Success" /* CommandResult.Success */)) {
|
|
55594
|
+
return new DispatchResult(results.flat());
|
|
55566
55595
|
}
|
|
55567
|
-
return
|
|
55596
|
+
return DispatchResult.Success;
|
|
55568
55597
|
}
|
|
55569
55598
|
checkDispatchAllowedCoreCommand(command) {
|
|
55570
55599
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
55571
55600
|
results.push(this.range.allowDispatch(command));
|
|
55572
|
-
return
|
|
55601
|
+
return results;
|
|
55573
55602
|
}
|
|
55574
55603
|
checkDispatchAllowedLocalCommand(command) {
|
|
55575
55604
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
55576
|
-
return
|
|
55605
|
+
return results;
|
|
55577
55606
|
}
|
|
55578
55607
|
finalize() {
|
|
55579
55608
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -55920,6 +55949,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
55920
55949
|
exports.tokenize = tokenize;
|
|
55921
55950
|
|
|
55922
55951
|
|
|
55923
|
-
__info__.version = "17.0.
|
|
55924
|
-
__info__.date = "2023-11-
|
|
55925
|
-
__info__.hash = "
|
|
55952
|
+
__info__.version = "17.0.4";
|
|
55953
|
+
__info__.date = "2023-11-24T13:13:42.575Z";
|
|
55954
|
+
__info__.hash = "7346d0a";
|