@odoo/o-spreadsheet 17.2.7 → 17.2.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 +367 -217
- package/dist/o-spreadsheet.d.ts +90 -85
- package/dist/o-spreadsheet.esm.js +368 -218
- package/dist/o-spreadsheet.iife.js +367 -217
- package/dist/o-spreadsheet.iife.min.js +286 -286
- package/dist/o_spreadsheet.xml +3 -3
- package/package.json +2 -2
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* This file is generated by o-spreadsheet build tools. Do not edit it.
|
|
5
5
|
* @see https://github.com/odoo/o-spreadsheet
|
|
6
|
-
* @version 17.2.
|
|
7
|
-
* @date 2024-
|
|
8
|
-
* @hash
|
|
6
|
+
* @version 17.2.9
|
|
7
|
+
* @date 2024-06-03T14:56:21.684Z
|
|
8
|
+
* @hash 086af6d
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import { useEnv, useSubEnv, onWillUnmount, useComponent, status, Component, useRef, onMounted, useEffect, useState, onPatched, onWillPatch, onWillUpdateProps, useExternalListener, onWillStart, xml, useChildSubEnv, markRaw } from '@odoo/owl';
|
|
12
12
|
|
|
13
13
|
const CANVAS_SHIFT = 0.5;
|
|
14
14
|
// Colors
|
|
@@ -502,6 +502,26 @@ function debounce(func, wait, immediate) {
|
|
|
502
502
|
};
|
|
503
503
|
return debounced;
|
|
504
504
|
}
|
|
505
|
+
/**
|
|
506
|
+
* Creates a batched version of a callback so that all calls to it in the same
|
|
507
|
+
* microtick will only call the original callback once.
|
|
508
|
+
*
|
|
509
|
+
* @param callback the callback to batch
|
|
510
|
+
* @returns a batched version of the original callback
|
|
511
|
+
*
|
|
512
|
+
* Copied from odoo/owl repo.
|
|
513
|
+
*/
|
|
514
|
+
function batched(callback) {
|
|
515
|
+
let scheduled = false;
|
|
516
|
+
return async (...args) => {
|
|
517
|
+
if (!scheduled) {
|
|
518
|
+
scheduled = true;
|
|
519
|
+
await Promise.resolve();
|
|
520
|
+
scheduled = false;
|
|
521
|
+
callback(...args);
|
|
522
|
+
}
|
|
523
|
+
};
|
|
524
|
+
}
|
|
505
525
|
/*
|
|
506
526
|
* Concatenate an array of strings.
|
|
507
527
|
*/
|
|
@@ -576,8 +596,9 @@ function deepEquals(o1, o2, ignoreFunctions) {
|
|
|
576
596
|
return false;
|
|
577
597
|
}
|
|
578
598
|
else {
|
|
579
|
-
if (ignoreFunctions && typeOfO1Key === "function")
|
|
580
|
-
|
|
599
|
+
if (ignoreFunctions && typeOfO1Key === "function") {
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
581
602
|
if (o1[key] !== o2[key])
|
|
582
603
|
return false;
|
|
583
604
|
}
|
|
@@ -1828,7 +1849,7 @@ class LazyTranslatedString extends String {
|
|
|
1828
1849
|
}
|
|
1829
1850
|
valueOf() {
|
|
1830
1851
|
const str = super.valueOf();
|
|
1831
|
-
return _loaded() ? sprintf(_translate(str), ...this.values) : str;
|
|
1852
|
+
return _loaded() ? sprintf(_translate(str), ...this.values) : sprintf(str, ...this.values);
|
|
1832
1853
|
}
|
|
1833
1854
|
toString() {
|
|
1834
1855
|
return this.valueOf();
|
|
@@ -2637,7 +2658,7 @@ function evaluatePredicate(value, criterion) {
|
|
|
2637
2658
|
return false;
|
|
2638
2659
|
}
|
|
2639
2660
|
if (typeof operand === "number" && operator === "=") {
|
|
2640
|
-
return toString(
|
|
2661
|
+
return value.toString() === operand.toString();
|
|
2641
2662
|
}
|
|
2642
2663
|
if (operator === "<>" || operator === "=") {
|
|
2643
2664
|
let result;
|
|
@@ -2697,14 +2718,13 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
|
|
|
2697
2718
|
if (countArg % 2 === 1) {
|
|
2698
2719
|
throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range and criterion to be in pairs."));
|
|
2699
2720
|
}
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2721
|
+
const firstArg = toMatrix(args[0]);
|
|
2722
|
+
const dimRow = firstArg.length;
|
|
2723
|
+
const dimCol = firstArg[0].length;
|
|
2702
2724
|
let predicates = [];
|
|
2703
2725
|
for (let i = 0; i < countArg - 1; i += 2) {
|
|
2704
|
-
const criteriaRange = args[i];
|
|
2705
|
-
if (
|
|
2706
|
-
criteriaRange.length !== dimRow ||
|
|
2707
|
-
criteriaRange[0].length !== dimCol) {
|
|
2726
|
+
const criteriaRange = toMatrix(args[i]);
|
|
2727
|
+
if (criteriaRange.length !== dimRow || criteriaRange[0].length !== dimCol) {
|
|
2708
2728
|
throw new EvaluationError(_t("Function [[FUNCTION_NAME]] expects criteria_range to have the same dimension"));
|
|
2709
2729
|
}
|
|
2710
2730
|
const description = toString(args[i + 1]);
|
|
@@ -2718,7 +2738,7 @@ function visitMatchingRanges(args, cb, locale, isQuery = false) {
|
|
|
2718
2738
|
for (let j = 0; j < dimCol; j++) {
|
|
2719
2739
|
let validatedPredicates = true;
|
|
2720
2740
|
for (let k = 0; k < countArg - 1; k += 2) {
|
|
2721
|
-
const criteriaValue = args[k][i][j].value;
|
|
2741
|
+
const criteriaValue = toMatrix(args[k])[i][j].value;
|
|
2722
2742
|
const criterion = predicates[k / 2];
|
|
2723
2743
|
validatedPredicates = evaluatePredicate(criteriaValue ?? undefined, criterion);
|
|
2724
2744
|
if (!validatedPredicates) {
|
|
@@ -4435,8 +4455,11 @@ function copyRangeWithNewSheetId(sheetIdFrom, sheetIdTo, range) {
|
|
|
4435
4455
|
/**
|
|
4436
4456
|
* Create a range from a xc. If the xc is empty, this function returns undefined.
|
|
4437
4457
|
*/
|
|
4438
|
-
function
|
|
4439
|
-
|
|
4458
|
+
function createValidRange(getters, sheetId, xc) {
|
|
4459
|
+
if (!xc)
|
|
4460
|
+
return;
|
|
4461
|
+
const range = getters.getRangeFromSheetXC(sheetId, xc);
|
|
4462
|
+
return !(range.invalidSheetName || range.invalidXc) ? range : undefined;
|
|
4440
4463
|
}
|
|
4441
4464
|
/**
|
|
4442
4465
|
* Spread multiple colrows zone to one row/col zone and add a many new input range as needed.
|
|
@@ -8012,10 +8035,66 @@ function getDateCriterionFormattedValues(criterion, getters) {
|
|
|
8012
8035
|
});
|
|
8013
8036
|
}
|
|
8014
8037
|
|
|
8038
|
+
/**
|
|
8039
|
+
* This is a generic event bus based on the Owl event bus.
|
|
8040
|
+
* This bus however ensures type safety across events and subscription callbacks.
|
|
8041
|
+
*/
|
|
8042
|
+
class EventBus {
|
|
8043
|
+
subscriptions = {};
|
|
8044
|
+
/**
|
|
8045
|
+
* Add a listener for the 'eventType' events.
|
|
8046
|
+
*
|
|
8047
|
+
* Note that the 'owner' of this event can be anything, but will more likely
|
|
8048
|
+
* be a component or a class. The idea is that the callback will be called with
|
|
8049
|
+
* the proper owner bound.
|
|
8050
|
+
*
|
|
8051
|
+
* Also, the owner should be kind of unique. This will be used to remove the
|
|
8052
|
+
* listener.
|
|
8053
|
+
*/
|
|
8054
|
+
on(type, owner, callback) {
|
|
8055
|
+
if (!callback) {
|
|
8056
|
+
throw new Error("Missing callback");
|
|
8057
|
+
}
|
|
8058
|
+
if (!this.subscriptions[type]) {
|
|
8059
|
+
this.subscriptions[type] = [];
|
|
8060
|
+
}
|
|
8061
|
+
this.subscriptions[type].push({
|
|
8062
|
+
owner,
|
|
8063
|
+
callback,
|
|
8064
|
+
});
|
|
8065
|
+
}
|
|
8066
|
+
/**
|
|
8067
|
+
* Emit an event of type 'eventType'. Any extra arguments will be passed to
|
|
8068
|
+
* the listeners callback.
|
|
8069
|
+
*/
|
|
8070
|
+
trigger(type, payload) {
|
|
8071
|
+
const subs = this.subscriptions[type] || [];
|
|
8072
|
+
for (let i = 0, iLen = subs.length; i < iLen; i++) {
|
|
8073
|
+
const sub = subs[i];
|
|
8074
|
+
sub.callback.call(sub.owner, payload);
|
|
8075
|
+
}
|
|
8076
|
+
}
|
|
8077
|
+
/**
|
|
8078
|
+
* Remove a listener
|
|
8079
|
+
*/
|
|
8080
|
+
off(eventType, owner) {
|
|
8081
|
+
const subs = this.subscriptions[eventType];
|
|
8082
|
+
if (subs) {
|
|
8083
|
+
this.subscriptions[eventType] = subs.filter((s) => s.owner !== owner);
|
|
8084
|
+
}
|
|
8085
|
+
}
|
|
8086
|
+
/**
|
|
8087
|
+
* Remove all subscriptions.
|
|
8088
|
+
*/
|
|
8089
|
+
clear() {
|
|
8090
|
+
this.subscriptions = {};
|
|
8091
|
+
}
|
|
8092
|
+
}
|
|
8093
|
+
|
|
8015
8094
|
/**
|
|
8016
8095
|
* A type-safe dependency container
|
|
8017
8096
|
*/
|
|
8018
|
-
class DependencyContainer {
|
|
8097
|
+
class DependencyContainer extends EventBus {
|
|
8019
8098
|
dependencies = new Map();
|
|
8020
8099
|
factory = new StoreFactory(this.get.bind(this));
|
|
8021
8100
|
/**
|
|
@@ -8092,15 +8171,12 @@ stores.inject(MyMetaStore, storeInstance);
|
|
|
8092
8171
|
}
|
|
8093
8172
|
return MetaStore;
|
|
8094
8173
|
}
|
|
8095
|
-
class
|
|
8174
|
+
class DisposableStore {
|
|
8096
8175
|
get;
|
|
8176
|
+
disposeCallbacks = [];
|
|
8097
8177
|
constructor(get) {
|
|
8098
8178
|
this.get = get;
|
|
8099
|
-
return reactive(this);
|
|
8100
8179
|
}
|
|
8101
|
-
}
|
|
8102
|
-
class DisposableStore extends ReactiveStore {
|
|
8103
|
-
disposeCallbacks = [];
|
|
8104
8180
|
onDispose(callback) {
|
|
8105
8181
|
this.disposeCallbacks.push(callback);
|
|
8106
8182
|
}
|
|
@@ -8120,7 +8196,10 @@ function useStoreProvider() {
|
|
|
8120
8196
|
const container = new DependencyContainer();
|
|
8121
8197
|
useSubEnv({
|
|
8122
8198
|
__spreadsheet_stores__: container,
|
|
8123
|
-
getStore:
|
|
8199
|
+
getStore: (Store) => {
|
|
8200
|
+
const store = container.get(Store);
|
|
8201
|
+
return proxifyStoreMutation(store, () => container.trigger("store-updated"));
|
|
8202
|
+
},
|
|
8124
8203
|
});
|
|
8125
8204
|
return container;
|
|
8126
8205
|
}
|
|
@@ -8130,14 +8209,57 @@ function useStoreProvider() {
|
|
|
8130
8209
|
function useStore(Store) {
|
|
8131
8210
|
const env = useEnv();
|
|
8132
8211
|
const container = getDependencyContainer(env);
|
|
8133
|
-
|
|
8212
|
+
const store = container.get(Store);
|
|
8213
|
+
return useStoreRenderProxy(container, store);
|
|
8134
8214
|
}
|
|
8135
8215
|
function useLocalStore(Store, ...args) {
|
|
8136
8216
|
const env = useEnv();
|
|
8137
8217
|
const container = getDependencyContainer(env);
|
|
8138
|
-
const store =
|
|
8218
|
+
const store = container.instantiate(Store, ...args);
|
|
8139
8219
|
onWillUnmount(() => store.dispose());
|
|
8140
|
-
return store;
|
|
8220
|
+
return useStoreRenderProxy(container, store);
|
|
8221
|
+
}
|
|
8222
|
+
/**
|
|
8223
|
+
* Trigger an event to re-render the app (deep render) when
|
|
8224
|
+
* a store is mutated by invoking one of its mutator methods.
|
|
8225
|
+
*/
|
|
8226
|
+
function useStoreRenderProxy(container, store) {
|
|
8227
|
+
const component = useComponent();
|
|
8228
|
+
const proxy = proxifyStoreMutation(store, () => {
|
|
8229
|
+
if (status(component) === "mounted") {
|
|
8230
|
+
container.trigger("store-updated");
|
|
8231
|
+
}
|
|
8232
|
+
});
|
|
8233
|
+
return proxy;
|
|
8234
|
+
}
|
|
8235
|
+
/**
|
|
8236
|
+
* Creates a proxied version of a store object with mutation tracking.
|
|
8237
|
+
* Whenever a mutator method of the store is called, the provided callback function is invoked.
|
|
8238
|
+
*/
|
|
8239
|
+
function proxifyStoreMutation(store, callback) {
|
|
8240
|
+
const proxy = new Proxy(store, {
|
|
8241
|
+
get(target, property, receiver) {
|
|
8242
|
+
const thisStore = target;
|
|
8243
|
+
// The third argument is `thisStore` (target) instead of `receiver`.
|
|
8244
|
+
// The goal is to always have the same `this` value in getter functions
|
|
8245
|
+
// (when `target[property]` is an accessor property).
|
|
8246
|
+
// `thisStore` is always the same object reference. `receiver` however is the
|
|
8247
|
+
// object on which the property is called, which is the Proxy object which is different for each component.
|
|
8248
|
+
const value = Reflect.get(target, property, thisStore);
|
|
8249
|
+
if (store.mutators.includes(property)) {
|
|
8250
|
+
const functionProxy = new Proxy(value, {
|
|
8251
|
+
// trap the function call
|
|
8252
|
+
apply(target, thisArg, argArray) {
|
|
8253
|
+
Reflect.apply(target, thisStore, argArray);
|
|
8254
|
+
callback();
|
|
8255
|
+
},
|
|
8256
|
+
});
|
|
8257
|
+
return functionProxy;
|
|
8258
|
+
}
|
|
8259
|
+
return value;
|
|
8260
|
+
},
|
|
8261
|
+
});
|
|
8262
|
+
return proxy;
|
|
8141
8263
|
}
|
|
8142
8264
|
function getDependencyContainer(env) {
|
|
8143
8265
|
const container = env.__spreadsheet_stores__;
|
|
@@ -8149,7 +8271,8 @@ function getDependencyContainer(env) {
|
|
|
8149
8271
|
|
|
8150
8272
|
const ModelStore = createAbstractStore("Model");
|
|
8151
8273
|
|
|
8152
|
-
class RendererStore
|
|
8274
|
+
class RendererStore {
|
|
8275
|
+
mutators = ["register", "unRegister"];
|
|
8153
8276
|
renderers = {};
|
|
8154
8277
|
register(renderer) {
|
|
8155
8278
|
if (!renderer.renderingLayers.length) {
|
|
@@ -8183,7 +8306,7 @@ class RendererStore extends ReactiveStore {
|
|
|
8183
8306
|
class SpreadsheetStore extends DisposableStore {
|
|
8184
8307
|
// cast the model store as Model to allow model.dispatch to return the DispatchResult
|
|
8185
8308
|
model = this.get(ModelStore);
|
|
8186
|
-
getters =
|
|
8309
|
+
getters = this.model.getters;
|
|
8187
8310
|
renderer = this.get(RendererStore);
|
|
8188
8311
|
constructor(get) {
|
|
8189
8312
|
super(get);
|
|
@@ -8230,6 +8353,7 @@ function drawHighlight(renderingContext, highlight, rect) {
|
|
|
8230
8353
|
}
|
|
8231
8354
|
|
|
8232
8355
|
class HighlightStore extends SpreadsheetStore {
|
|
8356
|
+
mutators = ["register", "unRegister"];
|
|
8233
8357
|
providers = [];
|
|
8234
8358
|
constructor(get) {
|
|
8235
8359
|
super(get);
|
|
@@ -8260,7 +8384,7 @@ class HighlightStore extends SpreadsheetStore {
|
|
|
8260
8384
|
this.providers.push(highlightProvider);
|
|
8261
8385
|
}
|
|
8262
8386
|
unRegister(highlightProvider) {
|
|
8263
|
-
this.providers = this.providers.filter((h) =>
|
|
8387
|
+
this.providers = this.providers.filter((h) => h !== highlightProvider);
|
|
8264
8388
|
}
|
|
8265
8389
|
drawLayer(ctx, layer) {
|
|
8266
8390
|
if (layer === "Highlights") {
|
|
@@ -8276,6 +8400,16 @@ const NotificationStore = createAbstractStore("Notifications");
|
|
|
8276
8400
|
|
|
8277
8401
|
const CELL_DELETED_MESSAGE = _t("The cell you are trying to edit has been deleted.");
|
|
8278
8402
|
class ComposerStore extends SpreadsheetStore {
|
|
8403
|
+
mutators = [
|
|
8404
|
+
"startEdition",
|
|
8405
|
+
"setCurrentContent",
|
|
8406
|
+
"stopEdition",
|
|
8407
|
+
"stopComposerRangeSelection",
|
|
8408
|
+
"cancelEdition",
|
|
8409
|
+
"cycleReferences",
|
|
8410
|
+
"changeComposerCursorSelection",
|
|
8411
|
+
"replaceComposerCursorSelection",
|
|
8412
|
+
];
|
|
8279
8413
|
col = 0;
|
|
8280
8414
|
row = 0;
|
|
8281
8415
|
editionMode = "inactive";
|
|
@@ -8290,9 +8424,9 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8290
8424
|
highlightStore = this.get(HighlightStore);
|
|
8291
8425
|
constructor(get) {
|
|
8292
8426
|
super(get);
|
|
8293
|
-
this.highlightStore.register(
|
|
8427
|
+
this.highlightStore.register(this);
|
|
8294
8428
|
this.onDispose(() => {
|
|
8295
|
-
this.highlightStore.unRegister(
|
|
8429
|
+
this.highlightStore.unRegister(this);
|
|
8296
8430
|
});
|
|
8297
8431
|
}
|
|
8298
8432
|
canStopEdition() {
|
|
@@ -8419,7 +8553,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8419
8553
|
if (this.isSelectingRange) {
|
|
8420
8554
|
this.editionMode = "editing";
|
|
8421
8555
|
}
|
|
8422
|
-
this.model.selection.resetAnchor(
|
|
8556
|
+
this.model.selection.resetAnchor(this, {
|
|
8423
8557
|
cell: { col: left, row: top },
|
|
8424
8558
|
zone: cmd.zone,
|
|
8425
8559
|
});
|
|
@@ -8437,7 +8571,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8437
8571
|
row: activePosition.row,
|
|
8438
8572
|
});
|
|
8439
8573
|
const zone = this.getters.expandZone(cmd.sheetIdTo, positionToZone({ col, row }));
|
|
8440
|
-
this.model.selection.resetAnchor(
|
|
8574
|
+
this.model.selection.resetAnchor(this, { cell: { col, row }, zone });
|
|
8441
8575
|
}
|
|
8442
8576
|
break;
|
|
8443
8577
|
case "DELETE_SHEET":
|
|
@@ -8536,7 +8670,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8536
8670
|
startComposerRangeSelection() {
|
|
8537
8671
|
if (this.sheetId === this.getters.getActiveSheetId()) {
|
|
8538
8672
|
const zone = positionToZone({ col: this.col, row: this.row });
|
|
8539
|
-
this.model.selection.resetAnchor(
|
|
8673
|
+
this.model.selection.resetAnchor(this, {
|
|
8540
8674
|
cell: { col: this.col, row: this.row },
|
|
8541
8675
|
zone,
|
|
8542
8676
|
});
|
|
@@ -8565,7 +8699,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8565
8699
|
this.setContent(str || this.initialContent, selection);
|
|
8566
8700
|
this.colorIndexByRange = {};
|
|
8567
8701
|
const zone = positionToZone({ col: this.col, row: this.row });
|
|
8568
|
-
this.model.selection.capture(
|
|
8702
|
+
this.model.selection.capture(this, { cell: { col: this.col, row: this.row }, zone }, {
|
|
8569
8703
|
handleEvent: this.handleEvent.bind(this),
|
|
8570
8704
|
release: () => {
|
|
8571
8705
|
this._stopEdition();
|
|
@@ -8673,7 +8807,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8673
8807
|
return;
|
|
8674
8808
|
}
|
|
8675
8809
|
this.editionMode = "inactive";
|
|
8676
|
-
this.model.selection.release(
|
|
8810
|
+
this.model.selection.release(this);
|
|
8677
8811
|
}
|
|
8678
8812
|
/**
|
|
8679
8813
|
* Reset the current content to the active cell content
|
|
@@ -8995,6 +9129,7 @@ class ComposerStore extends SpreadsheetStore {
|
|
|
8995
9129
|
}
|
|
8996
9130
|
|
|
8997
9131
|
class ComposerFocusStore extends SpreadsheetStore {
|
|
9132
|
+
mutators = ["focusTopBarComposer", "focusGridComposerContent", "focusGridComposerCell"];
|
|
8998
9133
|
composerStore = this.get(ComposerStore);
|
|
8999
9134
|
topBarFocus = "inactive";
|
|
9000
9135
|
gridFocusMode = "inactive";
|
|
@@ -9511,8 +9646,8 @@ let ScorecardChart$1 = class ScorecardChart extends AbstractChart {
|
|
|
9511
9646
|
type = "scorecard";
|
|
9512
9647
|
constructor(definition, sheetId, getters) {
|
|
9513
9648
|
super(definition, sheetId, getters);
|
|
9514
|
-
this.keyValue =
|
|
9515
|
-
this.baseline =
|
|
9649
|
+
this.keyValue = createValidRange(getters, sheetId, definition.keyValue);
|
|
9650
|
+
this.baseline = createValidRange(getters, sheetId, definition.baseline);
|
|
9516
9651
|
this.baselineMode = definition.baselineMode;
|
|
9517
9652
|
this.baselineDescr = definition.baselineDescr;
|
|
9518
9653
|
this.background = definition.background;
|
|
@@ -10082,6 +10217,9 @@ function makeArg(str, description) {
|
|
|
10082
10217
|
if (types.some((t) => t.startsWith("RANGE"))) {
|
|
10083
10218
|
result.acceptMatrix = true;
|
|
10084
10219
|
}
|
|
10220
|
+
if (types.every((t) => t.startsWith("RANGE"))) {
|
|
10221
|
+
result.acceptMatrixOnly = true;
|
|
10222
|
+
}
|
|
10085
10223
|
return result;
|
|
10086
10224
|
}
|
|
10087
10225
|
/**
|
|
@@ -10363,11 +10501,16 @@ const CHOOSECOLS = {
|
|
|
10363
10501
|
compute: function (array, ...columns) {
|
|
10364
10502
|
const _array = toMatrix(array);
|
|
10365
10503
|
const _columns = flattenRowFirst(columns, (item) => toInteger(item?.value, this.locale));
|
|
10366
|
-
|
|
10504
|
+
const argOutOfRange = _columns.filter((col) => col === 0 || _array.length < Math.abs(col));
|
|
10505
|
+
assert(() => argOutOfRange.length === 0, _t("The columns arguments must be between -%s and %s (got %s), excluding 0.", _array.length.toString(), _array.length.toString(), argOutOfRange.join(",")));
|
|
10367
10506
|
const result = Array(_columns.length);
|
|
10368
10507
|
for (let col = 0; col < _columns.length; col++) {
|
|
10369
|
-
|
|
10370
|
-
|
|
10508
|
+
if (_columns[col] > 0) {
|
|
10509
|
+
result[col] = _array[_columns[col] - 1]; // -1 because columns arguments are 1-indexed
|
|
10510
|
+
}
|
|
10511
|
+
else {
|
|
10512
|
+
result[col] = _array[_array.length + _columns[col]];
|
|
10513
|
+
}
|
|
10371
10514
|
}
|
|
10372
10515
|
return result;
|
|
10373
10516
|
},
|
|
@@ -10388,8 +10531,14 @@ const CHOOSEROWS = {
|
|
|
10388
10531
|
const _array = toMatrix(array);
|
|
10389
10532
|
const _rows = flattenRowFirst(rows, (item) => toInteger(item?.value, this.locale));
|
|
10390
10533
|
const _nbColumns = _array.length;
|
|
10391
|
-
|
|
10392
|
-
|
|
10534
|
+
const argOutOfRange = _rows.filter((row) => row === 0 || _array[0].length < Math.abs(row));
|
|
10535
|
+
assert(() => argOutOfRange.length === 0, _t("The rows arguments must be between -%s and %s (got %s), excluding 0.", _array[0].length.toString(), _array[0].length.toString(), argOutOfRange.join(",")));
|
|
10536
|
+
return generateMatrix(_nbColumns, _rows.length, (col, row) => {
|
|
10537
|
+
if (_rows[row] > 0) {
|
|
10538
|
+
return _array[col][_rows[row] - 1]; // -1 because columns arguments are 1-indexed
|
|
10539
|
+
}
|
|
10540
|
+
return _array[col][_array[col].length + _rows[row]];
|
|
10541
|
+
});
|
|
10393
10542
|
},
|
|
10394
10543
|
isExported: true,
|
|
10395
10544
|
};
|
|
@@ -11297,7 +11446,7 @@ const COUNTUNIQUEIFS = {
|
|
|
11297
11446
|
compute: function (range, ...args) {
|
|
11298
11447
|
let uniqueValues = new Set();
|
|
11299
11448
|
visitMatchingRanges(args, (i, j) => {
|
|
11300
|
-
const data = range[i][j];
|
|
11449
|
+
const data = range[i]?.[j];
|
|
11301
11450
|
if (isDefined(data)) {
|
|
11302
11451
|
uniqueValues.add(data.value);
|
|
11303
11452
|
}
|
|
@@ -11927,7 +12076,7 @@ const SUMIF = {
|
|
|
11927
12076
|
}
|
|
11928
12077
|
let sum = 0;
|
|
11929
12078
|
visitMatchingRanges([criteriaRange, criterion], (i, j) => {
|
|
11930
|
-
const value = sumRange[i][j]
|
|
12079
|
+
const value = sumRange[i]?.[j]?.value;
|
|
11931
12080
|
if (typeof value === "number") {
|
|
11932
12081
|
sum += value;
|
|
11933
12082
|
}
|
|
@@ -11952,7 +12101,7 @@ const SUMIFS = {
|
|
|
11952
12101
|
compute: function (sumRange, ...criters) {
|
|
11953
12102
|
let sum = 0;
|
|
11954
12103
|
visitMatchingRanges(criters, (i, j) => {
|
|
11955
|
-
const value = sumRange[i][j]
|
|
12104
|
+
const value = sumRange[i]?.[j]?.value;
|
|
11956
12105
|
if (typeof value === "number") {
|
|
11957
12106
|
sum += value;
|
|
11958
12107
|
}
|
|
@@ -12499,7 +12648,7 @@ const AVERAGEIF = {
|
|
|
12499
12648
|
let count = 0;
|
|
12500
12649
|
let sum = 0;
|
|
12501
12650
|
visitMatchingRanges([criteriaRange, criterion], (i, j) => {
|
|
12502
|
-
const value = _averageRange[i][j]
|
|
12651
|
+
const value = _averageRange[i]?.[j]?.value;
|
|
12503
12652
|
if (typeof value === "number") {
|
|
12504
12653
|
count += 1;
|
|
12505
12654
|
sum += value;
|
|
@@ -12528,7 +12677,7 @@ const AVERAGEIFS = {
|
|
|
12528
12677
|
let count = 0;
|
|
12529
12678
|
let sum = 0;
|
|
12530
12679
|
visitMatchingRanges(args, (i, j) => {
|
|
12531
|
-
const value = _averageRange[i][j]
|
|
12680
|
+
const value = _averageRange[i]?.[j]?.value;
|
|
12532
12681
|
if (typeof value === "number") {
|
|
12533
12682
|
count += 1;
|
|
12534
12683
|
sum += value;
|
|
@@ -12833,7 +12982,7 @@ const MAXIFS = {
|
|
|
12833
12982
|
compute: function (range, ...args) {
|
|
12834
12983
|
let result = -Infinity;
|
|
12835
12984
|
visitMatchingRanges(args, (i, j) => {
|
|
12836
|
-
const value = range[i][j]
|
|
12985
|
+
const value = range[i]?.[j]?.value;
|
|
12837
12986
|
if (typeof value === "number") {
|
|
12838
12987
|
result = result < value ? value : result;
|
|
12839
12988
|
}
|
|
@@ -12916,7 +13065,7 @@ const MINIFS = {
|
|
|
12916
13065
|
compute: function (range, ...args) {
|
|
12917
13066
|
let result = Infinity;
|
|
12918
13067
|
visitMatchingRanges(args, (i, j) => {
|
|
12919
|
-
const value = range[i][j]
|
|
13068
|
+
const value = range[i]?.[j]?.value;
|
|
12920
13069
|
if (typeof value === "number") {
|
|
12921
13070
|
result = result > value ? value : result;
|
|
12922
13071
|
}
|
|
@@ -18668,6 +18817,9 @@ function addInputHandling(descr) {
|
|
|
18668
18817
|
}
|
|
18669
18818
|
args[i] = arg[0][0];
|
|
18670
18819
|
}
|
|
18820
|
+
if (!isMatrix(arg) && argDefinition.acceptMatrixOnly) {
|
|
18821
|
+
throw new BadExpressionError(_t("Function [[FUNCTION_NAME]] expects the parameter '%s' to be reference to a cell or range.", (i + 1).toString()));
|
|
18822
|
+
}
|
|
18671
18823
|
}
|
|
18672
18824
|
return descr.compute.apply(this, args);
|
|
18673
18825
|
}
|
|
@@ -19670,7 +19822,7 @@ class BarChart extends AbstractChart {
|
|
|
19670
19822
|
constructor(definition, sheetId, getters) {
|
|
19671
19823
|
super(definition, sheetId, getters);
|
|
19672
19824
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
19673
|
-
this.labelRange =
|
|
19825
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
19674
19826
|
this.background = definition.background;
|
|
19675
19827
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
19676
19828
|
this.legendPosition = definition.legendPosition;
|
|
@@ -19914,7 +20066,7 @@ class GaugeChart extends AbstractChart {
|
|
|
19914
20066
|
type = "gauge";
|
|
19915
20067
|
constructor(definition, sheetId, getters) {
|
|
19916
20068
|
super(definition, sheetId, getters);
|
|
19917
|
-
this.dataRange =
|
|
20069
|
+
this.dataRange = createValidRange(this.getters, this.sheetId, definition.dataRange);
|
|
19918
20070
|
this.sectionRule = definition.sectionRule;
|
|
19919
20071
|
this.background = definition.background;
|
|
19920
20072
|
}
|
|
@@ -20435,7 +20587,7 @@ class LineChart extends AbstractChart {
|
|
|
20435
20587
|
constructor(definition, sheetId, getters) {
|
|
20436
20588
|
super(definition, sheetId, getters);
|
|
20437
20589
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20438
|
-
this.labelRange =
|
|
20590
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
20439
20591
|
this.background = definition.background;
|
|
20440
20592
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
20441
20593
|
this.legendPosition = definition.legendPosition;
|
|
@@ -20550,7 +20702,7 @@ class PieChart extends AbstractChart {
|
|
|
20550
20702
|
constructor(definition, sheetId, getters) {
|
|
20551
20703
|
super(definition, sheetId, getters);
|
|
20552
20704
|
this.dataSets = createDataSets(getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20553
|
-
this.labelRange =
|
|
20705
|
+
this.labelRange = createValidRange(getters, sheetId, definition.labelRange);
|
|
20554
20706
|
this.background = definition.background;
|
|
20555
20707
|
this.legendPosition = definition.legendPosition;
|
|
20556
20708
|
this.aggregated = definition.aggregated;
|
|
@@ -20752,7 +20904,7 @@ class ScatterChart extends AbstractChart {
|
|
|
20752
20904
|
constructor(definition, sheetId, getters) {
|
|
20753
20905
|
super(definition, sheetId, getters);
|
|
20754
20906
|
this.dataSets = createDataSets(this.getters, definition.dataSets, sheetId, definition.dataSetsHaveTitle);
|
|
20755
|
-
this.labelRange =
|
|
20907
|
+
this.labelRange = createValidRange(this.getters, sheetId, definition.labelRange);
|
|
20756
20908
|
this.background = definition.background;
|
|
20757
20909
|
this.verticalAxisPosition = definition.verticalAxisPosition;
|
|
20758
20910
|
this.legendPosition = definition.legendPosition;
|
|
@@ -20838,13 +20990,6 @@ function createScatterChartRuntime(chart, getters) {
|
|
|
20838
20990
|
// have less options than the line chart (it only works with linear labels)
|
|
20839
20991
|
chartJsConfig.type = "line";
|
|
20840
20992
|
const configOptions = chartJsConfig.options;
|
|
20841
|
-
configOptions.elements = {
|
|
20842
|
-
point: {
|
|
20843
|
-
radius: 3,
|
|
20844
|
-
hoverRadius: 3,
|
|
20845
|
-
hitRadius: 8,
|
|
20846
|
-
},
|
|
20847
|
-
};
|
|
20848
20993
|
const locale = getters.getLocale();
|
|
20849
20994
|
configOptions.plugins.tooltip.callbacks.title = () => "";
|
|
20850
20995
|
configOptions.plugins.tooltip.callbacks.label = (tooltipItem) => {
|
|
@@ -21451,6 +21596,7 @@ function interactiveAddMerge(env, sheetId, target) {
|
|
|
21451
21596
|
}
|
|
21452
21597
|
|
|
21453
21598
|
class HoveredCellStore extends SpreadsheetStore {
|
|
21599
|
+
mutators = ["clear", "hover"];
|
|
21454
21600
|
col;
|
|
21455
21601
|
row;
|
|
21456
21602
|
handle(cmd) {
|
|
@@ -21470,6 +21616,7 @@ class HoveredCellStore extends SpreadsheetStore {
|
|
|
21470
21616
|
}
|
|
21471
21617
|
|
|
21472
21618
|
class CellPopoverStore extends SpreadsheetStore {
|
|
21619
|
+
mutators = ["open", "close"];
|
|
21473
21620
|
persistentPopover;
|
|
21474
21621
|
hoveredCell = this.get(HoveredCellStore);
|
|
21475
21622
|
handle(cmd) {
|
|
@@ -25961,12 +26108,13 @@ function updateSelectionWithArrowKeys(ev, selection) {
|
|
|
25961
26108
|
|
|
25962
26109
|
// The name is misleading and can be confused with the DOM focus.
|
|
25963
26110
|
class FocusStore {
|
|
26111
|
+
mutators = ["focus", "unfocus"];
|
|
25964
26112
|
focusedElement = null;
|
|
25965
26113
|
focus(element) {
|
|
25966
26114
|
this.focusedElement = element;
|
|
25967
26115
|
}
|
|
25968
26116
|
unfocus(element) {
|
|
25969
|
-
if (this.focusedElement &&
|
|
26117
|
+
if (this.focusedElement && this.focusedElement === element) {
|
|
25970
26118
|
this.focusedElement = null;
|
|
25971
26119
|
}
|
|
25972
26120
|
}
|
|
@@ -25982,6 +26130,16 @@ class FocusStore {
|
|
|
25982
26130
|
class SelectionInputStore extends SpreadsheetStore {
|
|
25983
26131
|
initialRanges;
|
|
25984
26132
|
inputHasSingleRange;
|
|
26133
|
+
mutators = [
|
|
26134
|
+
"resetWithRanges",
|
|
26135
|
+
"focusById",
|
|
26136
|
+
"unfocus",
|
|
26137
|
+
"addEmptyRange",
|
|
26138
|
+
"removeRange",
|
|
26139
|
+
"changeRange",
|
|
26140
|
+
"reset",
|
|
26141
|
+
"confirm",
|
|
26142
|
+
];
|
|
25985
26143
|
ranges = [];
|
|
25986
26144
|
focusedRangeIndex = null;
|
|
25987
26145
|
inputSheetId;
|
|
@@ -26041,7 +26199,7 @@ class SelectionInputStore extends SpreadsheetStore {
|
|
|
26041
26199
|
row: 0,
|
|
26042
26200
|
});
|
|
26043
26201
|
const zone = this.getters.expandZone(cmd.sheetIdTo, positionToZone({ col, row }));
|
|
26044
|
-
this.model.selection.resetAnchor(
|
|
26202
|
+
this.model.selection.resetAnchor(this, { cell: { col, row }, zone });
|
|
26045
26203
|
}
|
|
26046
26204
|
break;
|
|
26047
26205
|
}
|
|
@@ -26060,7 +26218,7 @@ class SelectionInputStore extends SpreadsheetStore {
|
|
|
26060
26218
|
if (focusIndex !== -1) {
|
|
26061
26219
|
this.focus(focusIndex);
|
|
26062
26220
|
const { left, top } = newZone;
|
|
26063
|
-
this.model.selection.resetAnchor(
|
|
26221
|
+
this.model.selection.resetAnchor(this, {
|
|
26064
26222
|
cell: { col: left, row: top },
|
|
26065
26223
|
zone: newZone,
|
|
26066
26224
|
});
|
|
@@ -26151,7 +26309,7 @@ class SelectionInputStore extends SpreadsheetStore {
|
|
|
26151
26309
|
}
|
|
26152
26310
|
get hasMainFocus() {
|
|
26153
26311
|
const focusedElement = this.focusStore.focusedElement;
|
|
26154
|
-
return !!focusedElement &&
|
|
26312
|
+
return !!focusedElement && focusedElement === this;
|
|
26155
26313
|
}
|
|
26156
26314
|
get highlights() {
|
|
26157
26315
|
if (!this.hasMainFocus) {
|
|
@@ -26180,7 +26338,7 @@ class SelectionInputStore extends SpreadsheetStore {
|
|
|
26180
26338
|
unfocus() {
|
|
26181
26339
|
this.focusedRangeIndex = null;
|
|
26182
26340
|
this.focusStore.unfocus(this);
|
|
26183
|
-
this.model.selection.release(
|
|
26341
|
+
this.model.selection.release(this);
|
|
26184
26342
|
}
|
|
26185
26343
|
captureSelection() {
|
|
26186
26344
|
if (this.focusedRangeIndex === null) {
|
|
@@ -26189,7 +26347,7 @@ class SelectionInputStore extends SpreadsheetStore {
|
|
|
26189
26347
|
const range = this.ranges[this.focusedRangeIndex];
|
|
26190
26348
|
const sheetId = this.getters.getActiveSheetId();
|
|
26191
26349
|
const zone = this.getters.getRangeFromSheetXC(sheetId, range?.xc || "A1").zone;
|
|
26192
|
-
this.model.selection.capture(
|
|
26350
|
+
this.model.selection.capture(this, { cell: { col: zone.left, row: zone.top }, zone }, {
|
|
26193
26351
|
handleEvent: this.handleEvent.bind(this),
|
|
26194
26352
|
release: this.unfocus.bind(this),
|
|
26195
26353
|
});
|
|
@@ -26665,7 +26823,7 @@ class LineBarPieConfigPanel extends Component {
|
|
|
26665
26823
|
}
|
|
26666
26824
|
const getters = this.env.model.getters;
|
|
26667
26825
|
const sheetId = getters.getActiveSheetId();
|
|
26668
|
-
const labelRange =
|
|
26826
|
+
const labelRange = createValidRange(getters, sheetId, this.labelRange);
|
|
26669
26827
|
const dataSets = createDataSets(getters, this.dataSeriesRanges, sheetId, this.props.definition.dataSetsHaveTitle);
|
|
26670
26828
|
if (dataSets.length) {
|
|
26671
26829
|
return dataSets[0].dataRange.zone.top + 1;
|
|
@@ -26694,15 +26852,23 @@ class BarConfigPanel extends LineBarPieConfigPanel {
|
|
|
26694
26852
|
}
|
|
26695
26853
|
}
|
|
26696
26854
|
|
|
26855
|
+
/**
|
|
26856
|
+
* Start listening to pointer events and apply the given callbacks.
|
|
26857
|
+
*
|
|
26858
|
+
* @returns A function to remove the listeners.
|
|
26859
|
+
*/
|
|
26697
26860
|
function startDnd(onMouseMove, onMouseUp, onMouseDown = () => { }) {
|
|
26698
|
-
const
|
|
26699
|
-
onMouseUp(ev);
|
|
26861
|
+
const removeListeners = () => {
|
|
26700
26862
|
window.removeEventListener("pointerdown", onMouseDown);
|
|
26701
26863
|
window.removeEventListener("pointerup", _onMouseUp);
|
|
26702
26864
|
window.removeEventListener("dragstart", _onDragStart);
|
|
26703
26865
|
window.removeEventListener("pointermove", onMouseMove);
|
|
26704
26866
|
window.removeEventListener("wheel", onMouseMove);
|
|
26705
26867
|
};
|
|
26868
|
+
const _onMouseUp = (ev) => {
|
|
26869
|
+
onMouseUp(ev);
|
|
26870
|
+
removeListeners();
|
|
26871
|
+
};
|
|
26706
26872
|
function _onDragStart(ev) {
|
|
26707
26873
|
ev.preventDefault();
|
|
26708
26874
|
}
|
|
@@ -26714,6 +26880,7 @@ function startDnd(onMouseMove, onMouseUp, onMouseDown = () => { }) {
|
|
|
26714
26880
|
// preventDefault() is not allowed in passive event handler.
|
|
26715
26881
|
// https://chromestatus.com/feature/6662647093133312
|
|
26716
26882
|
window.addEventListener("wheel", onMouseMove, { passive: false });
|
|
26883
|
+
return removeListeners;
|
|
26717
26884
|
}
|
|
26718
26885
|
/**
|
|
26719
26886
|
* Function to be used during a pointerdown event, this function allows to
|
|
@@ -27657,6 +27824,7 @@ chartSidePanelComponentRegistry
|
|
|
27657
27824
|
});
|
|
27658
27825
|
|
|
27659
27826
|
class MainChartPanelStore extends SpreadsheetStore {
|
|
27827
|
+
mutators = ["activatePanel"];
|
|
27660
27828
|
panel = "configuration";
|
|
27661
27829
|
activatePanel(panel) {
|
|
27662
27830
|
this.panel = panel;
|
|
@@ -27907,6 +28075,7 @@ function useDragAndDropListItems() {
|
|
|
27907
28075
|
state.itemsStyle = {};
|
|
27908
28076
|
document.body.style.cursor = previousCursor;
|
|
27909
28077
|
args.onCancel?.();
|
|
28078
|
+
cleanUp();
|
|
27910
28079
|
};
|
|
27911
28080
|
const onDragEnd = (itemId, indexAtEnd) => {
|
|
27912
28081
|
state.draggedItemId = undefined;
|
|
@@ -27927,7 +28096,8 @@ function useDragAndDropListItems() {
|
|
|
27927
28096
|
onDragEnd,
|
|
27928
28097
|
onCancel: state.cancel,
|
|
27929
28098
|
});
|
|
27930
|
-
startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
28099
|
+
const stopListening = startDnd(dndHelper.onMouseMove.bind(dndHelper), dndHelper.onMouseUp.bind(dndHelper));
|
|
28100
|
+
cleanupFns.push(stopListening);
|
|
27931
28101
|
const onScroll = dndHelper.onScroll.bind(dndHelper);
|
|
27932
28102
|
args.containerEl.addEventListener("scroll", onScroll);
|
|
27933
28103
|
cleanupFns.push(() => args.containerEl.removeEventListener("scroll", onScroll));
|
|
@@ -28004,7 +28174,7 @@ class DOMDndHelper {
|
|
|
28004
28174
|
this.moveDraggedItemToPosition(this.currentMousePosition + this.scrollOffset);
|
|
28005
28175
|
}
|
|
28006
28176
|
onMouseMove(ev) {
|
|
28007
|
-
if (ev.button
|
|
28177
|
+
if (ev.button > 1) {
|
|
28008
28178
|
this.onCancel();
|
|
28009
28179
|
return;
|
|
28010
28180
|
}
|
|
@@ -28195,14 +28365,14 @@ function useHoveredElement(ref) {
|
|
|
28195
28365
|
|
|
28196
28366
|
function useHighlightsOnHover(ref, highlightProvider) {
|
|
28197
28367
|
const hoverState = useHoveredElement(ref);
|
|
28198
|
-
const
|
|
28368
|
+
const stores = useStoreProvider();
|
|
28199
28369
|
useHighlights({
|
|
28200
28370
|
get highlights() {
|
|
28201
28371
|
return hoverState.hovered ? highlightProvider.highlights : [];
|
|
28202
28372
|
},
|
|
28203
28373
|
});
|
|
28204
28374
|
useEffect(() => {
|
|
28205
|
-
|
|
28375
|
+
stores.trigger("store-updated");
|
|
28206
28376
|
}, () => [hoverState.hovered]);
|
|
28207
28377
|
}
|
|
28208
28378
|
function useHighlights(highlightProvider) {
|
|
@@ -29658,6 +29828,14 @@ var Direction;
|
|
|
29658
29828
|
Direction[Direction["next"] = 1] = "next";
|
|
29659
29829
|
})(Direction || (Direction = {}));
|
|
29660
29830
|
class FindAndReplaceStore extends SpreadsheetStore {
|
|
29831
|
+
mutators = [
|
|
29832
|
+
"updateSearchOptions",
|
|
29833
|
+
"updateSearchContent",
|
|
29834
|
+
"searchFormulas",
|
|
29835
|
+
"selectPreviousMatch",
|
|
29836
|
+
"selectNextMatch",
|
|
29837
|
+
"replace",
|
|
29838
|
+
];
|
|
29661
29839
|
allSheetsMatches = [];
|
|
29662
29840
|
activeSheetMatches = [];
|
|
29663
29841
|
specificRangeMatches = [];
|
|
@@ -29682,11 +29860,11 @@ class FindAndReplaceStore extends SpreadsheetStore {
|
|
|
29682
29860
|
this.initialShowFormulaState = this.model.getters.shouldShowFormulas();
|
|
29683
29861
|
this.searchOptions.searchFormulas = this.initialShowFormulaState;
|
|
29684
29862
|
const highlightStore = get(HighlightStore);
|
|
29685
|
-
highlightStore.register(
|
|
29863
|
+
highlightStore.register(this);
|
|
29686
29864
|
this.onDispose(() => {
|
|
29687
29865
|
this.model.dispatch("SET_FORMULA_VISIBILITY", { show: this.initialShowFormulaState });
|
|
29688
29866
|
this.updateSearchContent.stopDebounce();
|
|
29689
|
-
highlightStore.unRegister(
|
|
29867
|
+
highlightStore.unRegister(this);
|
|
29690
29868
|
});
|
|
29691
29869
|
}
|
|
29692
29870
|
get searchMatches() {
|
|
@@ -31166,14 +31344,14 @@ class FigureComponent extends Component {
|
|
|
31166
31344
|
}
|
|
31167
31345
|
onKeyDown(ev) {
|
|
31168
31346
|
const figure = this.props.figure;
|
|
31169
|
-
|
|
31347
|
+
const keyDownShortcut = keyboardEventToShortcutString(ev);
|
|
31348
|
+
switch (keyDownShortcut) {
|
|
31170
31349
|
case "Delete":
|
|
31171
31350
|
this.env.model.dispatch("DELETE_FIGURE", {
|
|
31172
31351
|
sheetId: this.env.model.getters.getActiveSheetId(),
|
|
31173
31352
|
id: figure.id,
|
|
31174
31353
|
});
|
|
31175
31354
|
this.props.onFigureDeleted();
|
|
31176
|
-
ev.stopPropagation();
|
|
31177
31355
|
ev.preventDefault();
|
|
31178
31356
|
ev.stopPropagation();
|
|
31179
31357
|
break;
|
|
@@ -31194,7 +31372,22 @@ class FigureComponent extends Component {
|
|
|
31194
31372
|
x: figure.x + delta[0],
|
|
31195
31373
|
y: figure.y + delta[1],
|
|
31196
31374
|
});
|
|
31375
|
+
ev.preventDefault();
|
|
31376
|
+
ev.stopPropagation();
|
|
31377
|
+
break;
|
|
31378
|
+
case "Ctrl+A":
|
|
31379
|
+
// Maybe in the future we will implement a way to select all figures
|
|
31380
|
+
ev.preventDefault();
|
|
31197
31381
|
ev.stopPropagation();
|
|
31382
|
+
break;
|
|
31383
|
+
case "Ctrl+Y":
|
|
31384
|
+
case "Ctrl+Z":
|
|
31385
|
+
if (keyDownShortcut === "Ctrl+Y") {
|
|
31386
|
+
this.env.model.dispatch("REQUEST_REDO");
|
|
31387
|
+
}
|
|
31388
|
+
else if (keyDownShortcut === "Ctrl+Z") {
|
|
31389
|
+
this.env.model.dispatch("REQUEST_UNDO");
|
|
31390
|
+
}
|
|
31198
31391
|
ev.preventDefault();
|
|
31199
31392
|
ev.stopPropagation();
|
|
31200
31393
|
break;
|
|
@@ -31329,6 +31522,7 @@ unGroupHeadersMenuRegistry
|
|
|
31329
31522
|
});
|
|
31330
31523
|
|
|
31331
31524
|
class DOMFocusableElementStore {
|
|
31525
|
+
mutators = ["setFocusableElement", "focus"];
|
|
31332
31526
|
focusableElement = undefined;
|
|
31333
31527
|
setFocusableElement(element) {
|
|
31334
31528
|
this.focusableElement = element;
|
|
@@ -32065,7 +32259,7 @@ class Composer extends Component {
|
|
|
32065
32259
|
"Ctrl+Enter": this.processNewLineEvent,
|
|
32066
32260
|
Escape: this.processEscapeKey,
|
|
32067
32261
|
F2: () => console.warn("Not implemented"),
|
|
32068
|
-
F4: this.processF4Key,
|
|
32262
|
+
F4: (ev) => this.processF4Key(ev),
|
|
32069
32263
|
Tab: (ev) => this.processTabKey(ev, "right"),
|
|
32070
32264
|
"Shift+Tab": (ev) => this.processTabKey(ev, "left"),
|
|
32071
32265
|
};
|
|
@@ -32187,7 +32381,8 @@ class Composer extends Component {
|
|
|
32187
32381
|
processEscapeKey() {
|
|
32188
32382
|
this.composerStore.cancelEdition();
|
|
32189
32383
|
}
|
|
32190
|
-
processF4Key() {
|
|
32384
|
+
processF4Key(ev) {
|
|
32385
|
+
ev.stopPropagation();
|
|
32191
32386
|
this.composerStore.cycleReferences();
|
|
32192
32387
|
this.processContent();
|
|
32193
32388
|
}
|
|
@@ -34390,13 +34585,6 @@ class GridRenderer {
|
|
|
34390
34585
|
this.getters = get(ModelStore).getters;
|
|
34391
34586
|
this.renderer = get(RendererStore);
|
|
34392
34587
|
this.renderer.register(this);
|
|
34393
|
-
/**
|
|
34394
|
-
* Mark the instance as raw to avoid reactivity as this class is instanciated
|
|
34395
|
-
* as a Store by `useGridDrawing` (which casts it as reactive).
|
|
34396
|
-
*
|
|
34397
|
-
* Calling `this.` on a reactive instance is significantly slower than on a raw object.
|
|
34398
|
-
*/
|
|
34399
|
-
markRaw(this);
|
|
34400
34588
|
}
|
|
34401
34589
|
get renderingLayers() {
|
|
34402
34590
|
return ["Background", "Headers"];
|
|
@@ -35026,7 +35214,7 @@ class GridRenderer {
|
|
|
35026
35214
|
function useGridDrawing(refName, model, canvasSize) {
|
|
35027
35215
|
const canvasRef = useRef(refName);
|
|
35028
35216
|
useEffect(drawGrid);
|
|
35029
|
-
const
|
|
35217
|
+
const rendererStore = useStore(RendererStore);
|
|
35030
35218
|
useStore(GridRenderer);
|
|
35031
35219
|
function drawGrid() {
|
|
35032
35220
|
const canvas = canvasRef.el;
|
|
@@ -35054,7 +35242,11 @@ function useGridDrawing(refName, model, canvasSize) {
|
|
|
35054
35242
|
ctx.scale(dpr, dpr);
|
|
35055
35243
|
for (const layer of OrderedLayers()) {
|
|
35056
35244
|
model.drawLayer(renderingContext, layer);
|
|
35057
|
-
|
|
35245
|
+
// @ts-ignore 'drawLayer' is not declated as a mutator because:
|
|
35246
|
+
// it does not mutate anything. Most importantly it's used
|
|
35247
|
+
// during rendering. Invoking a mutator during rendering would
|
|
35248
|
+
// trigger another rendering, ultimately resulting in an infinite loop.
|
|
35249
|
+
rendererStore.drawLayer(renderingContext, layer);
|
|
35058
35250
|
}
|
|
35059
35251
|
}
|
|
35060
35252
|
}
|
|
@@ -35456,6 +35648,7 @@ class VerticalScrollBar extends Component {
|
|
|
35456
35648
|
}
|
|
35457
35649
|
|
|
35458
35650
|
class SidePanelStore extends SpreadsheetStore {
|
|
35651
|
+
mutators = ["open", "toggle", "close"];
|
|
35459
35652
|
initialPanelProps = {};
|
|
35460
35653
|
componentTag = "";
|
|
35461
35654
|
get isOpen() {
|
|
@@ -40982,12 +41175,6 @@ function compileTokens(tokens) {
|
|
|
40982
41175
|
// detect when an argument need to be evaluated as a meta argument
|
|
40983
41176
|
const isMeta = argTypes.includes("META");
|
|
40984
41177
|
const hasRange = argTypes.some((t) => isRangeType(t));
|
|
40985
|
-
const isRangeOnly = argTypes.every((t) => isRangeType(t));
|
|
40986
|
-
if (isRangeOnly) {
|
|
40987
|
-
if (!isRangeInput(currentArg)) {
|
|
40988
|
-
throw new BadExpressionError(_t("Function %s expects the parameter %s to be reference to a cell or range, not a %s.", functionName, (i + 1).toString(), currentArg.type.toLowerCase()));
|
|
40989
|
-
}
|
|
40990
|
-
}
|
|
40991
41178
|
compiledArgs.push(compileAST(currentArg, isMeta, hasRange, {
|
|
40992
41179
|
functionName,
|
|
40993
41180
|
paramIndex: i + 1,
|
|
@@ -41158,16 +41345,6 @@ function assertEnoughArgs(ast) {
|
|
|
41158
41345
|
function isRangeType(type) {
|
|
41159
41346
|
return type.startsWith("RANGE");
|
|
41160
41347
|
}
|
|
41161
|
-
function isRangeInput(arg) {
|
|
41162
|
-
if (arg.type === "REFERENCE") {
|
|
41163
|
-
return true;
|
|
41164
|
-
}
|
|
41165
|
-
if (arg.type === "FUNCALL") {
|
|
41166
|
-
const fnDef = functions$1[arg.value.toUpperCase()];
|
|
41167
|
-
return fnDef && isRangeType(fnDef.returns[0]);
|
|
41168
|
-
}
|
|
41169
|
-
return false;
|
|
41170
|
-
}
|
|
41171
41348
|
|
|
41172
41349
|
const functions = functionRegistry.content;
|
|
41173
41350
|
function isExportableToExcel(tokens) {
|
|
@@ -43284,7 +43461,12 @@ class MergePlugin extends CorePlugin {
|
|
|
43284
43461
|
* if they have at least a common cell
|
|
43285
43462
|
*/
|
|
43286
43463
|
doesIntersectMerge(sheetId, zone) {
|
|
43287
|
-
|
|
43464
|
+
for (const merge of this.getMerges(sheetId)) {
|
|
43465
|
+
if (overlap(zone, merge)) {
|
|
43466
|
+
return true;
|
|
43467
|
+
}
|
|
43468
|
+
}
|
|
43469
|
+
return false;
|
|
43288
43470
|
}
|
|
43289
43471
|
/**
|
|
43290
43472
|
* Returns true if two columns have at least one merge in common
|
|
@@ -43900,6 +44082,9 @@ class RangeAdapter {
|
|
|
43900
44082
|
if (range.invalidXc) {
|
|
43901
44083
|
return range.invalidXc;
|
|
43902
44084
|
}
|
|
44085
|
+
if (!this.getters.tryGetSheet(range.sheetId)) {
|
|
44086
|
+
return CellErrorType.InvalidReference;
|
|
44087
|
+
}
|
|
43903
44088
|
if (range.zone.bottom - range.zone.top < 0 || range.zone.right - range.zone.left < 0) {
|
|
43904
44089
|
return CellErrorType.InvalidReference;
|
|
43905
44090
|
}
|
|
@@ -47284,7 +47469,6 @@ class PositionSet {
|
|
|
47284
47469
|
*
|
|
47285
47470
|
*/
|
|
47286
47471
|
class SpreadingRelation {
|
|
47287
|
-
createEmptyPositionSet;
|
|
47288
47472
|
/**
|
|
47289
47473
|
* Internal structure:
|
|
47290
47474
|
* For something like
|
|
@@ -47315,9 +47499,6 @@ class SpreadingRelation {
|
|
|
47315
47499
|
*/
|
|
47316
47500
|
resultsToArrayFormulas = new PositionMap();
|
|
47317
47501
|
arrayFormulasToResults = new PositionMap();
|
|
47318
|
-
constructor(createEmptyPositionSet) {
|
|
47319
|
-
this.createEmptyPositionSet = createEmptyPositionSet;
|
|
47320
|
-
}
|
|
47321
47502
|
getFormulaPositionsSpreadingOn(resultPosition) {
|
|
47322
47503
|
return this.resultsToArrayFormulas.get(resultPosition) || EMPTY_ARRAY;
|
|
47323
47504
|
}
|
|
@@ -47336,13 +47517,13 @@ class SpreadingRelation {
|
|
|
47336
47517
|
*/
|
|
47337
47518
|
addRelation({ arrayFormulaPosition, resultPosition, }) {
|
|
47338
47519
|
if (!this.resultsToArrayFormulas.has(resultPosition)) {
|
|
47339
|
-
this.resultsToArrayFormulas.set(resultPosition,
|
|
47520
|
+
this.resultsToArrayFormulas.set(resultPosition, []);
|
|
47340
47521
|
}
|
|
47341
|
-
this.resultsToArrayFormulas.get(resultPosition)?.
|
|
47522
|
+
this.resultsToArrayFormulas.get(resultPosition)?.push(arrayFormulaPosition);
|
|
47342
47523
|
if (!this.arrayFormulasToResults.has(arrayFormulaPosition)) {
|
|
47343
|
-
this.arrayFormulasToResults.set(arrayFormulaPosition,
|
|
47524
|
+
this.arrayFormulasToResults.set(arrayFormulaPosition, []);
|
|
47344
47525
|
}
|
|
47345
|
-
this.arrayFormulasToResults.get(arrayFormulaPosition)?.
|
|
47526
|
+
this.arrayFormulasToResults.get(arrayFormulaPosition)?.push(resultPosition);
|
|
47346
47527
|
}
|
|
47347
47528
|
hasArrayFormulaResult(position) {
|
|
47348
47529
|
return this.resultsToArrayFormulas.has(position);
|
|
@@ -47363,7 +47544,7 @@ class Evaluator {
|
|
|
47363
47544
|
evaluatedCells = new PositionMap();
|
|
47364
47545
|
formulaDependencies = lazy(new FormulaDependencyGraph(this.createEmptyPositionSet.bind(this)));
|
|
47365
47546
|
blockedArrayFormulas = new PositionSet({});
|
|
47366
|
-
spreadingRelations = new SpreadingRelation(
|
|
47547
|
+
spreadingRelations = new SpreadingRelation();
|
|
47367
47548
|
constructor(context, getters) {
|
|
47368
47549
|
this.context = context;
|
|
47369
47550
|
this.getters = getters;
|
|
@@ -47440,7 +47621,7 @@ class Evaluator {
|
|
|
47440
47621
|
}
|
|
47441
47622
|
buildDependencyGraph() {
|
|
47442
47623
|
this.blockedArrayFormulas = this.createEmptyPositionSet();
|
|
47443
|
-
this.spreadingRelations = new SpreadingRelation(
|
|
47624
|
+
this.spreadingRelations = new SpreadingRelation();
|
|
47444
47625
|
this.formulaDependencies = lazy(() => {
|
|
47445
47626
|
const dependencies = [...this.getAllCells()].flatMap((position) => this.getDirectDependencies(position)
|
|
47446
47627
|
.filter((range) => !range.invalidSheetName && !range.invalidXc)
|
|
@@ -47929,16 +48110,22 @@ class EvaluationPlugin extends UIPlugin {
|
|
|
47929
48110
|
let newContent = undefined;
|
|
47930
48111
|
let newFormat = undefined;
|
|
47931
48112
|
let isExported = true;
|
|
48113
|
+
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
47932
48114
|
const formulaCell = this.getCorrespondingFormulaCell(position);
|
|
47933
48115
|
if (formulaCell) {
|
|
47934
48116
|
isExported = isExportableToExcel(formulaCell.compiledFormula.tokens);
|
|
47935
48117
|
isFormula = isExported;
|
|
47936
48118
|
if (!isExported) {
|
|
47937
|
-
|
|
47938
|
-
|
|
48119
|
+
// If the cell contains a non-exported formula and that is evaluates to
|
|
48120
|
+
// nothing* ,we don't export it.
|
|
48121
|
+
// * non-falsy value are relevant and so are 0 and FALSE, which only leaves
|
|
48122
|
+
// the empty string.
|
|
48123
|
+
if (value !== "") {
|
|
48124
|
+
newContent = (value ?? "").toString();
|
|
48125
|
+
newFormat = evaluatedCell.format;
|
|
48126
|
+
}
|
|
47939
48127
|
}
|
|
47940
48128
|
}
|
|
47941
|
-
const exportedSheetData = data.sheets.find((sheet) => sheet.id === position.sheetId);
|
|
47942
48129
|
const exportedCellData = exportedSheetData.cells[xc] || {};
|
|
47943
48130
|
const format = newFormat
|
|
47944
48131
|
? getItemId(newFormat, data.formats)
|
|
@@ -49604,62 +49791,6 @@ class AutomaticSumPlugin extends UIPlugin {
|
|
|
49604
49791
|
}
|
|
49605
49792
|
}
|
|
49606
49793
|
|
|
49607
|
-
/**
|
|
49608
|
-
* This is a generic event bus based on the Owl event bus.
|
|
49609
|
-
* This bus however ensures type safety across events and subscription callbacks.
|
|
49610
|
-
*/
|
|
49611
|
-
class EventBus {
|
|
49612
|
-
subscriptions = {};
|
|
49613
|
-
/**
|
|
49614
|
-
* Add a listener for the 'eventType' events.
|
|
49615
|
-
*
|
|
49616
|
-
* Note that the 'owner' of this event can be anything, but will more likely
|
|
49617
|
-
* be a component or a class. The idea is that the callback will be called with
|
|
49618
|
-
* the proper owner bound.
|
|
49619
|
-
*
|
|
49620
|
-
* Also, the owner should be kind of unique. This will be used to remove the
|
|
49621
|
-
* listener.
|
|
49622
|
-
*/
|
|
49623
|
-
on(type, owner, callback) {
|
|
49624
|
-
if (!callback) {
|
|
49625
|
-
throw new Error("Missing callback");
|
|
49626
|
-
}
|
|
49627
|
-
if (!this.subscriptions[type]) {
|
|
49628
|
-
this.subscriptions[type] = [];
|
|
49629
|
-
}
|
|
49630
|
-
this.subscriptions[type].push({
|
|
49631
|
-
owner,
|
|
49632
|
-
callback,
|
|
49633
|
-
});
|
|
49634
|
-
}
|
|
49635
|
-
/**
|
|
49636
|
-
* Emit an event of type 'eventType'. Any extra arguments will be passed to
|
|
49637
|
-
* the listeners callback.
|
|
49638
|
-
*/
|
|
49639
|
-
trigger(type, payload) {
|
|
49640
|
-
const subs = this.subscriptions[type] || [];
|
|
49641
|
-
for (let i = 0, iLen = subs.length; i < iLen; i++) {
|
|
49642
|
-
const sub = subs[i];
|
|
49643
|
-
sub.callback.call(sub.owner, payload);
|
|
49644
|
-
}
|
|
49645
|
-
}
|
|
49646
|
-
/**
|
|
49647
|
-
* Remove a listener
|
|
49648
|
-
*/
|
|
49649
|
-
off(eventType, owner) {
|
|
49650
|
-
const subs = this.subscriptions[eventType];
|
|
49651
|
-
if (subs) {
|
|
49652
|
-
this.subscriptions[eventType] = subs.filter((s) => s.owner !== owner);
|
|
49653
|
-
}
|
|
49654
|
-
}
|
|
49655
|
-
/**
|
|
49656
|
-
* Remove all subscriptions.
|
|
49657
|
-
*/
|
|
49658
|
-
clear() {
|
|
49659
|
-
this.subscriptions = {};
|
|
49660
|
-
}
|
|
49661
|
-
}
|
|
49662
|
-
|
|
49663
49794
|
/*
|
|
49664
49795
|
* This file contains the specifics transformations
|
|
49665
49796
|
*/
|
|
@@ -51984,7 +52115,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
51984
52115
|
paintFormatStatus = "inactive";
|
|
51985
52116
|
originSheetId;
|
|
51986
52117
|
copiedData;
|
|
51987
|
-
_isCutOperation;
|
|
52118
|
+
_isCutOperation = false;
|
|
51988
52119
|
// ---------------------------------------------------------------------------
|
|
51989
52120
|
// Command Handling
|
|
51990
52121
|
// ---------------------------------------------------------------------------
|
|
@@ -51996,14 +52127,17 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
51996
52127
|
case "PASTE_FROM_OS_CLIPBOARD": {
|
|
51997
52128
|
const copiedData = this.convertOSClipboardData(cmd.text);
|
|
51998
52129
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
51999
|
-
return this.isPasteAllowed(cmd.target, copiedData, { pasteOption });
|
|
52130
|
+
return this.isPasteAllowed(cmd.target, copiedData, { pasteOption, isCutOperation: false });
|
|
52000
52131
|
}
|
|
52001
52132
|
case "PASTE": {
|
|
52002
52133
|
if (!this.copiedData) {
|
|
52003
52134
|
return "EmptyClipboard" /* CommandResult.EmptyClipboard */;
|
|
52004
52135
|
}
|
|
52005
52136
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52006
|
-
return this.isPasteAllowed(cmd.target, this.copiedData, {
|
|
52137
|
+
return this.isPasteAllowed(cmd.target, this.copiedData, {
|
|
52138
|
+
pasteOption: pasteOption,
|
|
52139
|
+
isCutOperation: this._isCutOperation,
|
|
52140
|
+
});
|
|
52007
52141
|
}
|
|
52008
52142
|
case "COPY_PASTE_CELLS_ABOVE": {
|
|
52009
52143
|
const zones = this.getters.getSelectedZones();
|
|
@@ -52021,13 +52155,13 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52021
52155
|
}
|
|
52022
52156
|
case "INSERT_CELL": {
|
|
52023
52157
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52024
|
-
const copiedData = this.copy(
|
|
52025
|
-
return this.isPasteAllowed(paste, copiedData, {});
|
|
52158
|
+
const copiedData = this.copy(cut);
|
|
52159
|
+
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
52026
52160
|
}
|
|
52027
52161
|
case "DELETE_CELL": {
|
|
52028
52162
|
const { cut, paste } = this.getDeleteCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52029
|
-
const copiedData = this.copy(
|
|
52030
|
-
return this.isPasteAllowed(paste, copiedData, {});
|
|
52163
|
+
const copiedData = this.copy(cut);
|
|
52164
|
+
return this.isPasteAllowed(paste, copiedData, { isCutOperation: true });
|
|
52031
52165
|
}
|
|
52032
52166
|
case "ACTIVATE_PAINT_FORMAT": {
|
|
52033
52167
|
if (this.paintFormatStatus !== "inactive") {
|
|
@@ -52045,23 +52179,27 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52045
52179
|
const zones = this.getters.getSelectedZones();
|
|
52046
52180
|
this.status = "visible";
|
|
52047
52181
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52048
|
-
this.copiedData = this.copy(
|
|
52182
|
+
this.copiedData = this.copy(zones);
|
|
52183
|
+
this._isCutOperation = cmd.type === "CUT";
|
|
52049
52184
|
break;
|
|
52050
52185
|
case "PASTE_FROM_OS_CLIPBOARD": {
|
|
52186
|
+
this._isCutOperation = false;
|
|
52051
52187
|
this.copiedData = this.convertOSClipboardData(cmd.text);
|
|
52052
52188
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52053
|
-
this.paste(cmd.target, {
|
|
52189
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52054
52190
|
pasteOption,
|
|
52055
52191
|
selectTarget: true,
|
|
52192
|
+
isCutOperation: false,
|
|
52056
52193
|
});
|
|
52057
52194
|
this.status = "invisible";
|
|
52058
52195
|
break;
|
|
52059
52196
|
}
|
|
52060
52197
|
case "PASTE": {
|
|
52061
52198
|
const pasteOption = cmd.pasteOption || (this.paintFormatStatus !== "inactive" ? "onlyFormat" : undefined);
|
|
52062
|
-
this.paste(cmd.target, {
|
|
52199
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52063
52200
|
pasteOption,
|
|
52064
52201
|
selectTarget: true,
|
|
52202
|
+
isCutOperation: this._isCutOperation,
|
|
52065
52203
|
});
|
|
52066
52204
|
if (this.paintFormatStatus === "oneOff") {
|
|
52067
52205
|
this.paintFormatStatus = "inactive";
|
|
@@ -52082,9 +52220,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52082
52220
|
top: multipleRowsInSelection ? zone.top : zone.top - 1,
|
|
52083
52221
|
};
|
|
52084
52222
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52085
|
-
|
|
52086
|
-
this.paste([zone], {
|
|
52087
|
-
|
|
52223
|
+
const copiedData = this.copy([copyTarget]);
|
|
52224
|
+
this.paste([zone], copiedData, {
|
|
52225
|
+
isCutOperation: false,
|
|
52088
52226
|
selectTarget: true,
|
|
52089
52227
|
});
|
|
52090
52228
|
}
|
|
@@ -52099,9 +52237,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52099
52237
|
left: multipleColsInSelection ? zone.left : zone.left - 1,
|
|
52100
52238
|
};
|
|
52101
52239
|
this.originSheetId = this.getters.getActiveSheetId();
|
|
52102
|
-
|
|
52103
|
-
this.paste([zone], {
|
|
52104
|
-
|
|
52240
|
+
const copiedData = this.copy([copyTarget]);
|
|
52241
|
+
this.paste([zone], copiedData, {
|
|
52242
|
+
isCutOperation: false,
|
|
52105
52243
|
selectTarget: true,
|
|
52106
52244
|
});
|
|
52107
52245
|
}
|
|
@@ -52117,20 +52255,20 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52117
52255
|
}
|
|
52118
52256
|
break;
|
|
52119
52257
|
}
|
|
52120
|
-
|
|
52121
|
-
this.paste(paste, {});
|
|
52258
|
+
const copiedData = this.copy(cut);
|
|
52259
|
+
this.paste(paste, copiedData, { isCutOperation: true });
|
|
52122
52260
|
break;
|
|
52123
52261
|
}
|
|
52124
52262
|
case "INSERT_CELL": {
|
|
52125
52263
|
const { cut, paste } = this.getInsertCellsTargets(cmd.zone, cmd.shiftDimension);
|
|
52126
|
-
|
|
52127
|
-
this.paste(paste, {});
|
|
52264
|
+
const copiedData = this.copy(cut);
|
|
52265
|
+
this.paste(paste, copiedData, { isCutOperation: true });
|
|
52128
52266
|
break;
|
|
52129
52267
|
}
|
|
52130
52268
|
case "ADD_COLUMNS_ROWS": {
|
|
52131
52269
|
this.status = "invisible";
|
|
52132
52270
|
// If we add a col/row inside or before the cut area, we invalidate the clipboard
|
|
52133
|
-
if (this._isCutOperation !== true) {
|
|
52271
|
+
if (this._isCutOperation !== true || cmd.sheetId !== this.copiedData?.sheetId) {
|
|
52134
52272
|
return;
|
|
52135
52273
|
}
|
|
52136
52274
|
const isClipboardDirty = this.isColRowDirtyingClipboard(cmd.position === "before" ? cmd.base : cmd.base + 1, cmd.dimension);
|
|
@@ -52142,7 +52280,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52142
52280
|
case "REMOVE_COLUMNS_ROWS": {
|
|
52143
52281
|
this.status = "invisible";
|
|
52144
52282
|
// If we remove a col/row inside or before the cut area, we invalidate the clipboard
|
|
52145
|
-
if (this._isCutOperation !== true) {
|
|
52283
|
+
if (this._isCutOperation !== true || cmd.sheetId !== this.copiedData?.sheetId) {
|
|
52146
52284
|
return;
|
|
52147
52285
|
}
|
|
52148
52286
|
for (let el of cmd.elements) {
|
|
@@ -52156,7 +52294,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52156
52294
|
break;
|
|
52157
52295
|
}
|
|
52158
52296
|
case "REPEAT_PASTE": {
|
|
52159
|
-
this.paste(cmd.target, {
|
|
52297
|
+
this.paste(cmd.target, this.copiedData, {
|
|
52298
|
+
isCutOperation: false,
|
|
52160
52299
|
pasteOption: cmd.pasteOption,
|
|
52161
52300
|
selectTarget: true,
|
|
52162
52301
|
});
|
|
@@ -52164,7 +52303,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52164
52303
|
}
|
|
52165
52304
|
case "ACTIVATE_PAINT_FORMAT": {
|
|
52166
52305
|
const zones = this.getters.getSelectedZones();
|
|
52167
|
-
this.copiedData = this.copy(
|
|
52306
|
+
this.copiedData = this.copy(zones);
|
|
52168
52307
|
this.status = "visible";
|
|
52169
52308
|
if (cmd.persistent) {
|
|
52170
52309
|
this.paintFormatStatus = "persistent";
|
|
@@ -52195,7 +52334,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52195
52334
|
}
|
|
52196
52335
|
}
|
|
52197
52336
|
convertOSClipboardData(clipboardData) {
|
|
52198
|
-
this._isCutOperation = false;
|
|
52199
52337
|
const handlers = clipboardHandlersRegistries.figureHandlers
|
|
52200
52338
|
.getAll()
|
|
52201
52339
|
.map((handler) => new handler(this.getters, this.dispatch));
|
|
@@ -52233,7 +52371,6 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52233
52371
|
for (const handler of this.selectClipboardHandlers(copiedData)) {
|
|
52234
52372
|
const result = handler.isPasteAllowed(this.getters.getActiveSheetId(), target, copiedData, {
|
|
52235
52373
|
...options,
|
|
52236
|
-
isCutOperation: this.isCutOperation(),
|
|
52237
52374
|
});
|
|
52238
52375
|
if (result !== "Success" /* CommandResult.Success */) {
|
|
52239
52376
|
return result;
|
|
@@ -52256,9 +52393,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52256
52393
|
}
|
|
52257
52394
|
return false;
|
|
52258
52395
|
}
|
|
52259
|
-
copy(
|
|
52396
|
+
copy(zones) {
|
|
52260
52397
|
let copiedData = {};
|
|
52261
|
-
this._isCutOperation = operation === "CUT";
|
|
52262
52398
|
const clipboardData = this.getClipboardData(zones);
|
|
52263
52399
|
for (const handler of this.selectClipboardHandlers(clipboardData)) {
|
|
52264
52400
|
const data = handler.copy(clipboardData);
|
|
@@ -52266,8 +52402,8 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52266
52402
|
}
|
|
52267
52403
|
return copiedData;
|
|
52268
52404
|
}
|
|
52269
|
-
paste(zones, options) {
|
|
52270
|
-
if (!
|
|
52405
|
+
paste(zones, copiedData, options) {
|
|
52406
|
+
if (!copiedData) {
|
|
52271
52407
|
return;
|
|
52272
52408
|
}
|
|
52273
52409
|
let zone = undefined;
|
|
@@ -52275,12 +52411,9 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52275
52411
|
let target = {
|
|
52276
52412
|
zones,
|
|
52277
52413
|
};
|
|
52278
|
-
const handlers = this.selectClipboardHandlers(
|
|
52414
|
+
const handlers = this.selectClipboardHandlers(copiedData);
|
|
52279
52415
|
for (const handler of handlers) {
|
|
52280
|
-
const currentTarget = handler.getPasteTarget(zones,
|
|
52281
|
-
...options,
|
|
52282
|
-
isCutOperation: this.isCutOperation(),
|
|
52283
|
-
});
|
|
52416
|
+
const currentTarget = handler.getPasteTarget(zones, copiedData, options);
|
|
52284
52417
|
if (currentTarget.figureId) {
|
|
52285
52418
|
target.figureId = currentTarget.figureId;
|
|
52286
52419
|
}
|
|
@@ -52296,7 +52429,7 @@ class ClipboardPlugin extends UIPlugin {
|
|
|
52296
52429
|
if (zone !== undefined) {
|
|
52297
52430
|
this.addMissingDimensions(this.getters.getActiveSheetId(), zone.right - zone.left + 1, zone.bottom - zone.top + 1, zone.left, zone.top);
|
|
52298
52431
|
}
|
|
52299
|
-
handlers.forEach((handler) => handler.paste(target,
|
|
52432
|
+
handlers.forEach((handler) => handler.paste(target, copiedData, options));
|
|
52300
52433
|
if (!options?.selectTarget) {
|
|
52301
52434
|
return;
|
|
52302
52435
|
}
|
|
@@ -54766,6 +54899,7 @@ class BottomBarSheet extends Component {
|
|
|
54766
54899
|
sheetDivRef = useRef("sheetDiv");
|
|
54767
54900
|
sheetNameRef = useRef("sheetNameSpan");
|
|
54768
54901
|
editionState = "initializing";
|
|
54902
|
+
DOMFocusableElementStore;
|
|
54769
54903
|
setup() {
|
|
54770
54904
|
onMounted(() => {
|
|
54771
54905
|
if (this.isSheetActive) {
|
|
@@ -54778,6 +54912,7 @@ class BottomBarSheet extends Component {
|
|
|
54778
54912
|
this.focusInputAndSelectContent();
|
|
54779
54913
|
}
|
|
54780
54914
|
});
|
|
54915
|
+
this.DOMFocusableElementStore = useStore(DOMFocusableElementStore);
|
|
54781
54916
|
}
|
|
54782
54917
|
focusInputAndSelectContent() {
|
|
54783
54918
|
if (!this.state.isEditing || !this.sheetNameRef.el)
|
|
@@ -54819,9 +54954,11 @@ class BottomBarSheet extends Component {
|
|
|
54819
54954
|
if (ev.key === "Enter") {
|
|
54820
54955
|
ev.preventDefault();
|
|
54821
54956
|
this.stopEdition();
|
|
54957
|
+
this.DOMFocusableElementStore.focus();
|
|
54822
54958
|
}
|
|
54823
54959
|
if (ev.key === "Escape") {
|
|
54824
54960
|
this.cancelEdition();
|
|
54961
|
+
this.DOMFocusableElementStore.focus();
|
|
54825
54962
|
}
|
|
54826
54963
|
}
|
|
54827
54964
|
onClickSheetName(ev) {
|
|
@@ -56777,16 +56914,25 @@ class Spreadsheet extends Component {
|
|
|
56777
56914
|
}
|
|
56778
56915
|
}, () => [this.env.model.getters.getActiveSheetId()]);
|
|
56779
56916
|
useExternalListener(window, "resize", () => this.render(true));
|
|
56917
|
+
// For some reason, the wheel event is not properly registered inside templates
|
|
56918
|
+
// in Chromium-based browsers based on chromium 125
|
|
56919
|
+
// This hack ensures the event declared in the template is properly registered/working
|
|
56920
|
+
useExternalListener(document.body, "wheel", () => { });
|
|
56780
56921
|
this.bindModelEvents();
|
|
56781
56922
|
onWillUpdateProps((nextProps) => {
|
|
56782
56923
|
if (nextProps.model !== this.props.model) {
|
|
56783
56924
|
throw new Error("Changing the props model is not supported at the moment.");
|
|
56784
56925
|
}
|
|
56785
56926
|
});
|
|
56927
|
+
const render = batched(this.render.bind(this, true));
|
|
56786
56928
|
onMounted(() => {
|
|
56787
56929
|
this.checkViewportSize();
|
|
56930
|
+
stores.on("store-updated", this, render);
|
|
56931
|
+
});
|
|
56932
|
+
onWillUnmount(() => {
|
|
56933
|
+
this.unbindModelEvents();
|
|
56934
|
+
stores.off("store-updated", this);
|
|
56788
56935
|
});
|
|
56789
|
-
onWillUnmount(() => this.unbindModelEvents());
|
|
56790
56936
|
onPatched(() => {
|
|
56791
56937
|
this.checkViewportSize();
|
|
56792
56938
|
});
|
|
@@ -59535,7 +59681,11 @@ function addRows(construct, data, sheet) {
|
|
|
59535
59681
|
let cellNode = escapeXml ``;
|
|
59536
59682
|
// Either formula or static value inside the cell
|
|
59537
59683
|
if (cell.isFormula) {
|
|
59538
|
-
|
|
59684
|
+
const res = addFormula(cell);
|
|
59685
|
+
if (!res) {
|
|
59686
|
+
continue;
|
|
59687
|
+
}
|
|
59688
|
+
({ attrs: additionalAttrs, node: cellNode } = res);
|
|
59539
59689
|
}
|
|
59540
59690
|
else if (cell.content && isMarkdownLink(cell.content)) {
|
|
59541
59691
|
const { label } = parseMarkdownLink(cell.content);
|
|
@@ -60574,6 +60724,6 @@ const constants = {
|
|
|
60574
60724
|
export { AbstractCellClipboardHandler, AbstractChart, AbstractFigureClipboardHandler, CellErrorType, CommandResult, CorePlugin, DispatchResult, EvaluationError, Model, Registry, Revision, SPREADSHEET_DIMENSIONS, Spreadsheet, UIPlugin, __info__, addFunction, addRenderingLayer, astToFormula, 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 };
|
|
60575
60725
|
|
|
60576
60726
|
|
|
60577
|
-
__info__.version = "17.2.
|
|
60578
|
-
__info__.date = "2024-
|
|
60579
|
-
__info__.hash = "
|
|
60727
|
+
__info__.version = "17.2.9";
|
|
60728
|
+
__info__.date = "2024-06-03T14:56:21.684Z";
|
|
60729
|
+
__info__.hash = "086af6d";
|