@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
|
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw, toRaw } from '@odoo/owl';
|
|
@@ -2218,17 +2218,7 @@ function toZoneWithoutBoundaryChanges(xc) {
|
|
|
2218
2218
|
*/
|
|
2219
2219
|
function toUnboundedZone(xc) {
|
|
2220
2220
|
const zone = toZoneWithoutBoundaryChanges(xc);
|
|
2221
|
-
|
|
2222
|
-
const tmp = zone.left;
|
|
2223
|
-
zone.left = zone.right;
|
|
2224
|
-
zone.right = tmp;
|
|
2225
|
-
}
|
|
2226
|
-
if (zone.bottom !== undefined && zone.bottom < zone.top) {
|
|
2227
|
-
const tmp = zone.top;
|
|
2228
|
-
zone.top = zone.bottom;
|
|
2229
|
-
zone.bottom = tmp;
|
|
2230
|
-
}
|
|
2231
|
-
return zone;
|
|
2221
|
+
return reorderZone(zone);
|
|
2232
2222
|
}
|
|
2233
2223
|
/**
|
|
2234
2224
|
* Convert from a cartesian reference to a Zone.
|
|
@@ -2502,11 +2492,11 @@ function positions(zone) {
|
|
|
2502
2492
|
return positions;
|
|
2503
2493
|
}
|
|
2504
2494
|
function reorderZone(zone) {
|
|
2505
|
-
if (zone.left > zone.right) {
|
|
2506
|
-
zone = { left: zone.right, right: zone.left
|
|
2495
|
+
if (zone.right !== undefined && zone.left > zone.right) {
|
|
2496
|
+
zone = { ...zone, left: zone.right, right: zone.left };
|
|
2507
2497
|
}
|
|
2508
|
-
if (zone.top > zone.bottom) {
|
|
2509
|
-
zone = {
|
|
2498
|
+
if (zone.bottom !== undefined && zone.top > zone.bottom) {
|
|
2499
|
+
zone = { ...zone, top: zone.bottom, bottom: zone.top };
|
|
2510
2500
|
}
|
|
2511
2501
|
return zone;
|
|
2512
2502
|
}
|
|
@@ -3411,12 +3401,12 @@ function isTargetDependent(cmd) {
|
|
|
3411
3401
|
function isRangeDependant(cmd) {
|
|
3412
3402
|
return "ranges" in cmd;
|
|
3413
3403
|
}
|
|
3414
|
-
function isZoneDependent(cmd) {
|
|
3415
|
-
return "zone" in cmd;
|
|
3416
|
-
}
|
|
3417
3404
|
function isPositionDependent(cmd) {
|
|
3418
3405
|
return "col" in cmd && "row" in cmd && "sheetId" in cmd;
|
|
3419
3406
|
}
|
|
3407
|
+
function isZoneDependent(cmd) {
|
|
3408
|
+
return "sheetId" in cmd && "zone" in cmd;
|
|
3409
|
+
}
|
|
3420
3410
|
const invalidateEvaluationCommands = new Set([
|
|
3421
3411
|
"RENAME_SHEET",
|
|
3422
3412
|
"DELETE_SHEET",
|
|
@@ -3428,6 +3418,7 @@ const invalidateEvaluationCommands = new Set([
|
|
|
3428
3418
|
"REDO",
|
|
3429
3419
|
"ADD_MERGE",
|
|
3430
3420
|
"REMOVE_MERGE",
|
|
3421
|
+
"DUPLICATE_SHEET",
|
|
3431
3422
|
"UPDATE_LOCALE",
|
|
3432
3423
|
"ADD_PIVOT",
|
|
3433
3424
|
"UPDATE_PIVOT",
|
|
@@ -3457,7 +3448,6 @@ const invalidateChartEvaluationCommands = new Set([
|
|
|
3457
3448
|
]);
|
|
3458
3449
|
const invalidateDependenciesCommands = new Set(["MOVE_RANGES"]);
|
|
3459
3450
|
const invalidateCFEvaluationCommands = new Set([
|
|
3460
|
-
"DUPLICATE_SHEET",
|
|
3461
3451
|
"EVALUATE_CELLS",
|
|
3462
3452
|
"ADD_CONDITIONAL_FORMAT",
|
|
3463
3453
|
"REMOVE_CONDITIONAL_FORMAT",
|
|
@@ -3627,6 +3617,7 @@ var CommandResult;
|
|
|
3627
3617
|
CommandResult["InvalidRange"] = "InvalidRange";
|
|
3628
3618
|
CommandResult["InvalidZones"] = "InvalidZones";
|
|
3629
3619
|
CommandResult["InvalidSheetId"] = "InvalidSheetId";
|
|
3620
|
+
CommandResult["InvalidCellId"] = "InvalidCellId";
|
|
3630
3621
|
CommandResult["InvalidFigureId"] = "InvalidFigureId";
|
|
3631
3622
|
CommandResult["InputAlreadyFocused"] = "InputAlreadyFocused";
|
|
3632
3623
|
CommandResult["MaximumRangesReached"] = "MaximumRangesReached";
|
|
@@ -4458,7 +4449,7 @@ function dichotomicSearch(data, target, mode, sortOrder, rangeLength, getValueIn
|
|
|
4458
4449
|
* @param reverseSearch if true, search in the array starting from the end.
|
|
4459
4450
|
|
|
4460
4451
|
*/
|
|
4461
|
-
function linearSearch(data, target, mode, numberOfValues, getValueInData, reverseSearch = false) {
|
|
4452
|
+
function linearSearch(data, target, mode, numberOfValues, getValueInData, lookupCaches, reverseSearch = false) {
|
|
4462
4453
|
if (target === undefined || target.value === null) {
|
|
4463
4454
|
return -1;
|
|
4464
4455
|
}
|
|
@@ -4467,17 +4458,48 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4467
4458
|
}
|
|
4468
4459
|
const _target = normalizeValue(target.value);
|
|
4469
4460
|
const getValue = reverseSearch
|
|
4470
|
-
? (data, i) => getValueInData(data, numberOfValues - i - 1)
|
|
4471
|
-
: getValueInData;
|
|
4461
|
+
? (data, i) => normalizeValue(getValueInData(data, numberOfValues - i - 1))
|
|
4462
|
+
: (data, i) => normalizeValue(getValueInData(data, i));
|
|
4463
|
+
// first check if the target is in the cache
|
|
4464
|
+
const isNotWildcardTarget = mode !== "wildcard" ||
|
|
4465
|
+
typeof _target !== "string" ||
|
|
4466
|
+
!(_target.includes("*") || _target.includes("?"));
|
|
4467
|
+
if (lookupCaches && isNotWildcardTarget) {
|
|
4468
|
+
const searchMode = reverseSearch ? "reverseSearch" : "forwardSearch";
|
|
4469
|
+
let cache = lookupCaches[searchMode].get(data);
|
|
4470
|
+
if (cache === undefined) {
|
|
4471
|
+
// build the cache for all the values
|
|
4472
|
+
cache = new Map();
|
|
4473
|
+
for (let i = 0; i < numberOfValues; i++) {
|
|
4474
|
+
const value = getValue(data, i) ?? null;
|
|
4475
|
+
if (!cache.has(value)) {
|
|
4476
|
+
cache.set(value, i);
|
|
4477
|
+
}
|
|
4478
|
+
}
|
|
4479
|
+
lookupCaches[searchMode].set(data, cache);
|
|
4480
|
+
}
|
|
4481
|
+
if (cache.has(_target)) {
|
|
4482
|
+
const resultIndex = cache.get(_target);
|
|
4483
|
+
return reverseSearch ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4484
|
+
}
|
|
4485
|
+
if (mode === "strict") {
|
|
4486
|
+
return -1;
|
|
4487
|
+
}
|
|
4488
|
+
}
|
|
4489
|
+
// else perform the linear search
|
|
4490
|
+
const resultIndex = _linearSearch(data, _target, mode, numberOfValues, getValue);
|
|
4491
|
+
return reverseSearch && resultIndex !== -1 ? numberOfValues - resultIndex - 1 : resultIndex;
|
|
4492
|
+
}
|
|
4493
|
+
function _linearSearch(data, _target, mode, numberOfValues, getNormalizeValue) {
|
|
4472
4494
|
let indexMatchTarget = (i) => {
|
|
4473
|
-
return
|
|
4495
|
+
return getNormalizeValue(data, i) === _target;
|
|
4474
4496
|
};
|
|
4475
4497
|
if (mode === "wildcard" &&
|
|
4476
4498
|
typeof _target === "string" &&
|
|
4477
4499
|
(_target.includes("*") || _target.includes("?"))) {
|
|
4478
4500
|
const regExp = wildcardToRegExp(_target);
|
|
4479
4501
|
indexMatchTarget = (i) => {
|
|
4480
|
-
const value =
|
|
4502
|
+
const value = getNormalizeValue(data, i);
|
|
4481
4503
|
if (typeof value === "string") {
|
|
4482
4504
|
return regExp.test(value);
|
|
4483
4505
|
}
|
|
@@ -4488,7 +4510,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4488
4510
|
let closestMatchIndex = -1;
|
|
4489
4511
|
if (mode === "nextSmaller") {
|
|
4490
4512
|
indexMatchTarget = (i) => {
|
|
4491
|
-
const value =
|
|
4513
|
+
const value = getNormalizeValue(data, i);
|
|
4492
4514
|
if ((!closestMatch && compareCellValues(_target, value) >= 0) ||
|
|
4493
4515
|
(compareCellValues(_target, value) >= 0 && compareCellValues(value, closestMatch) > 0)) {
|
|
4494
4516
|
closestMatch = value;
|
|
@@ -4499,7 +4521,7 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4499
4521
|
}
|
|
4500
4522
|
if (mode === "nextGreater") {
|
|
4501
4523
|
indexMatchTarget = (i) => {
|
|
4502
|
-
const value =
|
|
4524
|
+
const value = getNormalizeValue(data, i);
|
|
4503
4525
|
if ((!closestMatch && compareCellValues(_target, value) <= 0) ||
|
|
4504
4526
|
(compareCellValues(_target, value) <= 0 && compareCellValues(value, closestMatch) < 0)) {
|
|
4505
4527
|
closestMatch = value;
|
|
@@ -4510,12 +4532,10 @@ function linearSearch(data, target, mode, numberOfValues, getValueInData, revers
|
|
|
4510
4532
|
}
|
|
4511
4533
|
for (let i = 0; i < numberOfValues; i++) {
|
|
4512
4534
|
if (indexMatchTarget(i)) {
|
|
4513
|
-
return
|
|
4535
|
+
return i;
|
|
4514
4536
|
}
|
|
4515
4537
|
}
|
|
4516
|
-
return
|
|
4517
|
-
? numberOfValues - closestMatchIndex - 1
|
|
4518
|
-
: closestMatchIndex;
|
|
4538
|
+
return closestMatchIndex;
|
|
4519
4539
|
}
|
|
4520
4540
|
/**
|
|
4521
4541
|
* Normalize a value.
|
|
@@ -6489,10 +6509,11 @@ class UuidGenerator {
|
|
|
6489
6509
|
*
|
|
6490
6510
|
*/
|
|
6491
6511
|
smallUuid() {
|
|
6492
|
-
|
|
6493
|
-
|
|
6494
|
-
|
|
6495
|
-
|
|
6512
|
+
if (window.crypto) {
|
|
6513
|
+
return "10000000-1000".replace(/[01]/g, (c) => {
|
|
6514
|
+
const n = Number(c);
|
|
6515
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6516
|
+
});
|
|
6496
6517
|
}
|
|
6497
6518
|
else {
|
|
6498
6519
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -6507,10 +6528,11 @@ class UuidGenerator {
|
|
|
6507
6528
|
* This method should be used when you need to avoid collisions at all costs, like the id of a revision.
|
|
6508
6529
|
*/
|
|
6509
6530
|
uuidv4() {
|
|
6510
|
-
|
|
6511
|
-
|
|
6512
|
-
|
|
6513
|
-
|
|
6531
|
+
if (window.crypto) {
|
|
6532
|
+
return "10000000-1000-4000-8000-100000000000".replace(/[018]/g, (c) => {
|
|
6533
|
+
const n = Number(c);
|
|
6534
|
+
return (n ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (n / 4)))).toString(16);
|
|
6535
|
+
});
|
|
6514
6536
|
}
|
|
6515
6537
|
else {
|
|
6516
6538
|
// mainly for jest and other browsers that do not have the crypto functionality
|
|
@@ -12063,6 +12085,25 @@ const LN = {
|
|
|
12063
12085
|
isExported: true,
|
|
12064
12086
|
};
|
|
12065
12087
|
// -----------------------------------------------------------------------------
|
|
12088
|
+
// LOG
|
|
12089
|
+
// -----------------------------------------------------------------------------
|
|
12090
|
+
const LOG = {
|
|
12091
|
+
description: _t("The logarithm of a number, for a given base."),
|
|
12092
|
+
args: [
|
|
12093
|
+
arg("value (number)", _t("The value for which to calculate the logarithm.")),
|
|
12094
|
+
arg("base (number, default=10)", _t("The base of the logarithm.")),
|
|
12095
|
+
],
|
|
12096
|
+
compute: function (value, base = { value: 10 }) {
|
|
12097
|
+
const _value = toNumber(value, this.locale);
|
|
12098
|
+
const _base = toNumber(base, this.locale);
|
|
12099
|
+
assert(() => _value > 0, _t("The value (%s) must be strictly positive.", _value.toString()));
|
|
12100
|
+
assert(() => _base > 0, _t("The base (%s) must be strictly positive.", _base.toString()));
|
|
12101
|
+
assert(() => _base !== 1, _t("The base must be different from 1."));
|
|
12102
|
+
return Math.log10(_value) / Math.log10(_base);
|
|
12103
|
+
},
|
|
12104
|
+
isExported: true,
|
|
12105
|
+
};
|
|
12106
|
+
// -----------------------------------------------------------------------------
|
|
12066
12107
|
// MOD
|
|
12067
12108
|
// -----------------------------------------------------------------------------
|
|
12068
12109
|
function mod(dividend, divisor) {
|
|
@@ -12602,6 +12643,7 @@ var math = /*#__PURE__*/Object.freeze({
|
|
|
12602
12643
|
ISODD: ISODD,
|
|
12603
12644
|
ISO_CEILING: ISO_CEILING,
|
|
12604
12645
|
LN: LN,
|
|
12646
|
+
LOG: LOG,
|
|
12605
12647
|
MOD: MOD,
|
|
12606
12648
|
MUNIT: MUNIT,
|
|
12607
12649
|
ODD: ODD,
|
|
@@ -18500,7 +18542,7 @@ const HLOOKUP = {
|
|
|
18500
18542
|
const _isSorted = toBoolean(isSorted.value);
|
|
18501
18543
|
const colIndex = _isSorted
|
|
18502
18544
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range.length, getValueFromRange)
|
|
18503
|
-
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange);
|
|
18545
|
+
: linearSearch(_range, searchKey, "wildcard", _range.length, getValueFromRange, this.lookupCaches);
|
|
18504
18546
|
const col = _range[colIndex];
|
|
18505
18547
|
if (col === undefined) {
|
|
18506
18548
|
return valueNotAvailable(searchKey);
|
|
@@ -18655,7 +18697,7 @@ const MATCH = {
|
|
|
18655
18697
|
index = dichotomicSearch(_range, searchKey, "nextSmaller", "asc", rangeLen, getElement);
|
|
18656
18698
|
break;
|
|
18657
18699
|
case 0:
|
|
18658
|
-
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement);
|
|
18700
|
+
index = linearSearch(_range, searchKey, "wildcard", rangeLen, getElement, this.lookupCaches);
|
|
18659
18701
|
break;
|
|
18660
18702
|
case -1:
|
|
18661
18703
|
index = dichotomicSearch(_range, searchKey, "nextGreater", "desc", rangeLen, getElement);
|
|
@@ -18723,7 +18765,7 @@ const VLOOKUP = {
|
|
|
18723
18765
|
const _isSorted = toBoolean(isSorted.value);
|
|
18724
18766
|
const rowIndex = _isSorted
|
|
18725
18767
|
? dichotomicSearch(_range, searchKey, "nextSmaller", "asc", _range[0].length, getValueFromRange)
|
|
18726
|
-
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange);
|
|
18768
|
+
: linearSearch(_range, searchKey, "wildcard", _range[0].length, getValueFromRange, this.lookupCaches);
|
|
18727
18769
|
const value = _range[_index - 1][rowIndex];
|
|
18728
18770
|
if (value === undefined) {
|
|
18729
18771
|
return valueNotAvailable(searchKey);
|
|
@@ -18779,7 +18821,7 @@ const XLOOKUP = {
|
|
|
18779
18821
|
const reverseSearch = _searchMode === -1;
|
|
18780
18822
|
const index = _searchMode === 2 || _searchMode === -2
|
|
18781
18823
|
? dichotomicSearch(_lookupRange, searchKey, mode, _searchMode === 2 ? "asc" : "desc", rangeLen, getElement)
|
|
18782
|
-
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, reverseSearch);
|
|
18824
|
+
: linearSearch(_lookupRange, searchKey, mode, rangeLen, getElement, this.lookupCaches, reverseSearch);
|
|
18783
18825
|
if (index !== -1) {
|
|
18784
18826
|
return lookupDirection === "col"
|
|
18785
18827
|
? _returnRange.map((col) => [col[index]])
|
|
@@ -28267,7 +28309,7 @@ function getBarChartData(definition, dataSets, labelRange, getters) {
|
|
|
28267
28309
|
}
|
|
28268
28310
|
function getPyramidChartData(definition, dataSets, labelRange, getters) {
|
|
28269
28311
|
const barChartData = getBarChartData(definition, dataSets, labelRange, getters);
|
|
28270
|
-
const barDataset = barChartData.dataSetsValues;
|
|
28312
|
+
const barDataset = barChartData.dataSetsValues.filter((ds) => !ds.hidden);
|
|
28271
28313
|
const pyramidDatasetValues = [];
|
|
28272
28314
|
if (barDataset[0]) {
|
|
28273
28315
|
const pyramidData = barDataset[0].data.map((value) => (value > 0 ? value : 0));
|
|
@@ -28744,10 +28786,8 @@ function getChartDatasetFormat(getters, allDataSets, axis) {
|
|
|
28744
28786
|
function getChartDatasetValues(getters, dataSets) {
|
|
28745
28787
|
const datasetValues = [];
|
|
28746
28788
|
for (const [dsIndex, ds] of Object.entries(dataSets)) {
|
|
28747
|
-
if (getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left)) {
|
|
28748
|
-
continue;
|
|
28749
|
-
}
|
|
28750
28789
|
let label;
|
|
28790
|
+
let hidden = getters.isColHidden(ds.dataRange.sheetId, ds.dataRange.zone.left);
|
|
28751
28791
|
if (ds.labelCell) {
|
|
28752
28792
|
const labelRange = ds.labelCell;
|
|
28753
28793
|
const cell = labelRange
|
|
@@ -28774,9 +28814,9 @@ function getChartDatasetValues(getters, dataSets) {
|
|
|
28774
28814
|
data.fill(1);
|
|
28775
28815
|
}
|
|
28776
28816
|
else if (data.every((cell) => cell === undefined || cell === null || !isNumber(cell.toString(), DEFAULT_LOCALE))) {
|
|
28777
|
-
|
|
28817
|
+
hidden = true;
|
|
28778
28818
|
}
|
|
28779
|
-
datasetValues.push({ data, label });
|
|
28819
|
+
datasetValues.push({ data, label, hidden });
|
|
28780
28820
|
}
|
|
28781
28821
|
return datasetValues;
|
|
28782
28822
|
}
|
|
@@ -28787,12 +28827,13 @@ function getBarChartDatasets(definition, args) {
|
|
|
28787
28827
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28788
28828
|
const trendDatasets = [];
|
|
28789
28829
|
for (const index in dataSetsValues) {
|
|
28790
|
-
let { label, data } = dataSetsValues[index];
|
|
28830
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28791
28831
|
label = definition.dataSets?.[index].label || label;
|
|
28792
28832
|
const backgroundColor = colors.next();
|
|
28793
28833
|
const dataset = {
|
|
28794
28834
|
label,
|
|
28795
28835
|
data,
|
|
28836
|
+
hidden,
|
|
28796
28837
|
borderColor: definition.background || BACKGROUND_CHART_COLOR,
|
|
28797
28838
|
borderWidth: definition.stacked ? 1 : 0,
|
|
28798
28839
|
backgroundColor,
|
|
@@ -28825,6 +28866,9 @@ function getWaterfallDatasetAndLabels(definition, args) {
|
|
|
28825
28866
|
const labelsWithSubTotals = [];
|
|
28826
28867
|
let lastValue = 0;
|
|
28827
28868
|
for (const dataSetsValue of dataSetsValues) {
|
|
28869
|
+
if (dataSetsValue.hidden) {
|
|
28870
|
+
continue;
|
|
28871
|
+
}
|
|
28828
28872
|
for (let i = 0; i < dataSetsValue.data.length; i++) {
|
|
28829
28873
|
const data = dataSetsValue.data[i];
|
|
28830
28874
|
labelsWithSubTotals.push(labels[i]);
|
|
@@ -28860,7 +28904,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28860
28904
|
const trendDatasets = [];
|
|
28861
28905
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28862
28906
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28863
|
-
let { label, data } = dataSetsValues[index];
|
|
28907
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28864
28908
|
label = definition.dataSets?.[index].label || label;
|
|
28865
28909
|
const color = colors.next();
|
|
28866
28910
|
if (axisType && ["linear", "time"].includes(axisType)) {
|
|
@@ -28870,6 +28914,7 @@ function getLineChartDatasets(definition, args) {
|
|
|
28870
28914
|
const dataset = {
|
|
28871
28915
|
label,
|
|
28872
28916
|
data,
|
|
28917
|
+
hidden,
|
|
28873
28918
|
tension: 0, // 0 -> render straight lines, which is much faster
|
|
28874
28919
|
borderColor: color,
|
|
28875
28920
|
backgroundColor: areaChart ? setColorAlpha(color, LINE_FILL_TRANSPARENCY) : color,
|
|
@@ -28902,11 +28947,13 @@ function getPieChartDatasets(definition, args) {
|
|
|
28902
28947
|
const dataSets = [];
|
|
28903
28948
|
const dataSetsLength = Math.max(0, ...dataSetsValues.map((ds) => ds?.data?.length ?? 0));
|
|
28904
28949
|
const backgroundColor = getPieColors(new ColorGenerator(dataSetsLength), dataSetsValues);
|
|
28905
|
-
for (const { label, data } of dataSetsValues) {
|
|
28950
|
+
for (const { label, data, hidden } of dataSetsValues) {
|
|
28951
|
+
if (hidden)
|
|
28952
|
+
continue;
|
|
28906
28953
|
const dataset = {
|
|
28907
28954
|
label,
|
|
28908
28955
|
data,
|
|
28909
|
-
borderColor:
|
|
28956
|
+
borderColor: definition.background || "#FFFFFF",
|
|
28910
28957
|
backgroundColor,
|
|
28911
28958
|
hoverOffset: 30,
|
|
28912
28959
|
};
|
|
@@ -28920,7 +28967,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28920
28967
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28921
28968
|
const trendDatasets = [];
|
|
28922
28969
|
for (let index = 0; index < dataSetsValues.length; index++) {
|
|
28923
|
-
let { label, data } = dataSetsValues[index];
|
|
28970
|
+
let { label, data, hidden } = dataSetsValues[index];
|
|
28924
28971
|
label = definition.dataSets?.[index].label || label;
|
|
28925
28972
|
const design = definition.dataSets?.[index];
|
|
28926
28973
|
const color = colors.next();
|
|
@@ -28928,6 +28975,7 @@ function getComboChartDatasets(definition, args) {
|
|
|
28928
28975
|
const dataset = {
|
|
28929
28976
|
label: label,
|
|
28930
28977
|
data,
|
|
28978
|
+
hidden,
|
|
28931
28979
|
borderColor: color,
|
|
28932
28980
|
backgroundColor: color,
|
|
28933
28981
|
yAxisID: definition.dataSets?.[index].yAxisId || "y",
|
|
@@ -28952,7 +29000,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28952
29000
|
const fill = definition.fillArea ?? false;
|
|
28953
29001
|
const colors = getChartColorsGenerator(definition, dataSetsValues.length);
|
|
28954
29002
|
for (let i = 0; i < dataSetsValues.length; i++) {
|
|
28955
|
-
let { label, data } = dataSetsValues[i];
|
|
29003
|
+
let { label, data, hidden } = dataSetsValues[i];
|
|
28956
29004
|
if (definition.dataSets?.[i]?.label) {
|
|
28957
29005
|
label = definition.dataSets[i].label;
|
|
28958
29006
|
}
|
|
@@ -28960,6 +29008,7 @@ function getRadarChartDatasets(definition, args) {
|
|
|
28960
29008
|
const dataset = {
|
|
28961
29009
|
label,
|
|
28962
29010
|
data,
|
|
29011
|
+
hidden,
|
|
28963
29012
|
borderColor,
|
|
28964
29013
|
backgroundColor: borderColor,
|
|
28965
29014
|
};
|
|
@@ -29105,6 +29154,11 @@ function getPieChartLegend(definition, args) {
|
|
|
29105
29154
|
hidden: false,
|
|
29106
29155
|
lineWidth: 2,
|
|
29107
29156
|
})),
|
|
29157
|
+
filter: (legendItem, data) => {
|
|
29158
|
+
return "datasetIndex" in legendItem
|
|
29159
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29160
|
+
: true;
|
|
29161
|
+
},
|
|
29108
29162
|
},
|
|
29109
29163
|
};
|
|
29110
29164
|
}
|
|
@@ -29166,6 +29220,11 @@ function getWaterfallChartLegend(definition, args) {
|
|
|
29166
29220
|
}
|
|
29167
29221
|
return legendValues;
|
|
29168
29222
|
},
|
|
29223
|
+
filter: (legendItem, data) => {
|
|
29224
|
+
return "datasetIndex" in legendItem
|
|
29225
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29226
|
+
: true;
|
|
29227
|
+
},
|
|
29169
29228
|
},
|
|
29170
29229
|
onClick: () => { }, // Disables click interaction with the waterfall chart legend items
|
|
29171
29230
|
};
|
|
@@ -29249,6 +29308,11 @@ function getCustomLegendLabels(fontColor, legendLabelConfig) {
|
|
|
29249
29308
|
...legendLabelConfig,
|
|
29250
29309
|
};
|
|
29251
29310
|
}),
|
|
29311
|
+
filter: (legendItem, data) => {
|
|
29312
|
+
return "datasetIndex" in legendItem
|
|
29313
|
+
? !data.datasets[legendItem.datasetIndex].hidden
|
|
29314
|
+
: true;
|
|
29315
|
+
},
|
|
29252
29316
|
},
|
|
29253
29317
|
};
|
|
29254
29318
|
}
|
|
@@ -33038,6 +33102,100 @@ function* iterateChildren(el) {
|
|
|
33038
33102
|
function getOpenedMenus() {
|
|
33039
33103
|
return Array.from(document.querySelectorAll(".o-spreadsheet .o-menu"));
|
|
33040
33104
|
}
|
|
33105
|
+
function getCurrentSelection(el) {
|
|
33106
|
+
let { startElement, endElement, startSelectionOffset, endSelectionOffset } = getStartAndEndSelection(el);
|
|
33107
|
+
let startSizeBefore = findSelectionIndex(el, startElement, startSelectionOffset);
|
|
33108
|
+
let endSizeBefore = findSelectionIndex(el, endElement, endSelectionOffset);
|
|
33109
|
+
return {
|
|
33110
|
+
start: startSizeBefore,
|
|
33111
|
+
end: endSizeBefore,
|
|
33112
|
+
};
|
|
33113
|
+
}
|
|
33114
|
+
function getStartAndEndSelection(el) {
|
|
33115
|
+
const selection = document.getSelection();
|
|
33116
|
+
return {
|
|
33117
|
+
startElement: selection.anchorNode || el,
|
|
33118
|
+
startSelectionOffset: selection.anchorOffset,
|
|
33119
|
+
endElement: selection.focusNode || el,
|
|
33120
|
+
endSelectionOffset: selection.focusOffset,
|
|
33121
|
+
};
|
|
33122
|
+
}
|
|
33123
|
+
/**
|
|
33124
|
+
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
33125
|
+
* The selected node is either a Text node or an Element node.
|
|
33126
|
+
*
|
|
33127
|
+
* case 1 -Text node:
|
|
33128
|
+
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
33129
|
+
* content length of all previous nodes.
|
|
33130
|
+
*
|
|
33131
|
+
* case 2 - Element node:
|
|
33132
|
+
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
33133
|
+
* all the nodes prior to the selected node as well as the content of the child node before the offset.
|
|
33134
|
+
*
|
|
33135
|
+
* See the MDN documentation for more details.
|
|
33136
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
33137
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
33138
|
+
*
|
|
33139
|
+
*/
|
|
33140
|
+
function findSelectionIndex(el, nodeToFind, nodeOffset) {
|
|
33141
|
+
let usedCharacters = 0;
|
|
33142
|
+
let it = iterateChildren(el);
|
|
33143
|
+
let current = it.next();
|
|
33144
|
+
let isFirstParagraph = true;
|
|
33145
|
+
while (!current.done && current.value !== nodeToFind) {
|
|
33146
|
+
if (!current.value.hasChildNodes()) {
|
|
33147
|
+
if (current.value.textContent) {
|
|
33148
|
+
usedCharacters += current.value.textContent.length;
|
|
33149
|
+
}
|
|
33150
|
+
}
|
|
33151
|
+
// One new paragraph = one new line character, except for the first paragraph
|
|
33152
|
+
if (current.value.nodeName === "P" ||
|
|
33153
|
+
(current.value.nodeName === "DIV" && current.value !== el) // On paste, the HTML may contain <div> instead of <p>
|
|
33154
|
+
) {
|
|
33155
|
+
if (isFirstParagraph) {
|
|
33156
|
+
isFirstParagraph = false;
|
|
33157
|
+
}
|
|
33158
|
+
else {
|
|
33159
|
+
usedCharacters++;
|
|
33160
|
+
}
|
|
33161
|
+
}
|
|
33162
|
+
current = it.next();
|
|
33163
|
+
}
|
|
33164
|
+
if (current.value !== nodeToFind) {
|
|
33165
|
+
/** This situation can happen if the code is called while the selection is not currently on the element.
|
|
33166
|
+
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
33167
|
+
*
|
|
33168
|
+
* A known occurrence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
33169
|
+
*/
|
|
33170
|
+
return 0;
|
|
33171
|
+
}
|
|
33172
|
+
else {
|
|
33173
|
+
if (!current.value.hasChildNodes()) {
|
|
33174
|
+
usedCharacters += nodeOffset;
|
|
33175
|
+
}
|
|
33176
|
+
else {
|
|
33177
|
+
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
33178
|
+
usedCharacters += children.reduce((acc, child, index) => {
|
|
33179
|
+
if (child.textContent !== null) {
|
|
33180
|
+
// need to account for paragraph nodes that implicitly add a new line
|
|
33181
|
+
// except for the last paragraph
|
|
33182
|
+
let chars = child.textContent.length;
|
|
33183
|
+
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
33184
|
+
chars++;
|
|
33185
|
+
}
|
|
33186
|
+
return acc + chars;
|
|
33187
|
+
}
|
|
33188
|
+
else {
|
|
33189
|
+
return acc;
|
|
33190
|
+
}
|
|
33191
|
+
}, 0);
|
|
33192
|
+
}
|
|
33193
|
+
}
|
|
33194
|
+
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
33195
|
+
usedCharacters++;
|
|
33196
|
+
}
|
|
33197
|
+
return usedCharacters;
|
|
33198
|
+
}
|
|
33041
33199
|
const letterRegex = /^[a-zA-Z]$/;
|
|
33042
33200
|
/**
|
|
33043
33201
|
* Transform a keyboard event into a shortcut string that represent this event. The letters keys will be uppercased.
|
|
@@ -38273,7 +38431,7 @@ css /* scss */ `
|
|
|
38273
38431
|
.o-font-size-editor {
|
|
38274
38432
|
height: calc(100% - 4px);
|
|
38275
38433
|
input.o-font-size {
|
|
38276
|
-
outline
|
|
38434
|
+
outline: none;
|
|
38277
38435
|
height: 20px;
|
|
38278
38436
|
width: 23px;
|
|
38279
38437
|
}
|
|
@@ -39886,6 +40044,10 @@ class ContentEditableHelper {
|
|
|
39886
40044
|
if (currentStart === start && currentEnd === end) {
|
|
39887
40045
|
return;
|
|
39888
40046
|
}
|
|
40047
|
+
if (selection.rangeCount === 0) {
|
|
40048
|
+
const range = document.createRange();
|
|
40049
|
+
selection.addRange(range);
|
|
40050
|
+
}
|
|
39889
40051
|
const currentRange = selection.getRangeAt(0);
|
|
39890
40052
|
let range;
|
|
39891
40053
|
if (this.el.contains(currentRange.startContainer)) {
|
|
@@ -39913,8 +40075,16 @@ class ContentEditableHelper {
|
|
|
39913
40075
|
}
|
|
39914
40076
|
let startNode = this.findChildAtCharacterIndex(start);
|
|
39915
40077
|
let endNode = this.findChildAtCharacterIndex(end);
|
|
39916
|
-
|
|
39917
|
-
|
|
40078
|
+
// setEnd (setStart) will result in a collapsed range if the end point is before the start point
|
|
40079
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/Range/setEnd
|
|
40080
|
+
if (start <= end) {
|
|
40081
|
+
range.setStart(startNode.node, startNode.offset);
|
|
40082
|
+
range.setEnd(endNode.node, endNode.offset);
|
|
40083
|
+
}
|
|
40084
|
+
else {
|
|
40085
|
+
range.setStart(endNode.node, endNode.offset);
|
|
40086
|
+
range.setEnd(startNode.node, startNode.offset);
|
|
40087
|
+
}
|
|
39918
40088
|
}
|
|
39919
40089
|
}
|
|
39920
40090
|
/**
|
|
@@ -40048,7 +40218,7 @@ class ContentEditableHelper {
|
|
|
40048
40218
|
if (!focusedNode || !this.el.contains(focusedNode))
|
|
40049
40219
|
return;
|
|
40050
40220
|
const element = focusedNode instanceof HTMLElement ? focusedNode : focusedNode.parentElement;
|
|
40051
|
-
element?.scrollIntoView({ block: "nearest" });
|
|
40221
|
+
element?.scrollIntoView?.({ block: "nearest" });
|
|
40052
40222
|
}
|
|
40053
40223
|
/**
|
|
40054
40224
|
* remove the current selection of the user
|
|
@@ -40068,100 +40238,7 @@ class ContentEditableHelper {
|
|
|
40068
40238
|
* finds the indexes of the current selection.
|
|
40069
40239
|
* */
|
|
40070
40240
|
getCurrentSelection() {
|
|
40071
|
-
|
|
40072
|
-
let startSizeBefore = this.findSelectionIndex(startElement, startSelectionOffset);
|
|
40073
|
-
let endSizeBefore = this.findSelectionIndex(endElement, endSelectionOffset);
|
|
40074
|
-
return {
|
|
40075
|
-
start: startSizeBefore,
|
|
40076
|
-
end: endSizeBefore,
|
|
40077
|
-
};
|
|
40078
|
-
}
|
|
40079
|
-
/**
|
|
40080
|
-
* Computes the text 'index' inside this.el based on the currently selected node and its offset.
|
|
40081
|
-
* The selected node is either a Text node or an Element node.
|
|
40082
|
-
*
|
|
40083
|
-
* case 1 -Text node:
|
|
40084
|
-
* the offset is the number of characters from the start of the node. We have to add this offset to the
|
|
40085
|
-
* content length of all previous nodes.
|
|
40086
|
-
*
|
|
40087
|
-
* case 2 - Element node:
|
|
40088
|
-
* the offset is the number of child nodes before the selected node. We have to add the content length of
|
|
40089
|
-
* all the bnodes prior to the selected node as well as the content of the child node before the offset.
|
|
40090
|
-
*
|
|
40091
|
-
* See the MDN documentation for more details.
|
|
40092
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/startOffset
|
|
40093
|
-
* https://developer.mozilla.org/en-US/docs/Web/API/Range/endOffset
|
|
40094
|
-
*
|
|
40095
|
-
*/
|
|
40096
|
-
findSelectionIndex(nodeToFind, nodeOffset) {
|
|
40097
|
-
let usedCharacters = 0;
|
|
40098
|
-
let it = iterateChildren(this.el);
|
|
40099
|
-
let current = it.next();
|
|
40100
|
-
let isFirstParagraph = true;
|
|
40101
|
-
while (!current.done && current.value !== nodeToFind) {
|
|
40102
|
-
if (!current.value.hasChildNodes()) {
|
|
40103
|
-
if (current.value.textContent) {
|
|
40104
|
-
usedCharacters += current.value.textContent.length;
|
|
40105
|
-
}
|
|
40106
|
-
}
|
|
40107
|
-
// One new paragraph = one new line character, except for the first paragraph
|
|
40108
|
-
if (current.value.nodeName === "P" ||
|
|
40109
|
-
(current.value.nodeName === "DIV" && current.value !== this.el) // On paste, the HTML may contain <div> instead of <p>
|
|
40110
|
-
) {
|
|
40111
|
-
if (isFirstParagraph) {
|
|
40112
|
-
isFirstParagraph = false;
|
|
40113
|
-
}
|
|
40114
|
-
else {
|
|
40115
|
-
usedCharacters++;
|
|
40116
|
-
}
|
|
40117
|
-
}
|
|
40118
|
-
current = it.next();
|
|
40119
|
-
}
|
|
40120
|
-
if (current.value !== nodeToFind) {
|
|
40121
|
-
/** This situation can happen if the code is called while the selection is not currently on the ContentEditableHelper.
|
|
40122
|
-
* In this case, we return 0 because we don't know the size of the text before the selection.
|
|
40123
|
-
*
|
|
40124
|
-
* A known occurence is triggered since the introduction of commit d4663158 (PR #2038).
|
|
40125
|
-
*
|
|
40126
|
-
* FIXME: find a way to test eventhough the selection API is not available in jsDOM.
|
|
40127
|
-
*/
|
|
40128
|
-
return 0;
|
|
40129
|
-
}
|
|
40130
|
-
else {
|
|
40131
|
-
if (!current.value.hasChildNodes()) {
|
|
40132
|
-
usedCharacters += nodeOffset;
|
|
40133
|
-
}
|
|
40134
|
-
else {
|
|
40135
|
-
const children = [...current.value.childNodes].slice(0, nodeOffset);
|
|
40136
|
-
usedCharacters += children.reduce((acc, child, index) => {
|
|
40137
|
-
if (child.textContent !== null) {
|
|
40138
|
-
// need to account for paragraph nodes that implicitely add a new line
|
|
40139
|
-
// except for the last paragraph
|
|
40140
|
-
let chars = child.textContent.length;
|
|
40141
|
-
if (child.nodeName === "P" && index !== children.length - 1) {
|
|
40142
|
-
chars++;
|
|
40143
|
-
}
|
|
40144
|
-
return acc + chars;
|
|
40145
|
-
}
|
|
40146
|
-
else {
|
|
40147
|
-
return acc;
|
|
40148
|
-
}
|
|
40149
|
-
}, 0);
|
|
40150
|
-
}
|
|
40151
|
-
}
|
|
40152
|
-
if (nodeToFind.nodeName === "P" && !isFirstParagraph && nodeToFind.textContent === "") {
|
|
40153
|
-
usedCharacters++;
|
|
40154
|
-
}
|
|
40155
|
-
return usedCharacters;
|
|
40156
|
-
}
|
|
40157
|
-
getStartAndEndSelection() {
|
|
40158
|
-
const selection = document.getSelection();
|
|
40159
|
-
return {
|
|
40160
|
-
startElement: selection.anchorNode || this.el,
|
|
40161
|
-
startSelectionOffset: selection.anchorOffset,
|
|
40162
|
-
endElement: selection.focusNode || this.el,
|
|
40163
|
-
endSelectionOffset: selection.focusOffset,
|
|
40164
|
-
};
|
|
40241
|
+
return getCurrentSelection(this.el);
|
|
40165
40242
|
}
|
|
40166
40243
|
getText() {
|
|
40167
40244
|
let text = "";
|
|
@@ -53116,6 +53193,10 @@ class CellPlugin extends CorePlugin {
|
|
|
53116
53193
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessUpdateCell);
|
|
53117
53194
|
case "CLEAR_CELL":
|
|
53118
53195
|
return this.checkValidations(cmd, this.checkCellOutOfSheet, this.checkUselessClearCell);
|
|
53196
|
+
case "UPDATE_CELL_POSITION":
|
|
53197
|
+
return !cmd.cellId || this.cells[cmd.sheetId]?.[cmd.cellId]
|
|
53198
|
+
? "Success" /* CommandResult.Success */
|
|
53199
|
+
: "InvalidCellId" /* CommandResult.InvalidCellId */;
|
|
53119
53200
|
default:
|
|
53120
53201
|
return "Success" /* CommandResult.Success */;
|
|
53121
53202
|
}
|
|
@@ -53160,6 +53241,9 @@ class CellPlugin extends CorePlugin {
|
|
|
53160
53241
|
case "DELETE_CONTENT":
|
|
53161
53242
|
this.clearZones(cmd.sheetId, cmd.target);
|
|
53162
53243
|
break;
|
|
53244
|
+
case "DELETE_SHEET": {
|
|
53245
|
+
this.history.update("cells", cmd.sheetId, undefined);
|
|
53246
|
+
}
|
|
53163
53247
|
}
|
|
53164
53248
|
}
|
|
53165
53249
|
clearZones(sheetId, zones) {
|
|
@@ -53950,6 +54034,9 @@ class ConditionalFormatPlugin extends CorePlugin {
|
|
|
53950
54034
|
allowDispatch(cmd) {
|
|
53951
54035
|
switch (cmd.type) {
|
|
53952
54036
|
case "ADD_CONDITIONAL_FORMAT":
|
|
54037
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54038
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54039
|
+
}
|
|
53953
54040
|
return this.checkValidations(cmd, this.checkCFRule, this.checkEmptyRange, this.checkCFHasChanged);
|
|
53954
54041
|
case "CHANGE_CONDITIONAL_FORMAT_PRIORITY":
|
|
53955
54042
|
return this.checkValidPriorityChange(cmd.cfId, cmd.delta, cmd.sheetId);
|
|
@@ -54366,8 +54453,17 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54366
54453
|
allowDispatch(cmd) {
|
|
54367
54454
|
switch (cmd.type) {
|
|
54368
54455
|
case "ADD_DATA_VALIDATION_RULE":
|
|
54456
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54457
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54458
|
+
}
|
|
54459
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
54460
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54461
|
+
}
|
|
54369
54462
|
return this.checkValidations(cmd, this.chainValidations(this.checkEmptyRange, this.checkValidRange, this.checkCriterionTypeIsValid, this.checkCriterionHasValidNumberOfValues, this.checkCriterionValuesAreValid));
|
|
54370
54463
|
case "REMOVE_DATA_VALIDATION_RULE":
|
|
54464
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
54465
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
54466
|
+
}
|
|
54371
54467
|
if (!this.rules[cmd.sheetId].find((rule) => rule.id === cmd.id)) {
|
|
54372
54468
|
return "UnknownDataValidationRule" /* CommandResult.UnknownDataValidationRule */;
|
|
54373
54469
|
}
|
|
@@ -54594,6 +54690,7 @@ class DataValidationPlugin extends CorePlugin {
|
|
|
54594
54690
|
class FigurePlugin extends CorePlugin {
|
|
54595
54691
|
static getters = ["getFigures", "getFigure", "getFigureSheetId"];
|
|
54596
54692
|
figures = {};
|
|
54693
|
+
insertionOrders = []; // TODO use a list in master
|
|
54597
54694
|
// ---------------------------------------------------------------------------
|
|
54598
54695
|
// Command Handling
|
|
54599
54696
|
// ---------------------------------------------------------------------------
|
|
@@ -54696,11 +54793,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
54696
54793
|
}
|
|
54697
54794
|
addFigure(figure, sheetId) {
|
|
54698
54795
|
this.history.update("figures", sheetId, figure.id, figure);
|
|
54796
|
+
this.history.update("insertionOrders", this.insertionOrders.length, figure.id);
|
|
54699
54797
|
}
|
|
54700
54798
|
deleteSheet(sheetId) {
|
|
54799
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((id) => !this.figures[sheetId]?.[id]));
|
|
54701
54800
|
this.history.update("figures", sheetId, undefined);
|
|
54702
54801
|
}
|
|
54703
54802
|
removeFigure(id, sheetId) {
|
|
54803
|
+
this.history.update("insertionOrders", this.insertionOrders.filter((figureId) => figureId !== id));
|
|
54704
54804
|
this.history.update("figures", sheetId, id, undefined);
|
|
54705
54805
|
}
|
|
54706
54806
|
checkFigureExists(sheetId, figureId) {
|
|
@@ -54719,7 +54819,14 @@ class FigurePlugin extends CorePlugin {
|
|
|
54719
54819
|
// Getters
|
|
54720
54820
|
// ---------------------------------------------------------------------------
|
|
54721
54821
|
getFigures(sheetId) {
|
|
54722
|
-
|
|
54822
|
+
const figures = [];
|
|
54823
|
+
for (const figureId of this.insertionOrders) {
|
|
54824
|
+
const figure = this.figures[sheetId]?.[figureId];
|
|
54825
|
+
if (figure) {
|
|
54826
|
+
figures.push(figure);
|
|
54827
|
+
}
|
|
54828
|
+
}
|
|
54829
|
+
return figures;
|
|
54723
54830
|
}
|
|
54724
54831
|
getFigure(sheetId, figureId) {
|
|
54725
54832
|
return this.figures[sheetId]?.[figureId];
|
|
@@ -54732,11 +54839,9 @@ class FigurePlugin extends CorePlugin {
|
|
|
54732
54839
|
// ---------------------------------------------------------------------------
|
|
54733
54840
|
import(data) {
|
|
54734
54841
|
for (let sheet of data.sheets) {
|
|
54735
|
-
const figures
|
|
54736
|
-
|
|
54737
|
-
|
|
54738
|
-
});
|
|
54739
|
-
this.figures[sheet.id] = figures;
|
|
54842
|
+
for (const figure of sheet.figures) {
|
|
54843
|
+
this.addFigure(figure, sheet.id);
|
|
54844
|
+
}
|
|
54740
54845
|
}
|
|
54741
54846
|
}
|
|
54742
54847
|
export(data) {
|
|
@@ -56162,6 +56267,9 @@ class SheetPlugin extends CorePlugin {
|
|
|
56162
56267
|
case "CREATE_SHEET": {
|
|
56163
56268
|
return this.checkValidations(cmd, this.checkSheetName, this.checkSheetPosition);
|
|
56164
56269
|
}
|
|
56270
|
+
case "DUPLICATE_SHEET": {
|
|
56271
|
+
return this.sheets[cmd.sheetIdTo] ? "DuplicatedSheetId" /* CommandResult.DuplicatedSheetId */ : "Success" /* CommandResult.Success */;
|
|
56272
|
+
}
|
|
56165
56273
|
case "MOVE_SHEET":
|
|
56166
56274
|
try {
|
|
56167
56275
|
const currentIndex = this.orderedSheetIds.findIndex((id) => id === cmd.sheetId);
|
|
@@ -56973,6 +57081,10 @@ class SheetPlugin extends CorePlugin {
|
|
|
56973
57081
|
checkZonesAreInSheet(cmd) {
|
|
56974
57082
|
if (!("sheetId" in cmd))
|
|
56975
57083
|
return "Success" /* CommandResult.Success */;
|
|
57084
|
+
if ("ranges" in cmd &&
|
|
57085
|
+
cmd.ranges.some((rangeData) => rangeData._sheetId !== "" && !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
57086
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57087
|
+
}
|
|
56976
57088
|
return this.checkZonesExistInSheet(cmd.sheetId, this.getCommandZones(cmd));
|
|
56977
57089
|
}
|
|
56978
57090
|
}
|
|
@@ -56981,6 +57093,7 @@ let nextTableId = 1;
|
|
|
56981
57093
|
class TablePlugin extends CorePlugin {
|
|
56982
57094
|
static getters = ["getCoreTable", "getCoreTables", "getCoreTableMatchingTopLeft"];
|
|
56983
57095
|
tables = {};
|
|
57096
|
+
insertionOrders = {};
|
|
56984
57097
|
adaptRanges(applyChange, sheetId) {
|
|
56985
57098
|
const sheetIds = sheetId ? [sheetId] : this.getters.getSheetIds();
|
|
56986
57099
|
for (const sheetId of sheetIds) {
|
|
@@ -56992,6 +57105,9 @@ class TablePlugin extends CorePlugin {
|
|
|
56992
57105
|
allowDispatch(cmd) {
|
|
56993
57106
|
switch (cmd.type) {
|
|
56994
57107
|
case "CREATE_TABLE":
|
|
57108
|
+
if (cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId) || rangeData._sheetId !== cmd.sheetId)) {
|
|
57109
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57110
|
+
}
|
|
56995
57111
|
const zones = cmd.ranges.map((rangeData) => this.getters.getRangeFromRangeData(rangeData).zone);
|
|
56996
57112
|
if (!areZonesContinuous(zones)) {
|
|
56997
57113
|
return "NonContinuousTargets" /* CommandResult.NonContinuousTargets */;
|
|
@@ -57022,11 +57138,13 @@ class TablePlugin extends CorePlugin {
|
|
|
57022
57138
|
switch (cmd.type) {
|
|
57023
57139
|
case "CREATE_SHEET":
|
|
57024
57140
|
this.history.update("tables", cmd.sheetId, {});
|
|
57141
|
+
this.history.update("insertionOrders", cmd.sheetId, []);
|
|
57025
57142
|
break;
|
|
57026
57143
|
case "DELETE_SHEET": {
|
|
57027
57144
|
const tables = { ...this.tables };
|
|
57028
57145
|
delete tables[cmd.sheetId];
|
|
57029
57146
|
this.history.update("tables", tables);
|
|
57147
|
+
this.history.update("insertionOrders", cmd.sheetId, undefined);
|
|
57030
57148
|
break;
|
|
57031
57149
|
}
|
|
57032
57150
|
case "DUPLICATE_SHEET": {
|
|
@@ -57038,6 +57156,9 @@ class TablePlugin extends CorePlugin {
|
|
|
57038
57156
|
: this.copyStaticTableForSheet(cmd.sheetIdTo, table);
|
|
57039
57157
|
}
|
|
57040
57158
|
this.history.update("tables", cmd.sheetIdTo, newTables);
|
|
57159
|
+
this.history.update("insertionOrders", cmd.sheetIdTo, [
|
|
57160
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57161
|
+
]);
|
|
57041
57162
|
break;
|
|
57042
57163
|
}
|
|
57043
57164
|
case "CREATE_TABLE": {
|
|
@@ -57051,6 +57172,10 @@ class TablePlugin extends CorePlugin {
|
|
|
57051
57172
|
? this.createDynamicTable(id, union, config)
|
|
57052
57173
|
: this.createStaticTable(id, cmd.tableType, union, config);
|
|
57053
57174
|
this.history.update("tables", cmd.sheetId, newTable.id, newTable);
|
|
57175
|
+
this.history.update("insertionOrders", cmd.sheetId, [
|
|
57176
|
+
...(this.insertionOrders[cmd.sheetId] ?? []),
|
|
57177
|
+
newTable.id,
|
|
57178
|
+
]);
|
|
57054
57179
|
break;
|
|
57055
57180
|
}
|
|
57056
57181
|
case "REMOVE_TABLE": {
|
|
@@ -57061,6 +57186,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57061
57186
|
}
|
|
57062
57187
|
}
|
|
57063
57188
|
this.history.update("tables", cmd.sheetId, tables);
|
|
57189
|
+
this.history.update("insertionOrders", cmd.sheetId, this.insertionOrders[cmd.sheetId]?.filter((id) => id in tables));
|
|
57064
57190
|
break;
|
|
57065
57191
|
}
|
|
57066
57192
|
case "UPDATE_TABLE": {
|
|
@@ -57096,7 +57222,14 @@ class TablePlugin extends CorePlugin {
|
|
|
57096
57222
|
}
|
|
57097
57223
|
}
|
|
57098
57224
|
getCoreTables(sheetId) {
|
|
57099
|
-
|
|
57225
|
+
const tables = [];
|
|
57226
|
+
for (const tableId of this.insertionOrders[sheetId] || []) {
|
|
57227
|
+
const table = this.tables[sheetId][tableId];
|
|
57228
|
+
if (table) {
|
|
57229
|
+
tables.push(table);
|
|
57230
|
+
}
|
|
57231
|
+
}
|
|
57232
|
+
return tables;
|
|
57100
57233
|
}
|
|
57101
57234
|
getCoreTable({ sheetId, col, row }) {
|
|
57102
57235
|
return this.getCoreTables(sheetId).find((table) => isInside(col, row, table.range.zone));
|
|
@@ -57379,6 +57512,7 @@ class TablePlugin extends CorePlugin {
|
|
|
57379
57512
|
// ---------------------------------------------------------------------------
|
|
57380
57513
|
import(data) {
|
|
57381
57514
|
for (const sheet of data.sheets) {
|
|
57515
|
+
const tableIds = [];
|
|
57382
57516
|
for (const tableData of sheet.tables || []) {
|
|
57383
57517
|
const uuid = `${nextTableId++}`;
|
|
57384
57518
|
const tableConfig = tableData.config || DEFAULT_TABLE_CONFIG;
|
|
@@ -57388,7 +57522,9 @@ class TablePlugin extends CorePlugin {
|
|
|
57388
57522
|
? this.createDynamicTable(uuid, range, tableConfig)
|
|
57389
57523
|
: this.createStaticTable(uuid, tableType, range, tableConfig);
|
|
57390
57524
|
this.history.update("tables", sheet.id, table.id, table);
|
|
57525
|
+
tableIds.push(table.id);
|
|
57391
57526
|
}
|
|
57527
|
+
this.history.update("insertionOrders", sheet.id, tableIds);
|
|
57392
57528
|
}
|
|
57393
57529
|
}
|
|
57394
57530
|
export(data) {
|
|
@@ -57428,7 +57564,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57428
57564
|
allowDispatch(cmd) {
|
|
57429
57565
|
switch (cmd.type) {
|
|
57430
57566
|
case "GROUP_HEADERS": {
|
|
57431
|
-
const { start, end } = cmd;
|
|
57567
|
+
const { start, end, sheetId } = cmd;
|
|
57568
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57569
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57570
|
+
}
|
|
57432
57571
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57433
57572
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57434
57573
|
}
|
|
@@ -57441,7 +57580,10 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57441
57580
|
break;
|
|
57442
57581
|
}
|
|
57443
57582
|
case "UNGROUP_HEADERS": {
|
|
57444
|
-
const { start, end } = cmd;
|
|
57583
|
+
const { start, end, sheetId } = cmd;
|
|
57584
|
+
if (!this.getters.tryGetSheet(sheetId)) {
|
|
57585
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57586
|
+
}
|
|
57445
57587
|
if (!this.getters.doesHeadersExist(cmd.sheetId, cmd.dimension, [start, end])) {
|
|
57446
57588
|
return "InvalidHeaderGroupStartEnd" /* CommandResult.InvalidHeaderGroupStartEnd */;
|
|
57447
57589
|
}
|
|
@@ -57452,6 +57594,9 @@ class HeaderGroupingPlugin extends CorePlugin {
|
|
|
57452
57594
|
}
|
|
57453
57595
|
case "UNFOLD_HEADER_GROUP":
|
|
57454
57596
|
case "FOLD_HEADER_GROUP":
|
|
57597
|
+
if (!this.getters.tryGetSheet(cmd.sheetId)) {
|
|
57598
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
57599
|
+
}
|
|
57455
57600
|
const group = this.findGroupWithStartEnd(cmd.sheetId, cmd.dimension, cmd.start, cmd.end);
|
|
57456
57601
|
if (!group) {
|
|
57457
57602
|
return "UnknownHeaderGroup" /* CommandResult.UnknownHeaderGroup */;
|
|
@@ -57852,6 +57997,9 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57852
57997
|
return this.checkDuplicatedMeasureIds(cmd.pivot);
|
|
57853
57998
|
}
|
|
57854
57999
|
case "UPDATE_PIVOT": {
|
|
58000
|
+
if (!(cmd.pivotId in this.pivots)) {
|
|
58001
|
+
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
58002
|
+
}
|
|
57855
58003
|
if (deepEquals(cmd.pivot, this.pivots[cmd.pivotId]?.definition)) {
|
|
57856
58004
|
return "NoChanges" /* CommandResult.NoChanges */;
|
|
57857
58005
|
}
|
|
@@ -57868,6 +58016,8 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57868
58016
|
return "EmptyName" /* CommandResult.EmptyName */;
|
|
57869
58017
|
}
|
|
57870
58018
|
break;
|
|
58019
|
+
case "REMOVE_PIVOT":
|
|
58020
|
+
case "DUPLICATE_PIVOT":
|
|
57871
58021
|
case "INSERT_PIVOT": {
|
|
57872
58022
|
if (!(cmd.pivotId in this.pivots)) {
|
|
57873
58023
|
return "PivotIdNotFound" /* CommandResult.PivotIdNotFound */;
|
|
@@ -57917,7 +58067,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57917
58067
|
break;
|
|
57918
58068
|
}
|
|
57919
58069
|
case "UPDATE_PIVOT": {
|
|
57920
|
-
this.history.update("pivots", cmd.pivotId, "definition", cmd.pivot);
|
|
58070
|
+
this.history.update("pivots", cmd.pivotId, "definition", deepCopy(cmd.pivot));
|
|
57921
58071
|
this.compileCalculatedMeasures(cmd.pivot.measures);
|
|
57922
58072
|
break;
|
|
57923
58073
|
}
|
|
@@ -57988,7 +58138,7 @@ class PivotCorePlugin extends CorePlugin {
|
|
|
57988
58138
|
// Private
|
|
57989
58139
|
// -------------------------------------------------------------------------
|
|
57990
58140
|
addPivot(pivotId, pivot, formulaId = this.nextFormulaId.toString()) {
|
|
57991
|
-
this.history.update("pivots", pivotId, { definition: pivot, formulaId });
|
|
58141
|
+
this.history.update("pivots", pivotId, { definition: deepCopy(pivot), formulaId });
|
|
57992
58142
|
this.compileCalculatedMeasures(pivot.measures);
|
|
57993
58143
|
this.history.update("formulaIds", formulaId, pivotId);
|
|
57994
58144
|
this.history.update("nextFormulaId", this.nextFormulaId + 1);
|
|
@@ -59574,6 +59724,10 @@ class Evaluator {
|
|
|
59574
59724
|
this.compilationParams = buildCompilationParameters(this.context, this.getters, this.computeAndSave.bind(this));
|
|
59575
59725
|
this.compilationParams.evalContext.updateDependencies = this.updateDependencies.bind(this);
|
|
59576
59726
|
this.compilationParams.evalContext.addDependencies = this.addDependencies.bind(this);
|
|
59727
|
+
this.compilationParams.evalContext.lookupCaches = {
|
|
59728
|
+
forwardSearch: new Map(),
|
|
59729
|
+
reverseSearch: new Map(),
|
|
59730
|
+
};
|
|
59577
59731
|
}
|
|
59578
59732
|
createEmptyPositionSet() {
|
|
59579
59733
|
const sheetSizes = {};
|
|
@@ -62894,6 +63048,9 @@ function updateChartRangesTransformation(toTransform, executed) {
|
|
|
62894
63048
|
};
|
|
62895
63049
|
}
|
|
62896
63050
|
function createSheetTransformation(toTransform, executed) {
|
|
63051
|
+
if (toTransform.sheetId === executed.sheetId) {
|
|
63052
|
+
toTransform = { ...toTransform, sheetId: `${toTransform.sheetId}~` };
|
|
63053
|
+
}
|
|
62897
63054
|
if (toTransform.name === executed.name) {
|
|
62898
63055
|
return {
|
|
62899
63056
|
...toTransform,
|
|
@@ -63537,15 +63694,6 @@ class Session extends EventBus {
|
|
|
63537
63694
|
}
|
|
63538
63695
|
this.sendPendingMessage();
|
|
63539
63696
|
}
|
|
63540
|
-
dropPendingRevision(revisionId) {
|
|
63541
|
-
this.revisions.drop(revisionId);
|
|
63542
|
-
const revisionIds = this.pendingMessages
|
|
63543
|
-
.filter((message) => message.type === "REMOTE_REVISION")
|
|
63544
|
-
.map((message) => message.nextRevisionId);
|
|
63545
|
-
this.trigger("pending-revisions-dropped", { revisionIds });
|
|
63546
|
-
this.waitingAck = false;
|
|
63547
|
-
this.waitingUndoRedoAck = false;
|
|
63548
|
-
}
|
|
63549
63697
|
/**
|
|
63550
63698
|
* Send the next pending message
|
|
63551
63699
|
*/
|
|
@@ -63554,15 +63702,14 @@ class Session extends EventBus {
|
|
|
63554
63702
|
if (!message)
|
|
63555
63703
|
return;
|
|
63556
63704
|
if (message.type === "REMOTE_REVISION") {
|
|
63557
|
-
|
|
63705
|
+
let revision = this.revisions.get(message.nextRevisionId);
|
|
63558
63706
|
if (revision.commands.length === 0) {
|
|
63559
63707
|
/**
|
|
63560
|
-
* The command is empty, we have to
|
|
63708
|
+
* The command is empty, we have to rebase all the next local revisions
|
|
63561
63709
|
* to avoid issues with undo/redo
|
|
63562
63710
|
*/
|
|
63563
|
-
this.
|
|
63564
|
-
|
|
63565
|
-
return;
|
|
63711
|
+
this.revisions.rebase(revision.id);
|
|
63712
|
+
revision = this.revisions.get(message.nextRevisionId);
|
|
63566
63713
|
}
|
|
63567
63714
|
message = {
|
|
63568
63715
|
...message,
|
|
@@ -63598,18 +63745,16 @@ class Session extends EventBus {
|
|
|
63598
63745
|
case "REVISION_UNDONE": {
|
|
63599
63746
|
this.waitingAck = false;
|
|
63600
63747
|
this.pendingMessages = this.pendingMessages.filter((msg) => msg.nextRevisionId !== message.nextRevisionId);
|
|
63601
|
-
const
|
|
63602
|
-
|
|
63603
|
-
if (firstTransformedRevisionIndex !== -1) {
|
|
63748
|
+
const firstPendingRevisionId = this.pendingMessages.findIndex((message) => message.type === "REMOTE_REVISION");
|
|
63749
|
+
if (firstPendingRevisionId !== -1) {
|
|
63604
63750
|
/**
|
|
63605
63751
|
* Some revisions undergo transformations that may cause issues with
|
|
63606
63752
|
* undo/redo if the transformation is destructive (we don't get back
|
|
63607
63753
|
* the original command by transforming it with the inverse).
|
|
63608
|
-
* To prevent these problems, we must
|
|
63754
|
+
* To prevent these problems, we must rebase all subsequent local
|
|
63609
63755
|
* revisions.
|
|
63610
63756
|
*/
|
|
63611
|
-
this.
|
|
63612
|
-
this.pendingMessages = this.pendingMessages.slice(0, firstTransformedRevisionIndex);
|
|
63757
|
+
this.revisions.rebase(this.pendingMessages[firstPendingRevisionId].nextRevisionId);
|
|
63613
63758
|
}
|
|
63614
63759
|
this.serverRevisionId = message.nextRevisionId;
|
|
63615
63760
|
this.processedRevisions.add(message.nextRevisionId);
|
|
@@ -64737,6 +64882,10 @@ class SheetUIPlugin extends UIPlugin {
|
|
|
64737
64882
|
*/
|
|
64738
64883
|
checkZonesAreInSheet(cmd) {
|
|
64739
64884
|
const sheetId = "sheetId" in cmd ? cmd.sheetId : this.getters.tryGetActiveSheetId();
|
|
64885
|
+
if ("ranges" in cmd &&
|
|
64886
|
+
cmd.ranges.some((rangeData) => !this.getters.tryGetSheet(rangeData._sheetId))) {
|
|
64887
|
+
return "InvalidSheetId" /* CommandResult.InvalidSheetId */;
|
|
64888
|
+
}
|
|
64740
64889
|
const zones = this.getters.getCommandZones(cmd);
|
|
64741
64890
|
if (!sheetId && zones.length > 0) {
|
|
64742
64891
|
return "NoActiveSheet" /* CommandResult.NoActiveSheet */;
|
|
@@ -65291,7 +65440,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65291
65440
|
super(config);
|
|
65292
65441
|
this.session = config.session;
|
|
65293
65442
|
this.session.on("new-local-state-update", this, this.onNewLocalStateUpdate);
|
|
65294
|
-
this.session.on("pending-revisions-dropped", this, ({ revisionIds }) => this.drop(revisionIds));
|
|
65295
65443
|
this.session.on("snapshot", this, () => {
|
|
65296
65444
|
this.undoStack = [];
|
|
65297
65445
|
this.redoStack = [];
|
|
@@ -65361,10 +65509,6 @@ class HistoryPlugin extends UIPlugin {
|
|
|
65361
65509
|
const lastNonRedoRevision = this.getPossibleRevisionToRepeat();
|
|
65362
65510
|
return canRepeatRevision(lastNonRedoRevision);
|
|
65363
65511
|
}
|
|
65364
|
-
drop(revisionIds) {
|
|
65365
|
-
this.undoStack = this.undoStack.filter((id) => !revisionIds.includes(id));
|
|
65366
|
-
this.redoStack = [];
|
|
65367
|
-
}
|
|
65368
65512
|
onNewLocalStateUpdate({ id }) {
|
|
65369
65513
|
this.undoStack.push(id);
|
|
65370
65514
|
this.redoStack = [];
|
|
@@ -68068,7 +68212,9 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68068
68212
|
case "UNGROUP_HEADERS":
|
|
68069
68213
|
case "GROUP_HEADERS":
|
|
68070
68214
|
case "CREATE_SHEET":
|
|
68071
|
-
this.
|
|
68215
|
+
if (this.getters.tryGetSheet(cmd.sheetId)) {
|
|
68216
|
+
this.headerPositions[cmd.sheetId] = this.computeHeaderPositionsOfSheet(cmd.sheetId);
|
|
68217
|
+
}
|
|
68072
68218
|
break;
|
|
68073
68219
|
case "DUPLICATE_SHEET":
|
|
68074
68220
|
this.headerPositions[cmd.sheetIdTo] = deepCopy(this.headerPositions[cmd.sheetId]);
|
|
@@ -68076,12 +68222,14 @@ class HeaderPositionsUIPlugin extends UIPlugin {
|
|
|
68076
68222
|
}
|
|
68077
68223
|
}
|
|
68078
68224
|
finalize() {
|
|
68079
|
-
|
|
68080
|
-
|
|
68225
|
+
for (const sheetId of this.getters.getSheetIds()) {
|
|
68226
|
+
// sheets can be created without this plugin being aware of it
|
|
68227
|
+
// in concurrent situations.
|
|
68228
|
+
if (this.isDirty || !this.headerPositions[sheetId]) {
|
|
68081
68229
|
this.headerPositions[sheetId] = this.computeHeaderPositionsOfSheet(sheetId);
|
|
68082
68230
|
}
|
|
68083
|
-
this.isDirty = false;
|
|
68084
68231
|
}
|
|
68232
|
+
this.isDirty = false;
|
|
68085
68233
|
}
|
|
68086
68234
|
/**
|
|
68087
68235
|
* Returns the size, start and end coordinates of a column on an unfolded sheet
|
|
@@ -71502,9 +71650,16 @@ class SelectiveHistory {
|
|
|
71502
71650
|
this.fastForward();
|
|
71503
71651
|
this.insert(redoId, this.buildEmpty(redoId), insertAfter);
|
|
71504
71652
|
}
|
|
71505
|
-
|
|
71653
|
+
rebase(operationId) {
|
|
71654
|
+
const operation = this.get(operationId);
|
|
71655
|
+
const execution = [...this.tree.execution(this.HEAD_BRANCH).startAfter(operationId)];
|
|
71506
71656
|
this.revertBefore(operationId);
|
|
71657
|
+
const baseId = this.HEAD_OPERATION.id;
|
|
71507
71658
|
this.tree.drop(operationId);
|
|
71659
|
+
this.insert(operationId, operation, baseId);
|
|
71660
|
+
for (const { operation } of execution) {
|
|
71661
|
+
this.insert(operation.id, operation.data, this.HEAD_OPERATION.id);
|
|
71662
|
+
}
|
|
71508
71663
|
}
|
|
71509
71664
|
/**
|
|
71510
71665
|
* Revert the state as it was *before* the given operation was executed.
|
|
@@ -74615,6 +74770,11 @@ class Model extends EventBus {
|
|
|
74615
74770
|
dispatch: (command) => {
|
|
74616
74771
|
const result = this.checkDispatchAllowed(command);
|
|
74617
74772
|
if (!result.isSuccessful) {
|
|
74773
|
+
// core views plugins need to be invalidated
|
|
74774
|
+
this.dispatchToHandlers(this.coreHandlers, {
|
|
74775
|
+
type: "UNDO",
|
|
74776
|
+
commands: [command],
|
|
74777
|
+
});
|
|
74618
74778
|
return;
|
|
74619
74779
|
}
|
|
74620
74780
|
this.isReplayingCommand = true;
|
|
@@ -75121,6 +75281,6 @@ const chartHelpers = { ...CHART_HELPERS, ...CHART_RUNTIME_HELPERS };
|
|
|
75121
75281
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, PivotRuntimeDefinition, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, SpreadsheetPivotTable, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, chartHelpers, compile, compileTokens, components, constants, convertAstNodes, coreTypes, findCellInNewZone, functionCache, helpers, hooks, invalidateCFEvaluationCommands, invalidateDependenciesCommands, invalidateEvaluationCommands, iterateAstNodes, links, load, parse, parseTokens, readonlyAllowedCommands, registries, setDefaultSheetViewSize, setTranslationMethod, stores, tokenColors, tokenize };
|
|
75122
75282
|
|
|
75123
75283
|
|
|
75124
|
-
__info__.version = "18.1.
|
|
75125
|
-
__info__.date = "2025-02-
|
|
75126
|
-
__info__.hash = "
|
|
75284
|
+
__info__.version = "18.1.9";
|
|
75285
|
+
__info__.date = "2025-02-25T05:59:45.472Z";
|
|
75286
|
+
__info__.hash = "6789c1c";
|