@odoo/o-spreadsheet 16.2.21 → 16.2.23
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 +106 -69
- package/dist/o-spreadsheet.d.ts +9 -15
- package/dist/o-spreadsheet.esm.js +106 -69
- package/dist/o-spreadsheet.iife.js +106 -69
- package/dist/o-spreadsheet.iife.min.js +65 -65
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -603,13 +603,6 @@ function getYearFrac(startDate, endDate, _dayCountConvention) {
|
|
|
603
603
|
}
|
|
604
604
|
|
|
605
605
|
//------------------------------------------------------------------------------
|
|
606
|
-
/**
|
|
607
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
608
|
-
* is ordered.
|
|
609
|
-
*/
|
|
610
|
-
function stringify(obj) {
|
|
611
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
612
|
-
}
|
|
613
606
|
/**
|
|
614
607
|
* Remove quotes from a quoted string
|
|
615
608
|
* ```js
|
|
@@ -909,7 +902,7 @@ function isObjectEmptyRecursive(argument) {
|
|
|
909
902
|
*/
|
|
910
903
|
function getItemId(item, itemsDic) {
|
|
911
904
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
912
|
-
if (
|
|
905
|
+
if (deepEquals(value, item)) {
|
|
913
906
|
return parseInt(key, 10);
|
|
914
907
|
}
|
|
915
908
|
}
|
|
@@ -975,6 +968,22 @@ function lazy(fn) {
|
|
|
975
968
|
lazyValue.map = (callback) => lazy(() => callback(lazyValue()));
|
|
976
969
|
return lazyValue;
|
|
977
970
|
}
|
|
971
|
+
/**
|
|
972
|
+
* Creates a version of the function that's memoized on the value of its first
|
|
973
|
+
* argument, if any.
|
|
974
|
+
*/
|
|
975
|
+
function memoize(func) {
|
|
976
|
+
const cache = new Map();
|
|
977
|
+
const funcName = func.name ? func.name + " (memoized)" : "memoized";
|
|
978
|
+
return {
|
|
979
|
+
[funcName](...args) {
|
|
980
|
+
if (!cache.has(args[0])) {
|
|
981
|
+
cache.set(args[0], func(...args));
|
|
982
|
+
}
|
|
983
|
+
return cache.get(args[0]);
|
|
984
|
+
},
|
|
985
|
+
}[funcName];
|
|
986
|
+
}
|
|
978
987
|
/**
|
|
979
988
|
* Find the next defined value after the given index in an array of strings. If there is no defined value
|
|
980
989
|
* after the index, return the closest defined value before the index. Return an empty string if no
|
|
@@ -3572,12 +3581,12 @@ function toString(value) {
|
|
|
3572
3581
|
}
|
|
3573
3582
|
}
|
|
3574
3583
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
3575
|
-
function normalizeString(str) {
|
|
3584
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
3576
3585
|
return str
|
|
3577
3586
|
.toLowerCase()
|
|
3578
3587
|
.normalize("NFD")
|
|
3579
3588
|
.replace(/[\u0300-\u036f]/g, "");
|
|
3580
|
-
}
|
|
3589
|
+
});
|
|
3581
3590
|
/**
|
|
3582
3591
|
* Normalize a value.
|
|
3583
3592
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -4301,6 +4310,7 @@ var CommandResult;
|
|
|
4301
4310
|
CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
|
|
4302
4311
|
CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
|
|
4303
4312
|
CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
|
|
4313
|
+
CommandResult[CommandResult["NoChanges"] = 88] = "NoChanges";
|
|
4304
4314
|
})(CommandResult || (CommandResult = {}));
|
|
4305
4315
|
|
|
4306
4316
|
function isMatrix(x) {
|
|
@@ -18732,7 +18742,7 @@ css /* scss */ `
|
|
|
18732
18742
|
}
|
|
18733
18743
|
.o-input-count {
|
|
18734
18744
|
width: fit-content;
|
|
18735
|
-
padding:
|
|
18745
|
+
padding: 4px 0 4px 4px;
|
|
18736
18746
|
}
|
|
18737
18747
|
}
|
|
18738
18748
|
}
|
|
@@ -27516,6 +27526,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
27516
27526
|
// ---------------------------------------------------------------------------
|
|
27517
27527
|
// Command Handling
|
|
27518
27528
|
// ---------------------------------------------------------------------------
|
|
27529
|
+
allowDispatch(cmd) {
|
|
27530
|
+
switch (cmd.type) {
|
|
27531
|
+
case "SET_BORDER":
|
|
27532
|
+
return this.checkBordersUnchanged(cmd);
|
|
27533
|
+
default:
|
|
27534
|
+
return 0 /* CommandResult.Success */;
|
|
27535
|
+
}
|
|
27536
|
+
}
|
|
27519
27537
|
handle(cmd) {
|
|
27520
27538
|
switch (cmd.type) {
|
|
27521
27539
|
case "ADD_MERGE":
|
|
@@ -27911,6 +27929,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
27911
27929
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right");
|
|
27912
27930
|
}
|
|
27913
27931
|
}
|
|
27932
|
+
checkBordersUnchanged(cmd) {
|
|
27933
|
+
var _a, _b, _c, _d;
|
|
27934
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
27935
|
+
const areAllNewBordersUndefined = !((_a = cmd.border) === null || _a === void 0 ? void 0 : _a.bottom) && !((_b = cmd.border) === null || _b === void 0 ? void 0 : _b.left) && !((_c = cmd.border) === null || _c === void 0 ? void 0 : _c.right) && !((_d = cmd.border) === null || _d === void 0 ? void 0 : _d.top);
|
|
27936
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
27937
|
+
return 88 /* CommandResult.NoChanges */;
|
|
27938
|
+
}
|
|
27939
|
+
return 0 /* CommandResult.Success */;
|
|
27940
|
+
}
|
|
27914
27941
|
// ---------------------------------------------------------------------------
|
|
27915
27942
|
// Import/Export
|
|
27916
27943
|
// ---------------------------------------------------------------------------
|
|
@@ -27946,7 +27973,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
27946
27973
|
*/
|
|
27947
27974
|
function getBorderId(border) {
|
|
27948
27975
|
for (let [key, value] of Object.entries(borders)) {
|
|
27949
|
-
if (
|
|
27976
|
+
if (deepEquals(value, border)) {
|
|
27950
27977
|
return parseInt(key, 10);
|
|
27951
27978
|
}
|
|
27952
27979
|
}
|
|
@@ -28013,8 +28040,9 @@ class CellPlugin extends CorePlugin {
|
|
|
28013
28040
|
allowDispatch(cmd) {
|
|
28014
28041
|
switch (cmd.type) {
|
|
28015
28042
|
case "UPDATE_CELL":
|
|
28043
|
+
return this.checkCellOutOfSheet(cmd);
|
|
28016
28044
|
case "CLEAR_CELL":
|
|
28017
|
-
return this.
|
|
28045
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
28018
28046
|
default:
|
|
28019
28047
|
return 0 /* CommandResult.Success */;
|
|
28020
28048
|
}
|
|
@@ -28173,14 +28201,9 @@ class CellPlugin extends CorePlugin {
|
|
|
28173
28201
|
*/
|
|
28174
28202
|
getCellById(cellId) {
|
|
28175
28203
|
// this must be as fast as possible
|
|
28176
|
-
|
|
28177
|
-
|
|
28178
|
-
|
|
28179
|
-
if (cell) {
|
|
28180
|
-
return cell;
|
|
28181
|
-
}
|
|
28182
|
-
}
|
|
28183
|
-
return undefined;
|
|
28204
|
+
const position = this.getters.getCellPosition(cellId);
|
|
28205
|
+
const sheet = this.cells[position.sheetId];
|
|
28206
|
+
return sheet[cellId];
|
|
28184
28207
|
}
|
|
28185
28208
|
/*
|
|
28186
28209
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -28418,13 +28441,23 @@ class CellPlugin extends CorePlugin {
|
|
|
28418
28441
|
dependencies: [],
|
|
28419
28442
|
};
|
|
28420
28443
|
}
|
|
28421
|
-
checkCellOutOfSheet(
|
|
28444
|
+
checkCellOutOfSheet(cmd) {
|
|
28445
|
+
const { sheetId, col, row } = cmd;
|
|
28422
28446
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
28423
28447
|
if (!sheet)
|
|
28424
28448
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
28425
28449
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
28426
28450
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
|
|
28427
28451
|
}
|
|
28452
|
+
checkUselessClearCell(cmd) {
|
|
28453
|
+
const cell = this.getters.getCell(cmd);
|
|
28454
|
+
if (!cell)
|
|
28455
|
+
return 88 /* CommandResult.NoChanges */;
|
|
28456
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
28457
|
+
return 88 /* CommandResult.NoChanges */;
|
|
28458
|
+
}
|
|
28459
|
+
return 0 /* CommandResult.Success */;
|
|
28460
|
+
}
|
|
28428
28461
|
}
|
|
28429
28462
|
CellPlugin.getters = [
|
|
28430
28463
|
"zoneToXC",
|
|
@@ -29327,6 +29360,13 @@ class FiltersPlugin extends CorePlugin {
|
|
|
29327
29360
|
}
|
|
29328
29361
|
onDeleteColumnsRows(cmd) {
|
|
29329
29362
|
for (const table of this.getFilterTables(cmd.sheetId)) {
|
|
29363
|
+
// Remove the filter tables whose data filter headers are in the removed rows.
|
|
29364
|
+
if (cmd.dimension === "ROW" && cmd.elements.includes(table.zone.top)) {
|
|
29365
|
+
const tables = { ...this.tables[cmd.sheetId] };
|
|
29366
|
+
delete tables[table.id];
|
|
29367
|
+
this.history.update("tables", cmd.sheetId, tables);
|
|
29368
|
+
continue;
|
|
29369
|
+
}
|
|
29330
29370
|
const zone = reduceZoneOnDeletion(table.zone, cmd.dimension === "COL" ? "left" : "top", cmd.elements);
|
|
29331
29371
|
if (!zone) {
|
|
29332
29372
|
const tables = { ...this.tables[cmd.sheetId] };
|
|
@@ -31483,10 +31523,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
31483
31523
|
// begin with the end.
|
|
31484
31524
|
rows.sort((a, b) => b - a);
|
|
31485
31525
|
for (let group of groupConsecutive(rows)) {
|
|
31526
|
+
// indexes are sorted in the descending order
|
|
31527
|
+
const from = group[group.length - 1];
|
|
31528
|
+
const to = group[0];
|
|
31486
31529
|
// Move the cells.
|
|
31487
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
31488
|
-
// Effectively delete the
|
|
31489
|
-
|
|
31530
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
31531
|
+
// Effectively delete the rows
|
|
31532
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
31490
31533
|
}
|
|
31491
31534
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
31492
31535
|
if (count) {
|
|
@@ -31508,8 +31551,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
31508
31551
|
this.addEmptyRows(sheet, quantity);
|
|
31509
31552
|
// Move the cells.
|
|
31510
31553
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
31511
|
-
// Recompute the left-right/top-bottom.
|
|
31512
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
31513
31554
|
if (index < sheet.panes.ySplit) {
|
|
31514
31555
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
31515
31556
|
}
|
|
@@ -31610,35 +31651,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
31610
31651
|
}
|
|
31611
31652
|
}
|
|
31612
31653
|
}
|
|
31613
|
-
updateRowsStructureOnDeletion(
|
|
31654
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
31614
31655
|
const rows = [];
|
|
31615
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
31656
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
31616
31657
|
for (let i in sheet.rows) {
|
|
31617
|
-
|
|
31658
|
+
const row = Number(i);
|
|
31659
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
31618
31660
|
continue;
|
|
31619
31661
|
}
|
|
31620
31662
|
rows.push({
|
|
31621
|
-
cells: cellsQueue.
|
|
31663
|
+
cells: cellsQueue.pop(),
|
|
31622
31664
|
});
|
|
31623
31665
|
}
|
|
31624
31666
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
31625
31667
|
}
|
|
31626
|
-
/**
|
|
31627
|
-
* Update the rows of the sheet after an addition:
|
|
31628
|
-
* - Rename the rows
|
|
31629
|
-
*
|
|
31630
|
-
* @param sheet Sheet on which the deletion occurs
|
|
31631
|
-
* @param addedRow Index of the added row
|
|
31632
|
-
* @param rowsToAdd Number of the rows to add
|
|
31633
|
-
*/
|
|
31634
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
31635
|
-
const rows = [];
|
|
31636
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
31637
|
-
sheet.rows.forEach(() => rows.push({
|
|
31638
|
-
cells: cellsQueue.shift(),
|
|
31639
|
-
}));
|
|
31640
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
31641
|
-
}
|
|
31642
31668
|
/**
|
|
31643
31669
|
* Add empty rows at the end of the rows
|
|
31644
31670
|
*
|
|
@@ -32122,6 +32148,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32122
32148
|
}
|
|
32123
32149
|
return evaluatedCell;
|
|
32124
32150
|
};
|
|
32151
|
+
const rangeCache = {};
|
|
32125
32152
|
/**
|
|
32126
32153
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
32127
32154
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -32138,21 +32165,26 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32138
32165
|
// Performance issue: Avoid fetching data on positions that are out of the spreadsheet
|
|
32139
32166
|
// e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
|
|
32140
32167
|
const sheetZone = getters.getSheetZone(sheetId);
|
|
32141
|
-
const result = [];
|
|
32142
32168
|
const zone = intersection(range.zone, sheetZone);
|
|
32143
32169
|
if (!zone) {
|
|
32144
|
-
|
|
32145
|
-
|
|
32170
|
+
return [[]];
|
|
32171
|
+
}
|
|
32172
|
+
const { top, left, bottom, right } = zone;
|
|
32173
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
32174
|
+
if (cacheKey in rangeCache) {
|
|
32175
|
+
return rangeCache[cacheKey];
|
|
32146
32176
|
}
|
|
32177
|
+
const result = new Array(right - left + 1);
|
|
32147
32178
|
// Performance issue: nested loop is faster than a map here
|
|
32148
|
-
for (let col =
|
|
32149
|
-
const rowValues =
|
|
32150
|
-
for (let row =
|
|
32179
|
+
for (let col = left; col <= right; col++) {
|
|
32180
|
+
const rowValues = new Array(bottom - top + 1);
|
|
32181
|
+
for (let row = top; row <= bottom; row++) {
|
|
32151
32182
|
const cell = evalContext.getters.getCell({ sheetId: range.sheetId, col, row });
|
|
32152
|
-
rowValues
|
|
32183
|
+
rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
|
|
32153
32184
|
}
|
|
32154
|
-
result
|
|
32185
|
+
result[col - left] = rowValues;
|
|
32155
32186
|
}
|
|
32187
|
+
rangeCache[cacheKey] = result;
|
|
32156
32188
|
return result;
|
|
32157
32189
|
}
|
|
32158
32190
|
/**
|
|
@@ -32699,6 +32731,8 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
32699
32731
|
case "EVALUATE_CELLS":
|
|
32700
32732
|
case "ACTIVATE_SHEET":
|
|
32701
32733
|
case "REMOVE_FILTER_TABLE":
|
|
32734
|
+
case "ADD_COLUMNS_ROWS":
|
|
32735
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
32702
32736
|
this.isEvaluationDirty = true;
|
|
32703
32737
|
break;
|
|
32704
32738
|
case "START":
|
|
@@ -42677,9 +42711,9 @@ function revertChanges(revisions) {
|
|
|
42677
42711
|
* Apply the changes of the given HistoryChange to the state
|
|
42678
42712
|
*/
|
|
42679
42713
|
function applyChange(change, target) {
|
|
42680
|
-
let val = change.
|
|
42681
|
-
|
|
42682
|
-
for (let pathIndex =
|
|
42714
|
+
let val = change.path[0];
|
|
42715
|
+
const key = change.path[change.path.length - 1];
|
|
42716
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
42683
42717
|
const p = change.path[pathIndex];
|
|
42684
42718
|
if (val[p] === undefined) {
|
|
42685
42719
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -43436,13 +43470,14 @@ class StateObserver {
|
|
|
43436
43470
|
}
|
|
43437
43471
|
addChange(...args) {
|
|
43438
43472
|
const val = args.pop();
|
|
43439
|
-
const
|
|
43473
|
+
const root = args[0];
|
|
43440
43474
|
let value = root;
|
|
43441
|
-
let key =
|
|
43442
|
-
|
|
43443
|
-
|
|
43475
|
+
let key = args[args.length - 1];
|
|
43476
|
+
const pathLength = args.length - 2;
|
|
43477
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
43478
|
+
const p = args[pathIndex];
|
|
43444
43479
|
if (value[p] === undefined) {
|
|
43445
|
-
const nextPath =
|
|
43480
|
+
const nextPath = args[pathIndex + 1];
|
|
43446
43481
|
value[p] = createEmptyStructure(nextPath);
|
|
43447
43482
|
}
|
|
43448
43483
|
value = value[p];
|
|
@@ -43451,8 +43486,7 @@ class StateObserver {
|
|
|
43451
43486
|
return;
|
|
43452
43487
|
}
|
|
43453
43488
|
this.changes.push({
|
|
43454
|
-
|
|
43455
|
-
path,
|
|
43489
|
+
path: args,
|
|
43456
43490
|
before: value[key],
|
|
43457
43491
|
after: val,
|
|
43458
43492
|
});
|
|
@@ -45304,7 +45338,10 @@ class Model extends EventBus {
|
|
|
45304
45338
|
*/
|
|
45305
45339
|
checkDispatchAllowed(command) {
|
|
45306
45340
|
const results = this.handlers.map((handler) => handler.allowDispatch(command));
|
|
45307
|
-
|
|
45341
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
45342
|
+
return new DispatchResult(results.flat());
|
|
45343
|
+
}
|
|
45344
|
+
return DispatchResult.Success;
|
|
45308
45345
|
}
|
|
45309
45346
|
finalize() {
|
|
45310
45347
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -45503,6 +45540,6 @@ function addFunction(functionName, functionDescription) {
|
|
|
45503
45540
|
export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
|
|
45504
45541
|
|
|
45505
45542
|
|
|
45506
|
-
__info__.version = '16.2.
|
|
45507
|
-
__info__.date = '2023-11-
|
|
45508
|
-
__info__.hash = '
|
|
45543
|
+
__info__.version = '16.2.23';
|
|
45544
|
+
__info__.date = '2023-11-24T13:11:02.651Z';
|
|
45545
|
+
__info__.hash = '3c723d3';
|