@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
|
@@ -668,8 +668,7 @@ function transpose2dArray(matrix, callback = (val) => val) {
|
|
|
668
668
|
*
|
|
669
669
|
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Character_Classes
|
|
670
670
|
*/
|
|
671
|
-
const
|
|
672
|
-
" ",
|
|
671
|
+
const whiteSpaceSpecialCharacters = [
|
|
673
672
|
"\t",
|
|
674
673
|
"\f",
|
|
675
674
|
"\v",
|
|
@@ -684,8 +683,7 @@ const whiteSpaceCharacters = [
|
|
|
684
683
|
String.fromCharCode(parseInt("3000", 16)),
|
|
685
684
|
String.fromCharCode(parseInt("feff", 16)),
|
|
686
685
|
];
|
|
687
|
-
const whiteSpaceRegexp = new RegExp(
|
|
688
|
-
const newLineRegex = /\r\n|\r|\n/g;
|
|
686
|
+
const whiteSpaceRegexp = new RegExp(whiteSpaceSpecialCharacters.join("|") + "|(\r\n|\r|\n)", "g");
|
|
689
687
|
/**
|
|
690
688
|
* Replace all the special spaces in a string (non-breaking, tabs, ...) by normal spaces, and all the
|
|
691
689
|
* different newlines types by \n.
|
|
@@ -693,9 +691,9 @@ const newLineRegex = /\r\n|\r|\n/g;
|
|
|
693
691
|
function replaceSpecialSpaces(text) {
|
|
694
692
|
if (!text)
|
|
695
693
|
return "";
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
return text;
|
|
694
|
+
if (!whiteSpaceRegexp.test(text))
|
|
695
|
+
return text;
|
|
696
|
+
return text.replace(whiteSpaceRegexp, (match, newLine) => (newLine ? NEWLINE : " "));
|
|
699
697
|
}
|
|
700
698
|
/**
|
|
701
699
|
* Determine if the numbers are consecutive.
|
|
@@ -4265,6 +4263,7 @@ var CommandResult;
|
|
|
4265
4263
|
CommandResult[CommandResult["NoActiveSheet"] = 94] = "NoActiveSheet";
|
|
4266
4264
|
CommandResult[CommandResult["InvalidLocale"] = 95] = "InvalidLocale";
|
|
4267
4265
|
CommandResult[CommandResult["AlreadyInPaintingFormatMode"] = 96] = "AlreadyInPaintingFormatMode";
|
|
4266
|
+
CommandResult[CommandResult["NoChanges"] = 97] = "NoChanges";
|
|
4268
4267
|
})(CommandResult || (CommandResult = {}));
|
|
4269
4268
|
|
|
4270
4269
|
const borderStyles = ["thin", "medium", "thick", "dashed", "dotted"];
|
|
@@ -4354,12 +4353,12 @@ function toString(value) {
|
|
|
4354
4353
|
}
|
|
4355
4354
|
}
|
|
4356
4355
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
4357
|
-
function normalizeString(str) {
|
|
4356
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
4358
4357
|
return str
|
|
4359
4358
|
.toLowerCase()
|
|
4360
4359
|
.normalize("NFD")
|
|
4361
4360
|
.replace(/[\u0300-\u036f]/g, "");
|
|
4362
|
-
}
|
|
4361
|
+
});
|
|
4363
4362
|
/**
|
|
4364
4363
|
* Normalize a value.
|
|
4365
4364
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -14170,7 +14169,7 @@ function tokenize(str, locale = DEFAULT_LOCALE) {
|
|
|
14170
14169
|
return result;
|
|
14171
14170
|
}
|
|
14172
14171
|
function tokenizeDebugger(chars) {
|
|
14173
|
-
if (chars.current
|
|
14172
|
+
if (chars.current === "?") {
|
|
14174
14173
|
chars.shift();
|
|
14175
14174
|
return { type: "DEBUGGER", value: "?" };
|
|
14176
14175
|
}
|
|
@@ -14181,7 +14180,7 @@ const misc = {
|
|
|
14181
14180
|
")": "RIGHT_PAREN",
|
|
14182
14181
|
};
|
|
14183
14182
|
function tokenizeMisc(chars) {
|
|
14184
|
-
if (chars.current
|
|
14183
|
+
if (chars.current in misc) {
|
|
14185
14184
|
const value = chars.shift();
|
|
14186
14185
|
const type = misc[value];
|
|
14187
14186
|
return { type, value };
|
|
@@ -14189,7 +14188,7 @@ function tokenizeMisc(chars) {
|
|
|
14189
14188
|
return null;
|
|
14190
14189
|
}
|
|
14191
14190
|
function tokenizeArgsSeparator(chars, locale) {
|
|
14192
|
-
if (chars.current
|
|
14191
|
+
if (chars.current === locale.formulaArgSeparator) {
|
|
14193
14192
|
const value = chars.shift();
|
|
14194
14193
|
const type = "ARG_SEPARATOR";
|
|
14195
14194
|
return { type, value };
|
|
@@ -14214,14 +14213,13 @@ function tokenizeNumber(chars, locale) {
|
|
|
14214
14213
|
return null;
|
|
14215
14214
|
}
|
|
14216
14215
|
function tokenizeString(chars) {
|
|
14217
|
-
if (chars.current
|
|
14216
|
+
if (chars.current === '"') {
|
|
14218
14217
|
const startChar = chars.shift();
|
|
14219
14218
|
let letters = startChar;
|
|
14220
|
-
while (chars.current()
|
|
14221
|
-
(chars.current() !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14219
|
+
while (chars.current && (chars.current !== startChar || letters[letters.length - 1] === "\\")) {
|
|
14222
14220
|
letters += chars.shift();
|
|
14223
14221
|
}
|
|
14224
|
-
if (chars.current
|
|
14222
|
+
if (chars.current === '"') {
|
|
14225
14223
|
letters += chars.shift();
|
|
14226
14224
|
}
|
|
14227
14225
|
return {
|
|
@@ -14248,14 +14246,14 @@ function tokenizeSymbol(chars) {
|
|
|
14248
14246
|
let result = "";
|
|
14249
14247
|
// there are two main cases to manage: either something which starts with
|
|
14250
14248
|
// a ', like 'Sheet 2'A2, or a word-like element.
|
|
14251
|
-
if (chars.current
|
|
14249
|
+
if (chars.current === "'") {
|
|
14252
14250
|
let lastChar = chars.shift();
|
|
14253
14251
|
result += lastChar;
|
|
14254
|
-
while (chars.current
|
|
14252
|
+
while (chars.current) {
|
|
14255
14253
|
lastChar = chars.shift();
|
|
14256
14254
|
result += lastChar;
|
|
14257
14255
|
if (lastChar === "'") {
|
|
14258
|
-
if (chars.current
|
|
14256
|
+
if (chars.current && chars.current === "'") {
|
|
14259
14257
|
lastChar = chars.shift();
|
|
14260
14258
|
result += lastChar;
|
|
14261
14259
|
}
|
|
@@ -14271,7 +14269,7 @@ function tokenizeSymbol(chars) {
|
|
|
14271
14269
|
};
|
|
14272
14270
|
}
|
|
14273
14271
|
}
|
|
14274
|
-
while (chars.current
|
|
14272
|
+
while (chars.current && separatorRegexp.test(chars.current)) {
|
|
14275
14273
|
result += chars.shift();
|
|
14276
14274
|
}
|
|
14277
14275
|
if (result.length) {
|
|
@@ -14286,14 +14284,14 @@ function tokenizeSymbol(chars) {
|
|
|
14286
14284
|
}
|
|
14287
14285
|
function tokenizeSpace(chars) {
|
|
14288
14286
|
let length = 0;
|
|
14289
|
-
while (chars.current
|
|
14287
|
+
while (chars.current === NEWLINE) {
|
|
14290
14288
|
length++;
|
|
14291
14289
|
chars.shift();
|
|
14292
14290
|
}
|
|
14293
14291
|
if (length) {
|
|
14294
14292
|
return { type: "SPACE", value: NEWLINE.repeat(length) };
|
|
14295
14293
|
}
|
|
14296
|
-
while (chars.current
|
|
14294
|
+
while (chars.current === " ") {
|
|
14297
14295
|
length++;
|
|
14298
14296
|
chars.shift();
|
|
14299
14297
|
}
|
|
@@ -14312,17 +14310,20 @@ function tokenizeInvalidRange(chars) {
|
|
|
14312
14310
|
class TokenizingChars {
|
|
14313
14311
|
text;
|
|
14314
14312
|
currentIndex = 0;
|
|
14313
|
+
current;
|
|
14315
14314
|
constructor(text) {
|
|
14316
14315
|
this.text = text;
|
|
14317
|
-
|
|
14318
|
-
current() {
|
|
14319
|
-
return this.text[this.currentIndex];
|
|
14316
|
+
this.current = text[0];
|
|
14320
14317
|
}
|
|
14321
14318
|
shift() {
|
|
14322
|
-
|
|
14319
|
+
const current = this.current;
|
|
14320
|
+
const next = this.text[++this.currentIndex];
|
|
14321
|
+
this.current = next;
|
|
14322
|
+
return current;
|
|
14323
14323
|
}
|
|
14324
14324
|
advanceBy(length) {
|
|
14325
14325
|
this.currentIndex += length;
|
|
14326
|
+
this.current = this.text[this.currentIndex];
|
|
14326
14327
|
}
|
|
14327
14328
|
isOver() {
|
|
14328
14329
|
return this.currentIndex >= this.text.length;
|
|
@@ -18565,6 +18566,17 @@ const SELECTION_CONTAINS_FILTER = (env) => {
|
|
|
18565
18566
|
//------------------------------------------------------------------------------
|
|
18566
18567
|
const IS_ONLY_ONE_RANGE = (env) => {
|
|
18567
18568
|
return env.model.getters.getSelectedZones().length === 1;
|
|
18569
|
+
};
|
|
18570
|
+
const CAN_INSERT_HEADER = (env, dimension) => {
|
|
18571
|
+
if (!IS_ONLY_ONE_RANGE(env)) {
|
|
18572
|
+
return false;
|
|
18573
|
+
}
|
|
18574
|
+
const activeHeaders = dimension === "COL" ? env.model.getters.getActiveCols() : env.model.getters.getActiveRows();
|
|
18575
|
+
const ortogonalActiveHeaders = dimension === "COL" ? env.model.getters.getActiveRows() : env.model.getters.getActiveCols();
|
|
18576
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
18577
|
+
const zone = env.model.getters.getSelectedZone();
|
|
18578
|
+
const allSheetSelected = isEqual(zone, env.model.getters.getSheetZone(sheetId));
|
|
18579
|
+
return isConsecutive(activeHeaders) && (ortogonalActiveHeaders.size === 0 || allSheetSelected);
|
|
18568
18580
|
};
|
|
18569
18581
|
|
|
18570
18582
|
const undo = {
|
|
@@ -18754,9 +18766,7 @@ const insertRow = {
|
|
|
18754
18766
|
const number = getRowsNumber(env);
|
|
18755
18767
|
return number === 1 ? _lt("Insert row") : _lt("Insert %s rows", number.toString());
|
|
18756
18768
|
},
|
|
18757
|
-
isVisible: (env) =>
|
|
18758
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18759
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18769
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18760
18770
|
icon: "o-spreadsheet-Icon.INSERT_ROW",
|
|
18761
18771
|
};
|
|
18762
18772
|
const rowInsertRowBefore = {
|
|
@@ -18765,9 +18775,7 @@ const rowInsertRowBefore = {
|
|
|
18765
18775
|
return number === 1 ? _lt("Insert row above") : _lt("Insert %s rows above", number.toString());
|
|
18766
18776
|
},
|
|
18767
18777
|
execute: INSERT_ROWS_BEFORE_ACTION,
|
|
18768
|
-
isVisible: (env) =>
|
|
18769
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18770
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18778
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18771
18779
|
icon: "o-spreadsheet-Icon.INSERT_ROW_BEFORE",
|
|
18772
18780
|
};
|
|
18773
18781
|
const topBarInsertRowsBefore = {
|
|
@@ -18798,9 +18806,7 @@ const rowInsertRowsAfter = {
|
|
|
18798
18806
|
const number = getRowsNumber(env);
|
|
18799
18807
|
return number === 1 ? _lt("Insert row below") : _lt("Insert %s rows below", number.toString());
|
|
18800
18808
|
},
|
|
18801
|
-
isVisible: (env) =>
|
|
18802
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18803
|
-
env.model.getters.getActiveCols().size === 0,
|
|
18809
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "ROW"),
|
|
18804
18810
|
icon: "o-spreadsheet-Icon.INSERT_ROW_AFTER",
|
|
18805
18811
|
};
|
|
18806
18812
|
const topBarInsertRowsAfter = {
|
|
@@ -18818,9 +18824,7 @@ const insertCol = {
|
|
|
18818
18824
|
const number = getColumnsNumber(env);
|
|
18819
18825
|
return number === 1 ? _lt("Insert column") : _lt("Insert %s columns", number.toString());
|
|
18820
18826
|
},
|
|
18821
|
-
isVisible: (env) =>
|
|
18822
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18823
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18827
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18824
18828
|
icon: "o-spreadsheet-Icon.INSERT_COL",
|
|
18825
18829
|
};
|
|
18826
18830
|
const colInsertColsBefore = {
|
|
@@ -18831,9 +18835,7 @@ const colInsertColsBefore = {
|
|
|
18831
18835
|
: _lt("Insert %s columns left", number.toString());
|
|
18832
18836
|
},
|
|
18833
18837
|
execute: INSERT_COLUMNS_BEFORE_ACTION,
|
|
18834
|
-
isVisible: (env) =>
|
|
18835
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18836
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18838
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18837
18839
|
icon: "o-spreadsheet-Icon.INSERT_COL_BEFORE",
|
|
18838
18840
|
};
|
|
18839
18841
|
const topBarInsertColsBefore = {
|
|
@@ -18866,9 +18868,7 @@ const colInsertColsAfter = {
|
|
|
18866
18868
|
: _lt("Insert %s columns right", number.toString());
|
|
18867
18869
|
},
|
|
18868
18870
|
execute: INSERT_COLUMNS_AFTER_ACTION,
|
|
18869
|
-
isVisible: (env) =>
|
|
18870
|
-
IS_ONLY_ONE_RANGE(env) &&
|
|
18871
|
-
env.model.getters.getActiveRows().size === 0,
|
|
18871
|
+
isVisible: (env) => CAN_INSERT_HEADER(env, "COL"),
|
|
18872
18872
|
icon: "o-spreadsheet-Icon.INSERT_COL_AFTER",
|
|
18873
18873
|
};
|
|
18874
18874
|
const topBarInsertColsAfter = {
|
|
@@ -22826,7 +22826,7 @@ css /* scss */ `
|
|
|
22826
22826
|
}
|
|
22827
22827
|
.o-input-count {
|
|
22828
22828
|
width: fit-content;
|
|
22829
|
-
padding:
|
|
22829
|
+
padding: 4px 0 4px 4px;
|
|
22830
22830
|
}
|
|
22831
22831
|
}
|
|
22832
22832
|
}
|
|
@@ -31167,6 +31167,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31167
31167
|
// ---------------------------------------------------------------------------
|
|
31168
31168
|
// Command Handling
|
|
31169
31169
|
// ---------------------------------------------------------------------------
|
|
31170
|
+
allowDispatch(cmd) {
|
|
31171
|
+
switch (cmd.type) {
|
|
31172
|
+
case "SET_BORDER":
|
|
31173
|
+
return this.checkBordersUnchanged(cmd);
|
|
31174
|
+
default:
|
|
31175
|
+
return 0 /* CommandResult.Success */;
|
|
31176
|
+
}
|
|
31177
|
+
}
|
|
31170
31178
|
handle(cmd) {
|
|
31171
31179
|
switch (cmd.type) {
|
|
31172
31180
|
case "ADD_MERGE":
|
|
@@ -31586,6 +31594,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
31586
31594
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right", bordersTopLeft.right);
|
|
31587
31595
|
}
|
|
31588
31596
|
}
|
|
31597
|
+
checkBordersUnchanged(cmd) {
|
|
31598
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
31599
|
+
const areAllNewBordersUndefined = !cmd.border?.bottom && !cmd.border?.left && !cmd.border?.right && !cmd.border?.top;
|
|
31600
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
31601
|
+
return 97 /* CommandResult.NoChanges */;
|
|
31602
|
+
}
|
|
31603
|
+
return 0 /* CommandResult.Success */;
|
|
31604
|
+
}
|
|
31589
31605
|
// ---------------------------------------------------------------------------
|
|
31590
31606
|
// Import/Export
|
|
31591
31607
|
// ---------------------------------------------------------------------------
|
|
@@ -31693,8 +31709,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31693
31709
|
allowDispatch(cmd) {
|
|
31694
31710
|
switch (cmd.type) {
|
|
31695
31711
|
case "UPDATE_CELL":
|
|
31712
|
+
return this.checkCellOutOfSheet(cmd);
|
|
31696
31713
|
case "CLEAR_CELL":
|
|
31697
|
-
return this.
|
|
31714
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
31698
31715
|
default:
|
|
31699
31716
|
return 0 /* CommandResult.Success */;
|
|
31700
31717
|
}
|
|
@@ -31853,14 +31870,9 @@ class CellPlugin extends CorePlugin {
|
|
|
31853
31870
|
*/
|
|
31854
31871
|
getCellById(cellId) {
|
|
31855
31872
|
// this must be as fast as possible
|
|
31856
|
-
|
|
31857
|
-
|
|
31858
|
-
|
|
31859
|
-
if (cell) {
|
|
31860
|
-
return cell;
|
|
31861
|
-
}
|
|
31862
|
-
}
|
|
31863
|
-
return undefined;
|
|
31873
|
+
const position = this.getters.getCellPosition(cellId);
|
|
31874
|
+
const sheet = this.cells[position.sheetId];
|
|
31875
|
+
return sheet[cellId];
|
|
31864
31876
|
}
|
|
31865
31877
|
/*
|
|
31866
31878
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -32086,13 +32098,23 @@ class CellPlugin extends CorePlugin {
|
|
|
32086
32098
|
dependencies: [],
|
|
32087
32099
|
};
|
|
32088
32100
|
}
|
|
32089
|
-
checkCellOutOfSheet(
|
|
32101
|
+
checkCellOutOfSheet(cmd) {
|
|
32102
|
+
const { sheetId, col, row } = cmd;
|
|
32090
32103
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
32091
32104
|
if (!sheet)
|
|
32092
32105
|
return 28 /* CommandResult.InvalidSheetId */;
|
|
32093
32106
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
32094
32107
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 19 /* CommandResult.TargetOutOfSheet */;
|
|
32095
32108
|
}
|
|
32109
|
+
checkUselessClearCell(cmd) {
|
|
32110
|
+
const cell = this.getters.getCell(cmd);
|
|
32111
|
+
if (!cell)
|
|
32112
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32113
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
32114
|
+
return 97 /* CommandResult.NoChanges */;
|
|
32115
|
+
}
|
|
32116
|
+
return 0 /* CommandResult.Success */;
|
|
32117
|
+
}
|
|
32096
32118
|
}
|
|
32097
32119
|
class FormulaCellWithDependencies {
|
|
32098
32120
|
id;
|
|
@@ -33073,6 +33095,13 @@ class FiltersPlugin extends CorePlugin {
|
|
|
33073
33095
|
}
|
|
33074
33096
|
onDeleteColumnsRows(cmd) {
|
|
33075
33097
|
for (const table of this.getFilterTables(cmd.sheetId)) {
|
|
33098
|
+
// Remove the filter tables whose data filter headers are in the removed rows.
|
|
33099
|
+
if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
|
|
33100
|
+
const tables = { ...this.tables[cmd.sheetId] };
|
|
33101
|
+
delete tables[table.id];
|
|
33102
|
+
this.history.update("tables", cmd.sheetId, tables);
|
|
33103
|
+
continue;
|
|
33104
|
+
}
|
|
33076
33105
|
const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
|
|
33077
33106
|
if (!zone) {
|
|
33078
33107
|
const tables = { ...this.tables[cmd.sheetId] };
|
|
@@ -35154,10 +35183,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
35154
35183
|
// begin with the end.
|
|
35155
35184
|
rows.sort((a, b) => b - a);
|
|
35156
35185
|
for (let group of groupConsecutive(rows)) {
|
|
35186
|
+
// indexes are sorted in the descending order
|
|
35187
|
+
const from = group[group.length - 1];
|
|
35188
|
+
const to = group[0];
|
|
35157
35189
|
// Move the cells.
|
|
35158
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
35159
|
-
// Effectively delete the
|
|
35160
|
-
|
|
35190
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
35191
|
+
// Effectively delete the rows
|
|
35192
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
35161
35193
|
}
|
|
35162
35194
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
35163
35195
|
if (count) {
|
|
@@ -35179,8 +35211,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
35179
35211
|
this.addEmptyRows(sheet, quantity);
|
|
35180
35212
|
// Move the cells.
|
|
35181
35213
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
35182
|
-
// Recompute the left-right/top-bottom.
|
|
35183
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
35184
35214
|
if (index < sheet.panes.ySplit) {
|
|
35185
35215
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
35186
35216
|
}
|
|
@@ -35281,35 +35311,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
35281
35311
|
}
|
|
35282
35312
|
}
|
|
35283
35313
|
}
|
|
35284
|
-
updateRowsStructureOnDeletion(
|
|
35314
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
35285
35315
|
const rows = [];
|
|
35286
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35316
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
35287
35317
|
for (let i in sheet.rows) {
|
|
35288
|
-
|
|
35318
|
+
const row = Number(i);
|
|
35319
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
35289
35320
|
continue;
|
|
35290
35321
|
}
|
|
35291
35322
|
rows.push({
|
|
35292
|
-
cells: cellsQueue.
|
|
35323
|
+
cells: cellsQueue.pop(),
|
|
35293
35324
|
});
|
|
35294
35325
|
}
|
|
35295
35326
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35296
35327
|
}
|
|
35297
|
-
/**
|
|
35298
|
-
* Update the rows of the sheet after an addition:
|
|
35299
|
-
* - Rename the rows
|
|
35300
|
-
*
|
|
35301
|
-
* @param sheet Sheet on which the deletion occurs
|
|
35302
|
-
* @param addedRow Index of the added row
|
|
35303
|
-
* @param rowsToAdd Number of the rows to add
|
|
35304
|
-
*/
|
|
35305
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
35306
|
-
const rows = [];
|
|
35307
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
35308
|
-
sheet.rows.forEach(() => rows.push({
|
|
35309
|
-
cells: cellsQueue.shift(),
|
|
35310
|
-
}));
|
|
35311
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
35312
|
-
}
|
|
35313
35328
|
/**
|
|
35314
35329
|
* Add empty rows at the end of the rows
|
|
35315
35330
|
*
|
|
@@ -35425,6 +35440,7 @@ class CompilationParametersBuilder {
|
|
|
35425
35440
|
getters;
|
|
35426
35441
|
computeCell;
|
|
35427
35442
|
evalContext;
|
|
35443
|
+
rangeCache = {};
|
|
35428
35444
|
constructor(context, getters, computeCell) {
|
|
35429
35445
|
this.getters = getters;
|
|
35430
35446
|
this.computeCell = computeCell;
|
|
@@ -35510,25 +35526,32 @@ class CompilationParametersBuilder {
|
|
|
35510
35526
|
if (!_zone) {
|
|
35511
35527
|
return { value: [[]], format: [[]] };
|
|
35512
35528
|
}
|
|
35529
|
+
const { top, left, bottom, right } = zone;
|
|
35530
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
35531
|
+
if (cacheKey in this.rangeCache) {
|
|
35532
|
+
return this.rangeCache[cacheKey];
|
|
35533
|
+
}
|
|
35513
35534
|
const height = _zone.bottom - _zone.top + 1;
|
|
35514
35535
|
const width = _zone.right - _zone.left + 1;
|
|
35515
|
-
const value = Array
|
|
35516
|
-
const format = Array
|
|
35536
|
+
const value = new Array(width);
|
|
35537
|
+
const format = new Array(width);
|
|
35517
35538
|
// Performance issue: nested loop is faster than a map here
|
|
35518
35539
|
for (let col = _zone.left; col <= _zone.right; col++) {
|
|
35540
|
+
const colIndex = col - _zone.left;
|
|
35541
|
+
value[colIndex] = new Array(height);
|
|
35542
|
+
format[colIndex] = new Array(height);
|
|
35519
35543
|
for (let row = _zone.top; row <= _zone.bottom; row++) {
|
|
35520
|
-
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId
|
|
35521
|
-
|
|
35522
|
-
|
|
35523
|
-
|
|
35524
|
-
|
|
35525
|
-
if (evaluatedCell.format !== undefined) {
|
|
35526
|
-
format[colIndex][rowIndex] = evaluatedCell.format;
|
|
35527
|
-
}
|
|
35544
|
+
const evaluatedCell = this.getEvaluatedCellIfNotEmpty({ sheetId, col, row });
|
|
35545
|
+
const rowIndex = row - _zone.top;
|
|
35546
|
+
value[colIndex][rowIndex] = evaluatedCell?.value;
|
|
35547
|
+
if (evaluatedCell?.format !== undefined) {
|
|
35548
|
+
format[colIndex][rowIndex] = evaluatedCell.format;
|
|
35528
35549
|
}
|
|
35529
35550
|
}
|
|
35530
35551
|
}
|
|
35531
|
-
|
|
35552
|
+
const result = { value, format };
|
|
35553
|
+
this.rangeCache[cacheKey] = result;
|
|
35554
|
+
return result;
|
|
35532
35555
|
}
|
|
35533
35556
|
}
|
|
35534
35557
|
|
|
@@ -35726,6 +35749,7 @@ class Evaluator {
|
|
|
35726
35749
|
this.formulaDependencies().addDependencies(positionId, dependencies);
|
|
35727
35750
|
}
|
|
35728
35751
|
updateCompilationParameters() {
|
|
35752
|
+
// rebuild the compilation parameters (with a clean cache)
|
|
35729
35753
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
35730
35754
|
}
|
|
35731
35755
|
evaluateCells(positions) {
|
|
@@ -35769,6 +35793,15 @@ class Evaluator {
|
|
|
35769
35793
|
this.evaluatedCells = new Map();
|
|
35770
35794
|
this.evaluate(this.getAllCells());
|
|
35771
35795
|
}
|
|
35796
|
+
evaluateFormula(sheetId, formulaString) {
|
|
35797
|
+
const compiledFormula = compile(formulaString);
|
|
35798
|
+
const ranges = [];
|
|
35799
|
+
for (let xc of compiledFormula.dependencies) {
|
|
35800
|
+
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
35801
|
+
}
|
|
35802
|
+
this.updateCompilationParameters();
|
|
35803
|
+
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
35804
|
+
}
|
|
35772
35805
|
getAllCells() {
|
|
35773
35806
|
const positionIds = new JetSet();
|
|
35774
35807
|
for (const sheetId of this.getters.getSheetIds()) {
|
|
@@ -35795,6 +35828,7 @@ class Evaluator {
|
|
|
35795
35828
|
this.nextPositionsToUpdate = cells;
|
|
35796
35829
|
let currentIteration = 0;
|
|
35797
35830
|
while (this.nextPositionsToUpdate.size && currentIteration++ < MAX_ITERATION) {
|
|
35831
|
+
this.updateCompilationParameters();
|
|
35798
35832
|
const positionIds = Array.from(this.nextPositionsToUpdate);
|
|
35799
35833
|
this.nextPositionsToUpdate.clear();
|
|
35800
35834
|
for (let i = 0; i < positionIds.length; ++i) {
|
|
@@ -36179,7 +36213,6 @@ class PositionBitsEncoder {
|
|
|
36179
36213
|
// of other cells depending on it, at the next iteration.
|
|
36180
36214
|
//#endregion
|
|
36181
36215
|
class EvaluationPlugin extends UIPlugin {
|
|
36182
|
-
config;
|
|
36183
36216
|
static getters = [
|
|
36184
36217
|
"evaluateFormula",
|
|
36185
36218
|
"getRangeFormattedValues",
|
|
@@ -36191,12 +36224,9 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36191
36224
|
];
|
|
36192
36225
|
shouldRebuildDependenciesGraph = true;
|
|
36193
36226
|
evaluator;
|
|
36194
|
-
compilationParams;
|
|
36195
36227
|
positionsToUpdate = [];
|
|
36196
36228
|
constructor(config) {
|
|
36197
36229
|
super(config);
|
|
36198
|
-
this.config = config;
|
|
36199
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36200
36230
|
this.evaluator = new Evaluator(config.custom, this.getters);
|
|
36201
36231
|
}
|
|
36202
36232
|
// ---------------------------------------------------------------------------
|
|
@@ -36221,10 +36251,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36221
36251
|
case "EVALUATE_CELLS":
|
|
36222
36252
|
this.evaluator.evaluateAllCells();
|
|
36223
36253
|
break;
|
|
36224
|
-
case "UPDATE_LOCALE":
|
|
36225
|
-
this.compilationParams = this.getCompilationParameters();
|
|
36226
|
-
this.evaluator.updateCompilationParameters();
|
|
36227
|
-
break;
|
|
36228
36254
|
}
|
|
36229
36255
|
}
|
|
36230
36256
|
finalize() {
|
|
@@ -36242,12 +36268,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36242
36268
|
// Getters
|
|
36243
36269
|
// ---------------------------------------------------------------------------
|
|
36244
36270
|
evaluateFormula(sheetId, formulaString) {
|
|
36245
|
-
|
|
36246
|
-
const ranges = [];
|
|
36247
|
-
for (let xc of compiledFormula.dependencies) {
|
|
36248
|
-
ranges.push(this.getters.getRangeFromSheetXC(sheetId, xc));
|
|
36249
|
-
}
|
|
36250
|
-
return compiledFormula.execute(ranges, ...this.compilationParams).value;
|
|
36271
|
+
return this.evaluator.evaluateFormula(sheetId, formulaString);
|
|
36251
36272
|
}
|
|
36252
36273
|
/**
|
|
36253
36274
|
* Return the value of each cell in the range as they are displayed in the grid.
|
|
@@ -36346,9 +36367,6 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
36346
36367
|
}
|
|
36347
36368
|
return undefined;
|
|
36348
36369
|
}
|
|
36349
|
-
getCompilationParameters() {
|
|
36350
|
-
return buildCompilationParameters(this.config.custom, this.getters, (position) => this.evaluator.getEvaluatedCell(position));
|
|
36351
|
-
}
|
|
36352
36370
|
}
|
|
36353
36371
|
function isBadExpression(formula) {
|
|
36354
36372
|
try {
|
|
@@ -36521,22 +36539,20 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
36521
36539
|
invalidateCFEvaluationCommands.has(cmd.type) ||
|
|
36522
36540
|
cmd.type === "EVALUATE_CELLS" ||
|
|
36523
36541
|
cmd.type === "UPDATE_CELL") {
|
|
36524
|
-
|
|
36525
|
-
|
|
36526
|
-
this.history.update("charts", chartId, undefined);
|
|
36527
|
-
}
|
|
36542
|
+
for (const chartId in this.charts) {
|
|
36543
|
+
this.charts[chartId] = undefined;
|
|
36528
36544
|
}
|
|
36529
36545
|
}
|
|
36530
36546
|
switch (cmd.type) {
|
|
36531
36547
|
case "UPDATE_CHART":
|
|
36532
36548
|
case "CREATE_CHART":
|
|
36533
36549
|
case "DELETE_FIGURE":
|
|
36534
|
-
this.
|
|
36550
|
+
this.charts[cmd.id] = undefined;
|
|
36535
36551
|
break;
|
|
36536
36552
|
case "DELETE_SHEET":
|
|
36537
36553
|
for (let chartId in this.charts) {
|
|
36538
36554
|
if (!this.getters.isChartDefined(chartId)) {
|
|
36539
|
-
this.
|
|
36555
|
+
this.charts[chartId] = undefined;
|
|
36540
36556
|
}
|
|
36541
36557
|
}
|
|
36542
36558
|
break;
|
|
@@ -36548,7 +36564,7 @@ class EvaluationChartPlugin extends UIPlugin {
|
|
|
36548
36564
|
if (!chart) {
|
|
36549
36565
|
throw new Error(`No chart for the given id: ${figureId}`);
|
|
36550
36566
|
}
|
|
36551
|
-
this.
|
|
36567
|
+
this.charts[figureId] = this.createRuntimeChart(chart);
|
|
36552
36568
|
}
|
|
36553
36569
|
return this.charts[figureId];
|
|
36554
36570
|
}
|
|
@@ -42067,8 +42083,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
42067
42083
|
this.lastPasteState = this.state;
|
|
42068
42084
|
if (this.paintFormatStatus === "oneOff") {
|
|
42069
42085
|
this.paintFormatStatus = "inactive";
|
|
42070
|
-
this.status = "invisible";
|
|
42071
42086
|
}
|
|
42087
|
+
this.status = "invisible";
|
|
42072
42088
|
break;
|
|
42073
42089
|
case "CLEAN_CLIPBOARD_HIGHLIGHT":
|
|
42074
42090
|
this.status = "invisible";
|
|
@@ -43012,6 +43028,8 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
43012
43028
|
case "EVALUATE_CELLS":
|
|
43013
43029
|
case "ACTIVATE_SHEET":
|
|
43014
43030
|
case "REMOVE_FILTER_TABLE":
|
|
43031
|
+
case "ADD_COLUMNS_ROWS":
|
|
43032
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
43015
43033
|
this.isEvaluationDirty = true;
|
|
43016
43034
|
break;
|
|
43017
43035
|
case "START":
|
|
@@ -47883,9 +47901,9 @@ function revertChanges(revisions) {
|
|
|
47883
47901
|
* Apply the changes of the given HistoryChange to the state
|
|
47884
47902
|
*/
|
|
47885
47903
|
function applyChange(change, target) {
|
|
47886
|
-
let val = change.
|
|
47887
|
-
|
|
47888
|
-
for (let pathIndex =
|
|
47904
|
+
let val = change.path[0];
|
|
47905
|
+
const key = change.path[change.path.length - 1];
|
|
47906
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
47889
47907
|
const p = change.path[pathIndex];
|
|
47890
47908
|
if (val[p] === undefined) {
|
|
47891
47909
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -48566,13 +48584,14 @@ class StateObserver {
|
|
|
48566
48584
|
}
|
|
48567
48585
|
addChange(...args) {
|
|
48568
48586
|
const val = args.pop();
|
|
48569
|
-
const
|
|
48587
|
+
const root = args[0];
|
|
48570
48588
|
let value = root;
|
|
48571
|
-
let key =
|
|
48572
|
-
|
|
48573
|
-
|
|
48589
|
+
let key = args[args.length - 1];
|
|
48590
|
+
const pathLength = args.length - 2;
|
|
48591
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
48592
|
+
const p = args[pathIndex];
|
|
48574
48593
|
if (value[p] === undefined) {
|
|
48575
|
-
const nextPath =
|
|
48594
|
+
const nextPath = args[pathIndex + 1];
|
|
48576
48595
|
value[p] = createEmptyStructure(nextPath);
|
|
48577
48596
|
}
|
|
48578
48597
|
value = value[p];
|
|
@@ -48581,8 +48600,7 @@ class StateObserver {
|
|
|
48581
48600
|
return;
|
|
48582
48601
|
}
|
|
48583
48602
|
this.changes.push({
|
|
48584
|
-
|
|
48585
|
-
path,
|
|
48603
|
+
path: args,
|
|
48586
48604
|
before: value[key],
|
|
48587
48605
|
after: val,
|
|
48588
48606
|
});
|
|
@@ -50432,19 +50450,22 @@ class Model extends EventBus {
|
|
|
50432
50450
|
* Check if the given command is allowed by all the plugins and the history.
|
|
50433
50451
|
*/
|
|
50434
50452
|
checkDispatchAllowed(command) {
|
|
50435
|
-
|
|
50436
|
-
|
|
50453
|
+
const results = isCoreCommand(command)
|
|
50454
|
+
? this.checkDispatchAllowedCoreCommand(command)
|
|
50455
|
+
: this.checkDispatchAllowedLocalCommand(command);
|
|
50456
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
50457
|
+
return new DispatchResult(results.flat());
|
|
50437
50458
|
}
|
|
50438
|
-
return
|
|
50459
|
+
return DispatchResult.Success;
|
|
50439
50460
|
}
|
|
50440
50461
|
checkDispatchAllowedCoreCommand(command) {
|
|
50441
50462
|
const results = this.corePlugins.map((handler) => handler.allowDispatch(command));
|
|
50442
50463
|
results.push(this.range.allowDispatch(command));
|
|
50443
|
-
return
|
|
50464
|
+
return results;
|
|
50444
50465
|
}
|
|
50445
50466
|
checkDispatchAllowedLocalCommand(command) {
|
|
50446
50467
|
const results = this.uiHandlers.map((handler) => handler.allowDispatch(command));
|
|
50447
|
-
return
|
|
50468
|
+
return results;
|
|
50448
50469
|
}
|
|
50449
50470
|
finalize() {
|
|
50450
50471
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -50736,6 +50757,6 @@ const constants = {
|
|
|
50736
50757
|
export { AbstractChart, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, tokenize };
|
|
50737
50758
|
|
|
50738
50759
|
|
|
50739
|
-
__info__.version = '16.4.
|
|
50740
|
-
__info__.date = '2023-11-
|
|
50741
|
-
__info__.hash = '
|
|
50760
|
+
__info__.version = '16.4.15';
|
|
50761
|
+
__info__.date = '2023-11-24T13:12:26.608Z';
|
|
50762
|
+
__info__.hash = '141943d';
|