@odoo/o-spreadsheet 16.2.22 → 16.2.24
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 +141 -94
- package/dist/o-spreadsheet.d.ts +11 -15
- package/dist/o-spreadsheet.esm.js +141 -94
- package/dist/o-spreadsheet.iife.js +141 -94
- package/dist/o-spreadsheet.iife.min.js +243 -243
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -607,13 +607,6 @@ function getYearFrac(startDate, endDate, _dayCountConvention) {
|
|
|
607
607
|
}
|
|
608
608
|
|
|
609
609
|
//------------------------------------------------------------------------------
|
|
610
|
-
/**
|
|
611
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
612
|
-
* is ordered.
|
|
613
|
-
*/
|
|
614
|
-
function stringify(obj) {
|
|
615
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
616
|
-
}
|
|
617
610
|
/**
|
|
618
611
|
* Remove quotes from a quoted string
|
|
619
612
|
* ```js
|
|
@@ -913,7 +906,7 @@ function isObjectEmptyRecursive(argument) {
|
|
|
913
906
|
*/
|
|
914
907
|
function getItemId(item, itemsDic) {
|
|
915
908
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
916
|
-
if (
|
|
909
|
+
if (deepEquals(value, item)) {
|
|
917
910
|
return parseInt(key, 10);
|
|
918
911
|
}
|
|
919
912
|
}
|
|
@@ -979,6 +972,22 @@ function lazy(fn) {
|
|
|
979
972
|
lazyValue.map = (callback) => lazy(() => callback(lazyValue()));
|
|
980
973
|
return lazyValue;
|
|
981
974
|
}
|
|
975
|
+
/**
|
|
976
|
+
* Creates a version of the function that's memoized on the value of its first
|
|
977
|
+
* argument, if any.
|
|
978
|
+
*/
|
|
979
|
+
function memoize(func) {
|
|
980
|
+
const cache = new Map();
|
|
981
|
+
const funcName = func.name ? func.name + " (memoized)" : "memoized";
|
|
982
|
+
return {
|
|
983
|
+
[funcName](...args) {
|
|
984
|
+
if (!cache.has(args[0])) {
|
|
985
|
+
cache.set(args[0], func(...args));
|
|
986
|
+
}
|
|
987
|
+
return cache.get(args[0]);
|
|
988
|
+
},
|
|
989
|
+
}[funcName];
|
|
990
|
+
}
|
|
982
991
|
/**
|
|
983
992
|
* Find the next defined value after the given index in an array of strings. If there is no defined value
|
|
984
993
|
* after the index, return the closest defined value before the index. Return an empty string if no
|
|
@@ -1357,8 +1366,10 @@ function isSameColor(color1, color2) {
|
|
|
1357
1366
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
1358
1367
|
// Same as above, but matches the exact string (nothing before or after)
|
|
1359
1368
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
1360
|
-
/** Reference of a column header (eg. A, AB) */
|
|
1361
|
-
const colHeader = new RegExp(
|
|
1369
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
1370
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
1371
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
1372
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
1362
1373
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
1363
1374
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
1364
1375
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -1388,6 +1399,9 @@ function isRowReference(xc) {
|
|
|
1388
1399
|
function isColHeader(str) {
|
|
1389
1400
|
return colHeader.test(str);
|
|
1390
1401
|
}
|
|
1402
|
+
function isRowHeader(str) {
|
|
1403
|
+
return rowHeader.test(str);
|
|
1404
|
+
}
|
|
1391
1405
|
/**
|
|
1392
1406
|
* Return true if the given xc is the reference of a single cell,
|
|
1393
1407
|
* without any specified sheet (e.g. A1)
|
|
@@ -2177,18 +2191,10 @@ class RangeImpl {
|
|
|
2177
2191
|
if (isFullCol) {
|
|
2178
2192
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2179
2193
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2180
|
-
if (zone.left === zone.right) {
|
|
2181
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2182
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2183
|
-
}
|
|
2184
2194
|
}
|
|
2185
2195
|
if (isFullRow) {
|
|
2186
2196
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2187
2197
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2188
|
-
if (zone.top === zone.bottom) {
|
|
2189
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2190
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2191
|
-
}
|
|
2192
2198
|
}
|
|
2193
2199
|
return parts;
|
|
2194
2200
|
}
|
|
@@ -3576,12 +3582,12 @@ function toString(value) {
|
|
|
3576
3582
|
}
|
|
3577
3583
|
}
|
|
3578
3584
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
3579
|
-
function normalizeString(str) {
|
|
3585
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
3580
3586
|
return str
|
|
3581
3587
|
.toLowerCase()
|
|
3582
3588
|
.normalize("NFD")
|
|
3583
3589
|
.replace(/[\u0300-\u036f]/g, "");
|
|
3584
|
-
}
|
|
3590
|
+
});
|
|
3585
3591
|
/**
|
|
3586
3592
|
* Normalize a value.
|
|
3587
3593
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -4305,6 +4311,7 @@ exports.CommandResult = void 0;
|
|
|
4305
4311
|
CommandResult[CommandResult["ChartDoesNotExist"] = 85] = "ChartDoesNotExist";
|
|
4306
4312
|
CommandResult[CommandResult["InvalidHeaderIndex"] = 86] = "InvalidHeaderIndex";
|
|
4307
4313
|
CommandResult[CommandResult["InvalidQuantity"] = 87] = "InvalidQuantity";
|
|
4314
|
+
CommandResult[CommandResult["NoChanges"] = 88] = "NoChanges";
|
|
4308
4315
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
4309
4316
|
|
|
4310
4317
|
function isMatrix(x) {
|
|
@@ -5086,6 +5093,9 @@ function setElementScrollTop(el, scroll) {
|
|
|
5086
5093
|
}
|
|
5087
5094
|
function getOpenedMenus() {
|
|
5088
5095
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
5096
|
+
}
|
|
5097
|
+
function isMacOS() {
|
|
5098
|
+
return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
5089
5099
|
}
|
|
5090
5100
|
|
|
5091
5101
|
/**
|
|
@@ -21129,6 +21139,7 @@ class AbstractResizer extends owl.Component {
|
|
|
21129
21139
|
draggerShadowThickness: 0,
|
|
21130
21140
|
delta: 0,
|
|
21131
21141
|
base: 0,
|
|
21142
|
+
position: "before",
|
|
21132
21143
|
});
|
|
21133
21144
|
}
|
|
21134
21145
|
_computeHandleDisplay(ev) {
|
|
@@ -21254,11 +21265,13 @@ class AbstractResizer extends owl.Component {
|
|
|
21254
21265
|
this.state.draggerLinePosition = dimensions.start;
|
|
21255
21266
|
this.state.draggerShadowPosition = dimensions.start;
|
|
21256
21267
|
this.state.base = elementIndex;
|
|
21268
|
+
this.state.position = "before";
|
|
21257
21269
|
}
|
|
21258
21270
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
21259
21271
|
this.state.draggerLinePosition = dimensions.end;
|
|
21260
21272
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
21261
|
-
this.state.base = elementIndex
|
|
21273
|
+
this.state.base = elementIndex;
|
|
21274
|
+
this.state.position = "after";
|
|
21262
21275
|
}
|
|
21263
21276
|
else {
|
|
21264
21277
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -21439,6 +21452,7 @@ class ColResizer extends AbstractResizer {
|
|
|
21439
21452
|
dimension: "COL",
|
|
21440
21453
|
base: this.state.base,
|
|
21441
21454
|
elements,
|
|
21455
|
+
position: this.state.position,
|
|
21442
21456
|
});
|
|
21443
21457
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
21444
21458
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -21611,6 +21625,7 @@ class RowResizer extends AbstractResizer {
|
|
|
21611
21625
|
dimension: "ROW",
|
|
21612
21626
|
base: this.state.base,
|
|
21613
21627
|
elements,
|
|
21628
|
+
position: this.state.position,
|
|
21614
21629
|
});
|
|
21615
21630
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
21616
21631
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -21719,8 +21734,8 @@ function useWheelHandler(handler) {
|
|
|
21719
21734
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
21720
21735
|
}
|
|
21721
21736
|
const onMouseWheel = (ev) => {
|
|
21722
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
21723
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
21737
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
21738
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
21724
21739
|
handler(deltaX, deltaY);
|
|
21725
21740
|
};
|
|
21726
21741
|
return onMouseWheel;
|
|
@@ -24308,7 +24323,7 @@ const machine = {
|
|
|
24308
24323
|
SPACE: goTo(State.RightRef),
|
|
24309
24324
|
NUMBER: goTo(State.Found),
|
|
24310
24325
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
24311
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
24326
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
24312
24327
|
},
|
|
24313
24328
|
[State.RightColumnRef]: {
|
|
24314
24329
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -24319,6 +24334,7 @@ const machine = {
|
|
|
24319
24334
|
SPACE: goTo(State.RightRowRef),
|
|
24320
24335
|
NUMBER: goTo(State.Found),
|
|
24321
24336
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
24337
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
24322
24338
|
},
|
|
24323
24339
|
[State.Found]: {},
|
|
24324
24340
|
};
|
|
@@ -27520,6 +27536,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
27520
27536
|
// ---------------------------------------------------------------------------
|
|
27521
27537
|
// Command Handling
|
|
27522
27538
|
// ---------------------------------------------------------------------------
|
|
27539
|
+
allowDispatch(cmd) {
|
|
27540
|
+
switch (cmd.type) {
|
|
27541
|
+
case "SET_BORDER":
|
|
27542
|
+
return this.checkBordersUnchanged(cmd);
|
|
27543
|
+
default:
|
|
27544
|
+
return 0 /* CommandResult.Success */;
|
|
27545
|
+
}
|
|
27546
|
+
}
|
|
27523
27547
|
handle(cmd) {
|
|
27524
27548
|
switch (cmd.type) {
|
|
27525
27549
|
case "ADD_MERGE":
|
|
@@ -27915,6 +27939,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
27915
27939
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right");
|
|
27916
27940
|
}
|
|
27917
27941
|
}
|
|
27942
|
+
checkBordersUnchanged(cmd) {
|
|
27943
|
+
var _a, _b, _c, _d;
|
|
27944
|
+
const currentBorder = this.getCellBorder(cmd);
|
|
27945
|
+
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);
|
|
27946
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
27947
|
+
return 88 /* CommandResult.NoChanges */;
|
|
27948
|
+
}
|
|
27949
|
+
return 0 /* CommandResult.Success */;
|
|
27950
|
+
}
|
|
27918
27951
|
// ---------------------------------------------------------------------------
|
|
27919
27952
|
// Import/Export
|
|
27920
27953
|
// ---------------------------------------------------------------------------
|
|
@@ -27950,7 +27983,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
27950
27983
|
*/
|
|
27951
27984
|
function getBorderId(border) {
|
|
27952
27985
|
for (let [key, value] of Object.entries(borders)) {
|
|
27953
|
-
if (
|
|
27986
|
+
if (deepEquals(value, border)) {
|
|
27954
27987
|
return parseInt(key, 10);
|
|
27955
27988
|
}
|
|
27956
27989
|
}
|
|
@@ -28017,8 +28050,9 @@ class CellPlugin extends CorePlugin {
|
|
|
28017
28050
|
allowDispatch(cmd) {
|
|
28018
28051
|
switch (cmd.type) {
|
|
28019
28052
|
case "UPDATE_CELL":
|
|
28053
|
+
return this.checkCellOutOfSheet(cmd);
|
|
28020
28054
|
case "CLEAR_CELL":
|
|
28021
|
-
return this.
|
|
28055
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
28022
28056
|
default:
|
|
28023
28057
|
return 0 /* CommandResult.Success */;
|
|
28024
28058
|
}
|
|
@@ -28177,14 +28211,9 @@ class CellPlugin extends CorePlugin {
|
|
|
28177
28211
|
*/
|
|
28178
28212
|
getCellById(cellId) {
|
|
28179
28213
|
// this must be as fast as possible
|
|
28180
|
-
|
|
28181
|
-
|
|
28182
|
-
|
|
28183
|
-
if (cell) {
|
|
28184
|
-
return cell;
|
|
28185
|
-
}
|
|
28186
|
-
}
|
|
28187
|
-
return undefined;
|
|
28214
|
+
const position = this.getters.getCellPosition(cellId);
|
|
28215
|
+
const sheet = this.cells[position.sheetId];
|
|
28216
|
+
return sheet[cellId];
|
|
28188
28217
|
}
|
|
28189
28218
|
/*
|
|
28190
28219
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -28422,13 +28451,23 @@ class CellPlugin extends CorePlugin {
|
|
|
28422
28451
|
dependencies: [],
|
|
28423
28452
|
};
|
|
28424
28453
|
}
|
|
28425
|
-
checkCellOutOfSheet(
|
|
28454
|
+
checkCellOutOfSheet(cmd) {
|
|
28455
|
+
const { sheetId, col, row } = cmd;
|
|
28426
28456
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
28427
28457
|
if (!sheet)
|
|
28428
28458
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
28429
28459
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
28430
28460
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
|
|
28431
28461
|
}
|
|
28462
|
+
checkUselessClearCell(cmd) {
|
|
28463
|
+
const cell = this.getters.getCell(cmd);
|
|
28464
|
+
if (!cell)
|
|
28465
|
+
return 88 /* CommandResult.NoChanges */;
|
|
28466
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
28467
|
+
return 88 /* CommandResult.NoChanges */;
|
|
28468
|
+
}
|
|
28469
|
+
return 0 /* CommandResult.Success */;
|
|
28470
|
+
}
|
|
28432
28471
|
}
|
|
28433
28472
|
CellPlugin.getters = [
|
|
28434
28473
|
"zoneToXC",
|
|
@@ -30898,7 +30937,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30898
30937
|
const elements = cmd.dimension === "COL"
|
|
30899
30938
|
? this.getNumberCols(cmd.sheetId)
|
|
30900
30939
|
: this.getNumberRows(cmd.sheetId);
|
|
30901
|
-
if (cmd.base < 0 || cmd.base
|
|
30940
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
30902
30941
|
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
30903
30942
|
}
|
|
30904
30943
|
else if (cmd.quantity <= 0) {
|
|
@@ -31494,10 +31533,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
31494
31533
|
// begin with the end.
|
|
31495
31534
|
rows.sort((a, b) => b - a);
|
|
31496
31535
|
for (let group of groupConsecutive(rows)) {
|
|
31536
|
+
// indexes are sorted in the descending order
|
|
31537
|
+
const from = group[group.length - 1];
|
|
31538
|
+
const to = group[0];
|
|
31497
31539
|
// Move the cells.
|
|
31498
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
31499
|
-
// Effectively delete the
|
|
31500
|
-
|
|
31540
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
31541
|
+
// Effectively delete the rows
|
|
31542
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
31501
31543
|
}
|
|
31502
31544
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
31503
31545
|
if (count) {
|
|
@@ -31519,8 +31561,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
31519
31561
|
this.addEmptyRows(sheet, quantity);
|
|
31520
31562
|
// Move the cells.
|
|
31521
31563
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
31522
|
-
// Recompute the left-right/top-bottom.
|
|
31523
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
31524
31564
|
if (index < sheet.panes.ySplit) {
|
|
31525
31565
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
31526
31566
|
}
|
|
@@ -31621,35 +31661,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
31621
31661
|
}
|
|
31622
31662
|
}
|
|
31623
31663
|
}
|
|
31624
|
-
updateRowsStructureOnDeletion(
|
|
31664
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
31625
31665
|
const rows = [];
|
|
31626
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
31666
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
31627
31667
|
for (let i in sheet.rows) {
|
|
31628
|
-
|
|
31668
|
+
const row = Number(i);
|
|
31669
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
31629
31670
|
continue;
|
|
31630
31671
|
}
|
|
31631
31672
|
rows.push({
|
|
31632
|
-
cells: cellsQueue.
|
|
31673
|
+
cells: cellsQueue.pop(),
|
|
31633
31674
|
});
|
|
31634
31675
|
}
|
|
31635
31676
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
31636
31677
|
}
|
|
31637
|
-
/**
|
|
31638
|
-
* Update the rows of the sheet after an addition:
|
|
31639
|
-
* - Rename the rows
|
|
31640
|
-
*
|
|
31641
|
-
* @param sheet Sheet on which the deletion occurs
|
|
31642
|
-
* @param addedRow Index of the added row
|
|
31643
|
-
* @param rowsToAdd Number of the rows to add
|
|
31644
|
-
*/
|
|
31645
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
31646
|
-
const rows = [];
|
|
31647
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
31648
|
-
sheet.rows.forEach(() => rows.push({
|
|
31649
|
-
cells: cellsQueue.shift(),
|
|
31650
|
-
}));
|
|
31651
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
31652
|
-
}
|
|
31653
31678
|
/**
|
|
31654
31679
|
* Add empty rows at the end of the rows
|
|
31655
31680
|
*
|
|
@@ -32133,6 +32158,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32133
32158
|
}
|
|
32134
32159
|
return evaluatedCell;
|
|
32135
32160
|
};
|
|
32161
|
+
const rangeCache = {};
|
|
32136
32162
|
/**
|
|
32137
32163
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
32138
32164
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -32149,21 +32175,26 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32149
32175
|
// Performance issue: Avoid fetching data on positions that are out of the spreadsheet
|
|
32150
32176
|
// e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
|
|
32151
32177
|
const sheetZone = getters.getSheetZone(sheetId);
|
|
32152
|
-
const result = [];
|
|
32153
32178
|
const zone = intersection(range.zone, sheetZone);
|
|
32154
32179
|
if (!zone) {
|
|
32155
|
-
|
|
32156
|
-
|
|
32180
|
+
return [[]];
|
|
32181
|
+
}
|
|
32182
|
+
const { top, left, bottom, right } = zone;
|
|
32183
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
32184
|
+
if (cacheKey in rangeCache) {
|
|
32185
|
+
return rangeCache[cacheKey];
|
|
32157
32186
|
}
|
|
32187
|
+
const result = new Array(right - left + 1);
|
|
32158
32188
|
// Performance issue: nested loop is faster than a map here
|
|
32159
|
-
for (let col =
|
|
32160
|
-
const rowValues =
|
|
32161
|
-
for (let row =
|
|
32189
|
+
for (let col = left; col <= right; col++) {
|
|
32190
|
+
const rowValues = new Array(bottom - top + 1);
|
|
32191
|
+
for (let row = top; row <= bottom; row++) {
|
|
32162
32192
|
const cell = evalContext.getters.getCell({ sheetId: range.sheetId, col, row });
|
|
32163
|
-
rowValues
|
|
32193
|
+
rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
|
|
32164
32194
|
}
|
|
32165
|
-
result
|
|
32195
|
+
result[col - left] = rowValues;
|
|
32166
32196
|
}
|
|
32197
|
+
rangeCache[cacheKey] = result;
|
|
32167
32198
|
return result;
|
|
32168
32199
|
}
|
|
32169
32200
|
/**
|
|
@@ -34071,24 +34102,27 @@ class AutofillPlugin extends UIPlugin {
|
|
|
34071
34102
|
* autofiller
|
|
34072
34103
|
*/
|
|
34073
34104
|
autofillAuto() {
|
|
34105
|
+
var _a, _b;
|
|
34074
34106
|
const zone = this.getters.getSelectedZone();
|
|
34075
34107
|
const sheetId = this.getters.getActiveSheetId();
|
|
34076
34108
|
let col = zone.left;
|
|
34077
34109
|
let row = zone.bottom;
|
|
34078
34110
|
if (col > 0) {
|
|
34079
|
-
let
|
|
34080
|
-
while (
|
|
34111
|
+
let leftPosition = { sheetId, col: col - 1, row };
|
|
34112
|
+
while (this.getters.getEvaluatedCell(leftPosition).type !== CellValueType.empty ||
|
|
34113
|
+
((_a = this.getters.getCell(leftPosition)) === null || _a === void 0 ? void 0 : _a.content)) {
|
|
34081
34114
|
row += 1;
|
|
34082
|
-
|
|
34115
|
+
leftPosition = { sheetId, col: col - 1, row };
|
|
34083
34116
|
}
|
|
34084
34117
|
}
|
|
34085
34118
|
if (row === zone.bottom) {
|
|
34086
34119
|
col = zone.right;
|
|
34087
34120
|
if (col <= this.getters.getNumberCols(sheetId)) {
|
|
34088
|
-
let
|
|
34089
|
-
while (
|
|
34121
|
+
let rightPosition = { sheetId, col: col + 1, row };
|
|
34122
|
+
while (this.getters.getEvaluatedCell(rightPosition).type !== CellValueType.empty ||
|
|
34123
|
+
((_b = this.getters.getCell(rightPosition)) === null || _b === void 0 ? void 0 : _b.content)) {
|
|
34090
34124
|
row += 1;
|
|
34091
|
-
|
|
34125
|
+
rightPosition = { sheetId, col: col + 1, row };
|
|
34092
34126
|
}
|
|
34093
34127
|
}
|
|
34094
34128
|
}
|
|
@@ -38406,6 +38440,10 @@ function setXcToReferenceType(xc, referenceType) {
|
|
|
38406
38440
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
38407
38441
|
case "colrow":
|
|
38408
38442
|
indexOfNumber = xc.search(/[0-9]/);
|
|
38443
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
38444
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
38445
|
+
return "$" + xc;
|
|
38446
|
+
}
|
|
38409
38447
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
38410
38448
|
return "$" + xc;
|
|
38411
38449
|
case "none":
|
|
@@ -39547,7 +39585,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39547
39585
|
sheetId: cmd.sheetId,
|
|
39548
39586
|
base: cmd.base,
|
|
39549
39587
|
quantity: thickness,
|
|
39550
|
-
position:
|
|
39588
|
+
position: cmd.position,
|
|
39551
39589
|
});
|
|
39552
39590
|
const isCol = cmd.dimension === "COL";
|
|
39553
39591
|
const start = cmd.elements[0];
|
|
@@ -39564,12 +39602,13 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39564
39602
|
},
|
|
39565
39603
|
];
|
|
39566
39604
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
39605
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
39567
39606
|
const pasteTarget = [
|
|
39568
39607
|
{
|
|
39569
|
-
left: isCol ?
|
|
39570
|
-
right: isCol ?
|
|
39571
|
-
top: !isCol ?
|
|
39572
|
-
bottom: !isCol ?
|
|
39608
|
+
left: isCol ? base : 0,
|
|
39609
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
39610
|
+
top: !isCol ? base : 0,
|
|
39611
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
39573
39612
|
},
|
|
39574
39613
|
];
|
|
39575
39614
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -39606,6 +39645,11 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
39606
39645
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
39607
39646
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
39608
39647
|
}
|
|
39648
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
39649
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
39650
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
39651
|
+
return 86 /* CommandResult.InvalidHeaderIndex */;
|
|
39652
|
+
}
|
|
39609
39653
|
return 0 /* CommandResult.Success */;
|
|
39610
39654
|
}
|
|
39611
39655
|
//-------------------------------------------
|
|
@@ -42690,9 +42734,9 @@ function revertChanges(revisions) {
|
|
|
42690
42734
|
* Apply the changes of the given HistoryChange to the state
|
|
42691
42735
|
*/
|
|
42692
42736
|
function applyChange(change, target) {
|
|
42693
|
-
let val = change.
|
|
42694
|
-
|
|
42695
|
-
for (let pathIndex =
|
|
42737
|
+
let val = change.path[0];
|
|
42738
|
+
const key = change.path[change.path.length - 1];
|
|
42739
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
42696
42740
|
const p = change.path[pathIndex];
|
|
42697
42741
|
if (val[p] === undefined) {
|
|
42698
42742
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -43449,13 +43493,14 @@ class StateObserver {
|
|
|
43449
43493
|
}
|
|
43450
43494
|
addChange(...args) {
|
|
43451
43495
|
const val = args.pop();
|
|
43452
|
-
const
|
|
43496
|
+
const root = args[0];
|
|
43453
43497
|
let value = root;
|
|
43454
|
-
let key =
|
|
43455
|
-
|
|
43456
|
-
|
|
43498
|
+
let key = args[args.length - 1];
|
|
43499
|
+
const pathLength = args.length - 2;
|
|
43500
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
43501
|
+
const p = args[pathIndex];
|
|
43457
43502
|
if (value[p] === undefined) {
|
|
43458
|
-
const nextPath =
|
|
43503
|
+
const nextPath = args[pathIndex + 1];
|
|
43459
43504
|
value[p] = createEmptyStructure(nextPath);
|
|
43460
43505
|
}
|
|
43461
43506
|
value = value[p];
|
|
@@ -43464,8 +43509,7 @@ class StateObserver {
|
|
|
43464
43509
|
return;
|
|
43465
43510
|
}
|
|
43466
43511
|
this.changes.push({
|
|
43467
|
-
|
|
43468
|
-
path,
|
|
43512
|
+
path: args,
|
|
43469
43513
|
before: value[key],
|
|
43470
43514
|
after: val,
|
|
43471
43515
|
});
|
|
@@ -45317,7 +45361,10 @@ class Model extends EventBus {
|
|
|
45317
45361
|
*/
|
|
45318
45362
|
checkDispatchAllowed(command) {
|
|
45319
45363
|
const results = this.handlers.map((handler) => handler.allowDispatch(command));
|
|
45320
|
-
|
|
45364
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
45365
|
+
return new DispatchResult(results.flat());
|
|
45366
|
+
}
|
|
45367
|
+
return DispatchResult.Success;
|
|
45321
45368
|
}
|
|
45322
45369
|
finalize() {
|
|
45323
45370
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -45544,6 +45591,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
45544
45591
|
exports.tokenize = tokenize;
|
|
45545
45592
|
|
|
45546
45593
|
|
|
45547
|
-
__info__.version = '16.2.
|
|
45548
|
-
__info__.date = '2023-
|
|
45549
|
-
__info__.hash = '
|
|
45594
|
+
__info__.version = '16.2.24';
|
|
45595
|
+
__info__.date = '2023-12-05T09:37:14.992Z';
|
|
45596
|
+
__info__.hash = '7b1a35c';
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -1080,7 +1080,7 @@ declare class StateObserver {
|
|
|
1080
1080
|
commands: CoreCommand[];
|
|
1081
1081
|
};
|
|
1082
1082
|
addCommand(command: CoreCommand): void;
|
|
1083
|
-
addChange(...args:
|
|
1083
|
+
addChange(...args: [...HistoryChange["path"], any]): void;
|
|
1084
1084
|
}
|
|
1085
1085
|
|
|
1086
1086
|
interface Validator {
|
|
@@ -1507,6 +1507,7 @@ interface MoveColumnsRowsCommand extends GridDependentCommand {
|
|
|
1507
1507
|
type: "MOVE_COLUMNS_ROWS";
|
|
1508
1508
|
base: HeaderIndex;
|
|
1509
1509
|
elements: HeaderIndex[];
|
|
1510
|
+
position: "before" | "after";
|
|
1510
1511
|
}
|
|
1511
1512
|
interface ResizeColumnsRowsCommand extends GridDependentCommand {
|
|
1512
1513
|
type: "RESIZE_COLUMNS_ROWS";
|
|
@@ -2140,7 +2141,8 @@ declare const enum CommandResult {
|
|
|
2140
2141
|
DuplicatedChartId = 84,
|
|
2141
2142
|
ChartDoesNotExist = 85,
|
|
2142
2143
|
InvalidHeaderIndex = 86,
|
|
2143
|
-
InvalidQuantity = 87
|
|
2144
|
+
InvalidQuantity = 87,
|
|
2145
|
+
NoChanges = 88
|
|
2144
2146
|
}
|
|
2145
2147
|
interface CommandHandler<T> {
|
|
2146
2148
|
allowDispatch(command: T): CommandResult | CommandResult[];
|
|
@@ -2933,7 +2935,8 @@ interface BordersPluginState {
|
|
|
2933
2935
|
declare class BordersPlugin extends CorePlugin<BordersPluginState> implements BordersPluginState {
|
|
2934
2936
|
static getters: readonly ["getCellBorder"];
|
|
2935
2937
|
readonly borders: BordersPluginState["borders"];
|
|
2936
|
-
|
|
2938
|
+
allowDispatch(cmd: CoreCommand): CommandResult.Success | CommandResult.NoChanges;
|
|
2939
|
+
handle(cmd: CoreCommand): void;
|
|
2937
2940
|
/**
|
|
2938
2941
|
* Move borders according to the inserted columns.
|
|
2939
2942
|
* Ensure borders continuity.
|
|
@@ -3030,6 +3033,7 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
|
|
|
3030
3033
|
* Compute the borders to add to the given zone merged.
|
|
3031
3034
|
*/
|
|
3032
3035
|
private addBordersToMerge;
|
|
3036
|
+
private checkBordersUnchanged;
|
|
3033
3037
|
import(data: WorkbookData): void;
|
|
3034
3038
|
export(data: WorkbookData): void;
|
|
3035
3039
|
exportForExcel(data: ExcelWorkbookData): void;
|
|
@@ -3054,7 +3058,7 @@ declare class CellPlugin extends CorePlugin<CoreState> implements CoreState {
|
|
|
3054
3058
|
};
|
|
3055
3059
|
};
|
|
3056
3060
|
adaptRanges(applyChange: ApplyRangeChange, sheetId?: UID): void;
|
|
3057
|
-
allowDispatch(cmd: CoreCommand): CommandResult;
|
|
3061
|
+
allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];
|
|
3058
3062
|
handle(cmd: CoreCommand): void;
|
|
3059
3063
|
/**
|
|
3060
3064
|
* Set a format to all the cells in a zone
|
|
@@ -3127,6 +3131,7 @@ declare class CellPlugin extends CorePlugin<CoreState> implements CoreState {
|
|
|
3127
3131
|
private createFormulaCellWithDependencies;
|
|
3128
3132
|
private createErrorFormula;
|
|
3129
3133
|
private checkCellOutOfSheet;
|
|
3134
|
+
private checkUselessClearCell;
|
|
3130
3135
|
}
|
|
3131
3136
|
|
|
3132
3137
|
/**
|
|
@@ -3635,15 +3640,6 @@ declare class SheetPlugin extends CorePlugin<SheetState$1> implements SheetState
|
|
|
3635
3640
|
*/
|
|
3636
3641
|
private moveCellOnRowsDeletion;
|
|
3637
3642
|
private updateRowsStructureOnDeletion;
|
|
3638
|
-
/**
|
|
3639
|
-
* Update the rows of the sheet after an addition:
|
|
3640
|
-
* - Rename the rows
|
|
3641
|
-
*
|
|
3642
|
-
* @param sheet Sheet on which the deletion occurs
|
|
3643
|
-
* @param addedRow Index of the added row
|
|
3644
|
-
* @param rowsToAdd Number of the rows to add
|
|
3645
|
-
*/
|
|
3646
|
-
private updateRowsStructureOnAddition;
|
|
3647
3643
|
/**
|
|
3648
3644
|
* Add empty rows at the end of the rows
|
|
3649
3645
|
*
|
|
@@ -4699,8 +4695,7 @@ type Getters = {
|
|
|
4699
4695
|
} & LocalHistoryGetters & CoreGetters & SessionGetters & AutofillGetters & AutomaticSumGetters & ClipboardGetters & EditionGetters & EvaluationGetters & EvaluationChartGetters & EvaluationConditionalFormatGetters & FindAndReplaceGetters & HighlightGetters & CustomColorsGetters & RendererGetters & SelectionGetters & SelectionInputGetters & SelectionMultiUserGetters & SortGetters & UIOptionsGetters & SheetUIGetters & ViewportGetters & CellPopoverPluginGetters & FilterEvaluationGetters & HeaderVisibilityIUIGetters;
|
|
4700
4696
|
|
|
4701
4697
|
interface HistoryChange {
|
|
4702
|
-
|
|
4703
|
-
path: (string | number)[];
|
|
4698
|
+
path: [any, ...(number | string)[]];
|
|
4704
4699
|
before: any;
|
|
4705
4700
|
after: any;
|
|
4706
4701
|
}
|
|
@@ -6351,6 +6346,7 @@ interface ResizerState {
|
|
|
6351
6346
|
draggerShadowThickness: number;
|
|
6352
6347
|
delta: number;
|
|
6353
6348
|
base: number;
|
|
6349
|
+
position: "before" | "after";
|
|
6354
6350
|
}
|
|
6355
6351
|
interface ResizerProps {
|
|
6356
6352
|
onOpenContextMenu: (type: ContextMenuType, x: Pixel, y: Pixel) => void;
|