@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
|
@@ -1027,6 +1027,10 @@ function deepEquals(o1, o2) {
|
|
|
1027
1027
|
}
|
|
1028
1028
|
return true;
|
|
1029
1029
|
}
|
|
1030
|
+
/** Check if the given array contains all the values of the other array. */
|
|
1031
|
+
function includesAll(arr, values) {
|
|
1032
|
+
return values.every((value) => arr.includes(value));
|
|
1033
|
+
}
|
|
1030
1034
|
/**
|
|
1031
1035
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
1032
1036
|
*/
|
|
@@ -1572,12 +1576,77 @@ const numberRepresentation = [];
|
|
|
1572
1576
|
* - all digit stored in the decimal part of the number
|
|
1573
1577
|
*
|
|
1574
1578
|
* The 'maxDecimal' parameter allows to indicate the number of digits to not
|
|
1575
|
-
* exceed in the decimal part, in which case digits are rounded
|
|
1579
|
+
* exceed in the decimal part, in which case digits are rounded.
|
|
1576
1580
|
*
|
|
1577
|
-
* Intl.Numberformat is used to properly handle all the roundings.
|
|
1578
|
-
* e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
|
|
1579
1581
|
**/
|
|
1580
1582
|
function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1583
|
+
const asString = value.toString();
|
|
1584
|
+
if (asString.includes("e"))
|
|
1585
|
+
return splitNumberIntl(value, maxDecimals);
|
|
1586
|
+
if (Number.isInteger(value)) {
|
|
1587
|
+
return { integerDigits: asString, decimalDigits: undefined };
|
|
1588
|
+
}
|
|
1589
|
+
const indexOfDot = asString.indexOf(".");
|
|
1590
|
+
let integerDigits = asString.substring(0, indexOfDot);
|
|
1591
|
+
let decimalDigits = asString.substring(indexOfDot + 1);
|
|
1592
|
+
if (maxDecimals === 0) {
|
|
1593
|
+
if (Number(decimalDigits[0]) >= 5) {
|
|
1594
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1595
|
+
}
|
|
1596
|
+
return { integerDigits, decimalDigits: undefined };
|
|
1597
|
+
}
|
|
1598
|
+
if (decimalDigits.length > maxDecimals) {
|
|
1599
|
+
const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
|
|
1600
|
+
decimalDigits = roundedDecimalDigits;
|
|
1601
|
+
if (roundedIntegerDigits !== "0") {
|
|
1602
|
+
integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
|
|
1606
|
+
}
|
|
1607
|
+
/**
|
|
1608
|
+
* Return the given string minus the trailing "0" characters.
|
|
1609
|
+
*
|
|
1610
|
+
* @param numberString : a string of integers
|
|
1611
|
+
* @returns the numberString, minus the eventual zeroes at the end
|
|
1612
|
+
*/
|
|
1613
|
+
function removeTrailingZeroes(numberString) {
|
|
1614
|
+
let i = numberString.length - 1;
|
|
1615
|
+
while (i >= 0 && numberString[i] === "0") {
|
|
1616
|
+
i--;
|
|
1617
|
+
}
|
|
1618
|
+
return numberString.slice(0, i + 1) || undefined;
|
|
1619
|
+
}
|
|
1620
|
+
/**
|
|
1621
|
+
* Limit the size of the decimal part of a number to the given number of digits.
|
|
1622
|
+
*/
|
|
1623
|
+
function limitDecimalDigits(decimalDigits, maxDecimals) {
|
|
1624
|
+
let integerDigits = "0";
|
|
1625
|
+
let resultDecimalDigits = decimalDigits;
|
|
1626
|
+
// Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
|
|
1627
|
+
// but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
|
|
1628
|
+
let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
|
|
1629
|
+
const i = maxDecimals;
|
|
1630
|
+
if (Number(Number(decimalDigits[i]) < 5)) {
|
|
1631
|
+
return { integerDigits, decimalDigits: slicedDecimalDigits };
|
|
1632
|
+
}
|
|
1633
|
+
// round up
|
|
1634
|
+
const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
|
|
1635
|
+
if (slicedRoundedUp.length > slicedDecimalDigits.length) {
|
|
1636
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1637
|
+
resultDecimalDigits = undefined;
|
|
1638
|
+
}
|
|
1639
|
+
else {
|
|
1640
|
+
resultDecimalDigits = slicedRoundedUp;
|
|
1641
|
+
}
|
|
1642
|
+
return { integerDigits, decimalDigits: resultDecimalDigits };
|
|
1643
|
+
}
|
|
1644
|
+
/**
|
|
1645
|
+
* Split numbers into decimal/integer digits using Intl.NumberFormat.
|
|
1646
|
+
* Supports numbers with a lot of digits that are transformed to scientific notation by
|
|
1647
|
+
* number.toString(), but is slow.
|
|
1648
|
+
*/
|
|
1649
|
+
function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1581
1650
|
let formatter = numberRepresentation[maxDecimals];
|
|
1582
1651
|
if (!formatter) {
|
|
1583
1652
|
formatter = new Intl.NumberFormat("en-US", {
|
|
@@ -3204,6 +3273,8 @@ exports.CommandResult = void 0;
|
|
|
3204
3273
|
CommandResult[CommandResult["InvalidSelectionStep"] = 82] = "InvalidSelectionStep";
|
|
3205
3274
|
CommandResult[CommandResult["DuplicatedChartId"] = 83] = "DuplicatedChartId";
|
|
3206
3275
|
CommandResult[CommandResult["ChartDoesNotExist"] = 84] = "ChartDoesNotExist";
|
|
3276
|
+
CommandResult[CommandResult["InvalidHeaderIndex"] = 85] = "InvalidHeaderIndex";
|
|
3277
|
+
CommandResult[CommandResult["InvalidQuantity"] = 86] = "InvalidQuantity";
|
|
3207
3278
|
})(exports.CommandResult || (exports.CommandResult = {}));
|
|
3208
3279
|
|
|
3209
3280
|
var DIRECTION;
|
|
@@ -3974,13 +4045,16 @@ class Menu extends owl.Component {
|
|
|
3974
4045
|
}
|
|
3975
4046
|
});
|
|
3976
4047
|
}
|
|
4048
|
+
get visibleMenuItems() {
|
|
4049
|
+
return this.props.menuItems.filter((x) => x.isVisible(this.env));
|
|
4050
|
+
}
|
|
3977
4051
|
get subMenuPosition() {
|
|
3978
4052
|
const position = Object.assign({}, this.subMenu.position);
|
|
3979
4053
|
position.y -= this.subMenu.scrollOffset || 0;
|
|
3980
4054
|
return position;
|
|
3981
4055
|
}
|
|
3982
4056
|
get menuHeight() {
|
|
3983
|
-
return this.menuComponentHeight(this.
|
|
4057
|
+
return this.menuComponentHeight(this.visibleMenuItems);
|
|
3984
4058
|
}
|
|
3985
4059
|
get subMenuHeight() {
|
|
3986
4060
|
return this.menuComponentHeight(this.subMenu.menuItems);
|
|
@@ -4016,7 +4090,7 @@ class Menu extends owl.Component {
|
|
|
4016
4090
|
* and the menu item at a given index.
|
|
4017
4091
|
*/
|
|
4018
4092
|
subMenuVerticalPosition(position) {
|
|
4019
|
-
const menusAbove = this.
|
|
4093
|
+
const menusAbove = this.visibleMenuItems.slice(0, position);
|
|
4020
4094
|
return this.menuComponentHeight(menusAbove) + this.position.y;
|
|
4021
4095
|
}
|
|
4022
4096
|
onExternalClick(ev) {
|
|
@@ -5549,6 +5623,11 @@ colMenuRegistry
|
|
|
5549
5623
|
name: REMOVE_COLUMNS_NAME,
|
|
5550
5624
|
sequence: 90,
|
|
5551
5625
|
action: REMOVE_COLUMNS_ACTION,
|
|
5626
|
+
isVisible: (env) => {
|
|
5627
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
5628
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
5629
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
5630
|
+
},
|
|
5552
5631
|
})
|
|
5553
5632
|
.add("clear_column", {
|
|
5554
5633
|
name: DELETE_CONTENT_COLUMNS_NAME,
|
|
@@ -5561,9 +5640,8 @@ colMenuRegistry
|
|
|
5561
5640
|
action: HIDE_COLUMNS_ACTION,
|
|
5562
5641
|
isVisible: (env) => {
|
|
5563
5642
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
5564
|
-
const
|
|
5565
|
-
return
|
|
5566
|
-
hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
|
|
5643
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
5644
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
5567
5645
|
},
|
|
5568
5646
|
separator: true,
|
|
5569
5647
|
})
|
|
@@ -5637,6 +5715,11 @@ rowMenuRegistry
|
|
|
5637
5715
|
name: REMOVE_ROWS_NAME,
|
|
5638
5716
|
sequence: 70,
|
|
5639
5717
|
action: REMOVE_ROWS_ACTION,
|
|
5718
|
+
isVisible: (env) => {
|
|
5719
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
5720
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
5721
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
5722
|
+
},
|
|
5640
5723
|
})
|
|
5641
5724
|
.add("clear_row", {
|
|
5642
5725
|
name: DELETE_CONTENT_ROWS_NAME,
|
|
@@ -5649,9 +5732,8 @@ rowMenuRegistry
|
|
|
5649
5732
|
action: HIDE_ROWS_ACTION,
|
|
5650
5733
|
isVisible: (env) => {
|
|
5651
5734
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
5652
|
-
const
|
|
5653
|
-
return
|
|
5654
|
-
hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
|
|
5735
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
5736
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
5655
5737
|
},
|
|
5656
5738
|
separator: true,
|
|
5657
5739
|
})
|
|
@@ -10313,7 +10395,7 @@ class ChartFigure extends owl.Component {
|
|
|
10313
10395
|
openContextMenu(position) {
|
|
10314
10396
|
const registry = this.getMenuItemRegistry();
|
|
10315
10397
|
this.menuState.isOpen = true;
|
|
10316
|
-
this.menuState.menuItems = registry.getAll()
|
|
10398
|
+
this.menuState.menuItems = registry.getAll();
|
|
10317
10399
|
this.menuState.position = position;
|
|
10318
10400
|
}
|
|
10319
10401
|
get chartComponent() {
|
|
@@ -17331,7 +17413,7 @@ const POW = {
|
|
|
17331
17413
|
base (number) ${_lt("The number to raise to the exponent power.")}
|
|
17332
17414
|
exponent (number) ${_lt("The exponent to raise base to.")}
|
|
17333
17415
|
`),
|
|
17334
|
-
returns: ["
|
|
17416
|
+
returns: ["NUMBER"],
|
|
17335
17417
|
compute: function (base, exponent) {
|
|
17336
17418
|
return POWER.compute(base, exponent);
|
|
17337
17419
|
},
|
|
@@ -19833,14 +19915,31 @@ class ContentEditableHelper {
|
|
|
19833
19915
|
* */
|
|
19834
19916
|
getCurrentSelection() {
|
|
19835
19917
|
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
|
|
19836
|
-
let startSizeBefore = this.
|
|
19837
|
-
let endSizeBefore = this.
|
|
19918
|
+
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
19919
|
+
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
19838
19920
|
return {
|
|
19839
|
-
start: startSizeBefore
|
|
19840
|
-
end: endSizeBefore
|
|
19921
|
+
start: startSizeBefore,
|
|
19922
|
+
end: endSizeBefore,
|
|
19841
19923
|
};
|
|
19842
19924
|
}
|
|
19843
|
-
|
|
19925
|
+
/**
|
|
19926
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
19927
|
+
* The selected node is either a Text node or an Element node.
|
|
19928
|
+
*
|
|
19929
|
+
* case 1 -Text node:
|
|
19930
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
19931
|
+
* content length of all previous nodes.
|
|
19932
|
+
*
|
|
19933
|
+
* case 2 - Element node:
|
|
19934
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
19935
|
+
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
19936
|
+
*
|
|
19937
|
+
* See the MDN documentation for more details.
|
|
19938
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
19939
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
19940
|
+
*
|
|
19941
|
+
*/
|
|
19942
|
+
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
19844
19943
|
let it = this.iterateChildren(this.el);
|
|
19845
19944
|
let usedCharacters = 0;
|
|
19846
19945
|
let current = it.next();
|
|
@@ -19852,6 +19951,19 @@ class ContentEditableHelper {
|
|
|
19852
19951
|
}
|
|
19853
19952
|
current = it.next();
|
|
19854
19953
|
}
|
|
19954
|
+
if (current.value === nodeToFind) {
|
|
19955
|
+
if (!current.value.hasChildNodes()) {
|
|
19956
|
+
usedCharacters += nodeOffset;
|
|
19957
|
+
}
|
|
19958
|
+
else {
|
|
19959
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
19960
|
+
for (const child of children) {
|
|
19961
|
+
if (!child.textContent)
|
|
19962
|
+
continue;
|
|
19963
|
+
usedCharacters += child.textContent.length;
|
|
19964
|
+
}
|
|
19965
|
+
}
|
|
19966
|
+
}
|
|
19855
19967
|
return usedCharacters;
|
|
19856
19968
|
}
|
|
19857
19969
|
getStartAndEndSelection() {
|
|
@@ -22337,8 +22449,8 @@ class Grid extends owl.Component {
|
|
|
22337
22449
|
},
|
|
22338
22450
|
"CTRL+END": () => {
|
|
22339
22451
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
22340
|
-
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL",
|
|
22341
|
-
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW",
|
|
22452
|
+
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
|
|
22453
|
+
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
|
|
22342
22454
|
this.env.model.selection.selectCell(col, row);
|
|
22343
22455
|
},
|
|
22344
22456
|
"SHIFT+ ": () => {
|
|
@@ -22414,9 +22526,10 @@ class Grid extends owl.Component {
|
|
|
22414
22526
|
this.focus();
|
|
22415
22527
|
}
|
|
22416
22528
|
focus() {
|
|
22529
|
+
var _a;
|
|
22417
22530
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
22418
22531
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
22419
|
-
this.hiddenInput.el.focus();
|
|
22532
|
+
(_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
|
|
22420
22533
|
}
|
|
22421
22534
|
}
|
|
22422
22535
|
get gridEl() {
|
|
@@ -22620,9 +22733,7 @@ class Grid extends owl.Component {
|
|
|
22620
22733
|
this.closeOpenedPopover();
|
|
22621
22734
|
this.menuState.isOpen = true;
|
|
22622
22735
|
this.menuState.position = { x, y };
|
|
22623
|
-
this.menuState.menuItems = registries$1[type]
|
|
22624
|
-
.getAll()
|
|
22625
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
22736
|
+
this.menuState.menuItems = registries$1[type].getAll();
|
|
22626
22737
|
}
|
|
22627
22738
|
copy(cut, ev) {
|
|
22628
22739
|
if (!this.gridEl.contains(document.activeElement)) {
|
|
@@ -24246,7 +24357,7 @@ function extractStyle(cell, data) {
|
|
|
24246
24357
|
if (cell.style) {
|
|
24247
24358
|
style = data.styles[cell.style];
|
|
24248
24359
|
}
|
|
24249
|
-
const format = cell
|
|
24360
|
+
const format = extractFormat(cell, data);
|
|
24250
24361
|
const exportedBorder = {};
|
|
24251
24362
|
if (cell.border) {
|
|
24252
24363
|
const border = data.borders[cell.border];
|
|
@@ -24280,6 +24391,22 @@ function extractStyle(cell, data) {
|
|
|
24280
24391
|
styles.font["italic"] = !!(style === null || style === void 0 ? void 0 : style.italic) || undefined;
|
|
24281
24392
|
return styles;
|
|
24282
24393
|
}
|
|
24394
|
+
function extractFormat(cell, data) {
|
|
24395
|
+
if (cell.format) {
|
|
24396
|
+
return data.formats[cell.format];
|
|
24397
|
+
}
|
|
24398
|
+
if (cell.isFormula) {
|
|
24399
|
+
const tokens = tokenize(cell.content || "");
|
|
24400
|
+
const functions = functionRegistry.content;
|
|
24401
|
+
const isExported = tokens
|
|
24402
|
+
.filter((tk) => tk.type === "FUNCTION")
|
|
24403
|
+
.every((tk) => functions[tk.value.toUpperCase()].isExported);
|
|
24404
|
+
if (!isExported) {
|
|
24405
|
+
return cell.computedFormat;
|
|
24406
|
+
}
|
|
24407
|
+
}
|
|
24408
|
+
return undefined;
|
|
24409
|
+
}
|
|
24283
24410
|
function normalizeStyle(construct, styles) {
|
|
24284
24411
|
const { id: fontId } = pushElement(styles["font"], construct.fonts);
|
|
24285
24412
|
const { id: fillId } = pushElement(styles["fill"], construct.fills);
|
|
@@ -26360,7 +26487,7 @@ function load(data, verboseImport) {
|
|
|
26360
26487
|
}
|
|
26361
26488
|
}
|
|
26362
26489
|
}
|
|
26363
|
-
data =
|
|
26490
|
+
data = deepCopy(data);
|
|
26364
26491
|
// apply migrations, if needed
|
|
26365
26492
|
if ("version" in data) {
|
|
26366
26493
|
if (data.version < CURRENT_VERSION) {
|
|
@@ -27502,6 +27629,9 @@ class CellPlugin extends CorePlugin {
|
|
|
27502
27629
|
const exportedCellData = sheet.cells[xc];
|
|
27503
27630
|
exportedCellData.value = cell.evaluated.value;
|
|
27504
27631
|
exportedCellData.isFormula = cell.isFormula();
|
|
27632
|
+
if (cell.format !== cell.evaluated.format) {
|
|
27633
|
+
exportedCellData.computedFormat = cell.evaluated.format;
|
|
27634
|
+
}
|
|
27505
27635
|
}
|
|
27506
27636
|
}
|
|
27507
27637
|
}
|
|
@@ -28945,7 +29075,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
28945
29075
|
allowDispatch(cmd) {
|
|
28946
29076
|
switch (cmd.type) {
|
|
28947
29077
|
case "HIDE_COLUMNS_ROWS": {
|
|
28948
|
-
if (!this.
|
|
29078
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
28949
29079
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
28950
29080
|
}
|
|
28951
29081
|
const hiddenGroup = cmd.dimension === "COL"
|
|
@@ -28954,10 +29084,25 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
28954
29084
|
const elements = cmd.dimension === "COL"
|
|
28955
29085
|
? this.getters.getNumberCols(cmd.sheetId)
|
|
28956
29086
|
: this.getters.getNumberRows(cmd.sheetId);
|
|
28957
|
-
|
|
28958
|
-
|
|
28959
|
-
|
|
29087
|
+
const hiddenElements = new Set((hiddenGroup || []).flat().concat(cmd.elements));
|
|
29088
|
+
if (hiddenElements.size >= elements) {
|
|
29089
|
+
return 65 /* CommandResult.TooManyHiddenElements */;
|
|
29090
|
+
}
|
|
29091
|
+
else if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
|
|
29092
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29093
|
+
}
|
|
29094
|
+
else {
|
|
29095
|
+
return 0 /* CommandResult.Success */;
|
|
29096
|
+
}
|
|
28960
29097
|
}
|
|
29098
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
29099
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
29100
|
+
return 27 /* CommandResult.InvalidSheetId */;
|
|
29101
|
+
}
|
|
29102
|
+
if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
29103
|
+
return 8 /* CommandResult.NotEnoughElements */;
|
|
29104
|
+
}
|
|
29105
|
+
return 0 /* CommandResult.Success */;
|
|
28961
29106
|
}
|
|
28962
29107
|
return 0 /* CommandResult.Success */;
|
|
28963
29108
|
}
|
|
@@ -29004,6 +29149,10 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29004
29149
|
}
|
|
29005
29150
|
return;
|
|
29006
29151
|
}
|
|
29152
|
+
canRemoveHeaders(sheetId, dimension, elements) {
|
|
29153
|
+
const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
|
|
29154
|
+
return !includesAll(elements, visibleHeaders);
|
|
29155
|
+
}
|
|
29007
29156
|
isRowHiddenByUser(sheetId, index) {
|
|
29008
29157
|
return this.hiddenHeaders[sheetId].ROW[index];
|
|
29009
29158
|
}
|
|
@@ -29048,6 +29197,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29048
29197
|
}
|
|
29049
29198
|
return consecutiveIndexes;
|
|
29050
29199
|
}
|
|
29200
|
+
getAllVisibleHeaders(sheetId, dimension) {
|
|
29201
|
+
return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
|
|
29202
|
+
}
|
|
29051
29203
|
import(data) {
|
|
29052
29204
|
var _a, _b;
|
|
29053
29205
|
for (let sheet of data.sheets) {
|
|
@@ -29095,6 +29247,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29095
29247
|
}
|
|
29096
29248
|
}
|
|
29097
29249
|
HeaderVisibilityPlugin.getters = [
|
|
29250
|
+
"canRemoveHeaders",
|
|
29098
29251
|
"getHiddenColsGroups",
|
|
29099
29252
|
"getHiddenRowsGroups",
|
|
29100
29253
|
"isRowHiddenByUser",
|
|
@@ -29595,13 +29748,27 @@ class SheetPlugin extends CorePlugin {
|
|
|
29595
29748
|
return this.orderedSheetIds.length > 1
|
|
29596
29749
|
? 0 /* CommandResult.Success */
|
|
29597
29750
|
: 9 /* CommandResult.NotEnoughSheets */;
|
|
29751
|
+
case "ADD_COLUMNS_ROWS":
|
|
29752
|
+
const elements = cmd.dimension === "COL"
|
|
29753
|
+
? this.getNumberCols(cmd.sheetId)
|
|
29754
|
+
: this.getNumberRows(cmd.sheetId);
|
|
29755
|
+
if (cmd.base < 0 || cmd.base > elements) {
|
|
29756
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29757
|
+
}
|
|
29758
|
+
else if (cmd.quantity <= 0) {
|
|
29759
|
+
return 86 /* CommandResult.InvalidQuantity */;
|
|
29760
|
+
}
|
|
29761
|
+
return 0 /* CommandResult.Success */;
|
|
29598
29762
|
case "REMOVE_COLUMNS_ROWS": {
|
|
29599
|
-
const
|
|
29763
|
+
const elements = cmd.dimension === "COL"
|
|
29600
29764
|
? this.getNumberCols(cmd.sheetId)
|
|
29601
29765
|
: this.getNumberRows(cmd.sheetId);
|
|
29602
|
-
|
|
29603
|
-
|
|
29604
|
-
|
|
29766
|
+
if (Math.min(...cmd.elements) < 0 || Math.max(...cmd.elements) > elements) {
|
|
29767
|
+
return 85 /* CommandResult.InvalidHeaderIndex */;
|
|
29768
|
+
}
|
|
29769
|
+
else {
|
|
29770
|
+
return 0 /* CommandResult.Success */;
|
|
29771
|
+
}
|
|
29605
29772
|
}
|
|
29606
29773
|
case "FREEZE_ROWS": {
|
|
29607
29774
|
return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
|
|
@@ -30086,7 +30253,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30086
30253
|
duplicateSheet(fromId, toId) {
|
|
30087
30254
|
const sheet = this.getSheet(fromId);
|
|
30088
30255
|
const toName = this.getDuplicateSheetName(sheet.name);
|
|
30089
|
-
const newSheet =
|
|
30256
|
+
const newSheet = deepCopy(sheet);
|
|
30090
30257
|
newSheet.id = toId;
|
|
30091
30258
|
newSheet.name = toName;
|
|
30092
30259
|
for (let col = 0; col <= newSheet.numberOfCols; col++) {
|
|
@@ -30213,10 +30380,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
30213
30380
|
}
|
|
30214
30381
|
}
|
|
30215
30382
|
moveCellOnColumnsDeletion(sheet, deletedColumn) {
|
|
30216
|
-
for (let
|
|
30217
|
-
const
|
|
30383
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30384
|
+
const row = sheet.rows[rowIndex];
|
|
30218
30385
|
for (let i in row.cells) {
|
|
30219
|
-
const colIndex =
|
|
30386
|
+
const colIndex = Number(i);
|
|
30220
30387
|
const cellId = row.cells[i];
|
|
30221
30388
|
if (cellId) {
|
|
30222
30389
|
if (colIndex === deletedColumn) {
|
|
@@ -30243,11 +30410,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
30243
30410
|
*/
|
|
30244
30411
|
moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
|
|
30245
30412
|
const commands = [];
|
|
30246
|
-
for (
|
|
30247
|
-
const
|
|
30413
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30414
|
+
const row = sheet.rows[rowIndex];
|
|
30248
30415
|
if (dimension !== "rows" || rowIndex >= addedElement) {
|
|
30249
30416
|
for (let i in row.cells) {
|
|
30250
|
-
const colIndex =
|
|
30417
|
+
const colIndex = Number(i);
|
|
30251
30418
|
const cellId = row.cells[i];
|
|
30252
30419
|
if (cellId) {
|
|
30253
30420
|
if (dimension === "rows" || colIndex >= addedElement) {
|
|
@@ -30277,11 +30444,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
30277
30444
|
*/
|
|
30278
30445
|
moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
30279
30446
|
const numberRows = deleteToRow - deleteFromRow + 1;
|
|
30280
|
-
for (let
|
|
30281
|
-
const
|
|
30447
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
30448
|
+
const row = sheet.rows[rowIndex];
|
|
30282
30449
|
if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
|
|
30283
30450
|
for (let i in row.cells) {
|
|
30284
|
-
const colIndex =
|
|
30451
|
+
const colIndex = Number(i);
|
|
30285
30452
|
const cellId = row.cells[i];
|
|
30286
30453
|
if (cellId) {
|
|
30287
30454
|
this.dispatch("CLEAR_CELL", {
|
|
@@ -30294,7 +30461,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30294
30461
|
}
|
|
30295
30462
|
if (rowIndex > deleteToRow) {
|
|
30296
30463
|
for (let i in row.cells) {
|
|
30297
|
-
const colIndex =
|
|
30464
|
+
const colIndex = Number(i);
|
|
30298
30465
|
const cellId = row.cells[i];
|
|
30299
30466
|
if (cellId) {
|
|
30300
30467
|
this.dispatch("UPDATE_CELL_POSITION", {
|
|
@@ -30312,7 +30479,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
30312
30479
|
const rows = [];
|
|
30313
30480
|
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
30314
30481
|
for (let i in sheet.rows) {
|
|
30315
|
-
if (
|
|
30482
|
+
if (Number(i) === index) {
|
|
30316
30483
|
continue;
|
|
30317
30484
|
}
|
|
30318
30485
|
rows.push({
|
|
@@ -32948,13 +33115,11 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
32948
33115
|
return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
|
|
32949
33116
|
}
|
|
32950
33117
|
intersectZoneWithViewport(sheetId, zone) {
|
|
32951
|
-
const colsRange = range(zone.left, zone.right + 1);
|
|
32952
|
-
const rowsRange = range(zone.top, zone.bottom + 1);
|
|
32953
33118
|
return {
|
|
32954
|
-
left: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32955
|
-
right: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32956
|
-
top: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
32957
|
-
bottom: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
33119
|
+
left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
|
|
33120
|
+
right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
|
|
33121
|
+
top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
|
|
33122
|
+
bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
|
|
32958
33123
|
};
|
|
32959
33124
|
}
|
|
32960
33125
|
updateFilter({ col, row, values, sheetId }) {
|
|
@@ -33396,13 +33561,33 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
33396
33561
|
}
|
|
33397
33562
|
getNextVisibleCellPosition(sheetId, col, row) {
|
|
33398
33563
|
return {
|
|
33399
|
-
col: this.findVisibleHeader(sheetId, "COL",
|
|
33400
|
-
row: this.findVisibleHeader(sheetId, "ROW",
|
|
33564
|
+
col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
|
|
33565
|
+
row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
|
|
33401
33566
|
};
|
|
33402
33567
|
}
|
|
33403
|
-
|
|
33404
|
-
|
|
33405
|
-
|
|
33568
|
+
/**
|
|
33569
|
+
* Find the first visible header in the range [`from` => `to`].
|
|
33570
|
+
*
|
|
33571
|
+
* Both `from` and `to` are inclusive.
|
|
33572
|
+
*/
|
|
33573
|
+
findVisibleHeader(sheetId, dimension, from, to) {
|
|
33574
|
+
if (from <= to) {
|
|
33575
|
+
for (let i = from; i <= to; i++) {
|
|
33576
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
33577
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
33578
|
+
return i;
|
|
33579
|
+
}
|
|
33580
|
+
}
|
|
33581
|
+
}
|
|
33582
|
+
if (from > to) {
|
|
33583
|
+
for (let i = from; i >= to; i--) {
|
|
33584
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
33585
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
33586
|
+
return i;
|
|
33587
|
+
}
|
|
33588
|
+
}
|
|
33589
|
+
}
|
|
33590
|
+
return undefined;
|
|
33406
33591
|
}
|
|
33407
33592
|
findLastVisibleColRowIndex(sheetId, dimension, indexes) {
|
|
33408
33593
|
let lastIndex;
|
|
@@ -33415,7 +33600,7 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
33415
33600
|
}
|
|
33416
33601
|
findFirstVisibleColRowIndex(sheetId, dimension) {
|
|
33417
33602
|
const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
|
|
33418
|
-
for (let i = 0; i < numberOfHeaders
|
|
33603
|
+
for (let i = 0; i < numberOfHeaders; i++) {
|
|
33419
33604
|
if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
|
|
33420
33605
|
return i;
|
|
33421
33606
|
}
|
|
@@ -37542,7 +37727,7 @@ class BottomBar extends owl.Component {
|
|
|
37542
37727
|
}
|
|
37543
37728
|
openContextMenu(x, y, registry, menuId) {
|
|
37544
37729
|
this.menuState.isOpen = true;
|
|
37545
|
-
this.menuState.menuItems = registry.getAll()
|
|
37730
|
+
this.menuState.menuItems = registry.getAll();
|
|
37546
37731
|
this.menuState.position = { x, y };
|
|
37547
37732
|
this.menuState.menuId = menuId;
|
|
37548
37733
|
}
|
|
@@ -38303,7 +38488,7 @@ class TopBar extends owl.Component {
|
|
|
38303
38488
|
const { left, top, height } = ev.target.getBoundingClientRect();
|
|
38304
38489
|
this.state.menuState.isOpen = true;
|
|
38305
38490
|
this.state.menuState.position = { x: left, y: top + height };
|
|
38306
|
-
this.state.menuState.menuItems = getMenuChildren(menu, this.env)
|
|
38491
|
+
this.state.menuState.menuItems = getMenuChildren(menu, this.env);
|
|
38307
38492
|
this.state.menuState.parentMenu = menu;
|
|
38308
38493
|
this.isSelectingMenu = true;
|
|
38309
38494
|
this.openedEl = ev.target;
|
|
@@ -38352,9 +38537,7 @@ class TopBar extends owl.Component {
|
|
|
38352
38537
|
this.style.align = this.style.align || (cell === null || cell === void 0 ? void 0 : cell.defaultAlign);
|
|
38353
38538
|
this.fillColor = this.style.fillColor || "#ffffff";
|
|
38354
38539
|
this.textColor = this.style.textColor || "#000000";
|
|
38355
|
-
this.menus = topbarMenuRegistry
|
|
38356
|
-
.getAll()
|
|
38357
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
38540
|
+
this.menus = topbarMenuRegistry.getAll();
|
|
38358
38541
|
}
|
|
38359
38542
|
getMenuName(menu) {
|
|
38360
38543
|
return getMenuName(menu, this.env);
|
|
@@ -40420,8 +40603,8 @@ class SelectionStreamProcessor {
|
|
|
40420
40603
|
}
|
|
40421
40604
|
const { left, right, top, bottom } = zone;
|
|
40422
40605
|
const sheetId = this.getters.getActiveSheetId();
|
|
40423
|
-
const refCol = this.getters.findVisibleHeader(sheetId, "COL",
|
|
40424
|
-
const refRow = this.getters.findVisibleHeader(sheetId, "ROW",
|
|
40606
|
+
const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
|
|
40607
|
+
const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
|
|
40425
40608
|
if (refRow === undefined || refCol === undefined) {
|
|
40426
40609
|
return 17 /* CommandResult.SelectionOutOfBound */;
|
|
40427
40610
|
}
|
|
@@ -40496,10 +40679,10 @@ class SelectionStreamProcessor {
|
|
|
40496
40679
|
const { col: anchorCol, row: anchorRow } = anchor.cell;
|
|
40497
40680
|
return {
|
|
40498
40681
|
col: this.getters.isColHidden(sheetId, anchorCol)
|
|
40499
|
-
? this.getters.findVisibleHeader(sheetId, "COL",
|
|
40682
|
+
? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
|
|
40500
40683
|
: anchorCol,
|
|
40501
40684
|
row: this.getters.isRowHidden(sheetId, anchorRow)
|
|
40502
|
-
? this.getters.findVisibleHeader(sheetId, "ROW",
|
|
40685
|
+
? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
|
|
40503
40686
|
: anchorRow,
|
|
40504
40687
|
};
|
|
40505
40688
|
}
|
|
@@ -41034,12 +41217,9 @@ function addFormula(cell) {
|
|
|
41034
41217
|
else {
|
|
41035
41218
|
// Shouldn't we always output the value then ?
|
|
41036
41219
|
const value = cell.value;
|
|
41037
|
-
|
|
41038
|
-
|
|
41039
|
-
|
|
41040
|
-
attrs.push(["t", type]);
|
|
41041
|
-
node = escapeXml /*xml*/ `<v>${value}</v>`;
|
|
41042
|
-
}
|
|
41220
|
+
const type = getCellType(value);
|
|
41221
|
+
attrs.push(["t", type]);
|
|
41222
|
+
node = escapeXml /*xml*/ `<v>${value}</v>`;
|
|
41043
41223
|
return { attrs, node };
|
|
41044
41224
|
}
|
|
41045
41225
|
}
|
|
@@ -42139,6 +42319,8 @@ class Model extends EventBus {
|
|
|
42139
42319
|
* Internal status of the model. Important for command handling coordination
|
|
42140
42320
|
*/
|
|
42141
42321
|
this.status = 0 /* Status.Ready */;
|
|
42322
|
+
this.handlers = [];
|
|
42323
|
+
this.coreHandlers = [];
|
|
42142
42324
|
/**
|
|
42143
42325
|
* The dispatch method is the only entry point to manipulate data in the model.
|
|
42144
42326
|
* This is through this method that commands are dispatched most of the time
|
|
@@ -42211,7 +42393,7 @@ class Model extends EventBus {
|
|
|
42211
42393
|
const command = { type, ...payload };
|
|
42212
42394
|
const previousStatus = this.status;
|
|
42213
42395
|
this.status = 2 /* Status.RunningCore */;
|
|
42214
|
-
const handlers = this.isReplayingCommand ?
|
|
42396
|
+
const handlers = this.isReplayingCommand ? this.coreHandlers : this.handlers;
|
|
42215
42397
|
this.dispatchToHandlers(handlers, command);
|
|
42216
42398
|
this.status = previousStatus;
|
|
42217
42399
|
return DispatchResult.Success;
|
|
@@ -42245,6 +42427,8 @@ class Model extends EventBus {
|
|
|
42245
42427
|
this.uuidGenerator.setIsFastStrategy(true);
|
|
42246
42428
|
// Initiate stream processor
|
|
42247
42429
|
this.selection = new SelectionStreamProcessor(this.getters);
|
|
42430
|
+
this.coreHandlers.push(this.range);
|
|
42431
|
+
this.handlers.push(this.range);
|
|
42248
42432
|
// registering plugins
|
|
42249
42433
|
for (let Plugin of corePluginRegistry.getAll()) {
|
|
42250
42434
|
this.setupCorePlugin(Plugin, workbookData);
|
|
@@ -42254,6 +42438,7 @@ class Model extends EventBus {
|
|
|
42254
42438
|
this.setupUiPlugin(Plugin);
|
|
42255
42439
|
}
|
|
42256
42440
|
this.uuidGenerator.setIsFastStrategy(false);
|
|
42441
|
+
this.handlers.push(this.history);
|
|
42257
42442
|
// starting plugins
|
|
42258
42443
|
this.dispatch("START");
|
|
42259
42444
|
// Model should be the last permanent subscriber in the list since he should render
|
|
@@ -42274,9 +42459,6 @@ class Model extends EventBus {
|
|
|
42274
42459
|
// by owl, since we do not rely on reactivity
|
|
42275
42460
|
owl.markRaw(this);
|
|
42276
42461
|
}
|
|
42277
|
-
get handlers() {
|
|
42278
|
-
return [this.range, ...this.corePlugins, ...this.uiPlugins, this.history];
|
|
42279
|
-
}
|
|
42280
42462
|
joinSession() {
|
|
42281
42463
|
this.session.join(this.config.client);
|
|
42282
42464
|
}
|
|
@@ -42295,6 +42477,7 @@ class Model extends EventBus {
|
|
|
42295
42477
|
this.getters[name] = plugin[name].bind(plugin);
|
|
42296
42478
|
}
|
|
42297
42479
|
this.uiPlugins.push(plugin);
|
|
42480
|
+
this.handlers.push(plugin);
|
|
42298
42481
|
const layers = Plugin.layers.map((l) => [plugin, l]);
|
|
42299
42482
|
this.renderers.push(...layers);
|
|
42300
42483
|
this.renderers.sort((p1, p2) => p1[1] - p2[1]);
|
|
@@ -42318,6 +42501,8 @@ class Model extends EventBus {
|
|
|
42318
42501
|
}
|
|
42319
42502
|
plugin.import(data);
|
|
42320
42503
|
this.corePlugins.push(plugin);
|
|
42504
|
+
this.coreHandlers.push(plugin);
|
|
42505
|
+
this.handlers.push(plugin);
|
|
42321
42506
|
}
|
|
42322
42507
|
onRemoteRevisionReceived({ commands }) {
|
|
42323
42508
|
for (let command of commands) {
|
|
@@ -42335,7 +42520,7 @@ class Model extends EventBus {
|
|
|
42335
42520
|
return;
|
|
42336
42521
|
}
|
|
42337
42522
|
this.isReplayingCommand = true;
|
|
42338
|
-
this.dispatchToHandlers(
|
|
42523
|
+
this.dispatchToHandlers(this.coreHandlers, command);
|
|
42339
42524
|
this.isReplayingCommand = false;
|
|
42340
42525
|
}), this.config.transportService, revisionId);
|
|
42341
42526
|
return session;
|
|
@@ -42435,7 +42620,7 @@ class Model extends EventBus {
|
|
|
42435
42620
|
}
|
|
42436
42621
|
}
|
|
42437
42622
|
data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
|
|
42438
|
-
data =
|
|
42623
|
+
data = deepCopy(data);
|
|
42439
42624
|
return data;
|
|
42440
42625
|
}
|
|
42441
42626
|
updateMode(mode) {
|
|
@@ -42462,7 +42647,7 @@ class Model extends EventBus {
|
|
|
42462
42647
|
handler.exportForExcel(data);
|
|
42463
42648
|
}
|
|
42464
42649
|
}
|
|
42465
|
-
data =
|
|
42650
|
+
data = deepCopy(data);
|
|
42466
42651
|
return getXLSX(data);
|
|
42467
42652
|
}
|
|
42468
42653
|
}
|
|
@@ -42594,6 +42779,6 @@ exports.setTranslationMethod = setTranslationMethod;
|
|
|
42594
42779
|
exports.tokenize = tokenize;
|
|
42595
42780
|
|
|
42596
42781
|
|
|
42597
|
-
__info__.version = '16.0.
|
|
42598
|
-
__info__.date = '2023-04-
|
|
42599
|
-
__info__.hash = '
|
|
42782
|
+
__info__.version = '16.0.9';
|
|
42783
|
+
__info__.date = '2023-04-28T12:25:41.572Z';
|
|
42784
|
+
__info__.hash = 'e06ca83';
|