@odoo/o-spreadsheet 16.1.7 → 16.1.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 +271 -112
- package/dist/o-spreadsheet.d.ts +33 -8
- package/dist/o-spreadsheet.esm.js +271 -112
- package/dist/o-spreadsheet.iife.js +271 -112
- package/dist/o-spreadsheet.iife.min.js +227 -227
- package/package.json +1 -1
|
@@ -1019,6 +1019,10 @@ function deepEquals(o1, o2) {
|
|
|
1019
1019
|
}
|
|
1020
1020
|
return true;
|
|
1021
1021
|
}
|
|
1022
|
+
/** Check if the given array contains all the values of the other array. */
|
|
1023
|
+
function includesAll(arr, values) {
|
|
1024
|
+
return values.every((value) => arr.includes(value));
|
|
1025
|
+
}
|
|
1022
1026
|
/**
|
|
1023
1027
|
* Return an object with all the keys in the object that have a falsy value removed.
|
|
1024
1028
|
*/
|
|
@@ -1658,12 +1662,77 @@ const numberRepresentation = [];
|
|
|
1658
1662
|
* - all digit stored in the decimal part of the number
|
|
1659
1663
|
*
|
|
1660
1664
|
* The 'maxDecimal' parameter allows to indicate the number of digits to not
|
|
1661
|
-
* exceed in the decimal part, in which case digits are rounded
|
|
1665
|
+
* exceed in the decimal part, in which case digits are rounded.
|
|
1662
1666
|
*
|
|
1663
|
-
* Intl.Numberformat is used to properly handle all the roundings.
|
|
1664
|
-
* e.g. 1234.7 with format ### (<> maxDecimals=0) should become 1235, not 1234
|
|
1665
1667
|
**/
|
|
1666
1668
|
function splitNumber(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1669
|
+
const asString = value.toString();
|
|
1670
|
+
if (asString.includes("e"))
|
|
1671
|
+
return splitNumberIntl(value, maxDecimals);
|
|
1672
|
+
if (Number.isInteger(value)) {
|
|
1673
|
+
return { integerDigits: asString, decimalDigits: undefined };
|
|
1674
|
+
}
|
|
1675
|
+
const indexOfDot = asString.indexOf(".");
|
|
1676
|
+
let integerDigits = asString.substring(0, indexOfDot);
|
|
1677
|
+
let decimalDigits = asString.substring(indexOfDot + 1);
|
|
1678
|
+
if (maxDecimals === 0) {
|
|
1679
|
+
if (Number(decimalDigits[0]) >= 5) {
|
|
1680
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1681
|
+
}
|
|
1682
|
+
return { integerDigits, decimalDigits: undefined };
|
|
1683
|
+
}
|
|
1684
|
+
if (decimalDigits.length > maxDecimals) {
|
|
1685
|
+
const { integerDigits: roundedIntegerDigits, decimalDigits: roundedDecimalDigits } = limitDecimalDigits(decimalDigits, maxDecimals);
|
|
1686
|
+
decimalDigits = roundedDecimalDigits;
|
|
1687
|
+
if (roundedIntegerDigits !== "0") {
|
|
1688
|
+
integerDigits = (Number(integerDigits) + Number(roundedIntegerDigits)).toString();
|
|
1689
|
+
}
|
|
1690
|
+
}
|
|
1691
|
+
return { integerDigits, decimalDigits: removeTrailingZeroes(decimalDigits || "") };
|
|
1692
|
+
}
|
|
1693
|
+
/**
|
|
1694
|
+
* Return the given string minus the trailing "0" characters.
|
|
1695
|
+
*
|
|
1696
|
+
* @param numberString : a string of integers
|
|
1697
|
+
* @returns the numberString, minus the eventual zeroes at the end
|
|
1698
|
+
*/
|
|
1699
|
+
function removeTrailingZeroes(numberString) {
|
|
1700
|
+
let i = numberString.length - 1;
|
|
1701
|
+
while (i >= 0 && numberString[i] === "0") {
|
|
1702
|
+
i--;
|
|
1703
|
+
}
|
|
1704
|
+
return numberString.slice(0, i + 1) || undefined;
|
|
1705
|
+
}
|
|
1706
|
+
/**
|
|
1707
|
+
* Limit the size of the decimal part of a number to the given number of digits.
|
|
1708
|
+
*/
|
|
1709
|
+
function limitDecimalDigits(decimalDigits, maxDecimals) {
|
|
1710
|
+
let integerDigits = "0";
|
|
1711
|
+
let resultDecimalDigits = decimalDigits;
|
|
1712
|
+
// Note : we'd want to simply use number.toFixed() to handle the max digits & rounding,
|
|
1713
|
+
// but it has very strange behaviour. Ex: 12.345.toFixed(2) => "12.35", but 1.345.toFixed(2) => "1.34"
|
|
1714
|
+
let slicedDecimalDigits = decimalDigits.slice(0, maxDecimals);
|
|
1715
|
+
const i = maxDecimals;
|
|
1716
|
+
if (Number(Number(decimalDigits[i]) < 5)) {
|
|
1717
|
+
return { integerDigits, decimalDigits: slicedDecimalDigits };
|
|
1718
|
+
}
|
|
1719
|
+
// round up
|
|
1720
|
+
const slicedRoundedUp = (Number(slicedDecimalDigits) + 1).toString();
|
|
1721
|
+
if (slicedRoundedUp.length > slicedDecimalDigits.length) {
|
|
1722
|
+
integerDigits = (Number(integerDigits) + 1).toString();
|
|
1723
|
+
resultDecimalDigits = undefined;
|
|
1724
|
+
}
|
|
1725
|
+
else {
|
|
1726
|
+
resultDecimalDigits = slicedRoundedUp;
|
|
1727
|
+
}
|
|
1728
|
+
return { integerDigits, decimalDigits: resultDecimalDigits };
|
|
1729
|
+
}
|
|
1730
|
+
/**
|
|
1731
|
+
* Split numbers into decimal/integer digits using Intl.NumberFormat.
|
|
1732
|
+
* Supports numbers with a lot of digits that are transformed to scientific notation by
|
|
1733
|
+
* number.toString(), but is slow.
|
|
1734
|
+
*/
|
|
1735
|
+
function splitNumberIntl(value, maxDecimals = MAX_DECIMAL_PLACES) {
|
|
1667
1736
|
let formatter = numberRepresentation[maxDecimals];
|
|
1668
1737
|
if (!formatter) {
|
|
1669
1738
|
formatter = new Intl.NumberFormat("en-US", {
|
|
@@ -5902,13 +5971,16 @@ class Menu extends Component {
|
|
|
5902
5971
|
}
|
|
5903
5972
|
});
|
|
5904
5973
|
}
|
|
5974
|
+
get visibleMenuItems() {
|
|
5975
|
+
return this.props.menuItems.filter((x) => x.isVisible(this.env));
|
|
5976
|
+
}
|
|
5905
5977
|
get subMenuPosition() {
|
|
5906
5978
|
const position = Object.assign({}, this.subMenu.position);
|
|
5907
5979
|
position.y -= this.subMenu.scrollOffset || 0;
|
|
5908
5980
|
return position;
|
|
5909
5981
|
}
|
|
5910
5982
|
get menuHeight() {
|
|
5911
|
-
const menuItems = this.
|
|
5983
|
+
const menuItems = this.visibleMenuItems;
|
|
5912
5984
|
let menuItemsHeight = this.getMenuItemsHeight(menuItems);
|
|
5913
5985
|
// We don't display separator at the end of a menu
|
|
5914
5986
|
if (menuItems[menuItems.length - 1].separator) {
|
|
@@ -5950,7 +6022,7 @@ class Menu extends Component {
|
|
|
5950
6022
|
* and the menu item at a given index.
|
|
5951
6023
|
*/
|
|
5952
6024
|
subMenuVerticalPosition(menuIndex) {
|
|
5953
|
-
const menusAbove = this.
|
|
6025
|
+
const menusAbove = this.visibleMenuItems.slice(0, menuIndex);
|
|
5954
6026
|
return this.position.y + this.getMenuItemsHeight(menusAbove) + MENU_VERTICAL_PADDING;
|
|
5955
6027
|
}
|
|
5956
6028
|
onExternalClick(ev) {
|
|
@@ -6122,7 +6194,7 @@ class ChartFigure extends Component {
|
|
|
6122
6194
|
openContextMenu(position) {
|
|
6123
6195
|
const registry = this.getMenuItemRegistry();
|
|
6124
6196
|
this.menuState.isOpen = true;
|
|
6125
|
-
this.menuState.menuItems = registry.getAll()
|
|
6197
|
+
this.menuState.menuItems = registry.getAll();
|
|
6126
6198
|
this.menuState.position = position;
|
|
6127
6199
|
}
|
|
6128
6200
|
get chartComponent() {
|
|
@@ -7253,6 +7325,11 @@ colMenuRegistry
|
|
|
7253
7325
|
name: REMOVE_COLUMNS_NAME,
|
|
7254
7326
|
sequence: 90,
|
|
7255
7327
|
action: REMOVE_COLUMNS_ACTION,
|
|
7328
|
+
isVisible: (env) => {
|
|
7329
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
7330
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
7331
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
7332
|
+
},
|
|
7256
7333
|
})
|
|
7257
7334
|
.add("clear_column", {
|
|
7258
7335
|
name: DELETE_CONTENT_COLUMNS_NAME,
|
|
@@ -7265,9 +7342,8 @@ colMenuRegistry
|
|
|
7265
7342
|
action: HIDE_COLUMNS_ACTION,
|
|
7266
7343
|
isVisible: (env) => {
|
|
7267
7344
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
7268
|
-
const
|
|
7269
|
-
return
|
|
7270
|
-
hiddenCols.length + env.model.getters.getElementsFromSelection("COL").length);
|
|
7345
|
+
const selectedCols = env.model.getters.getElementsFromSelection("COL");
|
|
7346
|
+
return env.model.getters.canRemoveHeaders(sheetId, "COL", selectedCols);
|
|
7271
7347
|
},
|
|
7272
7348
|
separator: true,
|
|
7273
7349
|
})
|
|
@@ -7341,6 +7417,11 @@ rowMenuRegistry
|
|
|
7341
7417
|
name: REMOVE_ROWS_NAME,
|
|
7342
7418
|
sequence: 70,
|
|
7343
7419
|
action: REMOVE_ROWS_ACTION,
|
|
7420
|
+
isVisible: (env) => {
|
|
7421
|
+
const sheetId = env.model.getters.getActiveSheetId();
|
|
7422
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
7423
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
7424
|
+
},
|
|
7344
7425
|
})
|
|
7345
7426
|
.add("clear_row", {
|
|
7346
7427
|
name: DELETE_CONTENT_ROWS_NAME,
|
|
@@ -7353,9 +7434,8 @@ rowMenuRegistry
|
|
|
7353
7434
|
action: HIDE_ROWS_ACTION,
|
|
7354
7435
|
isVisible: (env) => {
|
|
7355
7436
|
const sheetId = env.model.getters.getActiveSheetId();
|
|
7356
|
-
const
|
|
7357
|
-
return
|
|
7358
|
-
hiddenRows.length + env.model.getters.getElementsFromSelection("ROW").length);
|
|
7437
|
+
const selectedRows = env.model.getters.getElementsFromSelection("ROW");
|
|
7438
|
+
return env.model.getters.canRemoveHeaders(sheetId, "ROW", selectedRows);
|
|
7359
7439
|
},
|
|
7360
7440
|
separator: true,
|
|
7361
7441
|
})
|
|
@@ -16928,14 +17008,31 @@ class ContentEditableHelper {
|
|
|
16928
17008
|
* */
|
|
16929
17009
|
getCurrentSelection() {
|
|
16930
17010
|
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = this.getStartAndEndSelection();
|
|
16931
|
-
let startSizeBefore = this.
|
|
16932
|
-
let endSizeBefore = this.
|
|
17011
|
+
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
17012
|
+
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
16933
17013
|
return {
|
|
16934
|
-
start: startSizeBefore
|
|
16935
|
-
end: endSizeBefore
|
|
17014
|
+
start: startSizeBefore,
|
|
17015
|
+
end: endSizeBefore,
|
|
16936
17016
|
};
|
|
16937
17017
|
}
|
|
16938
|
-
|
|
17018
|
+
/**
|
|
17019
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
17020
|
+
* The selected node is either a Text node or an Element node.
|
|
17021
|
+
*
|
|
17022
|
+
* case 1 -Text node:
|
|
17023
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
17024
|
+
* content length of all previous nodes.
|
|
17025
|
+
*
|
|
17026
|
+
* case 2 - Element node:
|
|
17027
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
17028
|
+
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
17029
|
+
*
|
|
17030
|
+
* See the MDN documentation for more details.
|
|
17031
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
17032
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
17033
|
+
*
|
|
17034
|
+
*/
|
|
17035
|
+
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
16939
17036
|
let it = this.iterateChildren(this.el);
|
|
16940
17037
|
let usedCharacters = 0;
|
|
16941
17038
|
let current = it.next();
|
|
@@ -16947,6 +17044,19 @@ class ContentEditableHelper {
|
|
|
16947
17044
|
}
|
|
16948
17045
|
current = it.next();
|
|
16949
17046
|
}
|
|
17047
|
+
if (current.value === nodeToFind) {
|
|
17048
|
+
if (!current.value.hasChildNodes()) {
|
|
17049
|
+
usedCharacters += nodeOffset;
|
|
17050
|
+
}
|
|
17051
|
+
else {
|
|
17052
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
17053
|
+
for (const child of children) {
|
|
17054
|
+
if (!child.textContent)
|
|
17055
|
+
continue;
|
|
17056
|
+
usedCharacters += child.textContent.length;
|
|
17057
|
+
}
|
|
17058
|
+
}
|
|
17059
|
+
}
|
|
16950
17060
|
return usedCharacters;
|
|
16951
17061
|
}
|
|
16952
17062
|
getStartAndEndSelection() {
|
|
@@ -23538,8 +23648,8 @@ class Grid extends Component {
|
|
|
23538
23648
|
},
|
|
23539
23649
|
"CTRL+END": () => {
|
|
23540
23650
|
const sheetId = this.env.model.getters.getActiveSheetId();
|
|
23541
|
-
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL",
|
|
23542
|
-
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW",
|
|
23651
|
+
const col = this.env.model.getters.findVisibleHeader(sheetId, "COL", this.env.model.getters.getNumberCols(sheetId) - 1, 0);
|
|
23652
|
+
const row = this.env.model.getters.findVisibleHeader(sheetId, "ROW", this.env.model.getters.getNumberRows(sheetId) - 1, 0);
|
|
23543
23653
|
this.env.model.selection.selectCell(col, row);
|
|
23544
23654
|
},
|
|
23545
23655
|
"SHIFT+ ": () => {
|
|
@@ -23619,9 +23729,10 @@ class Grid extends Component {
|
|
|
23619
23729
|
this.focus();
|
|
23620
23730
|
}
|
|
23621
23731
|
focus() {
|
|
23732
|
+
var _a;
|
|
23622
23733
|
if (!this.env.model.getters.getSelectedFigureId() &&
|
|
23623
23734
|
this.env.model.getters.getEditionMode() === "inactive") {
|
|
23624
|
-
this.hiddenInput.el.focus();
|
|
23735
|
+
(_a = this.hiddenInput.el) === null || _a === void 0 ? void 0 : _a.focus();
|
|
23625
23736
|
}
|
|
23626
23737
|
}
|
|
23627
23738
|
get gridEl() {
|
|
@@ -23822,9 +23933,7 @@ class Grid extends Component {
|
|
|
23822
23933
|
}
|
|
23823
23934
|
this.menuState.isOpen = true;
|
|
23824
23935
|
this.menuState.position = { x, y };
|
|
23825
|
-
this.menuState.menuItems = registries$1[type]
|
|
23826
|
-
.getAll()
|
|
23827
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
23936
|
+
this.menuState.menuItems = registries$1[type].getAll();
|
|
23828
23937
|
}
|
|
23829
23938
|
copy(cut, ev) {
|
|
23830
23939
|
if (!this.gridEl.contains(document.activeElement)) {
|
|
@@ -27193,7 +27302,7 @@ function load(data, verboseImport) {
|
|
|
27193
27302
|
}
|
|
27194
27303
|
}
|
|
27195
27304
|
}
|
|
27196
|
-
data =
|
|
27305
|
+
data = deepCopy(data);
|
|
27197
27306
|
// apply migrations, if needed
|
|
27198
27307
|
if ("version" in data) {
|
|
27199
27308
|
if (data.version < CURRENT_VERSION) {
|
|
@@ -29853,7 +29962,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29853
29962
|
allowDispatch(cmd) {
|
|
29854
29963
|
switch (cmd.type) {
|
|
29855
29964
|
case "HIDE_COLUMNS_ROWS": {
|
|
29856
|
-
if (!this.
|
|
29965
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
29857
29966
|
return 27 /* CommandResult.InvalidSheetId */;
|
|
29858
29967
|
}
|
|
29859
29968
|
const hiddenGroup = cmd.dimension === "COL"
|
|
@@ -29866,6 +29975,14 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29866
29975
|
? 0 /* CommandResult.Success */
|
|
29867
29976
|
: 66 /* CommandResult.TooManyHiddenElements */;
|
|
29868
29977
|
}
|
|
29978
|
+
case "REMOVE_COLUMNS_ROWS":
|
|
29979
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
29980
|
+
return 27 /* CommandResult.InvalidSheetId */;
|
|
29981
|
+
}
|
|
29982
|
+
if (!this.canRemoveHeaders(cmd.sheetId, cmd.dimension, cmd.elements)) {
|
|
29983
|
+
return 8 /* CommandResult.NotEnoughElements */;
|
|
29984
|
+
}
|
|
29985
|
+
return 0 /* CommandResult.Success */;
|
|
29869
29986
|
}
|
|
29870
29987
|
return 0 /* CommandResult.Success */;
|
|
29871
29988
|
}
|
|
@@ -29912,6 +30029,10 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29912
30029
|
}
|
|
29913
30030
|
return;
|
|
29914
30031
|
}
|
|
30032
|
+
canRemoveHeaders(sheetId, dimension, elements) {
|
|
30033
|
+
const visibleHeaders = this.getAllVisibleHeaders(sheetId, dimension);
|
|
30034
|
+
return !includesAll(elements, visibleHeaders);
|
|
30035
|
+
}
|
|
29915
30036
|
isRowHiddenByUser(sheetId, index) {
|
|
29916
30037
|
return this.hiddenHeaders[sheetId].ROW[index];
|
|
29917
30038
|
}
|
|
@@ -29956,6 +30077,9 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
29956
30077
|
}
|
|
29957
30078
|
return consecutiveIndexes;
|
|
29958
30079
|
}
|
|
30080
|
+
getAllVisibleHeaders(sheetId, dimension) {
|
|
30081
|
+
return range(0, this.hiddenHeaders[sheetId][dimension].length).filter((i) => !this.hiddenHeaders[sheetId][dimension][i]);
|
|
30082
|
+
}
|
|
29959
30083
|
import(data) {
|
|
29960
30084
|
var _a, _b;
|
|
29961
30085
|
for (let sheet of data.sheets) {
|
|
@@ -30003,6 +30127,7 @@ class HeaderVisibilityPlugin extends CorePlugin {
|
|
|
30003
30127
|
}
|
|
30004
30128
|
}
|
|
30005
30129
|
HeaderVisibilityPlugin.getters = [
|
|
30130
|
+
"canRemoveHeaders",
|
|
30006
30131
|
"getHiddenColsGroups",
|
|
30007
30132
|
"getHiddenRowsGroups",
|
|
30008
30133
|
"isRowHiddenByUser",
|
|
@@ -31012,14 +31137,6 @@ class SheetPlugin extends CorePlugin {
|
|
|
31012
31137
|
return this.orderedSheetIds.length > 1
|
|
31013
31138
|
? 0 /* CommandResult.Success */
|
|
31014
31139
|
: 9 /* CommandResult.NotEnoughSheets */;
|
|
31015
|
-
case "REMOVE_COLUMNS_ROWS": {
|
|
31016
|
-
const length = cmd.dimension === "COL"
|
|
31017
|
-
? this.getNumberCols(cmd.sheetId)
|
|
31018
|
-
: this.getNumberRows(cmd.sheetId);
|
|
31019
|
-
return length > cmd.elements.length
|
|
31020
|
-
? 0 /* CommandResult.Success */
|
|
31021
|
-
: 8 /* CommandResult.NotEnoughElements */;
|
|
31022
|
-
}
|
|
31023
31140
|
case "FREEZE_ROWS": {
|
|
31024
31141
|
return this.checkValidations(cmd, this.checkRowFreezeQuantity, this.checkRowFreezeOverlapMerge);
|
|
31025
31142
|
}
|
|
@@ -31490,7 +31607,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
31490
31607
|
duplicateSheet(fromId, toId) {
|
|
31491
31608
|
const sheet = this.getSheet(fromId);
|
|
31492
31609
|
const toName = this.getDuplicateSheetName(sheet.name);
|
|
31493
|
-
const newSheet =
|
|
31610
|
+
const newSheet = deepCopy(sheet);
|
|
31494
31611
|
newSheet.id = toId;
|
|
31495
31612
|
newSheet.name = toName;
|
|
31496
31613
|
for (let col = 0; col <= newSheet.numberOfCols; col++) {
|
|
@@ -31617,10 +31734,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
31617
31734
|
}
|
|
31618
31735
|
}
|
|
31619
31736
|
moveCellOnColumnsDeletion(sheet, deletedColumn) {
|
|
31620
|
-
for (let
|
|
31621
|
-
const
|
|
31737
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
31738
|
+
const row = sheet.rows[rowIndex];
|
|
31622
31739
|
for (let i in row.cells) {
|
|
31623
|
-
const colIndex =
|
|
31740
|
+
const colIndex = Number(i);
|
|
31624
31741
|
const cellId = row.cells[i];
|
|
31625
31742
|
if (cellId) {
|
|
31626
31743
|
if (colIndex === deletedColumn) {
|
|
@@ -31647,11 +31764,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
31647
31764
|
*/
|
|
31648
31765
|
moveCellsOnAddition(sheet, addedElement, quantity, dimension) {
|
|
31649
31766
|
const commands = [];
|
|
31650
|
-
for (
|
|
31651
|
-
const
|
|
31767
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
31768
|
+
const row = sheet.rows[rowIndex];
|
|
31652
31769
|
if (dimension !== "rows" || rowIndex >= addedElement) {
|
|
31653
31770
|
for (let i in row.cells) {
|
|
31654
|
-
const colIndex =
|
|
31771
|
+
const colIndex = Number(i);
|
|
31655
31772
|
const cellId = row.cells[i];
|
|
31656
31773
|
if (cellId) {
|
|
31657
31774
|
if (dimension === "rows" || colIndex >= addedElement) {
|
|
@@ -31681,11 +31798,11 @@ class SheetPlugin extends CorePlugin {
|
|
|
31681
31798
|
*/
|
|
31682
31799
|
moveCellOnRowsDeletion(sheet, deleteFromRow, deleteToRow) {
|
|
31683
31800
|
const numberRows = deleteToRow - deleteFromRow + 1;
|
|
31684
|
-
for (let
|
|
31685
|
-
const
|
|
31801
|
+
for (let rowIndex = 0; rowIndex < sheet.rows.length; rowIndex++) {
|
|
31802
|
+
const row = sheet.rows[rowIndex];
|
|
31686
31803
|
if (rowIndex >= deleteFromRow && rowIndex <= deleteToRow) {
|
|
31687
31804
|
for (let i in row.cells) {
|
|
31688
|
-
const colIndex =
|
|
31805
|
+
const colIndex = Number(i);
|
|
31689
31806
|
const cellId = row.cells[i];
|
|
31690
31807
|
if (cellId) {
|
|
31691
31808
|
this.dispatch("CLEAR_CELL", {
|
|
@@ -31698,7 +31815,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
31698
31815
|
}
|
|
31699
31816
|
if (rowIndex > deleteToRow) {
|
|
31700
31817
|
for (let i in row.cells) {
|
|
31701
|
-
const colIndex =
|
|
31818
|
+
const colIndex = Number(i);
|
|
31702
31819
|
const cellId = row.cells[i];
|
|
31703
31820
|
if (cellId) {
|
|
31704
31821
|
this.dispatch("UPDATE_CELL_POSITION", {
|
|
@@ -31716,7 +31833,7 @@ class SheetPlugin extends CorePlugin {
|
|
|
31716
31833
|
const rows = [];
|
|
31717
31834
|
const cellsQueue = sheet.rows.map((row) => row.cells);
|
|
31718
31835
|
for (let i in sheet.rows) {
|
|
31719
|
-
if (
|
|
31836
|
+
if (Number(i) === index) {
|
|
31720
31837
|
continue;
|
|
31721
31838
|
}
|
|
31722
31839
|
rows.push({
|
|
@@ -32859,13 +32976,11 @@ class FilterEvaluationPlugin extends UIPlugin {
|
|
|
32859
32976
|
return Boolean(id && ((_b = (_a = this.filterValues[sheetId]) === null || _a === void 0 ? void 0 : _a[id]) === null || _b === void 0 ? void 0 : _b.length));
|
|
32860
32977
|
}
|
|
32861
32978
|
intersectZoneWithViewport(sheetId, zone) {
|
|
32862
|
-
const colsRange = range(zone.left, zone.right + 1);
|
|
32863
|
-
const rowsRange = range(zone.top, zone.bottom + 1);
|
|
32864
32979
|
return {
|
|
32865
|
-
left: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32866
|
-
right: this.getters.findVisibleHeader(sheetId, "COL",
|
|
32867
|
-
top: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
32868
|
-
bottom: this.getters.findVisibleHeader(sheetId, "ROW",
|
|
32980
|
+
left: this.getters.findVisibleHeader(sheetId, "COL", zone.left, zone.right),
|
|
32981
|
+
right: this.getters.findVisibleHeader(sheetId, "COL", zone.right, zone.left),
|
|
32982
|
+
top: this.getters.findVisibleHeader(sheetId, "ROW", zone.top, zone.bottom),
|
|
32983
|
+
bottom: this.getters.findVisibleHeader(sheetId, "ROW", zone.bottom, zone.top),
|
|
32869
32984
|
};
|
|
32870
32985
|
}
|
|
32871
32986
|
updateFilter({ col, row, values, sheetId }) {
|
|
@@ -33069,48 +33184,66 @@ class InternalViewport {
|
|
|
33069
33184
|
this.adjustPositionY(row);
|
|
33070
33185
|
}
|
|
33071
33186
|
}
|
|
33072
|
-
adjustPositionX(
|
|
33187
|
+
adjustPositionX(targetCol) {
|
|
33073
33188
|
const sheetId = this.sheetId;
|
|
33074
|
-
const {
|
|
33075
|
-
|
|
33076
|
-
|
|
33077
|
-
|
|
33078
|
-
|
|
33079
|
-
this.adjustViewportZoneX();
|
|
33080
|
-
}
|
|
33081
|
-
while (col < this.left) {
|
|
33082
|
-
let leftCol;
|
|
33083
|
-
for (leftCol = this.left; leftCol >= 0; leftCol--) {
|
|
33084
|
-
if (!this.getters.isColHidden(sheetId, leftCol)) {
|
|
33189
|
+
const { end } = this.getters.getColDimensions(sheetId, targetCol);
|
|
33190
|
+
const maxCol = this.getters.getNumberCols(sheetId);
|
|
33191
|
+
if (this.offsetX + this.offsetCorrectionX + this.viewportWidth < end) {
|
|
33192
|
+
for (let col = this.left; this.offsetX + this.offsetCorrectionX + this.viewportWidth < end; col++) {
|
|
33193
|
+
if (col > maxCol) {
|
|
33085
33194
|
break;
|
|
33086
33195
|
}
|
|
33196
|
+
if (this.getters.isColHidden(sheetId, col)) {
|
|
33197
|
+
continue;
|
|
33198
|
+
}
|
|
33199
|
+
this.offsetX = this.getters.getColDimensions(sheetId, col).end - this.offsetCorrectionX;
|
|
33200
|
+
this.offsetScrollbarX = this.offsetX;
|
|
33201
|
+
this.adjustViewportZoneX();
|
|
33202
|
+
}
|
|
33203
|
+
}
|
|
33204
|
+
else if (this.left > targetCol) {
|
|
33205
|
+
for (let col = this.left; col >= targetCol; col--) {
|
|
33206
|
+
if (col < 0) {
|
|
33207
|
+
break;
|
|
33208
|
+
}
|
|
33209
|
+
if (this.getters.isColHidden(sheetId, col)) {
|
|
33210
|
+
continue;
|
|
33211
|
+
}
|
|
33212
|
+
this.offsetX = this.getters.getColDimensions(sheetId, col).start - this.offsetCorrectionX;
|
|
33213
|
+
this.offsetScrollbarX = this.offsetX;
|
|
33214
|
+
this.adjustViewportZoneX();
|
|
33087
33215
|
}
|
|
33088
|
-
this.offsetX =
|
|
33089
|
-
this.getters.getColDimensions(sheetId, leftCol - 1).start - this.offsetCorrectionX;
|
|
33090
|
-
this.offsetScrollbarX = this.offsetX;
|
|
33091
|
-
this.adjustViewportZoneX();
|
|
33092
33216
|
}
|
|
33093
33217
|
}
|
|
33094
|
-
adjustPositionY(
|
|
33218
|
+
adjustPositionY(targetRow) {
|
|
33095
33219
|
const sheetId = this.sheetId;
|
|
33096
|
-
|
|
33097
|
-
|
|
33098
|
-
|
|
33099
|
-
|
|
33100
|
-
|
|
33101
|
-
this.adjustViewportZoneY();
|
|
33102
|
-
}
|
|
33103
|
-
while (row < this.top) {
|
|
33104
|
-
let topRow;
|
|
33105
|
-
for (topRow = this.top; topRow >= 0; topRow--) {
|
|
33106
|
-
if (!this.getters.isRowHidden(sheetId, topRow)) {
|
|
33220
|
+
const { end } = this.getters.getRowDimensions(sheetId, targetRow);
|
|
33221
|
+
const maxRow = this.getters.getNumberRows(sheetId);
|
|
33222
|
+
if (this.offsetY + this.viewportHeight + this.offsetCorrectionY < end) {
|
|
33223
|
+
for (let row = this.top; this.offsetY + this.viewportHeight + this.offsetCorrectionY < end; row++) {
|
|
33224
|
+
if (row > maxRow) {
|
|
33107
33225
|
break;
|
|
33108
33226
|
}
|
|
33227
|
+
if (this.getters.isRowHidden(sheetId, row)) {
|
|
33228
|
+
continue;
|
|
33229
|
+
}
|
|
33230
|
+
this.offsetY = this.getters.getRowDimensions(sheetId, row).end - this.offsetCorrectionY;
|
|
33231
|
+
this.offsetScrollbarY = this.offsetY;
|
|
33232
|
+
this.adjustViewportZoneY();
|
|
33233
|
+
}
|
|
33234
|
+
}
|
|
33235
|
+
else if (this.top > targetRow) {
|
|
33236
|
+
for (let row = this.top; row >= targetRow; row--) {
|
|
33237
|
+
if (row < 0) {
|
|
33238
|
+
break;
|
|
33239
|
+
}
|
|
33240
|
+
if (this.getters.isRowHidden(sheetId, row)) {
|
|
33241
|
+
continue;
|
|
33242
|
+
}
|
|
33243
|
+
this.offsetY = this.getters.getRowDimensions(sheetId, row).start - this.offsetCorrectionY;
|
|
33244
|
+
this.offsetScrollbarY = this.offsetY;
|
|
33245
|
+
this.adjustViewportZoneY();
|
|
33109
33246
|
}
|
|
33110
|
-
this.offsetY =
|
|
33111
|
-
this.getters.getRowDimensions(sheetId, topRow - 1).start - this.offsetCorrectionY;
|
|
33112
|
-
this.offsetScrollbarY = this.offsetY;
|
|
33113
|
-
this.adjustViewportZoneY();
|
|
33114
33247
|
}
|
|
33115
33248
|
}
|
|
33116
33249
|
setViewportOffset(offsetX, offsetY) {
|
|
@@ -34953,13 +35086,33 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
34953
35086
|
getNextVisibleCellPosition({ sheetId, col, row }) {
|
|
34954
35087
|
return {
|
|
34955
35088
|
sheetId,
|
|
34956
|
-
col: this.findVisibleHeader(sheetId, "COL",
|
|
34957
|
-
row: this.findVisibleHeader(sheetId, "ROW",
|
|
35089
|
+
col: this.findVisibleHeader(sheetId, "COL", col, this.getters.getNumberCols(sheetId) - 1),
|
|
35090
|
+
row: this.findVisibleHeader(sheetId, "ROW", row, this.getters.getNumberRows(sheetId) - 1),
|
|
34958
35091
|
};
|
|
34959
35092
|
}
|
|
34960
|
-
|
|
34961
|
-
|
|
34962
|
-
|
|
35093
|
+
/**
|
|
35094
|
+
* Find the first visible header in the range [`from` => `to`].
|
|
35095
|
+
*
|
|
35096
|
+
* Both `from` and `to` are inclusive.
|
|
35097
|
+
*/
|
|
35098
|
+
findVisibleHeader(sheetId, dimension, from, to) {
|
|
35099
|
+
if (from <= to) {
|
|
35100
|
+
for (let i = from; i <= to; i++) {
|
|
35101
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
35102
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
35103
|
+
return i;
|
|
35104
|
+
}
|
|
35105
|
+
}
|
|
35106
|
+
}
|
|
35107
|
+
if (from > to) {
|
|
35108
|
+
for (let i = from; i >= to; i--) {
|
|
35109
|
+
if (this.getters.doesHeaderExist(sheetId, dimension, i) &&
|
|
35110
|
+
!this.isHeaderHidden(sheetId, dimension, i)) {
|
|
35111
|
+
return i;
|
|
35112
|
+
}
|
|
35113
|
+
}
|
|
35114
|
+
}
|
|
35115
|
+
return undefined;
|
|
34963
35116
|
}
|
|
34964
35117
|
findLastVisibleColRowIndex(sheetId, dimension, { last, first }) {
|
|
34965
35118
|
const lastVisibleIndex = range(last, first, -1).find((index) => !this.isHeaderHidden(sheetId, dimension, index));
|
|
@@ -34967,7 +35120,7 @@ class HeaderVisibilityUIPlugin extends UIPlugin {
|
|
|
34967
35120
|
}
|
|
34968
35121
|
findFirstVisibleColRowIndex(sheetId, dimension) {
|
|
34969
35122
|
const numberOfHeaders = this.getters.getNumberHeaders(sheetId, dimension);
|
|
34970
|
-
for (let i = 0; i < numberOfHeaders
|
|
35123
|
+
for (let i = 0; i < numberOfHeaders; i++) {
|
|
34971
35124
|
if (dimension === "COL" && !this.isColHidden(sheetId, i)) {
|
|
34972
35125
|
return i;
|
|
34973
35126
|
}
|
|
@@ -39194,7 +39347,7 @@ class BottomBar extends Component {
|
|
|
39194
39347
|
}
|
|
39195
39348
|
openContextMenu(x, y, registry, menuId) {
|
|
39196
39349
|
this.menuState.isOpen = true;
|
|
39197
|
-
this.menuState.menuItems = registry.getAll()
|
|
39350
|
+
this.menuState.menuItems = registry.getAll();
|
|
39198
39351
|
this.menuState.position = { x, y };
|
|
39199
39352
|
this.menuState.menuId = menuId;
|
|
39200
39353
|
}
|
|
@@ -40001,7 +40154,7 @@ class TopBar extends Component {
|
|
|
40001
40154
|
const { left, top, height } = ev.target.getBoundingClientRect();
|
|
40002
40155
|
this.state.menuState.isOpen = true;
|
|
40003
40156
|
this.state.menuState.position = { x: left, y: top + height };
|
|
40004
|
-
this.state.menuState.menuItems = getMenuChildren(menu, this.env)
|
|
40157
|
+
this.state.menuState.menuItems = getMenuChildren(menu, this.env);
|
|
40005
40158
|
this.state.menuState.parentMenu = menu;
|
|
40006
40159
|
this.isSelectingMenu = true;
|
|
40007
40160
|
this.openedEl = ev.target;
|
|
@@ -40044,9 +40197,7 @@ class TopBar extends Component {
|
|
|
40044
40197
|
this.style.align = this.style.align || cell.defaultAlign;
|
|
40045
40198
|
this.fillColor = this.style.fillColor || "#ffffff";
|
|
40046
40199
|
this.textColor = this.style.textColor || "#000000";
|
|
40047
|
-
this.menus = topbarMenuRegistry
|
|
40048
|
-
.getAll()
|
|
40049
|
-
.filter((item) => !item.isVisible || item.isVisible(this.env));
|
|
40200
|
+
this.menus = topbarMenuRegistry.getAll();
|
|
40050
40201
|
}
|
|
40051
40202
|
getMenuName(menu) {
|
|
40052
40203
|
return getMenuName(menu, this.env);
|
|
@@ -41760,8 +41911,8 @@ class SelectionStreamProcessor {
|
|
|
41760
41911
|
}
|
|
41761
41912
|
const { left, right, top, bottom } = zone;
|
|
41762
41913
|
const sheetId = this.getters.getActiveSheetId();
|
|
41763
|
-
const refCol = this.getters.findVisibleHeader(sheetId, "COL",
|
|
41764
|
-
const refRow = this.getters.findVisibleHeader(sheetId, "ROW",
|
|
41914
|
+
const refCol = this.getters.findVisibleHeader(sheetId, "COL", left, right);
|
|
41915
|
+
const refRow = this.getters.findVisibleHeader(sheetId, "ROW", top, bottom);
|
|
41765
41916
|
if (refRow === undefined || refCol === undefined) {
|
|
41766
41917
|
return 17 /* CommandResult.SelectionOutOfBound */;
|
|
41767
41918
|
}
|
|
@@ -41836,10 +41987,10 @@ class SelectionStreamProcessor {
|
|
|
41836
41987
|
const { col: anchorCol, row: anchorRow } = anchor.cell;
|
|
41837
41988
|
return {
|
|
41838
41989
|
col: this.getters.isColHidden(sheetId, anchorCol)
|
|
41839
|
-
? this.getters.findVisibleHeader(sheetId, "COL",
|
|
41990
|
+
? this.getters.findVisibleHeader(sheetId, "COL", left, right) || anchorCol
|
|
41840
41991
|
: anchorCol,
|
|
41841
41992
|
row: this.getters.isRowHidden(sheetId, anchorRow)
|
|
41842
|
-
? this.getters.findVisibleHeader(sheetId, "ROW",
|
|
41993
|
+
? this.getters.findVisibleHeader(sheetId, "ROW", top, bottom) || anchorRow
|
|
41843
41994
|
: anchorRow,
|
|
41844
41995
|
};
|
|
41845
41996
|
}
|
|
@@ -43520,6 +43671,8 @@ class Model extends EventBus {
|
|
|
43520
43671
|
* Internal status of the model. Important for command handling coordination
|
|
43521
43672
|
*/
|
|
43522
43673
|
this.status = 0 /* Status.Ready */;
|
|
43674
|
+
this.handlers = [];
|
|
43675
|
+
this.coreHandlers = [];
|
|
43523
43676
|
/**
|
|
43524
43677
|
* The dispatch method is the only entry point to manipulate data in the model.
|
|
43525
43678
|
* This is through this method that commands are dispatched most of the time
|
|
@@ -43624,6 +43777,8 @@ class Model extends EventBus {
|
|
|
43624
43777
|
this.uuidGenerator.setIsFastStrategy(true);
|
|
43625
43778
|
// Initiate stream processor
|
|
43626
43779
|
this.selection = new SelectionStreamProcessor(this.getters);
|
|
43780
|
+
this.coreHandlers.push(this.range);
|
|
43781
|
+
this.handlers.push(this.range);
|
|
43627
43782
|
this.corePluginConfig = this.setupCorePluginConfig();
|
|
43628
43783
|
this.uiPluginConfig = this.setupUiPluginConfig();
|
|
43629
43784
|
// registering plugins
|
|
@@ -43632,15 +43787,23 @@ class Model extends EventBus {
|
|
|
43632
43787
|
}
|
|
43633
43788
|
Object.assign(this.getters, this.coreGetters);
|
|
43634
43789
|
for (let Plugin of statefulUIPluginRegistry.getAll()) {
|
|
43635
|
-
this.
|
|
43790
|
+
const plugin = this.setupUiPlugin(Plugin);
|
|
43791
|
+
this.statefulUIPlugins.push(plugin);
|
|
43792
|
+
this.handlers.push(plugin);
|
|
43636
43793
|
}
|
|
43637
43794
|
for (let Plugin of coreViewsPluginRegistry.getAll()) {
|
|
43638
|
-
this.
|
|
43795
|
+
const plugin = this.setupUiPlugin(Plugin);
|
|
43796
|
+
this.coreViewsPlugins.push(plugin);
|
|
43797
|
+
this.handlers.push(plugin);
|
|
43798
|
+
this.coreHandlers.push(plugin);
|
|
43639
43799
|
}
|
|
43640
43800
|
for (let Plugin of featurePluginRegistry.getAll()) {
|
|
43641
|
-
this.
|
|
43801
|
+
const plugin = this.setupUiPlugin(Plugin);
|
|
43802
|
+
this.featurePlugins.push(plugin);
|
|
43803
|
+
this.handlers.push(plugin);
|
|
43642
43804
|
}
|
|
43643
43805
|
this.uuidGenerator.setIsFastStrategy(false);
|
|
43806
|
+
this.handlers.push(this.history);
|
|
43644
43807
|
// starting plugins
|
|
43645
43808
|
this.dispatch("START");
|
|
43646
43809
|
// Model should be the last permanent subscriber in the list since he should render
|
|
@@ -43662,12 +43825,6 @@ class Model extends EventBus {
|
|
|
43662
43825
|
// by owl, since we do not rely on reactivity
|
|
43663
43826
|
markRaw(this);
|
|
43664
43827
|
}
|
|
43665
|
-
get handlers() {
|
|
43666
|
-
return [this.range, ...this.corePlugins, ...this.allUIPlugins, this.history];
|
|
43667
|
-
}
|
|
43668
|
-
get allUIPlugins() {
|
|
43669
|
-
return [...this.statefulUIPlugins, ...this.coreViewsPlugins, ...this.featurePlugins];
|
|
43670
|
-
}
|
|
43671
43828
|
joinSession() {
|
|
43672
43829
|
this.session.join(this.config.client);
|
|
43673
43830
|
}
|
|
@@ -43709,6 +43866,8 @@ class Model extends EventBus {
|
|
|
43709
43866
|
}
|
|
43710
43867
|
plugin.import(data);
|
|
43711
43868
|
this.corePlugins.push(plugin);
|
|
43869
|
+
this.coreHandlers.push(plugin);
|
|
43870
|
+
this.handlers.push(plugin);
|
|
43712
43871
|
}
|
|
43713
43872
|
onRemoteRevisionReceived({ commands }) {
|
|
43714
43873
|
for (let command of commands) {
|
|
@@ -43851,7 +44010,7 @@ class Model extends EventBus {
|
|
|
43851
44010
|
}
|
|
43852
44011
|
}
|
|
43853
44012
|
data.revisionId = this.session.getRevisionId() || DEFAULT_REVISION_ID;
|
|
43854
|
-
data =
|
|
44013
|
+
data = deepCopy(data);
|
|
43855
44014
|
return data;
|
|
43856
44015
|
}
|
|
43857
44016
|
updateMode(mode) {
|
|
@@ -43879,7 +44038,7 @@ class Model extends EventBus {
|
|
|
43879
44038
|
handler.exportForExcel(data);
|
|
43880
44039
|
}
|
|
43881
44040
|
}
|
|
43882
|
-
data =
|
|
44041
|
+
data = deepCopy(data);
|
|
43883
44042
|
return getXLSX(data);
|
|
43884
44043
|
}
|
|
43885
44044
|
garbageCollectExternalResources() {
|
|
@@ -43992,6 +44151,6 @@ function addFunction(functionName, functionDescription) {
|
|
|
43992
44151
|
export { AbstractChart, CommandResult, CorePlugin, DATETIME_FORMAT, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, astToFormula, compile, components, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, invalidateEvaluationCommands, links, load, parse, readonlyAllowedCommands, registries, setTranslationMethod, tokenize };
|
|
43993
44152
|
|
|
43994
44153
|
|
|
43995
|
-
__info__.version = '16.1.
|
|
43996
|
-
__info__.date = '2023-04-
|
|
43997
|
-
__info__.hash = '
|
|
44154
|
+
__info__.version = '16.1.9';
|
|
44155
|
+
__info__.date = '2023-04-21T07:29:41.080Z';
|
|
44156
|
+
__info__.hash = '686bffa';
|