@odoo/o-spreadsheet 16.0.7 → 16.0.9
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 +268 -83
- package/dist/o-spreadsheet.d.ts +35 -6
- package/dist/o-spreadsheet.esm.js +268 -83
- package/dist/o-spreadsheet.iife.js +268 -83
- package/dist/o-spreadsheet.iife.min.js +242 -242
- package/package.json +1 -1
|
@@ -1023,6 +1023,10 @@ function deepEquals(o1, o2) {
|
|
|
1023
1023
|
}
|
|
1024
1024
|
return true;
|
|
1025
1025
|
}
|
|
1026
|
+
/** Check if the given array contains all the values of the other array. */
|
|
1027
|
+
function includesAll(arr, values) {
|
|
1028
|
+
return values.every((value) => arr.includes(value));
|
|
1029
|
+
}
|
|
1026
1030
|
/**
|
|
1027
1031
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
1028
1032
|
*/
|
|
@@ -1568,12 +1572,77 @@ const numberRepresentation = [];
|
|
|
1568
1572
|
* - all digit stored in the decimal part of the number
|
|
1569
1573
|
*
|
|
1570
1574
|
* The 'maxDecimal' parameter allows to indicate the number of digits to not
|
|
1571
|
-
* exceed in the decimal part, in which case digits are rounded
|
|
1575
|
+
* exceed in the decimal part, in which case digits are rounded.
|
|
1572
1576
|
*
|
|
1573
|
-
* Intl.Numberformat is used to properly handle all the roundings.
|
|
1574
|
-
* e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
|
|
1575
1577
|
**/
|
|
1576
1578
|
function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1579
|
+
const asString = value.toString();
|
|
1580
|
+
if (asString.includes("e"))
|
|
1581
|
+
return splitNumberIntl(value, maxDecimals);
|
|
1582
|
+
if (Number.isInteger(value)) {
|
|
1583
|
+
return { integerDigits: asString, decimalDigits: undefined };
|
|
1584
|
+
}
|
|
1585
|
+
const indexOfDot = asString.indexOf(".");
|
|
1586
|
+
let integerDigits = asString.substring(0, indexOfDot);
|
|
1587
|
+
let decimalDigits = asString.substring(indexOfDot + 1);
|
|
1588
|
+
if (maxDecimals === 0) {
|
|
1589
|
+
if (Number(decimalDigits[0]) >= 5) {
|
|
1590
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1591
|
+
}
|
|
1592
|
+
return { integerDigits, decimalDigits: undefined };
|
|
1593
|
+
}
|
|
1594
|
+
if (decimalDigits.length > maxDecimals) {
|
|
1595
|
+
const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
|
|
1596
|
+
decimalDigits = roundedDecimalDigits;
|
|
1597
|
+
if (roundedIntegerDigits !== "0") {
|
|
1598
|
+
integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
|
|
1602
|
+
}
|
|
1603
|
+
/**
|
|
1604
|
+
* Return the given string minus the trailing "0" characters.
|
|
1605
|
+
*
|
|
1606
|
+
* @param numberString : a string of integers
|
|
1607
|
+
* @returns the numberString, minus the eventual zeroes at the end
|
|
1608
|
+
*/
|
|
1609
|
+
function removeTrailingZeroes(numberString) {
|
|
1610
|
+
let i = numberString.length - 1;
|
|
1611
|
+
while (i >= 0 && numberString[i] === "0") {
|
|
1612
|
+
i--;
|
|
1613
|
+
}
|
|
1614
|
+
return numberString.slice(0, i + 1) || undefined;
|
|
1615
|
+
}
|
|
1616
|
+
/**
|
|
1617
|
+
* Limit the size of the decimal part of a number to the given number of digits.
|
|
1618
|
+
*/
|
|
1619
|
+
function limitDecimalDigits(decimalDigits, maxDecimals) {
|
|
1620
|
+
let integerDigits = "0";
|
|
1621
|
+
let resultDecimalDigits = decimalDigits;
|
|
1622
|
+
// Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
|
|
1623
|
+
// but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
|
|
1624
|
+
let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
|
|
1625
|
+
const i = maxDecimals;
|
|
1626
|
+
if (Number(Number(decimalDigits[i]) < 5)) {
|
|
1627
|
+
return { integerDigits, decimalDigits: slicedDecimalDigits };
|
|
1628
|
+
}
|
|
1629
|
+
// round up
|
|
1630
|
+
const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
|
|
1631
|
+
if (slicedRoundedUp.length > slicedDecimalDigits.length) {
|
|
1632
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1633
|
+
resultDecimalDigits = undefined;
|
|
1634
|
+
}
|
|
1635
|
+
else {
|
|
1636
|
+
resultDecimalDigits = slicedRoundedUp;
|
|
1637
|
+
}
|
|
1638
|
+
return { integerDigits, decimalDigits: resultDecimalDigits };
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Split numbers into decimal/integer digits using Intl.NumberFormat.
|
|
1642
|
+
* Supports numbers with a lot of digits that are transformed to scientific notation by
|
|
1643
|
+
* number.toString(), but is slow.
|
|
1644
|
+
*/
|
|
1645
|
+
function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1577
1646
|
let formatter = numberRepresentation[maxDecimals];
|
|
1578
1647
|
if (!formatter) {
|
|
1579
1648
|
formatter = new Intl.NumberFormat("en-US", {
|
|
@@ -3200,6 +3269,8 @@ var CommandResult;
|
|
|
3200
3269
|
CommandResult[CommandResult["InvalidSelectionStep"] = 82] = "InvalidSelectionStep";
|
|
3201
3270
|
CommandResult[CommandResult["DuplicatedChartId"] = 83] = "DuplicatedChartId";
|
|
3202
3271
|
CommandResult[CommandResult["ChartDoesNotExist"] = 84] = "ChartDoesNotExist";
|
|
3272
|
+
CommandResult[CommandResult["InvalidHeaderIndex"] = 85] = "InvalidHeaderIndex";
|
|
3273
|
+
CommandResult[CommandResult["InvalidQuantity"] = 86] = "InvalidQuantity";
|
|
3203
3274
|
})(CommandResult || (CommandResult = {}));
|
|
3204
3275
|
|
|
3205
3276
|
var DIRECTION;
|
|
@@ -3970,13 +4041,16 @@ class Menu extends Component {
|
|
|
3970
4041
|
}
|
|
3971
4042
|
});
|
|
3972
4043
|
}
|
|
4044
|
+
get visibleMenuItems() {
|
|
4045
|
+
return this.props.menuItems.filter((x) => x.isVisible(this.env));
|
|
4046
|
+
}
|
|
3973
4047
|
get subMenuPosition() {
|
|
3974
4048
|
const position = Object.assign({}, this.subMenu.position);
|
|
3975
4049
|
position.y -= this.subMenu.scrollOffset || 0;
|
|
3976
4050
|
return position;
|
|
3977
4051
|
}
|
|
3978
4052
|
get menuHeight() {
|
|
3979
|
-
return this.menuComponentHeight(this.
|
|
4053
|
+
return this.menuComponentHeight(this.visibleMenuItems);
|
|
3980
4054
|
}
|
|
3981
4055
|
get subMenuHeight() {
|
|
3982
4056
|
return this.menuComponentHeight(this.subMenu.menuItems);
|
|
@@ -4012,7 +4086,7 @@ class Menu extends Component {
|
|
|
4012
4086
|
* and the menu item at a given index.
|
|
4013
4087
|
*/
|
|
4014
4088
|
subMenuVerticalPosition(position) {
|
|
4015
|
-
const menusAbove = this.
|
|
4089
|
+
const menusAbove = this.visibleMenuItems.slice(0, position);
|
|
4016
4090
|
return this.menuComponentHeight(menusAbove) + this.position.y;
|
|
4017
4091
|
}
|
|
4018
4092
|
onExternalClick(ev) {
|
|
@@ -5545,6 +5619,11 @@ colMenuRegistry
|
|
|
5545
5619
|
name: REMOVE_COLUMNS_NAME,
|
|
5546
5620
|
sequence: 90,
|
|
5547
5621
|
action: REMOVE_COLUMNS_ACTION,
|
|
5622
|
+
isVisible: (env) => {
|
|
5623
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
5624
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
5625
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
5626
|
+
},
|
|
5548
5627
|
})
|
|
5549
5628
|
.add("clear_column", {
|
|
5550
5629
|
name: DELETE_CONTENT_COLUMNS_NAME,
|
|
@@ -5557,9 +5636,8 @@ colMenuRegistry
|
|
|
5557
5636
|
action: HIDE_COLUMNS_ACTION,
|
|
5558
5637
|
isVisible: (env) => {
|
|
5559
5638
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
5560
|
-
const
|
|
5561
|
-
return
|
|
5562
|
-
hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
|
|
5639
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
5640
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
5563
5641
|
},
|
|
5564
5642
|
separator: true,
|
|
5565
5643
|
})
|
|
@@ -5633,6 +5711,11 @@ rowMenuRegistry
|
|
|
5633
5711
|
name: REMOVE_ROWS_NAME,
|
|
5634
5712
|
sequence: 70,
|
|
5635
5713
|
action: REMOVE_ROWS_ACTION,
|
|
5714
|
+
isVisible: (env) => {
|
|
5715
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
5716
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
5717
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
5718
|
+
},
|
|
5636
5719
|
})
|
|
5637
5720
|
.add("clear_row", {
|
|
5638
5721
|
name: DELETE_CONTENT_ROWS_NAME,
|
|
@@ -5645,9 +5728,8 @@ rowMenuRegistry
|
|
|
5645
5728
|
action: HIDE_ROWS_ACTION,
|
|
5646
5729
|
isVisible: (env) => {
|
|
5647
5730
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
5648
|
-
const
|
|
5649
|
-
return
|
|
5650
|
-
hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
|
|
5731
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
5732
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
5651
5733
|
},
|
|
5652
5734
|
separator: true,
|
|
5653
5735
|
})
|
|
@@ -10309,7 +10391,7 @@ class ChartFigure extends Component {
|
|
|
10309
10391
|
openContextMenu(position) {
|
|
10310
10392
|
const registry = this.getMenuItemRegistry();
|
|
10311
10393
|
this.menuState.isOpen = true;
|
|
10312
|
-
this.menuState.menuItems = registry.getAll()
|
|
10394
|
+
this.menuState.menuItems = registry.getAll();
|
|
10313
10395
|
this.menuState.position = position;
|
|
10314
10396
|
}
|
|
10315
10397
|
get chartComponent() {
|
|
@@ -17327,7 +17409,7 @@ const POW = {
|
|
|
17327
17409
|
base (number) ${_lt("The number to raise to the exponent power.")}
|
|
17328
17410
|
exponent (number) ${_lt("The exponent to raise base to.")}
|
|
17329
17411
|
`),
|
|
17330
|
-
returns: ["
|
|
17412
|
+
returns: ["NUMBER"],
|
|
17331
17413
|
compute: function (base, exponent) {
|
|
17332
17414
|
return POWER.compute(base, exponent);
|
|
17333
17415
|
},
|
|
@@ -19829,14 +19911,31 @@ class ContentEditableHelper {
|
|
|
19829
19911
|
* */
|
|
19830
19912
|
getCurrentSelection() {
|
|
19831
19913
|
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
|
|
19832
|
-
let startSizeBefore = this.
|
|
19833
|
-
let endSizeBefore = this.
|
|
19914
|
+
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
19915
|
+
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
19834
19916
|
return {
|
|
19835
|
-
start: startSizeBefore
|
|
19836
|
-
end: endSizeBefore
|
|
19917
|
+
start: startSizeBefore,
|
|
19918
|
+
end: endSizeBefore,
|
|
19837
19919
|
};
|
|
19838
19920
|
}
|
|
19839
|
-
|
|
19921
|
+
/**
|
|
19922
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
19923
|
+
* The selected node is either a Text node or an Element node.
|
|
19924
|
+
*
|
|
19925
|
+
* case 1 -Text node:
|
|
19926
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
19927
|
+
* content length of all previous nodes.
|
|
19928
|
+
*
|
|
19929
|
+
* case 2 - Element node:
|
|
19930
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
19931
|
+
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
19932
|
+
*
|
|
19933
|
+
* See the MDN documentation for more details.
|
|
19934
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
19935
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
19936
|
+
*
|
|
19937
|
+
*/
|
|
19938
|
+
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
19840
19939
|
let it = this.iterateChildren(this.el);
|
|
19841
19940
|
let usedCharacters = 0;
|
|
19842
19941
|
let current = it.next();
|
|
@@ -19848,6 +19947,19 @@ class ContentEditableHelper {
|
|
|
19848
19947
|
}
|
|
19849
19948
|
current = it.next();
|
|
19850
19949
|
}
|
|
19950
|
+
if (current.value === nodeToFind) {
|
|
19951
|
+
if (!current.value.hasChildNodes()) {
|
|
19952
|
+
usedCharacters += nodeOffset;
|
|
19953
|
+
}
|
|
19954
|
+
else {
|
|
19955
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
19956
|
+
for (const child of children) {
|
|
19957
|
+
if (!child.textContent)
|
|
19958
|
+
continue;
|
|
19959
|
+
usedCharacters += child.textContent.length;
|
|
19960
|
+
}
|
|
19961
|
+
}
|
|
19962
|
+
}
|
|
19851
19963
|
return usedCharacters;
|
|
19852
19964
|
}
|
|
19853
19965
|
getStartAndEndSelection() {
|
|
@@ -22333,8 +22445,8 @@ class Grid extends Component {
|
|
|
22333
22445
|
},
|
|
22334
22446
|
"CTRL+END": () => {
|
|
22335
22447
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
22336
|
-
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL",
|
|
22337
|
-
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW",
|
|
22448
|
+
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
|
|
22449
|
+
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
|
|
22338
22450
|
this.env.model.selection.selectCell(col, row);
|
|
22339
22451
|
},
|
|
22340
22452
|
"SHIFT+ ": () => {
|
|
@@ -22410,9 +22522,10 @@ class Grid extends Component {
|
|
|
22410
22522
|
this.focus();
|
|
22411
22523
|
}
|
|
22412
22524
|
focus() {
|
|
22525
|
+
var _a;
|
|
22413
22526
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
22414
22527
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
22415
|
-
this.hiddenInput.el.focus();
|
|
22528
|
+
(_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
|
|
22416
22529
|
}
|
|
22417
22530
|
}
|
|
22418
22531
|
get gridEl() {
|
|
@@ -22616,9 +22729,7 @@ class Grid extends Component {
|
|
|
22616
22729
|
this.closeOpenedPopover();
|
|
22617
22730
|
this.menuState.isOpen = true;
|
|
22618
22731
|
this.menuState.position = { x, y };
|
|
22619
|
-
this.menuState.menuItems = registries$1[type]
|
|
22620
|
-
.getAll()
|
|
22621
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
22732
|
+
this.menuState.menuItems = registries$1[type].getAll();
|
|
22622
22733
|
}
|
|
22623
22734
|
copy(cut, ev) {
|
|
22624
22735
|
if (!this.gridEl.contains(document.activeElement)) {
|
|
@@ -24242,7 +24353,7 @@ function extractStyle(cell, data) {
|
|
|
24242
24353
|
if (cell.style) {
|
|
24243
24354
|
style = data.styles[cell.style];
|
|
24244
24355
|
}
|
|
24245
|
-
const format = cell
|
|
24356
|
+
const format = extractFormat(cell, data);
|
|
24246
24357
|
const exportedBorder = {};
|
|
24247
24358
|
if (cell.border) {
|
|
24248
24359
|
const border = data.borders[cell.border];
|
|
@@ -24276,6 +24387,22 @@ function extractStyle(cell, data) {
|
|
|
24276
24387
|
styles.font["italic"] = !!(style === null || style === void 0 ? void 0 : style.italic) || undefined;
|
|
24277
24388
|
return styles;
|
|
24278
24389
|
}
|
|
24390
|
+
function extractFormat(cell, data) {
|
|
24391
|
+
if (cell.format) {
|
|
24392
|
+
return data.formats[cell.format];
|
|
24393
|
+
}
|
|
24394
|
+
if (cell.isFormula) {
|
|
24395
|
+
const tokens = tokenize(cell.content || "");
|
|
24396
|
+
const functions = functionRegistry.content;
|
|
24397
|
+
const isExported = tokens
|
|
24398
|
+
.filter((tk) => tk.type === "FUNCTION")
|
|
24399
|
+
.every((tk) => functions[tk.value.toUpperCase()].isExported);
|
|
24400
|
+
if (!isExported) {
|
|
24401
|
+
return cell.computedFormat;
|
|
24402
|
+
}
|
|
24403
|
+
}
|
|
24404
|
+
return undefined;
|
|
24405
|
+
}
|
|
24279
24406
|
function normalizeStyle(construct, styles) {
|
|
24280
24407
|
const { id: fontId } = pushElement(styles["font"], construct.fonts);
|
|
24281
24408
|
const { id: fillId } = pushElement(styles["fill"], construct.fills);
|
|
@@ -26356,7 +26483,7 @@ function load(data, verboseImport) {
|
|
|
26356
26483
|
}
|
|
26357
26484
|
}
|
|
26358
26485
|
}
|
|
26359
|
-
data =
|
|
26486
|
+
data = deepCopy(data);
|
|
26360
26487
|
// apply migrations, if needed
|
|
26361
26488
|
if ("version" in data) {
|
|
26362
26489
|
if (data.version < CURRENT_VERSION) {
|
|
@@ -27498,6 +27625,9 @@ class CellPlugin extends CorePlugin {
|
|
|
27498
27625
|
const exportedCellData = sheet.cells[xc];
|
|
27499
27626
|
exportedCellData.value = cell.evaluated.value;
|
|
27500
27627
|
exportedCellData.isFormula = cell.isFormula();
|
|
27628
|
+
if (cell.format !== cell.evaluated.format) {
|
|
27629
|
+
exportedCellData.computedFormat = cell.evaluated.format;
|
|
27630
|
+
}
|
|
27501
27631
|
}
|
|
27502
27632
|
}
|
|
27503
27633
|
}
|
|
@@ -28941,7 +29071,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
28941
29071
|
allowDispatch(cmd) {
|
|
28942
29072
|
switch (cmd.type) {
|
|
28943
29073
|
case "HIDE_COLUMNS_ROWS": {
|
|
28944
|
-
if (!this.
|
|
29074
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
28945
29075
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
28946
29076
|
}
|
|
28947
29077
|
const hiddenGroup = cmd.dimension === "COL"
|
|
@@ -28950,10 +29080,25 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
28950
29080
|
const elements = cmd.dimension === "COL"
|
|
28951
29081
|
? this.getters.getNumberCols(cmd.sheetId)
|
|
28952
29082
|
: this.getters.getNumberRows(cmd.sheetId);
|
|
28953
|
-
|
|
28954
|
-
|
|
28955
|
-
|
|
29083
|
+
const hiddenElements = new Set((hiddenGroup || []).flat().concat(cmd.elements));
|
|
29084
|
+
if (hiddenElements.size >= elements) {
|
|
29085
|
+
return 65 /* CommandResult.TooManyHiddenElements */;
|
|
29086
|
+
}
|
|
29087
|
+
else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
|
|
29088
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29089
|
+
}
|
|
29090
|
+
else {
|
|
29091
|
+
return 0 /* CommandResult.Success */;
|
|
29092
|
+
}
|
|
28956
29093
|
}
|
|
29094
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
29095
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
29096
|
+
return 27 /* CommandResult.InvalidSheetId */;
|
|
29097
|
+
}
|
|
29098
|
+
if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
29099
|
+
return 8 /* CommandResult.NotEnoughElements */;
|
|
29100
|
+
}
|
|
29101
|
+
return 0 /* CommandResult.Success */;
|
|
28957
29102
|
}
|
|
28958
29103
|
return 0 /* CommandResult.Success */;
|
|
28959
29104
|
}
|
|
@@ -29000,6 +29145,10 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29000
29145
|
}
|
|
29001
29146
|
return;
|
|
29002
29147
|
}
|
|
29148
|
+
canRemoveHeaders(sheetId, dimension, elements) {
|
|
29149
|
+
const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
|
|
29150
|
+
return !includesAll(elements, visibleHeaders);
|
|
29151
|
+
}
|
|
29003
29152
|
isRowHiddenByUser(sheetId, index) {
|
|
29004
29153
|
return this.hiddenHeaders[sheetId].ROW[index];
|
|
29005
29154
|
}
|
|
@@ -29044,6 +29193,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29044
29193
|
}
|
|
29045
29194
|
return consecutiveIndexes;
|
|
29046
29195
|
}
|
|
29196
|
+
getAllVisibleHeaders(sheetId, dimension) {
|
|
29197
|
+
return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
|
|
29198
|
+
}
|
|
29047
29199
|
import(data) {
|
|
29048
29200
|
var _a, _b;
|
|
29049
29201
|
for (let sheet of data.sheets) {
|
|
@@ -29091,6 +29243,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29091
29243
|
}
|
|
29092
29244
|
}
|
|
29093
29245
|
HeaderVisibilityPlugin.getters = [
|
|
29246
|
+
"canRemoveHeaders",
|
|
29094
29247
|
"getHiddenColsGroups",
|
|
29095
29248
|
"getHiddenRowsGroups",
|
|
29096
29249
|
"isRowHiddenByUser",
|
|
@@ -29591,13 +29744,27 @@ class SheetPlugin extends CorePlugin {
|
|
|
29591
29744
|
return this.orderedSheetIds.length > 1
|
|
29592
29745
|
? 0 /* CommandResult.Success */
|
|
29593
29746
|
: 9 /* CommandResult.NotEnoughSheets */;
|
|
29747
|
+
case "ADD_COLUMNS_ROWS":
|
|
29748
|
+
const elements = cmd.dimension === "COL"
|
|
29749
|
+
? this.getNumberCols(cmd.sheetId)
|
|
29750
|
+
: this.getNumberRows(cmd.sheetId);
|
|
29751
|
+
if (cmd.base < 0 || cmd.base > elements) {
|
|
29752
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29753
|
+
}
|
|
29754
|
+
else if (cmd.quantity <= 0) {
|
|
29755
|
+
return 86 /* CommandResult.InvalidQuantity */;
|
|
29756
|
+
}
|
|
29757
|
+
return 0 /* CommandResult.Success */;
|
|
29594
29758
|
case "REMOVE_COLUMNS_ROWS": {
|
|
29595
|
-
const
|
|
29759
|
+
const elements = cmd.dimension === "COL"
|
|
29596
29760
|
? this.getNumberCols(cmd.sheetId)
|
|
29597
29761
|
: this.getNumberRows(cmd.sheetId);
|
|
29598
|
-
|
|
29599
|
-
|
|
29600
|
-
|
|
29762
|
+
if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
|
|
29763
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29764
|
+
}
|
|
29765
|
+
else {
|
|
29766
|
+
return 0 /* CommandResult.Success */;
|
|
29767
|
+
}
|
|
29601
29768
|
}
|
|
29602
29769
|
case "FREEZE_ROWS": {
|
|
29603
29770
|
return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
|
|
@@ -30082,7 +30249,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30082
30249
|
duplicateSheet(fromId, toId) {
|
|
30083
30250
|
const sheet = this.getSheet(fromId);
|
|
30084
30251
|
const toName = this.getDuplicateSheetName(sheet.name);
|
|
30085
|
-
const newSheet =
|
|
30252
|
+
const newSheet = deepCopy(sheet);
|
|
30086
30253
|
newSheet.id = toId;
|
|
30087
30254
|
newSheet.name = toName;
|
|
30088
30255
|
for (let col = 0; col <= newSheet.numberOfCols; col++) {
|
|
@@ -30209,10 +30376,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
30209
30376
|
}
|
|
30210
30377
|
}
|
|
30211
30378
|
moveCellOnColumnsDeletion(sheet, deletedColumn) {
|
|
30212
|
-
for (let
|
|
30213
|
-
const
|
|
30379
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30380
|
+
const row = sheet.rows[rowIndex];
|
|
30214
30381
|
for (let i in row.cells) {
|
|
30215
|
-
const colIndex =
|
|
30382
|
+
const colIndex = Number(i);
|
|
30216
30383
|
const cellId = row.cells[i];
|
|
30217
30384
|
if (cellId) {
|
|
30218
30385
|
if (colIndex === deletedColumn) {
|
|
@@ -30239,11 +30406,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
30239
30406
|
*/
|
|
30240
30407
|
moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
|
|
30241
30408
|
const commands = [];
|
|
30242
|
-
for (
|
|
30243
|
-
const
|
|
30409
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30410
|
+
const row = sheet.rows[rowIndex];
|
|
30244
30411
|
if (dimension !== "rows" || rowIndex >= addedElement) {
|
|
30245
30412
|
for (let i in row.cells) {
|
|
30246
|
-
const colIndex =
|
|
30413
|
+
const colIndex = Number(i);
|
|
30247
30414
|
const cellId = row.cells[i];
|
|
30248
30415
|
if (cellId) {
|
|
30249
30416
|
if (dimension === "rows" || colIndex >= addedElement) {
|
|
@@ -30273,11 +30440,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
30273
30440
|
*/
|
|
30274
30441
|
moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
30275
30442
|
const numberRows = deleteToRow - deleteFromRow + 1;
|
|
30276
|
-
for (let
|
|
30277
|
-
const
|
|
30443
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30444
|
+
const row = sheet.rows[rowIndex];
|
|
30278
30445
|
if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
|
|
30279
30446
|
for (let i in row.cells) {
|
|
30280
|
-
const colIndex =
|
|
30447
|
+
const colIndex = Number(i);
|
|
30281
30448
|
const cellId = row.cells[i];
|
|
30282
30449
|
if (cellId) {
|
|
30283
30450
|
this.dispatch("CLEAR_CELL", {
|
|
@@ -30290,7 +30457,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30290
30457
|
}
|
|
30291
30458
|
if (rowIndex > deleteToRow) {
|
|
30292
30459
|
for (let i in row.cells) {
|
|
30293
|
-
const colIndex =
|
|
30460
|
+
const colIndex = Number(i);
|
|
30294
30461
|
const cellId = row.cells[i];
|
|
30295
30462
|
if (cellId) {
|
|
30296
30463
|
this.dispatch("UPDATE_CELL_POSITION", {
|
|
@@ -30308,7 +30475,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30308
30475
|
const rows = [];
|
|
30309
30476
|
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
30310
30477
|
for (let i in sheet.rows) {
|
|
30311
|
-
if (
|
|
30478
|
+
if (Number(i) === index) {
|
|
30312
30479
|
continue;
|
|
30313
30480
|
}
|
|
30314
30481
|
rows.push({
|
|
@@ -32944,13 +33111,11 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
32944
33111
|
return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
|
|
32945
33112
|
}
|
|
32946
33113
|
intersectZoneWithViewport(sheetId, zone) {
|
|
32947
|
-
const colsRange = range(zone.left, zone.right + 1);
|
|
32948
|
-
const rowsRange = range(zone.top, zone.bottom + 1);
|
|
32949
33114
|
return {
|
|
32950
|
-
left: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32951
|
-
right: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32952
|
-
top: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
32953
|
-
bottom: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
33115
|
+
left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
|
|
33116
|
+
right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
|
|
33117
|
+
top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
|
|
33118
|
+
bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
|
|
32954
33119
|
};
|
|
32955
33120
|
}
|
|
32956
33121
|
updateFilter({ col, row, values, sheetId }) {
|
|
@@ -33392,13 +33557,33 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
33392
33557
|
}
|
|
33393
33558
|
getNextVisibleCellPosition(sheetId, col, row) {
|
|
33394
33559
|
return {
|
|
33395
|
-
col: this.findVisibleHeader(sheetId, "COL",
|
|
33396
|
-
row: this.findVisibleHeader(sheetId, "ROW",
|
|
33560
|
+
col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
|
|
33561
|
+
row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
|
|
33397
33562
|
};
|
|
33398
33563
|
}
|
|
33399
|
-
|
|
33400
|
-
|
|
33401
|
-
|
|
33564
|
+
/**
|
|
33565
|
+
* Find the first visible header in the range [`from` => `to`].
|
|
33566
|
+
*
|
|
33567
|
+
* Both `from` and `to` are inclusive.
|
|
33568
|
+
*/
|
|
33569
|
+
findVisibleHeader(sheetId, dimension, from, to) {
|
|
33570
|
+
if (from <= to) {
|
|
33571
|
+
for (let i = from; i <= to; i++) {
|
|
33572
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
33573
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
33574
|
+
return i;
|
|
33575
|
+
}
|
|
33576
|
+
}
|
|
33577
|
+
}
|
|
33578
|
+
if (from > to) {
|
|
33579
|
+
for (let i = from; i >= to; i--) {
|
|
33580
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
33581
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
33582
|
+
return i;
|
|
33583
|
+
}
|
|
33584
|
+
}
|
|
33585
|
+
}
|
|
33586
|
+
return undefined;
|
|
33402
33587
|
}
|
|
33403
33588
|
findLastVisibleColRowIndex(sheetId, dimension, indexes) {
|
|
33404
33589
|
let lastIndex;
|
|
@@ -33411,7 +33596,7 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
33411
33596
|
}
|
|
33412
33597
|
findFirstVisibleColRowIndex(sheetId, dimension) {
|
|
33413
33598
|
const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
|
|
33414
|
-
for (let i = 0; i < numberOfHeaders
|
|
33599
|
+
for (let i = 0; i < numberOfHeaders; i++) {
|
|
33415
33600
|
if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
|
|
33416
33601
|
return i;
|
|
33417
33602
|
}
|
|
@@ -37538,7 +37723,7 @@ class BottomBar extends Component {
|
|
|
37538
37723
|
}
|
|
37539
37724
|
openContextMenu(x, y, registry, menuId) {
|
|
37540
37725
|
this.menuState.isOpen = true;
|
|
37541
|
-
this.menuState.menuItems = registry.getAll()
|
|
37726
|
+
this.menuState.menuItems = registry.getAll();
|
|
37542
37727
|
this.menuState.position = { x, y };
|
|
37543
37728
|
this.menuState.menuId = menuId;
|
|
37544
37729
|
}
|
|
@@ -38299,7 +38484,7 @@ class TopBar extends Component {
|
|
|
38299
38484
|
const { left, top, height } = ev.target.getBoundingClientRect();
|
|
38300
38485
|
this.state.menuState.isOpen = true;
|
|
38301
38486
|
this.state.menuState.position = { x: left, y: top + height };
|
|
38302
|
-
this.state.menuState.menuItems = getMenuChildren(menu, this.env)
|
|
38487
|
+
this.state.menuState.menuItems = getMenuChildren(menu, this.env);
|
|
38303
38488
|
this.state.menuState.parentMenu = menu;
|
|
38304
38489
|
this.isSelectingMenu = true;
|
|
38305
38490
|
this.openedEl = ev.target;
|
|
@@ -38348,9 +38533,7 @@ class TopBar extends Component {
|
|
|
38348
38533
|
this.style.align = this.style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign);
|
|
38349
38534
|
this.fillColor = this.style.fillColor || "#ffffff";
|
|
38350
38535
|
this.textColor = this.style.textColor || "#000000";
|
|
38351
|
-
this.menus = topbarMenuRegistry
|
|
38352
|
-
.getAll()
|
|
38353
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
38536
|
+
this.menus = topbarMenuRegistry.getAll();
|
|
38354
38537
|
}
|
|
38355
38538
|
getMenuName(menu) {
|
|
38356
38539
|
return getMenuName(menu, this.env);
|
|
@@ -40416,8 +40599,8 @@ class SelectionStreamProcessor {
|
|
|
40416
40599
|
}
|
|
40417
40600
|
const { left, right, top, bottom } = zone;
|
|
40418
40601
|
const sheetId = this.getters.getActiveSheetId();
|
|
40419
|
-
const refCol = this.getters.findVisibleHeader(sheetId, "COL",
|
|
40420
|
-
const refRow = this.getters.findVisibleHeader(sheetId, "ROW",
|
|
40602
|
+
const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
|
|
40603
|
+
const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
|
|
40421
40604
|
if (refRow === undefined || refCol === undefined) {
|
|
40422
40605
|
return 17 /* CommandResult.SelectionOutOfBound */;
|
|
40423
40606
|
}
|
|
@@ -40492,10 +40675,10 @@ class SelectionStreamProcessor {
|
|
|
40492
40675
|
const { col: anchorCol, row: anchorRow } = anchor.cell;
|
|
40493
40676
|
return {
|
|
40494
40677
|
col: this.getters.isColHidden(sheetId, anchorCol)
|
|
40495
|
-
? this.getters.findVisibleHeader(sheetId, "COL",
|
|
40678
|
+
? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
|
|
40496
40679
|
: anchorCol,
|
|
40497
40680
|
row: this.getters.isRowHidden(sheetId, anchorRow)
|
|
40498
|
-
? this.getters.findVisibleHeader(sheetId, "ROW",
|
|
40681
|
+
? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
|
|
40499
40682
|
: anchorRow,
|
|
40500
40683
|
};
|
|
40501
40684
|
}
|
|
@@ -41030,12 +41213,9 @@ function addFormula(cell) {
|
|
|
41030
41213
|
else {
|
|
41031
41214
|
// Shouldn't we always output the value then ?
|
|
41032
41215
|
const value = cell.value;
|
|
41033
|
-
|
|
41034
|
-
|
|
41035
|
-
|
|
41036
|
-
attrs.push(["t", type]);
|
|
41037
|
-
node = escapeXml /*xml*/ `<v>${value}</v>`;
|
|
41038
|
-
}
|
|
41216
|
+
const type = getCellType(value);
|
|
41217
|
+
attrs.push(["t", type]);
|
|
41218
|
+
node = escapeXml /*xml*/ `<v>${value}</v>`;
|
|
41039
41219
|
return { attrs, node };
|
|
41040
41220
|
}
|
|
41041
41221
|
}
|
|
@@ -42135,6 +42315,8 @@ class Model extends EventBus {
|
|
|
42135
42315
|
* Internal status of the model. Important for command handling coordination
|
|
42136
42316
|
*/
|
|
42137
42317
|
this.status = 0 /* Status.Ready */;
|
|
42318
|
+
this.handlers = [];
|
|
42319
|
+
this.coreHandlers = [];
|
|
42138
42320
|
/**
|
|
42139
42321
|
* The dispatch method is the only entry point to manipulate data in the model.
|
|
42140
42322
|
* This is through this method that commands are dispatched most of the time
|
|
@@ -42207,7 +42389,7 @@ class Model extends EventBus {
|
|
|
42207
42389
|
const command = { type, ...payload };
|
|
42208
42390
|
const previousStatus = this.status;
|
|
42209
42391
|
this.status = 2 /* Status.RunningCore */;
|
|
42210
|
-
const handlers = this.isReplayingCommand ?
|
|
42392
|
+
const handlers = this.isReplayingCommand ? this.coreHandlers : this.handlers;
|
|
42211
42393
|
this.dispatchToHandlers(handlers, command);
|
|
42212
42394
|
this.status = previousStatus;
|
|
42213
42395
|
return DispatchResult.Success;
|
|
@@ -42241,6 +42423,8 @@ class Model extends EventBus {
|
|
|
42241
42423
|
this.uuidGenerator.setIsFastStrategy(true);
|
|
42242
42424
|
// Initiate stream processor
|
|
42243
42425
|
this.selection = new SelectionStreamProcessor(this.getters);
|
|
42426
|
+
this.coreHandlers.push(this.range);
|
|
42427
|
+
this.handlers.push(this.range);
|
|
42244
42428
|
// registering plugins
|
|
42245
42429
|
for (let Plugin of corePluginRegistry.getAll()) {
|
|
42246
42430
|
this.setupCorePlugin(Plugin, workbookData);
|
|
@@ -42250,6 +42434,7 @@ class Model extends EventBus {
|
|
|
42250
42434
|
this.setupUiPlugin(Plugin);
|
|
42251
42435
|
}
|
|
42252
42436
|
this.uuidGenerator.setIsFastStrategy(false);
|
|
42437
|
+
this.handlers.push(this.history);
|
|
42253
42438
|
// starting plugins
|
|
42254
42439
|
this.dispatch("START");
|
|
42255
42440
|
// Model should be the last permanent subscriber in the list since he should render
|
|
@@ -42270,9 +42455,6 @@ class Model extends EventBus {
|
|
|
42270
42455
|
// by owl, since we do not rely on reactivity
|
|
42271
42456
|
markRaw(this);
|
|
42272
42457
|
}
|
|
42273
|
-
get handlers() {
|
|
42274
|
-
return [this.range, ...this.corePlugins, ...this.uiPlugins, this.history];
|
|
42275
|
-
}
|
|
42276
42458
|
joinSession() {
|
|
42277
42459
|
this.session.join(this.config.client);
|
|
42278
42460
|
}
|
|
@@ -42291,6 +42473,7 @@ class Model extends EventBus {
|
|
|
42291
42473
|
this.getters[name] = plugin[name].bind(plugin);
|
|
42292
42474
|
}
|
|
42293
42475
|
this.uiPlugins.push(plugin);
|
|
42476
|
+
this.handlers.push(plugin);
|
|
42294
42477
|
const layers = Plugin.layers.map((l) => [plugin, l]);
|
|
42295
42478
|
this.renderers.push(...layers);
|
|
42296
42479
|
this.renderers.sort((p1, p2) => p1[1] - p2[1]);
|
|
@@ -42314,6 +42497,8 @@ class Model extends EventBus {
|
|
|
42314
42497
|
}
|
|
42315
42498
|
plugin.import(data);
|
|
42316
42499
|
this.corePlugins.push(plugin);
|
|
42500
|
+
this.coreHandlers.push(plugin);
|
|
42501
|
+
this.handlers.push(plugin);
|
|
42317
42502
|
}
|
|
42318
42503
|
onRemoteRevisionReceived({ commands }) {
|
|
42319
42504
|
for (let command of commands) {
|
|
@@ -42331,7 +42516,7 @@ class Model extends EventBus {
|
|
|
42331
42516
|
return;
|
|
42332
42517
|
}
|
|
42333
42518
|
this.isReplayingCommand = true;
|
|
42334
|
-
this.dispatchToHandlers(
|
|
42519
|
+
this.dispatchToHandlers(this.coreHandlers, command);
|
|
42335
42520
|
this.isReplayingCommand = false;
|
|
42336
42521
|
}), this.config.transportService, revisionId);
|
|
42337
42522
|
return session;
|
|
@@ -42431,7 +42616,7 @@ class Model extends EventBus {
|
|
|
42431
42616
|
}
|
|
42432
42617
|
}
|
|
42433
42618
|
data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
|
|
42434
|
-
data =
|
|
42619
|
+
data = deepCopy(data);
|
|
42435
42620
|
return data;
|
|
42436
42621
|
}
|
|
42437
42622
|
updateMode(mode) {
|
|
@@ -42458,7 +42643,7 @@ class Model extends EventBus {
|
|
|
42458
42643
|
handler.exportForExcel(data);
|
|
42459
42644
|
}
|
|
42460
42645
|
}
|
|
42461
|
-
data =
|
|
42646
|
+
data = deepCopy(data);
|
|
42462
42647
|
return getXLSX(data);
|
|
42463
42648
|
}
|
|
42464
42649
|
}
|
|
@@ -42562,6 +42747,6 @@ function addFunction(functionName, functionDescription) {
|
|
|
42562
42747
|
export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, cellTypes, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
|
|
42563
42748
|
|
|
42564
42749
|
|
|
42565
|
-
__info__.version = '16.0.
|
|
42566
|
-
__info__.date = '2023-04-
|
|
42567
|
-
__info__.hash = '
|
|
42750
|
+
__info__.version = '16.0.9';
|
|
42751
|
+
__info__.date = '2023-04-28T12:25:41.572Z';
|
|
42752
|
+
__info__.hash = 'e06ca83';
|