@odoo/o-spreadsheet 16.4.13 → 16.4.15
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 +155 -134
- package/dist/o-spreadsheet.d.ts +11 -20
- package/dist/o-spreadsheet.esm.js +155 -134
- package/dist/o-spreadsheet.iife.js +155 -134
- package/dist/o-spreadsheet.iife.min.js +77 -77
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -672,8 +672,7 @@ function transpose2dArray(matrix, callback = (val) => val) {
|
|
|
672
672
|
*
|
|
673
673
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
674
674
|
*/
|
|
675
|
-
const
|
|
676
|
-
" ",
|
|
675
|
+
const whiteSpaceSpecialCharacters = [
|
|
677
676
|
"\t",
|
|
678
677
|
"\f",
|
|
679
678
|
"\v",
|
|
@@ -688,8 +687,7 @@ const whiteSpaceCharacters = [
|
|
|
688
687
|
String.fromCharCode(parseInt("3000", 16)),
|
|
689
688
|
String.fromCharCode(parseInt("feff", 16)),
|
|
690
689
|
];
|
|
691
|
-
const whiteSpaceRegexp = new RegExp(
|
|
692
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
690
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
693
691
|
/**
|
|
694
692
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
695
693
|
* different newlines types by \n.
|
|
@@ -697,9 +695,9 @@ const newLineRegex = /\r\n|\r|\n/g;
|
|
|
697
695
|
function replaceSpecialSpaces(text) {
|
|
698
696
|
if (!text)
|
|
699
697
|
return "";
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
return text;
|
|
698
|
+
if (!whiteSpaceRegexp.test(text))
|
|
699
|
+
return text;
|
|
700
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
703
701
|
}
|
|
704
702
|
/**
|
|
705
703
|
* Determine if the numbers are consecutive.
|
|
@@ -4269,6 +4267,7 @@ exports.CommandResult = void 0;
|
|
|
4269
4267
|
CommandResult[CommandResult["NoActiveSheet"] = 94] = "NoActiveSheet";
|
|
4270
4268
|
CommandResult[CommandResult["InvalidLocale"] = 95] = "InvalidLocale";
|
|
4271
4269
|
CommandResult[CommandResult["AlreadyInPaintingFormatMode"] = 96] = "AlreadyInPaintingFormatMode";
|
|
4270
|
+
CommandResult[CommandResult["NoChanges"] = 97] = "NoChanges";
|
|
4272
4271
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
4273
4272
|
|
|
4274
4273
|
const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
@@ -4358,12 +4357,12 @@ function toString(value) {
|
|
|
4358
4357
|
}
|
|
4359
4358
|
}
|
|
4360
4359
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4361
|
-
function normalizeString(str) {
|
|
4360
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
4362
4361
|
return str
|
|
4363
4362
|
.toLowerCase()
|
|
4364
4363
|
.normalize("NFD")
|
|
4365
4364
|
.replace(/[\u0300-\u036f]/g, "");
|
|
4366
|
-
}
|
|
4365
|
+
});
|
|
4367
4366
|
/**
|
|
4368
4367
|
* Normalize a value.
|
|
4369
4368
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -14174,7 +14173,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
14174
14173
|
return result;
|
|
14175
14174
|
}
|
|
14176
14175
|
function tokenizeDebugger(chars) {
|
|
14177
|
-
if (chars.current
|
|
14176
|
+
if (chars.current === "?") {
|
|
14178
14177
|
chars.shift();
|
|
14179
14178
|
return { type: "DEBUGGER", value: "?" };
|
|
14180
14179
|
}
|
|
@@ -14185,7 +14184,7 @@ const misc = {
|
|
|
14185
14184
|
")": "RIGHT_PAREN",
|
|
14186
14185
|
};
|
|
14187
14186
|
function tokenizeMisc(chars) {
|
|
14188
|
-
if (chars.current
|
|
14187
|
+
if (chars.current in misc) {
|
|
14189
14188
|
const value = chars.shift();
|
|
14190
14189
|
const type = misc[value];
|
|
14191
14190
|
return { type, value };
|
|
@@ -14193,7 +14192,7 @@ function tokenizeMisc(chars) {
|
|
|
14193
14192
|
return null;
|
|
14194
14193
|
}
|
|
14195
14194
|
function tokenizeArgsSeparator(chars, locale) {
|
|
14196
|
-
if (chars.current
|
|
14195
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
14197
14196
|
const value = chars.shift();
|
|
14198
14197
|
const type = "ARG_SEPARATOR";
|
|
14199
14198
|
return { type, value };
|
|
@@ -14218,14 +14217,13 @@ function tokenizeNumber(chars, locale) {
|
|
|
14218
14217
|
return null;
|
|
14219
14218
|
}
|
|
14220
14219
|
function tokenizeString(chars) {
|
|
14221
|
-
if (chars.current
|
|
14220
|
+
if (chars.current === '"') {
|
|
14222
14221
|
const startChar = chars.shift();
|
|
14223
14222
|
let letters = startChar;
|
|
14224
|
-
while (chars.current()
|
|
14225
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14223
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14226
14224
|
letters += chars.shift();
|
|
14227
14225
|
}
|
|
14228
|
-
if (chars.current
|
|
14226
|
+
if (chars.current === '"') {
|
|
14229
14227
|
letters += chars.shift();
|
|
14230
14228
|
}
|
|
14231
14229
|
return {
|
|
@@ -14252,14 +14250,14 @@ function tokenizeSymbol(chars) {
|
|
|
14252
14250
|
let result = "";
|
|
14253
14251
|
// there are two main cases to manage: either something which starts with
|
|
14254
14252
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
14255
|
-
if (chars.current
|
|
14253
|
+
if (chars.current === "'") {
|
|
14256
14254
|
let lastChar = chars.shift();
|
|
14257
14255
|
result += lastChar;
|
|
14258
|
-
while (chars.current
|
|
14256
|
+
while (chars.current) {
|
|
14259
14257
|
lastChar = chars.shift();
|
|
14260
14258
|
result += lastChar;
|
|
14261
14259
|
if (lastChar === "'") {
|
|
14262
|
-
if (chars.current
|
|
14260
|
+
if (chars.current && chars.current === "'") {
|
|
14263
14261
|
lastChar = chars.shift();
|
|
14264
14262
|
result += lastChar;
|
|
14265
14263
|
}
|
|
@@ -14275,7 +14273,7 @@ function tokenizeSymbol(chars) {
|
|
|
14275
14273
|
};
|
|
14276
14274
|
}
|
|
14277
14275
|
}
|
|
14278
|
-
while (chars.current
|
|
14276
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
14279
14277
|
result += chars.shift();
|
|
14280
14278
|
}
|
|
14281
14279
|
if (result.length) {
|
|
@@ -14290,14 +14288,14 @@ function tokenizeSymbol(chars) {
|
|
|
14290
14288
|
}
|
|
14291
14289
|
function tokenizeSpace(chars) {
|
|
14292
14290
|
let length = 0;
|
|
14293
|
-
while (chars.current
|
|
14291
|
+
while (chars.current === NEWLINE) {
|
|
14294
14292
|
length++;
|
|
14295
14293
|
chars.shift();
|
|
14296
14294
|
}
|
|
14297
14295
|
if (length) {
|
|
14298
14296
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
14299
14297
|
}
|
|
14300
|
-
while (chars.current
|
|
14298
|
+
while (chars.current === " ") {
|
|
14301
14299
|
length++;
|
|
14302
14300
|
chars.shift();
|
|
14303
14301
|
}
|
|
@@ -14316,17 +14314,20 @@ function tokenizeInvalidRange(chars) {
|
|
|
14316
14314
|
class TokenizingChars {
|
|
14317
14315
|
text;
|
|
14318
14316
|
currentIndex = 0;
|
|
14317
|
+
current;
|
|
14319
14318
|
constructor(text) {
|
|
14320
14319
|
this.text = text;
|
|
14321
|
-
|
|
14322
|
-
current() {
|
|
14323
|
-
return this.text[this.currentIndex];
|
|
14320
|
+
this.current = text[0];
|
|
14324
14321
|
}
|
|
14325
14322
|
shift() {
|
|
14326
|
-
|
|
14323
|
+
const current = this.current;
|
|
14324
|
+
const next = this.text[++this.currentIndex];
|
|
14325
|
+
this.current = next;
|
|
14326
|
+
return current;
|
|
14327
14327
|
}
|
|
14328
14328
|
advanceBy(length) {
|
|
14329
14329
|
this.currentIndex += length;
|
|
14330
|
+
this.current = this.text[this.currentIndex];
|
|
14330
14331
|
}
|
|
14331
14332
|
isOver() {
|
|
14332
14333
|
return this.currentIndex >= this.text.length;
|
|
@@ -18569,6 +18570,17 @@ const SELECTION_CONTAINS_FILTER = (env) => {
|
|
|
18569
18570
|
//------------------------------------------------------------------------------
|
|
18570
18571
|
const IS_ONLY_ONE_RANGE = (env) => {
|
|
18571
18572
|
return env.model.getters.getSelectedZones().length === 1;
|
|
18573
|
+
};
|
|
18574
|
+
const CAN_INSERT_HEADER = (env, dimension) => {
|
|
18575
|
+
if (!IS_ONLY_ONE_RANGE(env)) {
|
|
18576
|
+
return false;
|
|
18577
|
+
}
|
|
18578
|
+
const activeHeaders = dimension === "COL" ? env.model.getters.getActiveCols() : env.model.getters.getActiveRows();
|
|
18579
|
+
const ortogonalActiveHeaders = dimension === "COL" ? env.model.getters.getActiveRows() : env.model.getters.getActiveCols();
|
|
18580
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18581
|
+
const zone = env.model.getters.getSelectedZone();
|
|
18582
|
+
const allSheetSelected = isEqual(zone, env.model.getters.getSheetZone(sheetId));
|
|
18583
|
+
return isConsecutive(activeHeaders) && (ortogonalActiveHeaders.size === 0 || allSheetSelected);
|
|
18572
18584
|
};
|
|
18573
18585
|
|
|
18574
18586
|
const undo = {
|
|
@@ -18758,9 +18770,7 @@ const insertRow = {
|
|
|
18758
18770
|
const number = getRowsNumber(env);
|
|
18759
18771
|
return number === 1 ? _lt("Insert row") : _lt("Insert %s rows", number.toString());
|
|
18760
18772
|
},
|
|
18761
|
-
isVisible: (env) =>
|
|
18762
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18763
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18773
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18764
18774
|
icon: "o-spreadsheet-Icon.INSERT_ROW",
|
|
18765
18775
|
};
|
|
18766
18776
|
const rowInsertRowBefore = {
|
|
@@ -18769,9 +18779,7 @@ const rowInsertRowBefore = {
|
|
|
18769
18779
|
return number === 1 ? _lt("Insert row above") : _lt("Insert %s rows above", number.toString());
|
|
18770
18780
|
},
|
|
18771
18781
|
execute: INSERT_ROWS_BEFORE_ACTION,
|
|
18772
|
-
isVisible: (env) =>
|
|
18773
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18774
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18782
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18775
18783
|
icon: "o-spreadsheet-Icon.INSERT_ROW_BEFORE",
|
|
18776
18784
|
};
|
|
18777
18785
|
const topBarInsertRowsBefore = {
|
|
@@ -18802,9 +18810,7 @@ const rowInsertRowsAfter = {
|
|
|
18802
18810
|
const number = getRowsNumber(env);
|
|
18803
18811
|
return number === 1 ? _lt("Insert row below") : _lt("Insert %s rows below", number.toString());
|
|
18804
18812
|
},
|
|
18805
|
-
isVisible: (env) =>
|
|
18806
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18807
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18813
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18808
18814
|
icon: "o-spreadsheet-Icon.INSERT_ROW_AFTER",
|
|
18809
18815
|
};
|
|
18810
18816
|
const topBarInsertRowsAfter = {
|
|
@@ -18822,9 +18828,7 @@ const insertCol = {
|
|
|
18822
18828
|
const number = getColumnsNumber(env);
|
|
18823
18829
|
return number === 1 ? _lt("Insert column") : _lt("Insert %s columns", number.toString());
|
|
18824
18830
|
},
|
|
18825
|
-
isVisible: (env) =>
|
|
18826
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18827
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18831
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18828
18832
|
icon: "o-spreadsheet-Icon.INSERT_COL",
|
|
18829
18833
|
};
|
|
18830
18834
|
const colInsertColsBefore = {
|
|
@@ -18835,9 +18839,7 @@ const colInsertColsBefore = {
|
|
|
18835
18839
|
: _lt("Insert %s columns left", number.toString());
|
|
18836
18840
|
},
|
|
18837
18841
|
execute: INSERT_COLUMNS_BEFORE_ACTION,
|
|
18838
|
-
isVisible: (env) =>
|
|
18839
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18840
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18842
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18841
18843
|
icon: "o-spreadsheet-Icon.INSERT_COL_BEFORE",
|
|
18842
18844
|
};
|
|
18843
18845
|
const topBarInsertColsBefore = {
|
|
@@ -18870,9 +18872,7 @@ const colInsertColsAfter = {
|
|
|
18870
18872
|
: _lt("Insert %s columns right", number.toString());
|
|
18871
18873
|
},
|
|
18872
18874
|
execute: INSERT_COLUMNS_AFTER_ACTION,
|
|
18873
|
-
isVisible: (env) =>
|
|
18874
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18875
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18875
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18876
18876
|
icon: "o-spreadsheet-Icon.INSERT_COL_AFTER",
|
|
18877
18877
|
};
|
|
18878
18878
|
const topBarInsertColsAfter = {
|
|
@@ -22830,7 +22830,7 @@ css /* scss */ `
|
|
|
22830
22830
|
}
|
|
22831
22831
|
.o-input-count {
|
|
22832
22832
|
width: fit-content;
|
|
22833
|
-
padding:
|
|
22833
|
+
padding: 4px 0 4px 4px;
|
|
22834
22834
|
}
|
|
22835
22835
|
}
|
|
22836
22836
|
}
|
|
@@ -31171,6 +31171,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31171
31171
|
// ---------------------------------------------------------------------------
|
|
31172
31172
|
// Command Handling
|
|
31173
31173
|
// ---------------------------------------------------------------------------
|
|
31174
|
+
allowDispatch(cmd) {
|
|
31175
|
+
switch (cmd.type) {
|
|
31176
|
+
case "SET_BORDER":
|
|
31177
|
+
return this.checkBordersUnchanged(cmd);
|
|
31178
|
+
default:
|
|
31179
|
+
return 0 /* CommandResult.Success */;
|
|
31180
|
+
}
|
|
31181
|
+
}
|
|
31174
31182
|
handle(cmd) {
|
|
31175
31183
|
switch (cmd.type) {
|
|
31176
31184
|
case "ADD_MERGE":
|
|
@@ -31590,6 +31598,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31590
31598
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
31591
31599
|
}
|
|
31592
31600
|
}
|
|
31601
|
+
checkBordersUnchanged(cmd) {
|
|
31602
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
31603
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
31604
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
31605
|
+
return 97 /* CommandResult.NoChanges */;
|
|
31606
|
+
}
|
|
31607
|
+
return 0 /* CommandResult.Success */;
|
|
31608
|
+
}
|
|
31593
31609
|
// ---------------------------------------------------------------------------
|
|
31594
31610
|
// Import/Export
|
|
31595
31611
|
// ---------------------------------------------------------------------------
|
|
@@ -31697,8 +31713,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31697
31713
|
allowDispatch(cmd) {
|
|
31698
31714
|
switch (cmd.type) {
|
|
31699
31715
|
case "UPDATE_CELL":
|
|
31716
|
+
return this.checkCellOutOfSheet(cmd);
|
|
31700
31717
|
case "CLEAR_CELL":
|
|
31701
|
-
return this.
|
|
31718
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
31702
31719
|
default:
|
|
31703
31720
|
return 0 /* CommandResult.Success */;
|
|
31704
31721
|
}
|
|
@@ -31857,14 +31874,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31857
31874
|
*/
|
|
31858
31875
|
getCellById(cellId) {
|
|
31859
31876
|
// this must be as fast as possible
|
|
31860
|
-
|
|
31861
|
-
|
|
31862
|
-
|
|
31863
|
-
if (cell) {
|
|
31864
|
-
return cell;
|
|
31865
|
-
}
|
|
31866
|
-
}
|
|
31867
|
-
return undefined;
|
|
31877
|
+
const position = this.getters.getCellPosition(cellId);
|
|
31878
|
+
const sheet = this.cells[position.sheetId];
|
|
31879
|
+
return sheet[cellId];
|
|
31868
31880
|
}
|
|
31869
31881
|
/*
|
|
31870
31882
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -32090,13 +32102,23 @@ class CellPlugin extends CorePlugin {
|
|
|
32090
32102
|
dependencies: [],
|
|
32091
32103
|
};
|
|
32092
32104
|
}
|
|
32093
|
-
checkCellOutOfSheet(
|
|
32105
|
+
checkCellOutOfSheet(cmd) {
|
|
32106
|
+
const { sheetId, col, row } = cmd;
|
|
32094
32107
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
32095
32108
|
if (!sheet)
|
|
32096
32109
|
return 28 /* CommandResult.InvalidSheetId */;
|
|
32097
32110
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
32098
32111
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 19 /* CommandResult.TargetOutOfSheet */;
|
|
32099
32112
|
}
|
|
32113
|
+
checkUselessClearCell(cmd) {
|
|
32114
|
+
const cell = this.getters.getCell(cmd);
|
|
32115
|
+
if (!cell)
|
|
32116
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32117
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
32118
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32119
|
+
}
|
|
32120
|
+
return 0 /* CommandResult.Success */;
|
|
32121
|
+
}
|
|
32100
32122
|
}
|
|
32101
32123
|
class FormulaCellWithDependencies {
|
|
32102
32124
|
id;
|
|
@@ -33077,6 +33099,13 @@ class FiltersPlugin extends CorePlugin {
|
|
|
33077
33099
|
}
|
|
33078
33100
|
onDeleteColumnsRows(cmd) {
|
|
33079
33101
|
for (const table of this.getFilterTables(cmd.sheetId)) {
|
|
33102
|
+
// Remove the filter tables whose data filter headers are in the removed rows.
|
|
33103
|
+
if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
|
|
33104
|
+
const tables = { ...this.tables[cmd.sheetId] };
|
|
33105
|
+
delete tables[table.id];
|
|
33106
|
+
this.history.update("tables", cmd.sheetId, tables);
|
|
33107
|
+
continue;
|
|
33108
|
+
}
|
|
33080
33109
|
const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
|
|
33081
33110
|
if (!zone) {
|
|
33082
33111
|
const tables = { ...this.tables[cmd.sheetId] };
|
|
@@ -35158,10 +35187,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
35158
35187
|
// begin with the end.
|
|
35159
35188
|
rows.sort((a, b) => b - a);
|
|
35160
35189
|
for (let group of groupConsecutive(rows)) {
|
|
35190
|
+
// indexes are sorted in the descending order
|
|
35191
|
+
const from = group[group.length - 1];
|
|
35192
|
+
const to = group[0];
|
|
35161
35193
|
// Move the cells.
|
|
35162
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
35163
|
-
// Effectively delete the
|
|
35164
|
-
|
|
35194
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
35195
|
+
// Effectively delete the rows
|
|
35196
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
35165
35197
|
}
|
|
35166
35198
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
35167
35199
|
if (count) {
|
|
@@ -35183,8 +35215,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
35183
35215
|
this.addEmptyRows(sheet, quantity);
|
|
35184
35216
|
// Move the cells.
|
|
35185
35217
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
35186
|
-
// Recompute the left-right/top-bottom.
|
|
35187
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
35188
35218
|
if (index < sheet.panes.ySplit) {
|
|
35189
35219
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
35190
35220
|
}
|
|
@@ -35285,35 +35315,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
35285
35315
|
}
|
|
35286
35316
|
}
|
|
35287
35317
|
}
|
|
35288
|
-
updateRowsStructureOnDeletion(
|
|
35318
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
35289
35319
|
const rows = [];
|
|
35290
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35320
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
35291
35321
|
for (let i in sheet.rows) {
|
|
35292
|
-
|
|
35322
|
+
const row = Number(i);
|
|
35323
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
35293
35324
|
continue;
|
|
35294
35325
|
}
|
|
35295
35326
|
rows.push({
|
|
35296
|
-
cells: cellsQueue.
|
|
35327
|
+
cells: cellsQueue.pop(),
|
|
35297
35328
|
});
|
|
35298
35329
|
}
|
|
35299
35330
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35300
35331
|
}
|
|
35301
|
-
/**
|
|
35302
|
-
* Update the rows of the sheet after an addition:
|
|
35303
|
-
* - Rename the rows
|
|
35304
|
-
*
|
|
35305
|
-
* @param sheet Sheet on which the deletion occurs
|
|
35306
|
-
* @param addedRow Index of the added row
|
|
35307
|
-
* @param rowsToAdd Number of the rows to add
|
|
35308
|
-
*/
|
|
35309
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
35310
|
-
const rows = [];
|
|
35311
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35312
|
-
sheet.rows.forEach(() => rows.push({
|
|
35313
|
-
cells: cellsQueue.shift(),
|
|
35314
|
-
}));
|
|
35315
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35316
|
-
}
|
|
35317
35332
|
/**
|
|
35318
35333
|
* Add empty rows at the end of the rows
|
|
35319
35334
|
*
|
|
@@ -35429,6 +35444,7 @@ class CompilationParametersBuilder {
|
|
|
35429
35444
|
getters;
|
|
35430
35445
|
computeCell;
|
|
35431
35446
|
evalContext;
|
|
35447
|
+
rangeCache = {};
|
|
35432
35448
|
constructor(context, getters, computeCell) {
|
|
35433
35449
|
this.getters = getters;
|
|
35434
35450
|
this.computeCell = computeCell;
|
|
@@ -35514,25 +35530,32 @@ class CompilationParametersBuilder {
|
|
|
35514
35530
|
if (!_zone) {
|
|
35515
35531
|
return { value: [[]], format: [[]] };
|
|
35516
35532
|
}
|
|
35533
|
+
const { top, left, bottom, right } = zone;
|
|
35534
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
35535
|
+
if (cacheKey in this.rangeCache) {
|
|
35536
|
+
return this.rangeCache[cacheKey];
|
|
35537
|
+
}
|
|
35517
35538
|
const height = _zone.bottom - _zone.top + 1;
|
|
35518
35539
|
const width = _zone.right - _zone.left + 1;
|
|
35519
|
-
const value = Array
|
|
35520
|
-
const format = Array
|
|
35540
|
+
const value = new Array(width);
|
|
35541
|
+
const format = new Array(width);
|
|
35521
35542
|
// Performance issue: nested loop is faster than a map here
|
|
35522
35543
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
35544
|
+
const colIndex = col - _zone.left;
|
|
35545
|
+
value[colIndex] = new Array(height);
|
|
35546
|
+
format[colIndex] = new Array(height);
|
|
35523
35547
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
35524
|
-
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId
|
|
35525
|
-
|
|
35526
|
-
|
|
35527
|
-
|
|
35528
|
-
|
|
35529
|
-
if (evaluatedCell.format !== undefined) {
|
|
35530
|
-
format[colIndex][rowIndex] = evaluatedCell.format;
|
|
35531
|
-
}
|
|
35548
|
+
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
|
|
35549
|
+
const rowIndex = row - _zone.top;
|
|
35550
|
+
value[colIndex][rowIndex] = evaluatedCell?.value;
|
|
35551
|
+
if (evaluatedCell?.format !== undefined) {
|
|
35552
|
+
format[colIndex][rowIndex] = evaluatedCell.format;
|
|
35532
35553
|
}
|
|
35533
35554
|
}
|
|
35534
35555
|
}
|
|
35535
|
-
|
|
35556
|
+
const result = { value, format };
|
|
35557
|
+
this.rangeCache[cacheKey] = result;
|
|
35558
|
+
return result;
|
|
35536
35559
|
}
|
|
35537
35560
|
}
|
|
35538
35561
|
|
|
@@ -35730,6 +35753,7 @@ class Evaluator {
|
|
|
35730
35753
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
35731
35754
|
}
|
|
35732
35755
|
updateCompilationParameters() {
|
|
35756
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
35733
35757
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
35734
35758
|
}
|
|
35735
35759
|
evaluateCells(positions) {
|
|
@@ -35773,6 +35797,15 @@ class Evaluator {
|
|
|
35773
35797
|
this.evaluatedCells = new Map();
|
|
35774
35798
|
this.evaluate(this.getAllCells());
|
|
35775
35799
|
}
|
|
35800
|
+
evaluateFormula(sheetId, formulaString) {
|
|
35801
|
+
const compiledFormula = compile(formulaString);
|
|
35802
|
+
const ranges = [];
|
|
35803
|
+
for (let xc of compiledFormula.dependencies) {
|
|
35804
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
35805
|
+
}
|
|
35806
|
+
this.updateCompilationParameters();
|
|
35807
|
+
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
35808
|
+
}
|
|
35776
35809
|
getAllCells() {
|
|
35777
35810
|
const positionIds = new JetSet();
|
|
35778
35811
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -35799,6 +35832,7 @@ class Evaluator {
|
|
|
35799
35832
|
this.nextPositionsToUpdate = cells;
|
|
35800
35833
|
let currentIteration = 0;
|
|
35801
35834
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
35835
|
+
this.updateCompilationParameters();
|
|
35802
35836
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
35803
35837
|
this.nextPositionsToUpdate.clear();
|
|
35804
35838
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -36183,7 +36217,6 @@ class PositionBitsEncoder {
|
|
|
36183
36217
|
// of other cells depending on it, at the next iteration.
|
|
36184
36218
|
//#endregion
|
|
36185
36219
|
class EvaluationPlugin extends UIPlugin {
|
|
36186
|
-
config;
|
|
36187
36220
|
static getters = [
|
|
36188
36221
|
"evaluateFormula",
|
|
36189
36222
|
"getRangeFormattedValues",
|
|
@@ -36195,12 +36228,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36195
36228
|
];
|
|
36196
36229
|
shouldRebuildDependenciesGraph = true;
|
|
36197
36230
|
evaluator;
|
|
36198
|
-
compilationParams;
|
|
36199
36231
|
positionsToUpdate = [];
|
|
36200
36232
|
constructor(config) {
|
|
36201
36233
|
super(config);
|
|
36202
|
-
this.config = config;
|
|
36203
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36204
36234
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
36205
36235
|
}
|
|
36206
36236
|
// ---------------------------------------------------------------------------
|
|
@@ -36225,10 +36255,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36225
36255
|
case "EVALUATE_CELLS":
|
|
36226
36256
|
this.evaluator.evaluateAllCells();
|
|
36227
36257
|
break;
|
|
36228
|
-
case "UPDATE_LOCALE":
|
|
36229
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36230
|
-
this.evaluator.updateCompilationParameters();
|
|
36231
|
-
break;
|
|
36232
36258
|
}
|
|
36233
36259
|
}
|
|
36234
36260
|
finalize() {
|
|
@@ -36246,12 +36272,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36246
36272
|
// Getters
|
|
36247
36273
|
// ---------------------------------------------------------------------------
|
|
36248
36274
|
evaluateFormula(sheetId, formulaString) {
|
|
36249
|
-
|
|
36250
|
-
const ranges = [];
|
|
36251
|
-
for (let xc of compiledFormula.dependencies) {
|
|
36252
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
36253
|
-
}
|
|
36254
|
-
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
36275
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
36255
36276
|
}
|
|
36256
36277
|
/**
|
|
36257
36278
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -36350,9 +36371,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36350
36371
|
}
|
|
36351
36372
|
return undefined;
|
|
36352
36373
|
}
|
|
36353
|
-
getCompilationParameters() {
|
|
36354
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
36355
|
-
}
|
|
36356
36374
|
}
|
|
36357
36375
|
function isBadExpression(formula) {
|
|
36358
36376
|
try {
|
|
@@ -36525,22 +36543,20 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
36525
36543
|
invalidateCFEvaluationCommands.has(cmd.type) ||
|
|
36526
36544
|
cmd.type === "EVALUATE_CELLS" ||
|
|
36527
36545
|
cmd.type === "UPDATE_CELL") {
|
|
36528
|
-
|
|
36529
|
-
|
|
36530
|
-
this.history.update("charts", chartId, undefined);
|
|
36531
|
-
}
|
|
36546
|
+
for (const chartId in this.charts) {
|
|
36547
|
+
this.charts[chartId] = undefined;
|
|
36532
36548
|
}
|
|
36533
36549
|
}
|
|
36534
36550
|
switch (cmd.type) {
|
|
36535
36551
|
case "UPDATE_CHART":
|
|
36536
36552
|
case "CREATE_CHART":
|
|
36537
36553
|
case "DELETE_FIGURE":
|
|
36538
|
-
this.
|
|
36554
|
+
this.charts[cmd.id] = undefined;
|
|
36539
36555
|
break;
|
|
36540
36556
|
case "DELETE_SHEET":
|
|
36541
36557
|
for (let chartId in this.charts) {
|
|
36542
36558
|
if (!this.getters.isChartDefined(chartId)) {
|
|
36543
|
-
this.
|
|
36559
|
+
this.charts[chartId] = undefined;
|
|
36544
36560
|
}
|
|
36545
36561
|
}
|
|
36546
36562
|
break;
|
|
@@ -36552,7 +36568,7 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
36552
36568
|
if (!chart) {
|
|
36553
36569
|
throw new Error(`No chart for the given id: ${figureId}`);
|
|
36554
36570
|
}
|
|
36555
|
-
this.
|
|
36571
|
+
this.charts[figureId] = this.createRuntimeChart(chart);
|
|
36556
36572
|
}
|
|
36557
36573
|
return this.charts[figureId];
|
|
36558
36574
|
}
|
|
@@ -42071,8 +42087,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
42071
42087
|
this.lastPasteState = this.state;
|
|
42072
42088
|
if (this.paintFormatStatus === "oneOff") {
|
|
42073
42089
|
this.paintFormatStatus = "inactive";
|
|
42074
|
-
this.status = "invisible";
|
|
42075
42090
|
}
|
|
42091
|
+
this.status = "invisible";
|
|
42076
42092
|
break;
|
|
42077
42093
|
case "CLEAN_CLIPBOARD_HIGHLIGHT":
|
|
42078
42094
|
this.status = "invisible";
|
|
@@ -43016,6 +43032,8 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
43016
43032
|
case "EVALUATE_CELLS":
|
|
43017
43033
|
case "ACTIVATE_SHEET":
|
|
43018
43034
|
case "REMOVE_FILTER_TABLE":
|
|
43035
|
+
case "ADD_COLUMNS_ROWS":
|
|
43036
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
43019
43037
|
this.isEvaluationDirty = true;
|
|
43020
43038
|
break;
|
|
43021
43039
|
case "START":
|
|
@@ -47887,9 +47905,9 @@ function revertChanges(revisions) {
|
|
|
47887
47905
|
* Apply the changes of the given HistoryChange to the state
|
|
47888
47906
|
*/
|
|
47889
47907
|
function applyChange(change, target) {
|
|
47890
|
-
let val = change.
|
|
47891
|
-
|
|
47892
|
-
for (let pathIndex =
|
|
47908
|
+
let val = change.path[0];
|
|
47909
|
+
const key = change.path[change.path.length - 1];
|
|
47910
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
47893
47911
|
const p = change.path[pathIndex];
|
|
47894
47912
|
if (val[p] === undefined) {
|
|
47895
47913
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -48570,13 +48588,14 @@ class StateObserver {
|
|
|
48570
48588
|
}
|
|
48571
48589
|
addChange(...args) {
|
|
48572
48590
|
const val = args.pop();
|
|
48573
|
-
const
|
|
48591
|
+
const root = args[0];
|
|
48574
48592
|
let value = root;
|
|
48575
|
-
let key =
|
|
48576
|
-
|
|
48577
|
-
|
|
48593
|
+
let key = args[args.length - 1];
|
|
48594
|
+
const pathLength = args.length - 2;
|
|
48595
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
48596
|
+
const p = args[pathIndex];
|
|
48578
48597
|
if (value[p] === undefined) {
|
|
48579
|
-
const nextPath =
|
|
48598
|
+
const nextPath = args[pathIndex + 1];
|
|
48580
48599
|
value[p] = createEmptyStructure(nextPath);
|
|
48581
48600
|
}
|
|
48582
48601
|
value = value[p];
|
|
@@ -48585,8 +48604,7 @@ class StateObserver {
|
|
|
48585
48604
|
return;
|
|
48586
48605
|
}
|
|
48587
48606
|
this.changes.push({
|
|
48588
|
-
|
|
48589
|
-
path,
|
|
48607
|
+
path: args,
|
|
48590
48608
|
before: value[key],
|
|
48591
48609
|
after: val,
|
|
48592
48610
|
});
|
|
@@ -50436,19 +50454,22 @@ class Model extends EventBus {
|
|
|
50436
50454
|
* Check if the given command is allowed by all the plugins and the history.
|
|
50437
50455
|
*/
|
|
50438
50456
|
checkDispatchAllowed(command) {
|
|
50439
|
-
|
|
50440
|
-
|
|
50457
|
+
const results = isCoreCommand(command)
|
|
50458
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
50459
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
50460
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
50461
|
+
return new DispatchResult(results.flat());
|
|
50441
50462
|
}
|
|
50442
|
-
return
|
|
50463
|
+
return DispatchResult.Success;
|
|
50443
50464
|
}
|
|
50444
50465
|
checkDispatchAllowedCoreCommand(command) {
|
|
50445
50466
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
50446
50467
|
results.push(this.range.allowDispatch(command));
|
|
50447
|
-
return
|
|
50468
|
+
return results;
|
|
50448
50469
|
}
|
|
50449
50470
|
checkDispatchAllowedLocalCommand(command) {
|
|
50450
50471
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
50451
|
-
return
|
|
50472
|
+
return results;
|
|
50452
50473
|
}
|
|
50453
50474
|
finalize() {
|
|
50454
50475
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -50772,6 +50793,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
50772
50793
|
exports.tokenize = tokenize;
|
|
50773
50794
|
|
|
50774
50795
|
|
|
50775
|
-
__info__.version = '16.4.
|
|
50776
|
-
__info__.date = '2023-11-
|
|
50777
|
-
__info__.hash = '
|
|
50796
|
+
__info__.version = '16.4.15';
|
|
50797
|
+
__info__.date = '2023-11-24T13:12:26.608Z';
|
|
50798
|
+
__info__.hash = '141943d';
|