@odoo/o-spreadsheet 16.0.24 → 16.0.26
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 +140 -90
- package/dist/o-spreadsheet.d.ts +14 -15
- package/dist/o-spreadsheet.esm.js +140 -90
- package/dist/o-spreadsheet.iife.js +140 -90
- package/dist/o-spreadsheet.iife.min.js +274 -274
- package/dist/o_spreadsheet.xml +6 -7
- package/package.json +1 -1
|
@@ -624,13 +624,6 @@ function getYearFrac(startDate, endDate, _dayCountConvention) {
|
|
|
624
624
|
}
|
|
625
625
|
|
|
626
626
|
//------------------------------------------------------------------------------
|
|
627
|
-
/**
|
|
628
|
-
* Stringify an object, like JSON.stringify, except that the first level of keys
|
|
629
|
-
* is ordered.
|
|
630
|
-
*/
|
|
631
|
-
function stringify(obj) {
|
|
632
|
-
return JSON.stringify(obj, Object.keys(obj).sort());
|
|
633
|
-
}
|
|
634
627
|
/**
|
|
635
628
|
* Remove quotes from a quoted string
|
|
636
629
|
* ```js
|
|
@@ -932,7 +925,7 @@ function isObjectEmptyRecursive(argument) {
|
|
|
932
925
|
*/
|
|
933
926
|
function getItemId(item, itemsDic) {
|
|
934
927
|
for (let [key, value] of Object.entries(itemsDic)) {
|
|
935
|
-
if (
|
|
928
|
+
if (deepEquals(value, item)) {
|
|
936
929
|
return parseInt(key, 10);
|
|
937
930
|
}
|
|
938
931
|
}
|
|
@@ -1068,6 +1061,22 @@ function transpose2dArray(matrix) {
|
|
|
1068
1061
|
if (!matrix.length)
|
|
1069
1062
|
return matrix;
|
|
1070
1063
|
return matrix[0].map((_, i) => matrix.map((row) => row[i]));
|
|
1064
|
+
}
|
|
1065
|
+
/**
|
|
1066
|
+
* Creates a version of the function that's memoized on the value of its first
|
|
1067
|
+
* argument, if any.
|
|
1068
|
+
*/
|
|
1069
|
+
function memoize(func) {
|
|
1070
|
+
const cache = new Map();
|
|
1071
|
+
const funcName = func.name ? func.name + " (memoized)" : "memoized";
|
|
1072
|
+
return {
|
|
1073
|
+
[funcName](...args) {
|
|
1074
|
+
if (!cache.has(args[0])) {
|
|
1075
|
+
cache.set(args[0], func(...args));
|
|
1076
|
+
}
|
|
1077
|
+
return cache.get(args[0]);
|
|
1078
|
+
},
|
|
1079
|
+
}[funcName];
|
|
1071
1080
|
}
|
|
1072
1081
|
|
|
1073
1082
|
const RBA_REGEX = /rgba?\(|\s+|\)/gi;
|
|
@@ -1347,8 +1356,10 @@ function isSameColor(color1, color2) {
|
|
|
1347
1356
|
const cellReference = new RegExp(/\$?([A-Z]{1,3})\$?([0-9]{1,7})/, "i");
|
|
1348
1357
|
// Same as above, but matches the exact string (nothing before or after)
|
|
1349
1358
|
const singleCellReference = new RegExp(/^\$?([A-Z]{1,3})\$?([0-9]{1,7})$/, "i");
|
|
1350
|
-
/** Reference of a column header (eg. A, AB) */
|
|
1351
|
-
const colHeader = new RegExp(
|
|
1359
|
+
/** Reference of a column header (eg. A, AB, $A) */
|
|
1360
|
+
const colHeader = new RegExp(/^\$?([A-Z]{1,3})+$/, "i");
|
|
1361
|
+
/** Reference of a row header (eg. 1, $1) */
|
|
1362
|
+
const rowHeader = new RegExp(/^\$?([0-9]{1,7})+$/, "i");
|
|
1352
1363
|
/** Reference of a column (eg. A, $CA, Sheet1!B) */
|
|
1353
1364
|
const colReference = new RegExp(/^\s*('.+'!|[^']+!)?\$?([A-Z]{1,3})$/, "i");
|
|
1354
1365
|
/** Reference of a row (eg. 1, 59, Sheet1!9) */
|
|
@@ -1378,6 +1389,9 @@ function isRowReference(xc) {
|
|
|
1378
1389
|
function isColHeader(str) {
|
|
1379
1390
|
return colHeader.test(str);
|
|
1380
1391
|
}
|
|
1392
|
+
function isRowHeader(str) {
|
|
1393
|
+
return rowHeader.test(str);
|
|
1394
|
+
}
|
|
1381
1395
|
/**
|
|
1382
1396
|
* Return true if the given xc is the reference of a single cell,
|
|
1383
1397
|
* without any specified sheet (e.g. A1)
|
|
@@ -2078,18 +2092,10 @@ class RangeImpl {
|
|
|
2078
2092
|
if (isFullCol) {
|
|
2079
2093
|
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2080
2094
|
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2081
|
-
if (zone.left === zone.right) {
|
|
2082
|
-
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2083
|
-
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2084
|
-
}
|
|
2085
2095
|
}
|
|
2086
2096
|
if (isFullRow) {
|
|
2087
2097
|
parts[0].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2088
2098
|
parts[1].colFixed = parts[0].colFixed || parts[1].colFixed;
|
|
2089
|
-
if (zone.top === zone.bottom) {
|
|
2090
|
-
parts[0].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2091
|
-
parts[1].rowFixed = parts[0].rowFixed || parts[1].rowFixed;
|
|
2092
|
-
}
|
|
2093
2099
|
}
|
|
2094
2100
|
return parts;
|
|
2095
2101
|
}
|
|
@@ -3305,6 +3311,7 @@ exports.CommandResult = void 0;
|
|
|
3305
3311
|
CommandResult[CommandResult["ChartDoesNotExist"] = 84] = "ChartDoesNotExist";
|
|
3306
3312
|
CommandResult[CommandResult["InvalidHeaderIndex"] = 85] = "InvalidHeaderIndex";
|
|
3307
3313
|
CommandResult[CommandResult["InvalidQuantity"] = 86] = "InvalidQuantity";
|
|
3314
|
+
CommandResult[CommandResult["NoChanges"] = 87] = "NoChanges";
|
|
3308
3315
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
3309
3316
|
|
|
3310
3317
|
function isMatrix(x) {
|
|
@@ -3897,6 +3904,9 @@ function gridOverlayPosition() {
|
|
|
3897
3904
|
}
|
|
3898
3905
|
function getOpenedMenus() {
|
|
3899
3906
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
3907
|
+
}
|
|
3908
|
+
function isMacOS() {
|
|
3909
|
+
return navigator.userAgent.toUpperCase().indexOf("MAC") >= 0;
|
|
3900
3910
|
}
|
|
3901
3911
|
|
|
3902
3912
|
/**
|
|
@@ -10980,12 +10990,12 @@ function toString(value) {
|
|
|
10980
10990
|
}
|
|
10981
10991
|
}
|
|
10982
10992
|
/** Normalize string by setting it to lowercase and replacing accent letters with plain letters */
|
|
10983
|
-
function normalizeString(str) {
|
|
10993
|
+
const normalizeString = memoize(function normalizeString(str) {
|
|
10984
10994
|
return str
|
|
10985
10995
|
.toLowerCase()
|
|
10986
10996
|
.normalize("NFD")
|
|
10987
10997
|
.replace(/[\u0300-\u036f]/g, "");
|
|
10988
|
-
}
|
|
10998
|
+
});
|
|
10989
10999
|
/**
|
|
10990
11000
|
* Normalize a value.
|
|
10991
11001
|
* If the cell value is a string, this will set it to lowercase and replacing accent letters with plain letters
|
|
@@ -18560,7 +18570,7 @@ const machine = {
|
|
|
18560
18570
|
SPACE: goTo(State.RightRef),
|
|
18561
18571
|
NUMBER: goTo(State.Found),
|
|
18562
18572
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
18563
|
-
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value)),
|
|
18573
|
+
SYMBOL: goTo(State.Found, (token) => isColHeader(token.value) || isRowHeader(token.value)),
|
|
18564
18574
|
},
|
|
18565
18575
|
[State.RightColumnRef]: {
|
|
18566
18576
|
SPACE: goTo(State.RightColumnRef),
|
|
@@ -18571,6 +18581,7 @@ const machine = {
|
|
|
18571
18581
|
SPACE: goTo(State.RightRowRef),
|
|
18572
18582
|
NUMBER: goTo(State.Found),
|
|
18573
18583
|
REFERENCE: goTo(State.Found, (token) => isSingleCellReference(token.value)),
|
|
18584
|
+
SYMBOL: goTo(State.Found, (token) => isRowHeader(token.value)),
|
|
18574
18585
|
},
|
|
18575
18586
|
[State.Found]: {},
|
|
18576
18587
|
};
|
|
@@ -19080,6 +19091,10 @@ function setXcToReferenceType(xc, referenceType) {
|
|
|
19080
19091
|
return xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
19081
19092
|
case "colrow":
|
|
19082
19093
|
indexOfNumber = xc.search(/[0-9]/);
|
|
19094
|
+
if (indexOfNumber === -1 || indexOfNumber === 0) {
|
|
19095
|
+
// no row number (eg. A) or no column (eg. 1)
|
|
19096
|
+
return "$" + xc;
|
|
19097
|
+
}
|
|
19083
19098
|
xc = xc.slice(0, indexOfNumber) + "$" + xc.slice(indexOfNumber);
|
|
19084
19099
|
return "$" + xc;
|
|
19085
19100
|
case "none":
|
|
@@ -21533,6 +21548,7 @@ class AbstractResizer extends owl.Component {
|
|
|
21533
21548
|
draggerShadowThickness: 0,
|
|
21534
21549
|
delta: 0,
|
|
21535
21550
|
base: 0,
|
|
21551
|
+
position: "before",
|
|
21536
21552
|
});
|
|
21537
21553
|
}
|
|
21538
21554
|
_computeHandleDisplay(ev) {
|
|
@@ -21658,11 +21674,13 @@ class AbstractResizer extends owl.Component {
|
|
|
21658
21674
|
this.state.draggerLinePosition = dimensions.start;
|
|
21659
21675
|
this.state.draggerShadowPosition = dimensions.start;
|
|
21660
21676
|
this.state.base = elementIndex;
|
|
21677
|
+
this.state.position = "before";
|
|
21661
21678
|
}
|
|
21662
21679
|
else if (this._getSelectedZoneEnd() < elementIndex) {
|
|
21663
21680
|
this.state.draggerLinePosition = dimensions.end;
|
|
21664
21681
|
this.state.draggerShadowPosition = dimensions.end - this.state.draggerShadowThickness;
|
|
21665
|
-
this.state.base = elementIndex
|
|
21682
|
+
this.state.base = elementIndex;
|
|
21683
|
+
this.state.position = "after";
|
|
21666
21684
|
}
|
|
21667
21685
|
else {
|
|
21668
21686
|
this.state.draggerLinePosition = startDimensions.start;
|
|
@@ -21840,6 +21858,7 @@ class ColResizer extends AbstractResizer {
|
|
|
21840
21858
|
dimension: "COL",
|
|
21841
21859
|
base: this.state.base,
|
|
21842
21860
|
elements,
|
|
21861
|
+
position: this.state.position,
|
|
21843
21862
|
});
|
|
21844
21863
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
21845
21864
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -22009,6 +22028,7 @@ class RowResizer extends AbstractResizer {
|
|
|
22009
22028
|
dimension: "ROW",
|
|
22010
22029
|
base: this.state.base,
|
|
22011
22030
|
elements,
|
|
22031
|
+
position: this.state.position,
|
|
22012
22032
|
});
|
|
22013
22033
|
if (!result.isSuccessful && result.reasons.includes(2 /* CommandResult.WillRemoveExistingMerge */)) {
|
|
22014
22034
|
this.env.raiseError(MergeErrorMessage);
|
|
@@ -22111,8 +22131,8 @@ function useWheelHandler(handler) {
|
|
|
22111
22131
|
return val * (deltaMode === 0 ? 1 : DEFAULT_CELL_HEIGHT);
|
|
22112
22132
|
}
|
|
22113
22133
|
const onMouseWheel = (ev) => {
|
|
22114
|
-
const deltaX = normalize(ev.shiftKey ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
22115
|
-
const deltaY = normalize(ev.shiftKey ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
22134
|
+
const deltaX = normalize(ev.shiftKey && !isMacOS() ? ev.deltaY : ev.deltaX, ev.deltaMode);
|
|
22135
|
+
const deltaY = normalize(ev.shiftKey && !isMacOS() ? ev.deltaX : ev.deltaY, ev.deltaMode);
|
|
22116
22136
|
handler(deltaX, deltaY);
|
|
22117
22137
|
};
|
|
22118
22138
|
return onMouseWheel;
|
|
@@ -27105,6 +27125,14 @@ class BordersPlugin extends CorePlugin {
|
|
|
27105
27125
|
// ---------------------------------------------------------------------------
|
|
27106
27126
|
// Command Handling
|
|
27107
27127
|
// ---------------------------------------------------------------------------
|
|
27128
|
+
allowDispatch(cmd) {
|
|
27129
|
+
switch (cmd.type) {
|
|
27130
|
+
case "SET_BORDER":
|
|
27131
|
+
return this.checkBordersUnchanged(cmd);
|
|
27132
|
+
default:
|
|
27133
|
+
return 0 /* CommandResult.Success */;
|
|
27134
|
+
}
|
|
27135
|
+
}
|
|
27108
27136
|
handle(cmd) {
|
|
27109
27137
|
switch (cmd.type) {
|
|
27110
27138
|
case "ADD_MERGE":
|
|
@@ -27500,6 +27528,15 @@ class BordersPlugin extends CorePlugin {
|
|
|
27500
27528
|
this.setBorders(sheetId, [{ ...zone, left: right }], "right");
|
|
27501
27529
|
}
|
|
27502
27530
|
}
|
|
27531
|
+
checkBordersUnchanged(cmd) {
|
|
27532
|
+
var _a, _b, _c, _d;
|
|
27533
|
+
const currentBorder = this.getCellBorder(cmd.sheetId, cmd.col, cmd.row);
|
|
27534
|
+
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);
|
|
27535
|
+
if ((!currentBorder && areAllNewBordersUndefined) || deepEquals(currentBorder, cmd.border)) {
|
|
27536
|
+
return 87 /* CommandResult.NoChanges */;
|
|
27537
|
+
}
|
|
27538
|
+
return 0 /* CommandResult.Success */;
|
|
27539
|
+
}
|
|
27503
27540
|
// ---------------------------------------------------------------------------
|
|
27504
27541
|
// Import/Export
|
|
27505
27542
|
// ---------------------------------------------------------------------------
|
|
@@ -27535,7 +27572,7 @@ class BordersPlugin extends CorePlugin {
|
|
|
27535
27572
|
*/
|
|
27536
27573
|
function getBorderId(border) {
|
|
27537
27574
|
for (let [key, value] of Object.entries(borders)) {
|
|
27538
|
-
if (
|
|
27575
|
+
if (deepEquals(value, border)) {
|
|
27539
27576
|
return parseInt(key, 10);
|
|
27540
27577
|
}
|
|
27541
27578
|
}
|
|
@@ -27578,6 +27615,7 @@ const nbspRegexp = new RegExp(String.fromCharCode(160), "g");
|
|
|
27578
27615
|
class CellPlugin extends CorePlugin {
|
|
27579
27616
|
constructor() {
|
|
27580
27617
|
super(...arguments);
|
|
27618
|
+
this.nextId = 1;
|
|
27581
27619
|
this.cells = {};
|
|
27582
27620
|
this.createCell = cellFactory(this.getters);
|
|
27583
27621
|
}
|
|
@@ -27603,8 +27641,9 @@ class CellPlugin extends CorePlugin {
|
|
|
27603
27641
|
allowDispatch(cmd) {
|
|
27604
27642
|
switch (cmd.type) {
|
|
27605
27643
|
case "UPDATE_CELL":
|
|
27644
|
+
return this.checkCellOutOfSheet(cmd);
|
|
27606
27645
|
case "CLEAR_CELL":
|
|
27607
|
-
return this.
|
|
27646
|
+
return this.checkValidations(cmd, this.chainValidations(this.checkCellOutOfSheet, this.checkUselessClearCell));
|
|
27608
27647
|
default:
|
|
27609
27648
|
return 0 /* CommandResult.Success */;
|
|
27610
27649
|
}
|
|
@@ -27745,7 +27784,7 @@ class CellPlugin extends CorePlugin {
|
|
|
27745
27784
|
importCell(sheetId, cellData, normalizedStyles, normalizedFormats) {
|
|
27746
27785
|
const style = (cellData.style && normalizedStyles[cellData.style]) || undefined;
|
|
27747
27786
|
const format = (cellData.format && normalizedFormats[cellData.format]) || undefined;
|
|
27748
|
-
const cellId = this.
|
|
27787
|
+
const cellId = this.getNextUid();
|
|
27749
27788
|
const properties = { format, style };
|
|
27750
27789
|
return this.createCell(cellId, (cellData === null || cellData === void 0 ? void 0 : cellData.content) || "", properties, sheetId);
|
|
27751
27790
|
}
|
|
@@ -27776,14 +27815,9 @@ class CellPlugin extends CorePlugin {
|
|
|
27776
27815
|
*/
|
|
27777
27816
|
getCellById(cellId) {
|
|
27778
27817
|
// this must be as fast as possible
|
|
27779
|
-
|
|
27780
|
-
|
|
27781
|
-
|
|
27782
|
-
if (cell) {
|
|
27783
|
-
return cell;
|
|
27784
|
-
}
|
|
27785
|
-
}
|
|
27786
|
-
return undefined;
|
|
27818
|
+
const position = this.getters.getCellPosition(cellId);
|
|
27819
|
+
const sheet = this.cells[position.sheetId];
|
|
27820
|
+
return sheet[cellId];
|
|
27787
27821
|
}
|
|
27788
27822
|
/*
|
|
27789
27823
|
* Reconstructs the original formula string based on a normalized form and its dependencies
|
|
@@ -27891,6 +27925,11 @@ class CellPlugin extends CorePlugin {
|
|
|
27891
27925
|
}
|
|
27892
27926
|
return format;
|
|
27893
27927
|
}
|
|
27928
|
+
getNextUid() {
|
|
27929
|
+
const id = this.nextId.toString();
|
|
27930
|
+
this.history.update("nextId", this.nextId + 1);
|
|
27931
|
+
return id;
|
|
27932
|
+
}
|
|
27894
27933
|
updateCell(sheetId, col, row, after) {
|
|
27895
27934
|
var _a;
|
|
27896
27935
|
const before = this.getters.getCell(sheetId, col, row);
|
|
@@ -27929,7 +27968,7 @@ class CellPlugin extends CorePlugin {
|
|
|
27929
27968
|
}
|
|
27930
27969
|
return;
|
|
27931
27970
|
}
|
|
27932
|
-
const cellId = (before === null || before === void 0 ? void 0 : before.id) || this.
|
|
27971
|
+
const cellId = (before === null || before === void 0 ? void 0 : before.id) || this.getNextUid();
|
|
27933
27972
|
const didContentChange = hasContent;
|
|
27934
27973
|
const properties = { format, style };
|
|
27935
27974
|
const cell = this.createCell(cellId, afterContent, properties, sheetId);
|
|
@@ -27943,13 +27982,23 @@ class CellPlugin extends CorePlugin {
|
|
|
27943
27982
|
this.history.update("cells", sheetId, cell.id, cell);
|
|
27944
27983
|
this.dispatch("UPDATE_CELL_POSITION", { cellId: cell.id, col, row, sheetId });
|
|
27945
27984
|
}
|
|
27946
|
-
checkCellOutOfSheet(
|
|
27985
|
+
checkCellOutOfSheet(cmd) {
|
|
27986
|
+
const { sheetId, col, row } = cmd;
|
|
27947
27987
|
const sheet = this.getters.tryGetSheet(sheetId);
|
|
27948
27988
|
if (!sheet)
|
|
27949
27989
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
27950
27990
|
const sheetZone = this.getters.getSheetZone(sheetId);
|
|
27951
27991
|
return isInside(col, row, sheetZone) ? 0 /* CommandResult.Success */ : 18 /* CommandResult.TargetOutOfSheet */;
|
|
27952
27992
|
}
|
|
27993
|
+
checkUselessClearCell(cmd) {
|
|
27994
|
+
const cell = this.getters.getCell(cmd.sheetId, cmd.col, cmd.row);
|
|
27995
|
+
if (!cell)
|
|
27996
|
+
return 87 /* CommandResult.NoChanges */;
|
|
27997
|
+
if (!cell.content && !cell.style && !cell.format) {
|
|
27998
|
+
return 87 /* CommandResult.NoChanges */;
|
|
27999
|
+
}
|
|
28000
|
+
return 0 /* CommandResult.Success */;
|
|
28001
|
+
}
|
|
27953
28002
|
}
|
|
27954
28003
|
CellPlugin.getters = [
|
|
27955
28004
|
"zoneToXC",
|
|
@@ -29901,7 +29950,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
29901
29950
|
const elements = cmd.dimension === "COL"
|
|
29902
29951
|
? this.getNumberCols(cmd.sheetId)
|
|
29903
29952
|
: this.getNumberRows(cmd.sheetId);
|
|
29904
|
-
if (cmd.base < 0 || cmd.base
|
|
29953
|
+
if (cmd.base < 0 || cmd.base >= elements) {
|
|
29905
29954
|
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29906
29955
|
}
|
|
29907
29956
|
else if (cmd.quantity <= 0) {
|
|
@@ -30514,10 +30563,13 @@ class SheetPlugin extends CorePlugin {
|
|
|
30514
30563
|
// begin with the end.
|
|
30515
30564
|
rows.sort((a, b) => b - a);
|
|
30516
30565
|
for (let group of groupConsecutive(rows)) {
|
|
30566
|
+
// indexes are sorted in the descending order
|
|
30567
|
+
const from = group[group.length - 1];
|
|
30568
|
+
const to = group[0];
|
|
30517
30569
|
// Move the cells.
|
|
30518
|
-
this.moveCellOnRowsDeletion(sheet,
|
|
30519
|
-
// Effectively delete the
|
|
30520
|
-
|
|
30570
|
+
this.moveCellOnRowsDeletion(sheet, from, to);
|
|
30571
|
+
// Effectively delete the rows
|
|
30572
|
+
this.updateRowsStructureOnDeletion(sheet, from, to);
|
|
30521
30573
|
}
|
|
30522
30574
|
const count = rows.filter((row) => row < sheet.panes.ySplit).length;
|
|
30523
30575
|
if (count) {
|
|
@@ -30539,8 +30591,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
30539
30591
|
this.addEmptyRows(sheet, quantity);
|
|
30540
30592
|
// Move the cells.
|
|
30541
30593
|
this.moveCellsOnAddition(sheet, index, quantity, "rows");
|
|
30542
|
-
// Recompute the left-right/top-bottom.
|
|
30543
|
-
this.updateRowsStructureOnAddition(sheet, row, quantity);
|
|
30544
30594
|
if (index < sheet.panes.ySplit) {
|
|
30545
30595
|
this.setPaneDivisions(sheet.id, sheet.panes.ySplit + quantity, "ROW");
|
|
30546
30596
|
}
|
|
@@ -30641,35 +30691,20 @@ class SheetPlugin extends CorePlugin {
|
|
|
30641
30691
|
}
|
|
30642
30692
|
}
|
|
30643
30693
|
}
|
|
30644
|
-
updateRowsStructureOnDeletion(
|
|
30694
|
+
updateRowsStructureOnDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
30645
30695
|
const rows = [];
|
|
30646
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
30696
|
+
const cellsQueue = sheet.rows.map((row) => row.cells).reverse();
|
|
30647
30697
|
for (let i in sheet.rows) {
|
|
30648
|
-
|
|
30698
|
+
const row = Number(i);
|
|
30699
|
+
if (row >= deleteFromRow && row <= deleteToRow) {
|
|
30649
30700
|
continue;
|
|
30650
30701
|
}
|
|
30651
30702
|
rows.push({
|
|
30652
|
-
cells: cellsQueue.
|
|
30703
|
+
cells: cellsQueue.pop(),
|
|
30653
30704
|
});
|
|
30654
30705
|
}
|
|
30655
30706
|
this.history.update("sheets", sheet.id, "rows", rows);
|
|
30656
30707
|
}
|
|
30657
|
-
/**
|
|
30658
|
-
* Update the rows of the sheet after an addition:
|
|
30659
|
-
* - Rename the rows
|
|
30660
|
-
*
|
|
30661
|
-
* @param sheet Sheet on which the deletion occurs
|
|
30662
|
-
* @param addedRow Index of the added row
|
|
30663
|
-
* @param rowsToAdd Number of the rows to add
|
|
30664
|
-
*/
|
|
30665
|
-
updateRowsStructureOnAddition(sheet, addedRow, rowsToAdd) {
|
|
30666
|
-
const rows = [];
|
|
30667
|
-
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
30668
|
-
sheet.rows.forEach(() => rows.push({
|
|
30669
|
-
cells: cellsQueue.shift(),
|
|
30670
|
-
}));
|
|
30671
|
-
this.history.update("sheets", sheet.id, "rows", rows);
|
|
30672
|
-
}
|
|
30673
30708
|
/**
|
|
30674
30709
|
* Add empty rows at the end of the rows
|
|
30675
30710
|
*
|
|
@@ -32658,6 +32693,7 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32658
32693
|
}
|
|
32659
32694
|
return cell.evaluated;
|
|
32660
32695
|
}
|
|
32696
|
+
const rangeCache = {};
|
|
32661
32697
|
/**
|
|
32662
32698
|
* Return the values of the cell(s) used in reference, but always in the format of a range even
|
|
32663
32699
|
* if a single cell is referenced. It is a list of col values. This is useful for the formulas that describe parameters as
|
|
@@ -32674,21 +32710,26 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
32674
32710
|
// Performance issue: Avoid fetching data on positions that are out of the spreadsheet
|
|
32675
32711
|
// e.g. A1:ZZZ9999 in a sheet with 10 cols and 10 rows should ignore everything past J10 and return a 10x10 array
|
|
32676
32712
|
const sheetZone = getters.getSheetZone(sheetId);
|
|
32677
|
-
const result = [];
|
|
32678
32713
|
const zone = intersection(range.zone, sheetZone);
|
|
32679
32714
|
if (!zone) {
|
|
32680
|
-
|
|
32681
|
-
|
|
32715
|
+
return [[]];
|
|
32716
|
+
}
|
|
32717
|
+
const { top, left, bottom, right } = zone;
|
|
32718
|
+
const cacheKey = `${sheetId}-${top}-${left}-${bottom}-${right}`;
|
|
32719
|
+
if (cacheKey in rangeCache) {
|
|
32720
|
+
return rangeCache[cacheKey];
|
|
32682
32721
|
}
|
|
32722
|
+
const result = new Array(right - left + 1);
|
|
32683
32723
|
// Performance issue: nested loop is faster than a map here
|
|
32684
|
-
for (let col =
|
|
32685
|
-
const rowValues =
|
|
32686
|
-
for (let row =
|
|
32724
|
+
for (let col = left; col <= right; col++) {
|
|
32725
|
+
const rowValues = new Array(bottom - top + 1);
|
|
32726
|
+
for (let row = top; row <= bottom; row++) {
|
|
32687
32727
|
const cell = evalContext.getters.getCell(range.sheetId, col, row);
|
|
32688
|
-
rowValues
|
|
32728
|
+
rowValues[row - top] = cell ? getEvaluatedCell(cell) : undefined;
|
|
32689
32729
|
}
|
|
32690
|
-
result
|
|
32730
|
+
result[col - left] = rowValues;
|
|
32691
32731
|
}
|
|
32732
|
+
rangeCache[cacheKey] = result;
|
|
32692
32733
|
return result;
|
|
32693
32734
|
}
|
|
32694
32735
|
/**
|
|
@@ -34942,7 +34983,7 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
34942
34983
|
sheetId: cmd.sheetId,
|
|
34943
34984
|
base: cmd.base,
|
|
34944
34985
|
quantity: thickness,
|
|
34945
|
-
position:
|
|
34986
|
+
position: cmd.position,
|
|
34946
34987
|
});
|
|
34947
34988
|
const isCol = cmd.dimension === "COL";
|
|
34948
34989
|
const start = cmd.elements[0];
|
|
@@ -34959,12 +35000,13 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
34959
35000
|
},
|
|
34960
35001
|
];
|
|
34961
35002
|
const state = new ClipboardCellsState(target, "CUT", this.getters, this.dispatch, this.selection);
|
|
35003
|
+
const base = isBasedBefore ? cmd.base : cmd.base + 1;
|
|
34962
35004
|
const pasteTarget = [
|
|
34963
35005
|
{
|
|
34964
|
-
left: isCol ?
|
|
34965
|
-
right: isCol ?
|
|
34966
|
-
top: !isCol ?
|
|
34967
|
-
bottom: !isCol ?
|
|
35006
|
+
left: isCol ? base : 0,
|
|
35007
|
+
right: isCol ? base + thickness - 1 : this.getters.getNumberCols(cmd.sheetId) - 1,
|
|
35008
|
+
top: !isCol ? base : 0,
|
|
35009
|
+
bottom: !isCol ? base + thickness - 1 : this.getters.getNumberRows(cmd.sheetId) - 1,
|
|
34968
35010
|
},
|
|
34969
35011
|
];
|
|
34970
35012
|
state.paste(pasteTarget, { selectTarget: true });
|
|
@@ -35001,6 +35043,11 @@ class GridSelectionPlugin extends UIPlugin {
|
|
|
35001
35043
|
doesElementsHaveCommonMerges(id, cmd.base - 1, cmd.base)) {
|
|
35002
35044
|
return 2 /* CommandResult.WillRemoveExistingMerge */;
|
|
35003
35045
|
}
|
|
35046
|
+
const headers = [cmd.base, ...cmd.elements];
|
|
35047
|
+
const maxHeaderValue = isCol ? this.getters.getNumberCols(id) : this.getters.getNumberRows(id);
|
|
35048
|
+
if (headers.some((h) => h < 0 || h >= maxHeaderValue)) {
|
|
35049
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
35050
|
+
}
|
|
35004
35051
|
return 0 /* CommandResult.Success */;
|
|
35005
35052
|
}
|
|
35006
35053
|
//-------------------------------------------
|
|
@@ -39911,9 +39958,9 @@ function revertChanges(revisions) {
|
|
|
39911
39958
|
* Apply the changes of the given HistoryChange to the state
|
|
39912
39959
|
*/
|
|
39913
39960
|
function applyChange(change, target) {
|
|
39914
|
-
let val = change.
|
|
39915
|
-
|
|
39916
|
-
for (let pathIndex =
|
|
39961
|
+
let val = change.path[0];
|
|
39962
|
+
const key = change.path[change.path.length - 1];
|
|
39963
|
+
for (let pathIndex = 1; pathIndex < change.path.slice(0, -1).length; pathIndex++) {
|
|
39917
39964
|
const p = change.path[pathIndex];
|
|
39918
39965
|
if (val[p] === undefined) {
|
|
39919
39966
|
const nextPath = change.path[pathIndex + 1];
|
|
@@ -41043,13 +41090,14 @@ class StateObserver {
|
|
|
41043
41090
|
}
|
|
41044
41091
|
addChange(...args) {
|
|
41045
41092
|
const val = args.pop();
|
|
41046
|
-
const
|
|
41093
|
+
const root = args[0];
|
|
41047
41094
|
let value = root;
|
|
41048
|
-
let key =
|
|
41049
|
-
|
|
41050
|
-
|
|
41095
|
+
let key = args[args.length - 1];
|
|
41096
|
+
const pathLength = args.length - 2;
|
|
41097
|
+
for (let pathIndex = 1; pathIndex <= pathLength; pathIndex++) {
|
|
41098
|
+
const p = args[pathIndex];
|
|
41051
41099
|
if (value[p] === undefined) {
|
|
41052
|
-
const nextPath =
|
|
41100
|
+
const nextPath = args[pathIndex + 1];
|
|
41053
41101
|
value[p] = createEmptyStructure(nextPath);
|
|
41054
41102
|
}
|
|
41055
41103
|
value = value[p];
|
|
@@ -41058,8 +41106,7 @@ class StateObserver {
|
|
|
41058
41106
|
return;
|
|
41059
41107
|
}
|
|
41060
41108
|
this.changes.push({
|
|
41061
|
-
|
|
41062
|
-
path,
|
|
41109
|
+
path: args,
|
|
41063
41110
|
before: value[key],
|
|
41064
41111
|
after: val,
|
|
41065
41112
|
});
|
|
@@ -42793,7 +42840,10 @@ class Model extends EventBus {
|
|
|
42793
42840
|
*/
|
|
42794
42841
|
checkDispatchAllowed(command) {
|
|
42795
42842
|
const results = this.handlers.map((handler) => handler.allowDispatch(command));
|
|
42796
|
-
|
|
42843
|
+
if (results.some((r) => r !== 0 /* CommandResult.Success */)) {
|
|
42844
|
+
return new DispatchResult(results.flat());
|
|
42845
|
+
}
|
|
42846
|
+
return DispatchResult.Success;
|
|
42797
42847
|
}
|
|
42798
42848
|
finalize() {
|
|
42799
42849
|
this.status = 3 /* Status.Finalizing */;
|
|
@@ -43011,6 +43061,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
43011
43061
|
exports.tokenize = tokenize;
|
|
43012
43062
|
|
|
43013
43063
|
|
|
43014
|
-
__info__.version = '16.0.
|
|
43015
|
-
__info__.date = '2023-
|
|
43016
|
-
__info__.hash = '
|
|
43064
|
+
__info__.version = '16.0.26';
|
|
43065
|
+
__info__.date = '2023-12-05T09:37:20.450Z';
|
|
43066
|
+
__info__.hash = '10de093';
|
package/dist/o-spreadsheet.d.ts
CHANGED
|
@@ -1146,7 +1146,7 @@ declare class StateObserver {
|
|
|
1146
1146
|
commands: CoreCommand[];
|
|
1147
1147
|
};
|
|
1148
1148
|
addCommand(command: CoreCommand): void;
|
|
1149
|
-
addChange(...args:
|
|
1149
|
+
addChange(...args: [...HistoryChange["path"], any]): void;
|
|
1150
1150
|
}
|
|
1151
1151
|
|
|
1152
1152
|
interface Validator {
|
|
@@ -1562,6 +1562,7 @@ interface MoveColumnsRowsCommand extends GridDependentCommand {
|
|
|
1562
1562
|
type: "MOVE_COLUMNS_ROWS";
|
|
1563
1563
|
base: HeaderIndex;
|
|
1564
1564
|
elements: HeaderIndex[];
|
|
1565
|
+
position: "before" | "after";
|
|
1565
1566
|
}
|
|
1566
1567
|
interface ResizeColumnsRowsCommand extends GridDependentCommand {
|
|
1567
1568
|
type: "RESIZE_COLUMNS_ROWS";
|
|
@@ -2182,7 +2183,8 @@ declare const enum CommandResult {
|
|
|
2182
2183
|
DuplicatedChartId = 83,
|
|
2183
2184
|
ChartDoesNotExist = 84,
|
|
2184
2185
|
InvalidHeaderIndex = 85,
|
|
2185
|
-
InvalidQuantity = 86
|
|
2186
|
+
InvalidQuantity = 86,
|
|
2187
|
+
NoChanges = 87
|
|
2186
2188
|
}
|
|
2187
2189
|
interface CommandHandler<T> {
|
|
2188
2190
|
allowDispatch(command: T): CommandResult | CommandResult[];
|
|
@@ -2946,7 +2948,8 @@ interface BordersPluginState {
|
|
|
2946
2948
|
declare class BordersPlugin extends CorePlugin<BordersPluginState> implements BordersPluginState {
|
|
2947
2949
|
static getters: readonly ["getCellBorder"];
|
|
2948
2950
|
readonly borders: BordersPluginState["borders"];
|
|
2949
|
-
|
|
2951
|
+
allowDispatch(cmd: CoreCommand): CommandResult.Success | CommandResult.NoChanges;
|
|
2952
|
+
handle(cmd: CoreCommand): void;
|
|
2950
2953
|
/**
|
|
2951
2954
|
* Move borders according to the inserted columns.
|
|
2952
2955
|
* Ensure borders continuity.
|
|
@@ -3043,6 +3046,7 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
|
|
|
3043
3046
|
* Compute the borders to add to the given zone merged.
|
|
3044
3047
|
*/
|
|
3045
3048
|
private addBordersToMerge;
|
|
3049
|
+
private checkBordersUnchanged;
|
|
3046
3050
|
import(data: WorkbookData): void;
|
|
3047
3051
|
export(data: WorkbookData): void;
|
|
3048
3052
|
exportForExcel(data: ExcelWorkbookData): void;
|
|
@@ -3050,6 +3054,7 @@ declare class BordersPlugin extends CorePlugin<BordersPluginState> implements Bo
|
|
|
3050
3054
|
|
|
3051
3055
|
interface CoreState {
|
|
3052
3056
|
cells: Record<UID, Record<UID, Cell | undefined>>;
|
|
3057
|
+
nextId: number;
|
|
3053
3058
|
}
|
|
3054
3059
|
/**
|
|
3055
3060
|
* Core Plugin
|
|
@@ -3059,6 +3064,7 @@ interface CoreState {
|
|
|
3059
3064
|
*/
|
|
3060
3065
|
declare class CellPlugin extends CorePlugin<CoreState> implements CoreState {
|
|
3061
3066
|
static getters: readonly ["zoneToXC", "getCells", "getFormulaCellContent", "getCellStyle", "buildFormulaContent", "getCellById"];
|
|
3067
|
+
readonly nextId = 1;
|
|
3062
3068
|
readonly cells: {
|
|
3063
3069
|
[sheetId: string]: {
|
|
3064
3070
|
[id: string]: Cell;
|
|
@@ -3066,7 +3072,7 @@ declare class CellPlugin extends CorePlugin<CoreState> implements CoreState {
|
|
|
3066
3072
|
};
|
|
3067
3073
|
private createCell;
|
|
3068
3074
|
adaptRanges(applyChange: ApplyRangeChange, sheetId?: UID): void;
|
|
3069
|
-
allowDispatch(cmd: CoreCommand): CommandResult;
|
|
3075
|
+
allowDispatch(cmd: CoreCommand): CommandResult | CommandResult[];
|
|
3070
3076
|
handle(cmd: CoreCommand): void;
|
|
3071
3077
|
/**
|
|
3072
3078
|
* Set a format to all the cells in a zone
|
|
@@ -3127,8 +3133,10 @@ declare class CellPlugin extends CorePlugin<CoreState> implements CoreState {
|
|
|
3127
3133
|
* gets the currently used style/border of a cell based on it's coordinates
|
|
3128
3134
|
*/
|
|
3129
3135
|
private getFormat;
|
|
3136
|
+
private getNextUid;
|
|
3130
3137
|
private updateCell;
|
|
3131
3138
|
private checkCellOutOfSheet;
|
|
3139
|
+
private checkUselessClearCell;
|
|
3132
3140
|
}
|
|
3133
3141
|
|
|
3134
3142
|
/**
|
|
@@ -3615,15 +3623,6 @@ declare class SheetPlugin extends CorePlugin<SheetState> implements SheetState {
|
|
|
3615
3623
|
*/
|
|
3616
3624
|
private moveCellOnRowsDeletion;
|
|
3617
3625
|
private updateRowsStructureOnDeletion;
|
|
3618
|
-
/**
|
|
3619
|
-
* Update the rows of the sheet after an addition:
|
|
3620
|
-
* - Rename the rows
|
|
3621
|
-
*
|
|
3622
|
-
* @param sheet Sheet on which the deletion occurs
|
|
3623
|
-
* @param addedRow Index of the added row
|
|
3624
|
-
* @param rowsToAdd Number of the rows to add
|
|
3625
|
-
*/
|
|
3626
|
-
private updateRowsStructureOnAddition;
|
|
3627
3626
|
/**
|
|
3628
3627
|
* Add empty rows at the end of the rows
|
|
3629
3628
|
*
|
|
@@ -4659,8 +4658,7 @@ type Getters = {
|
|
|
4659
4658
|
} & LocalHistoryGetters & CoreGetters & SessionGetters & AutofillGetters & AutomaticSumGetters & ClipboardGetters & EditionGetters & EvaluationGetters & EvaluationChartGetters & EvaluationConditionalFormatGetters & FindAndReplaceGetters & HighlightGetters & CustomColorsGetters & RendererGetters & SelectionGetters & SelectionInputGetters & SelectionMultiUserGetters & SortGetters & UIOptionsGetters & SheetUIGetters & ViewportGetters & CellPopoverPluginGetters & FilterEvaluationGetters & HeaderVisibilityIUIGetters;
|
|
4660
4659
|
|
|
4661
4660
|
interface HistoryChange {
|
|
4662
|
-
|
|
4663
|
-
path: (string | number)[];
|
|
4661
|
+
path: [any, ...(number | string)[]];
|
|
4664
4662
|
before: any;
|
|
4665
4663
|
after: any;
|
|
4666
4664
|
}
|
|
@@ -5821,6 +5819,7 @@ interface ResizerState {
|
|
|
5821
5819
|
draggerShadowThickness: number;
|
|
5822
5820
|
delta: number;
|
|
5823
5821
|
base: number;
|
|
5822
|
+
position: "before" | "after";
|
|
5824
5823
|
}
|
|
5825
5824
|
interface ResizerProps {
|
|
5826
5825
|
onOpenContextMenu: (type: ContextMenuType, x: Pixel, y: Pixel) => void;
|