@odoo/o-spreadsheet 18.1.8 → 18.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 +359 -199
- package/dist/o-spreadsheet.d.ts +34 -45
- package/dist/o-spreadsheet.esm.js +359 -199
- package/dist/o-spreadsheet.iife.js +359 -199
- package/dist/o-spreadsheet.iife.min.js +375 -375
- package/dist/o_spreadsheet.xml +4 -3
- package/package.json +4 -2
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
4
4
|
* @see https://github.com/odoo/o-spreadsheet
|
|
5
|
-
* @version 18.1.
|
|
6
|
-
* @date 2025-02-
|
|
7
|
-
* @hash
|
|
5
|
+
* @version 18.1.9
|
|
6
|
+
* @date 2025-02-25T05:59:45.472Z
|
|
7
|
+
* @hash 6789c1c
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
'use strict';
|
|
@@ -2220,17 +2220,7 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
2220
2220
|
*/
|
|
2221
2221
|
function toUnboundedZone(xc) {
|
|
2222
2222
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
2223
|
-
|
|
2224
|
-
const tmp = zone.left;
|
|
2225
|
-
zone.left = zone.right;
|
|
2226
|
-
zone.right = tmp;
|
|
2227
|
-
}
|
|
2228
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2229
|
-
const tmp = zone.top;
|
|
2230
|
-
zone.top = zone.bottom;
|
|
2231
|
-
zone.bottom = tmp;
|
|
2232
|
-
}
|
|
2233
|
-
return zone;
|
|
2223
|
+
return reorderZone(zone);
|
|
2234
2224
|
}
|
|
2235
2225
|
/**
|
|
2236
2226
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -2504,11 +2494,11 @@ function positions(zone) {
|
|
|
2504
2494
|
return positions;
|
|
2505
2495
|
}
|
|
2506
2496
|
function reorderZone(zone) {
|
|
2507
|
-
if (zone.left > zone.right) {
|
|
2508
|
-
zone = { left: zone.right, right: zone.left
|
|
2497
|
+
if (zone.right !== undefined && zone.left > zone.right) {
|
|
2498
|
+
zone = { ...zone, left: zone.right, right: zone.left };
|
|
2509
2499
|
}
|
|
2510
|
-
if (zone.top > zone.bottom) {
|
|
2511
|
-
zone = {
|
|
2500
|
+
if (zone.bottom !== undefined && zone.top > zone.bottom) {
|
|
2501
|
+
zone = { ...zone, top: zone.bottom, bottom: zone.top };
|
|
2512
2502
|
}
|
|
2513
2503
|
return zone;
|
|
2514
2504
|
}
|
|
@@ -3413,12 +3403,12 @@ function isTargetDependent(cmd) {
|
|
|
3413
3403
|
function isRangeDependant(cmd) {
|
|
3414
3404
|
return "ranges" in cmd;
|
|
3415
3405
|
}
|
|
3416
|
-
function isZoneDependent(cmd) {
|
|
3417
|
-
return "zone" in cmd;
|
|
3418
|
-
}
|
|
3419
3406
|
function isPositionDependent(cmd) {
|
|
3420
3407
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
3421
3408
|
}
|
|
3409
|
+
function isZoneDependent(cmd) {
|
|
3410
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
3411
|
+
}
|
|
3422
3412
|
const invalidateEvaluationCommands = new Set([
|
|
3423
3413
|
"RENAME_SHEET",
|
|
3424
3414
|
"DELETE_SHEET",
|
|
@@ -3430,6 +3420,7 @@ const invalidateEvaluationCommands = new Set([
|
|
|
3430
3420
|
"REDO",
|
|
3431
3421
|
"ADD_MERGE",
|
|
3432
3422
|
"REMOVE_MERGE",
|
|
3423
|
+
"DUPLICATE_SHEET",
|
|
3433
3424
|
"UPDATE_LOCALE",
|
|
3434
3425
|
"ADD_PIVOT",
|
|
3435
3426
|
"UPDATE_PIVOT",
|
|
@@ -3459,7 +3450,6 @@ const invalidateChartEvaluationCommands = new Set([
|
|
|
3459
3450
|
]);
|
|
3460
3451
|
const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
|
|
3461
3452
|
const invalidateCFEvaluationCommands = new Set([
|
|
3462
|
-
"DUPLICATE_SHEET",
|
|
3463
3453
|
"EVALUATE_CELLS",
|
|
3464
3454
|
"ADD_CONDITIONAL_FORMAT",
|
|
3465
3455
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -3629,6 +3619,7 @@ exports.CommandResult = void 0;
|
|
|
3629
3619
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
3630
3620
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
3631
3621
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
3622
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
3632
3623
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
3633
3624
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
3634
3625
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -4460,7 +4451,7 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
|
|
|
4460
4451
|
* @param reverseSearch if true, search in the array starting from the end.
|
|
4461
4452
|
|
|
4462
4453
|
*/
|
|
4463
|
-
function linearSearch(data, target, mode, numberOfValues, getValueInData, reverseSearch = false) {
|
|
4454
|
+
function linearSearch(data, target, mode, numberOfValues, getValueInData, lookupCaches, reverseSearch = false) {
|
|
4464
4455
|
if (target === undefined || target.value === null) {
|
|
4465
4456
|
return -1;
|
|
4466
4457
|
}
|
|
@@ -4469,17 +4460,48 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4469
4460
|
}
|
|
4470
4461
|
const _target = normalizeValue(target.value);
|
|
4471
4462
|
const getValue = reverseSearch
|
|
4472
|
-
? (data, i) => getValueInData(data, numberOfValues - i - 1)
|
|
4473
|
-
: getValueInData;
|
|
4463
|
+
? (data, i) => normalizeValue(getValueInData(data, numberOfValues - i - 1))
|
|
4464
|
+
: (data, i) => normalizeValue(getValueInData(data, i));
|
|
4465
|
+
// first check if the target is in the cache
|
|
4466
|
+
const isNotWildcardTarget = mode !== "wildcard" ||
|
|
4467
|
+
typeof _target !== "string" ||
|
|
4468
|
+
!(_target.includes("*") || _target.includes("?"));
|
|
4469
|
+
if (lookupCaches && isNotWildcardTarget) {
|
|
4470
|
+
const searchMode = reverseSearch ? "reverseSearch" : "forwardSearch";
|
|
4471
|
+
let cache = lookupCaches[searchMode].get(data);
|
|
4472
|
+
if (cache === undefined) {
|
|
4473
|
+
// build the cache for all the values
|
|
4474
|
+
cache = new Map();
|
|
4475
|
+
for (let i = 0; i < numberOfValues; i++) {
|
|
4476
|
+
const value = getValue(data, i) ?? null;
|
|
4477
|
+
if (!cache.has(value)) {
|
|
4478
|
+
cache.set(value, i);
|
|
4479
|
+
}
|
|
4480
|
+
}
|
|
4481
|
+
lookupCaches[searchMode].set(data, cache);
|
|
4482
|
+
}
|
|
4483
|
+
if (cache.has(_target)) {
|
|
4484
|
+
const resultIndex = cache.get(_target);
|
|
4485
|
+
return reverseSearch ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4486
|
+
}
|
|
4487
|
+
if (mode === "strict") {
|
|
4488
|
+
return -1;
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
// else perform the linear search
|
|
4492
|
+
const resultIndex = _linearSearch(data, _target, mode, numberOfValues, getValue);
|
|
4493
|
+
return reverseSearch && resultIndex !== -1 ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4494
|
+
}
|
|
4495
|
+
function _linearSearch(data, _target, mode, numberOfValues, getNormalizeValue) {
|
|
4474
4496
|
let indexMatchTarget = (i) => {
|
|
4475
|
-
return
|
|
4497
|
+
return getNormalizeValue(data, i) === _target;
|
|
4476
4498
|
};
|
|
4477
4499
|
if (mode === "wildcard" &&
|
|
4478
4500
|
typeof _target === "string" &&
|
|
4479
4501
|
(_target.includes("*") || _target.includes("?"))) {
|
|
4480
4502
|
const regExp = wildcardToRegExp(_target);
|
|
4481
4503
|
indexMatchTarget = (i) => {
|
|
4482
|
-
const value =
|
|
4504
|
+
const value = getNormalizeValue(data, i);
|
|
4483
4505
|
if (typeof value === "string") {
|
|
4484
4506
|
return regExp.test(value);
|
|
4485
4507
|
}
|
|
@@ -4490,7 +4512,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4490
4512
|
let closestMatchIndex = -1;
|
|
4491
4513
|
if (mode === "nextSmaller") {
|
|
4492
4514
|
indexMatchTarget = (i) => {
|
|
4493
|
-
const value =
|
|
4515
|
+
const value = getNormalizeValue(data, i);
|
|
4494
4516
|
if ((!closestMatch && compareCellValues(_target, value) >= 0) ||
|
|
4495
4517
|
(compareCellValues(_target, value) >= 0 && compareCellValues(value, closestMatch) > 0)) {
|
|
4496
4518
|
closestMatch = value;
|
|
@@ -4501,7 +4523,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4501
4523
|
}
|
|
4502
4524
|
if (mode === "nextGreater") {
|
|
4503
4525
|
indexMatchTarget = (i) => {
|
|
4504
|
-
const value =
|
|
4526
|
+
const value = getNormalizeValue(data, i);
|
|
4505
4527
|
if ((!closestMatch && compareCellValues(_target, value) <= 0) ||
|
|
4506
4528
|
(compareCellValues(_target, value) <= 0 && compareCellValues(value, closestMatch) < 0)) {
|
|
4507
4529
|
closestMatch = value;
|
|
@@ -4512,12 +4534,10 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4512
4534
|
}
|
|
4513
4535
|
for (let i = 0; i < numberOfValues; i++) {
|
|
4514
4536
|
if (indexMatchTarget(i)) {
|
|
4515
|
-
return
|
|
4537
|
+
return i;
|
|
4516
4538
|
}
|
|
4517
4539
|
}
|
|
4518
|
-
return
|
|
4519
|
-
? numberOfValues - closestMatchIndex - 1
|
|
4520
|
-
: closestMatchIndex;
|
|
4540
|
+
return closestMatchIndex;
|
|
4521
4541
|
}
|
|
4522
4542
|
/**
|
|
4523
4543
|
* Normalize a value.
|
|
@@ -6491,10 +6511,11 @@ class UuidGenerator {
|
|
|
6491
6511
|
*
|
|
6492
6512
|
*/
|
|
6493
6513
|
smallUuid() {
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6514
|
+
if (window.crypto) {
|
|
6515
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
6516
|
+
const n = Number(c);
|
|
6517
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6518
|
+
});
|
|
6498
6519
|
}
|
|
6499
6520
|
else {
|
|
6500
6521
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -6509,10 +6530,11 @@ class UuidGenerator {
|
|
|
6509
6530
|
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6510
6531
|
*/
|
|
6511
6532
|
uuidv4() {
|
|
6512
|
-
|
|
6513
|
-
|
|
6514
|
-
|
|
6515
|
-
|
|
6533
|
+
if (window.crypto) {
|
|
6534
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
6535
|
+
const n = Number(c);
|
|
6536
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6537
|
+
});
|
|
6516
6538
|
}
|
|
6517
6539
|
else {
|
|
6518
6540
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -12065,6 +12087,25 @@ const LN = {
|
|
|
12065
12087
|
isExported: true,
|
|
12066
12088
|
};
|
|
12067
12089
|
// -----------------------------------------------------------------------------
|
|
12090
|
+
// LOG
|
|
12091
|
+
// -----------------------------------------------------------------------------
|
|
12092
|
+
const LOG = {
|
|
12093
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12094
|
+
args: [
|
|
12095
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12096
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12097
|
+
],
|
|
12098
|
+
compute: function (value, base = { value: 10 }) {
|
|
12099
|
+
const _value = toNumber(value, this.locale);
|
|
12100
|
+
const _base = toNumber(base, this.locale);
|
|
12101
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12102
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12103
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12104
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12105
|
+
},
|
|
12106
|
+
isExported: true,
|
|
12107
|
+
};
|
|
12108
|
+
// -----------------------------------------------------------------------------
|
|
12068
12109
|
// MOD
|
|
12069
12110
|
// -----------------------------------------------------------------------------
|
|
12070
12111
|
function mod(dividend, divisor) {
|
|
@@ -12604,6 +12645,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
12604
12645
|
ISODD: ISODD,
|
|
12605
12646
|
ISO_CEILING: ISO_CEILING,
|
|
12606
12647
|
LN: LN,
|
|
12648
|
+
LOG: LOG,
|
|
12607
12649
|
MOD: MOD,
|
|
12608
12650
|
MUNIT: MUNIT,
|
|
12609
12651
|
ODD: ODD,
|
|
@@ -18502,7 +18544,7 @@ const HLOOKUP = {
|
|
|
18502
18544
|
const _isSorted = toBoolean(isSorted.value);
|
|
18503
18545
|
const colIndex = _isSorted
|
|
18504
18546
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18505
|
-
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18547
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
|
|
18506
18548
|
const col = _range[colIndex];
|
|
18507
18549
|
if (col === undefined) {
|
|
18508
18550
|
return valueNotAvailable(searchKey);
|
|
@@ -18657,7 +18699,7 @@ const MATCH = {
|
|
|
18657
18699
|
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18658
18700
|
break;
|
|
18659
18701
|
case 0:
|
|
18660
|
-
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18702
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
|
|
18661
18703
|
break;
|
|
18662
18704
|
case -1:
|
|
18663
18705
|
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
@@ -18725,7 +18767,7 @@ const VLOOKUP = {
|
|
|
18725
18767
|
const _isSorted = toBoolean(isSorted.value);
|
|
18726
18768
|
const rowIndex = _isSorted
|
|
18727
18769
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18728
|
-
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18770
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
|
|
18729
18771
|
const value = _range[_index - 1][rowIndex];
|
|
18730
18772
|
if (value === undefined) {
|
|
18731
18773
|
return valueNotAvailable(searchKey);
|
|
@@ -18781,7 +18823,7 @@ const XLOOKUP = {
|
|
|
18781
18823
|
const reverseSearch = _searchMode === -1;
|
|
18782
18824
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18783
18825
|
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18784
|
-
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18826
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
|
|
18785
18827
|
if (index !== -1) {
|
|
18786
18828
|
return lookupDirection === "col"
|
|
18787
18829
|
? _returnRange.map((col) => [col[index]])
|
|
@@ -28269,7 +28311,7 @@ function getBarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28269
28311
|
}
|
|
28270
28312
|
function getPyramidChartData(definition, dataSets, labelRange, getters) {
|
|
28271
28313
|
const barChartData = getBarChartData(definition, dataSets, labelRange, getters);
|
|
28272
|
-
const barDataset = barChartData.dataSetsValues;
|
|
28314
|
+
const barDataset = barChartData.dataSetsValues.filter((ds) => !ds.hidden);
|
|
28273
28315
|
const pyramidDatasetValues = [];
|
|
28274
28316
|
if (barDataset[0]) {
|
|
28275
28317
|
const pyramidData = barDataset[0].data.map((value) => (value > 0 ? value : 0));
|
|
@@ -28746,10 +28788,8 @@ function getChartDatasetFormat(getters, allDataSets, axis) {
|
|
|
28746
28788
|
function getChartDatasetValues(getters, dataSets) {
|
|
28747
28789
|
const datasetValues = [];
|
|
28748
28790
|
for (const [dsIndex, ds] of Object.entries(dataSets)) {
|
|
28749
|
-
if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
|
|
28750
|
-
continue;
|
|
28751
|
-
}
|
|
28752
28791
|
let label;
|
|
28792
|
+
let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
|
|
28753
28793
|
if (ds.labelCell) {
|
|
28754
28794
|
const labelRange = ds.labelCell;
|
|
28755
28795
|
const cell = labelRange
|
|
@@ -28776,9 +28816,9 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28776
28816
|
data.fill(1);
|
|
28777
28817
|
}
|
|
28778
28818
|
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28779
|
-
|
|
28819
|
+
hidden = true;
|
|
28780
28820
|
}
|
|
28781
|
-
datasetValues.push({ data, label });
|
|
28821
|
+
datasetValues.push({ data, label, hidden });
|
|
28782
28822
|
}
|
|
28783
28823
|
return datasetValues;
|
|
28784
28824
|
}
|
|
@@ -28789,12 +28829,13 @@ function getBarChartDatasets(definition, args) {
|
|
|
28789
28829
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28790
28830
|
const trendDatasets = [];
|
|
28791
28831
|
for (const index in dataSetsValues) {
|
|
28792
|
-
let { label, data } = dataSetsValues[index];
|
|
28832
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28793
28833
|
label = definition.dataSets?.[index].label || label;
|
|
28794
28834
|
const backgroundColor = colors.next();
|
|
28795
28835
|
const dataset = {
|
|
28796
28836
|
label,
|
|
28797
28837
|
data,
|
|
28838
|
+
hidden,
|
|
28798
28839
|
borderColor: definition.background || BACKGROUND_CHART_COLOR,
|
|
28799
28840
|
borderWidth: definition.stacked ? 1 : 0,
|
|
28800
28841
|
backgroundColor,
|
|
@@ -28827,6 +28868,9 @@ function getWaterfallDatasetAndLabels(definition, args) {
|
|
|
28827
28868
|
const labelsWithSubTotals = [];
|
|
28828
28869
|
let lastValue = 0;
|
|
28829
28870
|
for (const dataSetsValue of dataSetsValues) {
|
|
28871
|
+
if (dataSetsValue.hidden) {
|
|
28872
|
+
continue;
|
|
28873
|
+
}
|
|
28830
28874
|
for (let i = 0; i < dataSetsValue.data.length; i++) {
|
|
28831
28875
|
const data = dataSetsValue.data[i];
|
|
28832
28876
|
labelsWithSubTotals.push(labels[i]);
|
|
@@ -28862,7 +28906,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28862
28906
|
const trendDatasets = [];
|
|
28863
28907
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28864
28908
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28865
|
-
let { label, data } = dataSetsValues[index];
|
|
28909
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28866
28910
|
label = definition.dataSets?.[index].label || label;
|
|
28867
28911
|
const color = colors.next();
|
|
28868
28912
|
if (axisType && ["linear", "time"].includes(axisType)) {
|
|
@@ -28872,6 +28916,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28872
28916
|
const dataset = {
|
|
28873
28917
|
label,
|
|
28874
28918
|
data,
|
|
28919
|
+
hidden,
|
|
28875
28920
|
tension: 0, // 0 -> render straight lines, which is much faster
|
|
28876
28921
|
borderColor: color,
|
|
28877
28922
|
backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
|
|
@@ -28904,11 +28949,13 @@ function getPieChartDatasets(definition, args) {
|
|
|
28904
28949
|
const dataSets = [];
|
|
28905
28950
|
const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
|
|
28906
28951
|
const backgroundColor = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
|
|
28907
|
-
for (const { label, data } of dataSetsValues) {
|
|
28952
|
+
for (const { label, data, hidden } of dataSetsValues) {
|
|
28953
|
+
if (hidden)
|
|
28954
|
+
continue;
|
|
28908
28955
|
const dataset = {
|
|
28909
28956
|
label,
|
|
28910
28957
|
data,
|
|
28911
|
-
borderColor:
|
|
28958
|
+
borderColor: definition.background || "#FFFFFF",
|
|
28912
28959
|
backgroundColor,
|
|
28913
28960
|
hoverOffset: 30,
|
|
28914
28961
|
};
|
|
@@ -28922,7 +28969,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28922
28969
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28923
28970
|
const trendDatasets = [];
|
|
28924
28971
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28925
|
-
let { label, data } = dataSetsValues[index];
|
|
28972
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28926
28973
|
label = definition.dataSets?.[index].label || label;
|
|
28927
28974
|
const design = definition.dataSets?.[index];
|
|
28928
28975
|
const color = colors.next();
|
|
@@ -28930,6 +28977,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28930
28977
|
const dataset = {
|
|
28931
28978
|
label: label,
|
|
28932
28979
|
data,
|
|
28980
|
+
hidden,
|
|
28933
28981
|
borderColor: color,
|
|
28934
28982
|
backgroundColor: color,
|
|
28935
28983
|
yAxisID: definition.dataSets?.[index].yAxisId || "y",
|
|
@@ -28954,7 +29002,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28954
29002
|
const fill = definition.fillArea ?? false;
|
|
28955
29003
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28956
29004
|
for (let i = 0; i < dataSetsValues.length; i++) {
|
|
28957
|
-
let { label, data } = dataSetsValues[i];
|
|
29005
|
+
let { label, data, hidden } = dataSetsValues[i];
|
|
28958
29006
|
if (definition.dataSets?.[i]?.label) {
|
|
28959
29007
|
label = definition.dataSets[i].label;
|
|
28960
29008
|
}
|
|
@@ -28962,6 +29010,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28962
29010
|
const dataset = {
|
|
28963
29011
|
label,
|
|
28964
29012
|
data,
|
|
29013
|
+
hidden,
|
|
28965
29014
|
borderColor,
|
|
28966
29015
|
backgroundColor: borderColor,
|
|
28967
29016
|
};
|
|
@@ -29107,6 +29156,11 @@ function getPieChartLegend(definition, args) {
|
|
|
29107
29156
|
hidden: false,
|
|
29108
29157
|
lineWidth: 2,
|
|
29109
29158
|
})),
|
|
29159
|
+
filter: (legendItem, data) => {
|
|
29160
|
+
return "datasetIndex" in legendItem
|
|
29161
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29162
|
+
: true;
|
|
29163
|
+
},
|
|
29110
29164
|
},
|
|
29111
29165
|
};
|
|
29112
29166
|
}
|
|
@@ -29168,6 +29222,11 @@ function getWaterfallChartLegend(definition, args) {
|
|
|
29168
29222
|
}
|
|
29169
29223
|
return legendValues;
|
|
29170
29224
|
},
|
|
29225
|
+
filter: (legendItem, data) => {
|
|
29226
|
+
return "datasetIndex" in legendItem
|
|
29227
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29228
|
+
: true;
|
|
29229
|
+
},
|
|
29171
29230
|
},
|
|
29172
29231
|
onClick: () => { }, // Disables click interaction with the waterfall chart legend items
|
|
29173
29232
|
};
|
|
@@ -29251,6 +29310,11 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
29251
29310
|
...legendLabelConfig,
|
|
29252
29311
|
};
|
|
29253
29312
|
}),
|
|
29313
|
+
filter: (legendItem, data) => {
|
|
29314
|
+
return "datasetIndex" in legendItem
|
|
29315
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29316
|
+
: true;
|
|
29317
|
+
},
|
|
29254
29318
|
},
|
|
29255
29319
|
};
|
|
29256
29320
|
}
|
|
@@ -33040,6 +33104,100 @@ function* iterateChildren(el) {
|
|
|
33040
33104
|
function getOpenedMenus() {
|
|
33041
33105
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
33042
33106
|
}
|
|
33107
|
+
function getCurrentSelection(el) {
|
|
33108
|
+
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
33109
|
+
let startSizeBefore = findSelectionIndex(el, startElement, startSelectionOffset);
|
|
33110
|
+
let endSizeBefore = findSelectionIndex(el, endElement, endSelectionOffset);
|
|
33111
|
+
return {
|
|
33112
|
+
start: startSizeBefore,
|
|
33113
|
+
end: endSizeBefore,
|
|
33114
|
+
};
|
|
33115
|
+
}
|
|
33116
|
+
function getStartAndEndSelection(el) {
|
|
33117
|
+
const selection = document.getSelection();
|
|
33118
|
+
return {
|
|
33119
|
+
startElement: selection.anchorNode || el,
|
|
33120
|
+
startSelectionOffset: selection.anchorOffset,
|
|
33121
|
+
endElement: selection.focusNode || el,
|
|
33122
|
+
endSelectionOffset: selection.focusOffset,
|
|
33123
|
+
};
|
|
33124
|
+
}
|
|
33125
|
+
/**
|
|
33126
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
33127
|
+
* The selected node is either a Text node or an Element node.
|
|
33128
|
+
*
|
|
33129
|
+
* case 1 -Text node:
|
|
33130
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
33131
|
+
* content length of all previous nodes.
|
|
33132
|
+
*
|
|
33133
|
+
* case 2 - Element node:
|
|
33134
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
33135
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
33136
|
+
*
|
|
33137
|
+
* See the MDN documentation for more details.
|
|
33138
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
33139
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
33140
|
+
*
|
|
33141
|
+
*/
|
|
33142
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
33143
|
+
let usedCharacters = 0;
|
|
33144
|
+
let it = iterateChildren(el);
|
|
33145
|
+
let current = it.next();
|
|
33146
|
+
let isFirstParagraph = true;
|
|
33147
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
33148
|
+
if (!current.value.hasChildNodes()) {
|
|
33149
|
+
if (current.value.textContent) {
|
|
33150
|
+
usedCharacters += current.value.textContent.length;
|
|
33151
|
+
}
|
|
33152
|
+
}
|
|
33153
|
+
// One new paragraph = one new line character, except for the first paragraph
|
|
33154
|
+
if (current.value.nodeName === "P" ||
|
|
33155
|
+
(current.value.nodeName === "DIV" && current.value !== el) // On paste, the HTML may contain <div> instead of <p>
|
|
33156
|
+
) {
|
|
33157
|
+
if (isFirstParagraph) {
|
|
33158
|
+
isFirstParagraph = false;
|
|
33159
|
+
}
|
|
33160
|
+
else {
|
|
33161
|
+
usedCharacters++;
|
|
33162
|
+
}
|
|
33163
|
+
}
|
|
33164
|
+
current = it.next();
|
|
33165
|
+
}
|
|
33166
|
+
if (current.value !== nodeToFind) {
|
|
33167
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
33168
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
33169
|
+
*
|
|
33170
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
33171
|
+
*/
|
|
33172
|
+
return 0;
|
|
33173
|
+
}
|
|
33174
|
+
else {
|
|
33175
|
+
if (!current.value.hasChildNodes()) {
|
|
33176
|
+
usedCharacters += nodeOffset;
|
|
33177
|
+
}
|
|
33178
|
+
else {
|
|
33179
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
33180
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
33181
|
+
if (child.textContent !== null) {
|
|
33182
|
+
// need to account for paragraph nodes that implicitly add a new line
|
|
33183
|
+
// except for the last paragraph
|
|
33184
|
+
let chars = child.textContent.length;
|
|
33185
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
33186
|
+
chars++;
|
|
33187
|
+
}
|
|
33188
|
+
return acc + chars;
|
|
33189
|
+
}
|
|
33190
|
+
else {
|
|
33191
|
+
return acc;
|
|
33192
|
+
}
|
|
33193
|
+
}, 0);
|
|
33194
|
+
}
|
|
33195
|
+
}
|
|
33196
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
33197
|
+
usedCharacters++;
|
|
33198
|
+
}
|
|
33199
|
+
return usedCharacters;
|
|
33200
|
+
}
|
|
33043
33201
|
const letterRegex = /^[a-zA-Z]$/;
|
|
33044
33202
|
/**
|
|
33045
33203
|
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
@@ -38275,7 +38433,7 @@ css /* scss */ `
|
|
|
38275
38433
|
.o-font-size-editor {
|
|
38276
38434
|
height: calc(100% - 4px);
|
|
38277
38435
|
input.o-font-size {
|
|
38278
|
-
outline
|
|
38436
|
+
outline: none;
|
|
38279
38437
|
height: 20px;
|
|
38280
38438
|
width: 23px;
|
|
38281
38439
|
}
|
|
@@ -39888,6 +40046,10 @@ class ContentEditableHelper {
|
|
|
39888
40046
|
if (currentStart === start && currentEnd === end) {
|
|
39889
40047
|
return;
|
|
39890
40048
|
}
|
|
40049
|
+
if (selection.rangeCount === 0) {
|
|
40050
|
+
const range = document.createRange();
|
|
40051
|
+
selection.addRange(range);
|
|
40052
|
+
}
|
|
39891
40053
|
const currentRange = selection.getRangeAt(0);
|
|
39892
40054
|
let range;
|
|
39893
40055
|
if (this.el.contains(currentRange.startContainer)) {
|
|
@@ -39915,8 +40077,16 @@ class ContentEditableHelper {
|
|
|
39915
40077
|
}
|
|
39916
40078
|
let startNode = this.findChildAtCharacterIndex(start);
|
|
39917
40079
|
let endNode = this.findChildAtCharacterIndex(end);
|
|
39918
|
-
|
|
39919
|
-
|
|
40080
|
+
// setEnd (setStart) will result in a collapsed range if the end point is before the start point
|
|
40081
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Range/setEnd
|
|
40082
|
+
if (start <= end) {
|
|
40083
|
+
range.setStart(startNode.node, startNode.offset);
|
|
40084
|
+
range.setEnd(endNode.node, endNode.offset);
|
|
40085
|
+
}
|
|
40086
|
+
else {
|
|
40087
|
+
range.setStart(endNode.node, endNode.offset);
|
|
40088
|
+
range.setEnd(startNode.node, startNode.offset);
|
|
40089
|
+
}
|
|
39920
40090
|
}
|
|
39921
40091
|
}
|
|
39922
40092
|
/**
|
|
@@ -40050,7 +40220,7 @@ class ContentEditableHelper {
|
|
|
40050
40220
|
if (!focusedNode || !this.el.contains(focusedNode))
|
|
40051
40221
|
return;
|
|
40052
40222
|
const element = focusedNode instanceof HTMLElement ? focusedNode : focusedNode.parentElement;
|
|
40053
|
-
element?.scrollIntoView({ block: "nearest" });
|
|
40223
|
+
element?.scrollIntoView?.({ block: "nearest" });
|
|
40054
40224
|
}
|
|
40055
40225
|
/**
|
|
40056
40226
|
* remove the current selection of the user
|
|
@@ -40070,100 +40240,7 @@ class ContentEditableHelper {
|
|
|
40070
40240
|
* finds the indexes of the current selection.
|
|
40071
40241
|
* */
|
|
40072
40242
|
getCurrentSelection() {
|
|
40073
|
-
|
|
40074
|
-
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
40075
|
-
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
40076
|
-
return {
|
|
40077
|
-
start: startSizeBefore,
|
|
40078
|
-
end: endSizeBefore,
|
|
40079
|
-
};
|
|
40080
|
-
}
|
|
40081
|
-
/**
|
|
40082
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
40083
|
-
* The selected node is either a Text node or an Element node.
|
|
40084
|
-
*
|
|
40085
|
-
* case 1 -Text node:
|
|
40086
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
40087
|
-
* content length of all previous nodes.
|
|
40088
|
-
*
|
|
40089
|
-
* case 2 - Element node:
|
|
40090
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
40091
|
-
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
40092
|
-
*
|
|
40093
|
-
* See the MDN documentation for more details.
|
|
40094
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
40095
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
40096
|
-
*
|
|
40097
|
-
*/
|
|
40098
|
-
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
40099
|
-
let usedCharacters = 0;
|
|
40100
|
-
let it = iterateChildren(this.el);
|
|
40101
|
-
let current = it.next();
|
|
40102
|
-
let isFirstParagraph = true;
|
|
40103
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
40104
|
-
if (!current.value.hasChildNodes()) {
|
|
40105
|
-
if (current.value.textContent) {
|
|
40106
|
-
usedCharacters += current.value.textContent.length;
|
|
40107
|
-
}
|
|
40108
|
-
}
|
|
40109
|
-
// One new paragraph = one new line character, except for the first paragraph
|
|
40110
|
-
if (current.value.nodeName === "P" ||
|
|
40111
|
-
(current.value.nodeName === "DIV" && current.value !== this.el) // On paste, the HTML may contain <div> instead of <p>
|
|
40112
|
-
) {
|
|
40113
|
-
if (isFirstParagraph) {
|
|
40114
|
-
isFirstParagraph = false;
|
|
40115
|
-
}
|
|
40116
|
-
else {
|
|
40117
|
-
usedCharacters++;
|
|
40118
|
-
}
|
|
40119
|
-
}
|
|
40120
|
-
current = it.next();
|
|
40121
|
-
}
|
|
40122
|
-
if (current.value !== nodeToFind) {
|
|
40123
|
-
/** This situation can happen if the code is called while the selection is not currently on the ContentEditableHelper.
|
|
40124
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
40125
|
-
*
|
|
40126
|
-
* A known occurence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
40127
|
-
*
|
|
40128
|
-
* FIXME: find a way to test eventhough the selection API is not available in jsDOM.
|
|
40129
|
-
*/
|
|
40130
|
-
return 0;
|
|
40131
|
-
}
|
|
40132
|
-
else {
|
|
40133
|
-
if (!current.value.hasChildNodes()) {
|
|
40134
|
-
usedCharacters += nodeOffset;
|
|
40135
|
-
}
|
|
40136
|
-
else {
|
|
40137
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
40138
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
40139
|
-
if (child.textContent !== null) {
|
|
40140
|
-
// need to account for paragraph nodes that implicitely add a new line
|
|
40141
|
-
// except for the last paragraph
|
|
40142
|
-
let chars = child.textContent.length;
|
|
40143
|
-
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
40144
|
-
chars++;
|
|
40145
|
-
}
|
|
40146
|
-
return acc + chars;
|
|
40147
|
-
}
|
|
40148
|
-
else {
|
|
40149
|
-
return acc;
|
|
40150
|
-
}
|
|
40151
|
-
}, 0);
|
|
40152
|
-
}
|
|
40153
|
-
}
|
|
40154
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
40155
|
-
usedCharacters++;
|
|
40156
|
-
}
|
|
40157
|
-
return usedCharacters;
|
|
40158
|
-
}
|
|
40159
|
-
getStartAndEndSelection() {
|
|
40160
|
-
const selection = document.getSelection();
|
|
40161
|
-
return {
|
|
40162
|
-
startElement: selection.anchorNode || this.el,
|
|
40163
|
-
startSelectionOffset: selection.anchorOffset,
|
|
40164
|
-
endElement: selection.focusNode || this.el,
|
|
40165
|
-
endSelectionOffset: selection.focusOffset,
|
|
40166
|
-
};
|
|
40243
|
+
return getCurrentSelection(this.el);
|
|
40167
40244
|
}
|
|
40168
40245
|
getText() {
|
|
40169
40246
|
let text = "";
|
|
@@ -53118,6 +53195,10 @@ class CellPlugin extends CorePlugin {
|
|
|
53118
53195
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
53119
53196
|
case "CLEAR_CELL":
|
|
53120
53197
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
53198
|
+
case "UPDATE_CELL_POSITION":
|
|
53199
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
53200
|
+
? "Success" /* CommandResult.Success */
|
|
53201
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
53121
53202
|
default:
|
|
53122
53203
|
return "Success" /* CommandResult.Success */;
|
|
53123
53204
|
}
|
|
@@ -53162,6 +53243,9 @@ class CellPlugin extends CorePlugin {
|
|
|
53162
53243
|
case "DELETE_CONTENT":
|
|
53163
53244
|
this.clearZones(cmd.sheetId, cmd.target);
|
|
53164
53245
|
break;
|
|
53246
|
+
case "DELETE_SHEET": {
|
|
53247
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
53248
|
+
}
|
|
53165
53249
|
}
|
|
53166
53250
|
}
|
|
53167
53251
|
clearZones(sheetId, zones) {
|
|
@@ -53952,6 +54036,9 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
53952
54036
|
allowDispatch(cmd) {
|
|
53953
54037
|
switch (cmd.type) {
|
|
53954
54038
|
case "ADD_CONDITIONAL_FORMAT":
|
|
54039
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54040
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54041
|
+
}
|
|
53955
54042
|
return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
|
|
53956
54043
|
case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
|
|
53957
54044
|
return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
|
|
@@ -54368,8 +54455,17 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54368
54455
|
allowDispatch(cmd) {
|
|
54369
54456
|
switch (cmd.type) {
|
|
54370
54457
|
case "ADD_DATA_VALIDATION_RULE":
|
|
54458
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54459
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54460
|
+
}
|
|
54461
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54462
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54463
|
+
}
|
|
54371
54464
|
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
54372
54465
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
54466
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54467
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54468
|
+
}
|
|
54373
54469
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
54374
54470
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
54375
54471
|
}
|
|
@@ -54596,6 +54692,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54596
54692
|
class FigurePlugin extends CorePlugin {
|
|
54597
54693
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
54598
54694
|
figures = {};
|
|
54695
|
+
insertionOrders = []; // TODO use a list in master
|
|
54599
54696
|
// ---------------------------------------------------------------------------
|
|
54600
54697
|
// Command Handling
|
|
54601
54698
|
// ---------------------------------------------------------------------------
|
|
@@ -54698,11 +54795,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
54698
54795
|
}
|
|
54699
54796
|
addFigure(figure, sheetId) {
|
|
54700
54797
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
54798
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
54701
54799
|
}
|
|
54702
54800
|
deleteSheet(sheetId) {
|
|
54801
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
54703
54802
|
this.history.update("figures", sheetId, undefined);
|
|
54704
54803
|
}
|
|
54705
54804
|
removeFigure(id, sheetId) {
|
|
54805
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
54706
54806
|
this.history.update("figures", sheetId, id, undefined);
|
|
54707
54807
|
}
|
|
54708
54808
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -54721,7 +54821,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
54721
54821
|
// Getters
|
|
54722
54822
|
// ---------------------------------------------------------------------------
|
|
54723
54823
|
getFigures(sheetId) {
|
|
54724
|
-
|
|
54824
|
+
const figures = [];
|
|
54825
|
+
for (const figureId of this.insertionOrders) {
|
|
54826
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
54827
|
+
if (figure) {
|
|
54828
|
+
figures.push(figure);
|
|
54829
|
+
}
|
|
54830
|
+
}
|
|
54831
|
+
return figures;
|
|
54725
54832
|
}
|
|
54726
54833
|
getFigure(sheetId, figureId) {
|
|
54727
54834
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -54734,11 +54841,9 @@ class FigurePlugin extends CorePlugin {
|
|
|
54734
54841
|
// ---------------------------------------------------------------------------
|
|
54735
54842
|
import(data) {
|
|
54736
54843
|
for (let sheet of data.sheets) {
|
|
54737
|
-
const figures
|
|
54738
|
-
|
|
54739
|
-
|
|
54740
|
-
});
|
|
54741
|
-
this.figures[sheet.id] = figures;
|
|
54844
|
+
for (const figure of sheet.figures) {
|
|
54845
|
+
this.addFigure(figure, sheet.id);
|
|
54846
|
+
}
|
|
54742
54847
|
}
|
|
54743
54848
|
}
|
|
54744
54849
|
export(data) {
|
|
@@ -56164,6 +56269,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
56164
56269
|
case "CREATE_SHEET": {
|
|
56165
56270
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
56166
56271
|
}
|
|
56272
|
+
case "DUPLICATE_SHEET": {
|
|
56273
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
56274
|
+
}
|
|
56167
56275
|
case "MOVE_SHEET":
|
|
56168
56276
|
try {
|
|
56169
56277
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -56975,6 +57083,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
56975
57083
|
checkZonesAreInSheet(cmd) {
|
|
56976
57084
|
if (!("sheetId" in cmd))
|
|
56977
57085
|
return "Success" /* CommandResult.Success */;
|
|
57086
|
+
if ("ranges" in cmd &&
|
|
57087
|
+
cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
57088
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57089
|
+
}
|
|
56978
57090
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
56979
57091
|
}
|
|
56980
57092
|
}
|
|
@@ -56983,6 +57095,7 @@ let nextTableId = 1;
|
|
|
56983
57095
|
class TablePlugin extends CorePlugin {
|
|
56984
57096
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
56985
57097
|
tables = {};
|
|
57098
|
+
insertionOrders = {};
|
|
56986
57099
|
adaptRanges(applyChange, sheetId) {
|
|
56987
57100
|
const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
|
|
56988
57101
|
for (const sheetId of sheetIds) {
|
|
@@ -56994,6 +57107,9 @@ class TablePlugin extends CorePlugin {
|
|
|
56994
57107
|
allowDispatch(cmd) {
|
|
56995
57108
|
switch (cmd.type) {
|
|
56996
57109
|
case "CREATE_TABLE":
|
|
57110
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
|
|
57111
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57112
|
+
}
|
|
56997
57113
|
const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
|
|
56998
57114
|
if (!areZonesContinuous(zones)) {
|
|
56999
57115
|
return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
|
|
@@ -57024,11 +57140,13 @@ class TablePlugin extends CorePlugin {
|
|
|
57024
57140
|
switch (cmd.type) {
|
|
57025
57141
|
case "CREATE_SHEET":
|
|
57026
57142
|
this.history.update("tables", cmd.sheetId, {});
|
|
57143
|
+
this.history.update("insertionOrders", cmd.sheetId, []);
|
|
57027
57144
|
break;
|
|
57028
57145
|
case "DELETE_SHEET": {
|
|
57029
57146
|
const tables = { ...this.tables };
|
|
57030
57147
|
delete tables[cmd.sheetId];
|
|
57031
57148
|
this.history.update("tables", tables);
|
|
57149
|
+
this.history.update("insertionOrders", cmd.sheetId, undefined);
|
|
57032
57150
|
break;
|
|
57033
57151
|
}
|
|
57034
57152
|
case "DUPLICATE_SHEET": {
|
|
@@ -57040,6 +57158,9 @@ class TablePlugin extends CorePlugin {
|
|
|
57040
57158
|
: this.copyStaticTableForSheet(cmd.sheetIdTo, table);
|
|
57041
57159
|
}
|
|
57042
57160
|
this.history.update("tables", cmd.sheetIdTo, newTables);
|
|
57161
|
+
this.history.update("insertionOrders", cmd.sheetIdTo, [
|
|
57162
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57163
|
+
]);
|
|
57043
57164
|
break;
|
|
57044
57165
|
}
|
|
57045
57166
|
case "CREATE_TABLE": {
|
|
@@ -57053,6 +57174,10 @@ class TablePlugin extends CorePlugin {
|
|
|
57053
57174
|
? this.createDynamicTable(id, union, config)
|
|
57054
57175
|
: this.createStaticTable(id, cmd.tableType, union, config);
|
|
57055
57176
|
this.history.update("tables", cmd.sheetId, newTable.id, newTable);
|
|
57177
|
+
this.history.update("insertionOrders", cmd.sheetId, [
|
|
57178
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57179
|
+
newTable.id,
|
|
57180
|
+
]);
|
|
57056
57181
|
break;
|
|
57057
57182
|
}
|
|
57058
57183
|
case "REMOVE_TABLE": {
|
|
@@ -57063,6 +57188,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57063
57188
|
}
|
|
57064
57189
|
}
|
|
57065
57190
|
this.history.update("tables", cmd.sheetId, tables);
|
|
57191
|
+
this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
|
|
57066
57192
|
break;
|
|
57067
57193
|
}
|
|
57068
57194
|
case "UPDATE_TABLE": {
|
|
@@ -57098,7 +57224,14 @@ class TablePlugin extends CorePlugin {
|
|
|
57098
57224
|
}
|
|
57099
57225
|
}
|
|
57100
57226
|
getCoreTables(sheetId) {
|
|
57101
|
-
|
|
57227
|
+
const tables = [];
|
|
57228
|
+
for (const tableId of this.insertionOrders[sheetId] || []) {
|
|
57229
|
+
const table = this.tables[sheetId][tableId];
|
|
57230
|
+
if (table) {
|
|
57231
|
+
tables.push(table);
|
|
57232
|
+
}
|
|
57233
|
+
}
|
|
57234
|
+
return tables;
|
|
57102
57235
|
}
|
|
57103
57236
|
getCoreTable({ sheetId, col, row }) {
|
|
57104
57237
|
return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
|
|
@@ -57381,6 +57514,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57381
57514
|
// ---------------------------------------------------------------------------
|
|
57382
57515
|
import(data) {
|
|
57383
57516
|
for (const sheet of data.sheets) {
|
|
57517
|
+
const tableIds = [];
|
|
57384
57518
|
for (const tableData of sheet.tables || []) {
|
|
57385
57519
|
const uuid = `${nextTableId++}`;
|
|
57386
57520
|
const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
|
|
@@ -57390,7 +57524,9 @@ class TablePlugin extends CorePlugin {
|
|
|
57390
57524
|
? this.createDynamicTable(uuid, range, tableConfig)
|
|
57391
57525
|
: this.createStaticTable(uuid, tableType, range, tableConfig);
|
|
57392
57526
|
this.history.update("tables", sheet.id, table.id, table);
|
|
57527
|
+
tableIds.push(table.id);
|
|
57393
57528
|
}
|
|
57529
|
+
this.history.update("insertionOrders", sheet.id, tableIds);
|
|
57394
57530
|
}
|
|
57395
57531
|
}
|
|
57396
57532
|
export(data) {
|
|
@@ -57430,7 +57566,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57430
57566
|
allowDispatch(cmd) {
|
|
57431
57567
|
switch (cmd.type) {
|
|
57432
57568
|
case "GROUP_HEADERS": {
|
|
57433
|
-
const { start, end } = cmd;
|
|
57569
|
+
const { start, end, sheetId } = cmd;
|
|
57570
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57571
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57572
|
+
}
|
|
57434
57573
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57435
57574
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57436
57575
|
}
|
|
@@ -57443,7 +57582,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57443
57582
|
break;
|
|
57444
57583
|
}
|
|
57445
57584
|
case "UNGROUP_HEADERS": {
|
|
57446
|
-
const { start, end } = cmd;
|
|
57585
|
+
const { start, end, sheetId } = cmd;
|
|
57586
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57587
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57588
|
+
}
|
|
57447
57589
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57448
57590
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57449
57591
|
}
|
|
@@ -57454,6 +57596,9 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57454
57596
|
}
|
|
57455
57597
|
case "UNFOLD_HEADER_GROUP":
|
|
57456
57598
|
case "FOLD_HEADER_GROUP":
|
|
57599
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
57600
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57601
|
+
}
|
|
57457
57602
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
57458
57603
|
if (!group) {
|
|
57459
57604
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -57854,6 +57999,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57854
57999
|
return this.checkDuplicatedMeasureIds(cmd.pivot);
|
|
57855
58000
|
}
|
|
57856
58001
|
case "UPDATE_PIVOT": {
|
|
58002
|
+
if (!(cmd.pivotId in this.pivots)) {
|
|
58003
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
58004
|
+
}
|
|
57857
58005
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
57858
58006
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
57859
58007
|
}
|
|
@@ -57870,6 +58018,8 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57870
58018
|
return "EmptyName" /* CommandResult.EmptyName */;
|
|
57871
58019
|
}
|
|
57872
58020
|
break;
|
|
58021
|
+
case "REMOVE_PIVOT":
|
|
58022
|
+
case "DUPLICATE_PIVOT":
|
|
57873
58023
|
case "INSERT_PIVOT": {
|
|
57874
58024
|
if (!(cmd.pivotId in this.pivots)) {
|
|
57875
58025
|
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
@@ -57919,7 +58069,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57919
58069
|
break;
|
|
57920
58070
|
}
|
|
57921
58071
|
case "UPDATE_PIVOT": {
|
|
57922
|
-
this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
|
|
58072
|
+
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
57923
58073
|
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
57924
58074
|
break;
|
|
57925
58075
|
}
|
|
@@ -57990,7 +58140,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57990
58140
|
// Private
|
|
57991
58141
|
// -------------------------------------------------------------------------
|
|
57992
58142
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
57993
|
-
this.history.update("pivots", pivotId, { definition: pivot, formulaId });
|
|
58143
|
+
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
57994
58144
|
this.compileCalculatedMeasures(pivot.measures);
|
|
57995
58145
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
57996
58146
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
@@ -59576,6 +59726,10 @@ class Evaluator {
|
|
|
59576
59726
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
59577
59727
|
this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
|
|
59578
59728
|
this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
|
|
59729
|
+
this.compilationParams.evalContext.lookupCaches = {
|
|
59730
|
+
forwardSearch: new Map(),
|
|
59731
|
+
reverseSearch: new Map(),
|
|
59732
|
+
};
|
|
59579
59733
|
}
|
|
59580
59734
|
createEmptyPositionSet() {
|
|
59581
59735
|
const sheetSizes = {};
|
|
@@ -62896,6 +63050,9 @@ function updateChartRangesTransformation(toTransform, executed) {
|
|
|
62896
63050
|
};
|
|
62897
63051
|
}
|
|
62898
63052
|
function createSheetTransformation(toTransform, executed) {
|
|
63053
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
63054
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
63055
|
+
}
|
|
62899
63056
|
if (toTransform.name === executed.name) {
|
|
62900
63057
|
return {
|
|
62901
63058
|
...toTransform,
|
|
@@ -63539,15 +63696,6 @@ class Session extends EventBus {
|
|
|
63539
63696
|
}
|
|
63540
63697
|
this.sendPendingMessage();
|
|
63541
63698
|
}
|
|
63542
|
-
dropPendingRevision(revisionId) {
|
|
63543
|
-
this.revisions.drop(revisionId);
|
|
63544
|
-
const revisionIds = this.pendingMessages
|
|
63545
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63546
|
-
.map((message) => message.nextRevisionId);
|
|
63547
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63548
|
-
this.waitingAck = false;
|
|
63549
|
-
this.waitingUndoRedoAck = false;
|
|
63550
|
-
}
|
|
63551
63699
|
/**
|
|
63552
63700
|
* Send the next pending message
|
|
63553
63701
|
*/
|
|
@@ -63556,15 +63704,14 @@ class Session extends EventBus {
|
|
|
63556
63704
|
if (!message)
|
|
63557
63705
|
return;
|
|
63558
63706
|
if (message.type === "REMOTE_REVISION") {
|
|
63559
|
-
|
|
63707
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
63560
63708
|
if (revision.commands.length === 0) {
|
|
63561
63709
|
/**
|
|
63562
|
-
* The command is empty, we have to
|
|
63710
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
63563
63711
|
* to avoid issues with undo/redo
|
|
63564
63712
|
*/
|
|
63565
|
-
this.
|
|
63566
|
-
|
|
63567
|
-
return;
|
|
63713
|
+
this.revisions.rebase(revision.id);
|
|
63714
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
63568
63715
|
}
|
|
63569
63716
|
message = {
|
|
63570
63717
|
...message,
|
|
@@ -63600,18 +63747,16 @@ class Session extends EventBus {
|
|
|
63600
63747
|
case "REVISION_UNDONE": {
|
|
63601
63748
|
this.waitingAck = false;
|
|
63602
63749
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63603
|
-
const
|
|
63604
|
-
|
|
63605
|
-
if (firstTransformedRevisionIndex !== -1) {
|
|
63750
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
63751
|
+
if (firstPendingRevisionId !== -1) {
|
|
63606
63752
|
/**
|
|
63607
63753
|
* Some revisions undergo transformations that may cause issues with
|
|
63608
63754
|
* undo/redo if the transformation is destructive (we don't get back
|
|
63609
63755
|
* the original command by transforming it with the inverse).
|
|
63610
|
-
* To prevent these problems, we must
|
|
63756
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
63611
63757
|
* revisions.
|
|
63612
63758
|
*/
|
|
63613
|
-
this.
|
|
63614
|
-
this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
|
|
63759
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
63615
63760
|
}
|
|
63616
63761
|
this.serverRevisionId = message.nextRevisionId;
|
|
63617
63762
|
this.processedRevisions.add(message.nextRevisionId);
|
|
@@ -64739,6 +64884,10 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
64739
64884
|
*/
|
|
64740
64885
|
checkZonesAreInSheet(cmd) {
|
|
64741
64886
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
64887
|
+
if ("ranges" in cmd &&
|
|
64888
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
64889
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
64890
|
+
}
|
|
64742
64891
|
const zones = this.getters.getCommandZones(cmd);
|
|
64743
64892
|
if (!sheetId && zones.length > 0) {
|
|
64744
64893
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -65293,7 +65442,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65293
65442
|
super(config);
|
|
65294
65443
|
this.session = config.session;
|
|
65295
65444
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
65296
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
65297
65445
|
this.session.on("snapshot", this, () => {
|
|
65298
65446
|
this.undoStack = [];
|
|
65299
65447
|
this.redoStack = [];
|
|
@@ -65363,10 +65511,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65363
65511
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
65364
65512
|
return canRepeatRevision(lastNonRedoRevision);
|
|
65365
65513
|
}
|
|
65366
|
-
drop(revisionIds) {
|
|
65367
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
65368
|
-
this.redoStack = [];
|
|
65369
|
-
}
|
|
65370
65514
|
onNewLocalStateUpdate({ id }) {
|
|
65371
65515
|
this.undoStack.push(id);
|
|
65372
65516
|
this.redoStack = [];
|
|
@@ -68070,7 +68214,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68070
68214
|
case "UNGROUP_HEADERS":
|
|
68071
68215
|
case "GROUP_HEADERS":
|
|
68072
68216
|
case "CREATE_SHEET":
|
|
68073
|
-
this.
|
|
68217
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
68218
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
68219
|
+
}
|
|
68074
68220
|
break;
|
|
68075
68221
|
case "DUPLICATE_SHEET":
|
|
68076
68222
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -68078,12 +68224,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68078
68224
|
}
|
|
68079
68225
|
}
|
|
68080
68226
|
finalize() {
|
|
68081
|
-
|
|
68082
|
-
|
|
68227
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68228
|
+
// sheets can be created without this plugin being aware of it
|
|
68229
|
+
// in concurrent situations.
|
|
68230
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
68083
68231
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
68084
68232
|
}
|
|
68085
|
-
this.isDirty = false;
|
|
68086
68233
|
}
|
|
68234
|
+
this.isDirty = false;
|
|
68087
68235
|
}
|
|
68088
68236
|
/**
|
|
68089
68237
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -71504,9 +71652,16 @@ class SelectiveHistory {
|
|
|
71504
71652
|
this.fastForward();
|
|
71505
71653
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
71506
71654
|
}
|
|
71507
|
-
|
|
71655
|
+
rebase(operationId) {
|
|
71656
|
+
const operation = this.get(operationId);
|
|
71657
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
71508
71658
|
this.revertBefore(operationId);
|
|
71659
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
71509
71660
|
this.tree.drop(operationId);
|
|
71661
|
+
this.insert(operationId, operation, baseId);
|
|
71662
|
+
for (const { operation } of execution) {
|
|
71663
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
71664
|
+
}
|
|
71510
71665
|
}
|
|
71511
71666
|
/**
|
|
71512
71667
|
* Revert the state as it was *before* the given operation was executed.
|
|
@@ -74617,6 +74772,11 @@ class Model extends EventBus {
|
|
|
74617
74772
|
dispatch: (command) => {
|
|
74618
74773
|
const result = this.checkDispatchAllowed(command);
|
|
74619
74774
|
if (!result.isSuccessful) {
|
|
74775
|
+
// core views plugins need to be invalidated
|
|
74776
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
74777
|
+
type: "UNDO",
|
|
74778
|
+
commands: [command],
|
|
74779
|
+
});
|
|
74620
74780
|
return;
|
|
74621
74781
|
}
|
|
74622
74782
|
this.isReplayingCommand = true;
|
|
@@ -75167,6 +75327,6 @@ exports.tokenColors = tokenColors;
|
|
|
75167
75327
|
exports.tokenize = tokenize;
|
|
75168
75328
|
|
|
75169
75329
|
|
|
75170
|
-
__info__.version = "18.1.
|
|
75171
|
-
__info__.date = "2025-02-
|
|
75172
|
-
__info__.hash = "
|
|
75330
|
+
__info__.version = "18.1.9";
|
|
75331
|
+
__info__.date = "2025-02-25T05:59:45.472Z";
|
|
75332
|
+
__info__.hash = "6789c1c";
|