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