@ricsam/formula-engine 0.2.13 → 0.2.15
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/README.md +7 -0
- package/dist/cjs/core/engine-snapshot.cjs.map +2 -2
- package/dist/cjs/core/engine.cjs +690 -513
- package/dist/cjs/core/engine.cjs.map +3 -3
- package/dist/cjs/core/managers/undo-redo-manager.cjs +109 -0
- package/dist/cjs/core/managers/undo-redo-manager.cjs.map +10 -0
- package/dist/cjs/core/managers/workbook-manager.cjs +89 -55
- package/dist/cjs/core/managers/workbook-manager.cjs.map +3 -3
- package/dist/cjs/core/types.cjs +4 -2
- package/dist/cjs/core/types.cjs.map +3 -3
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/core/engine-snapshot.mjs.map +2 -2
- package/dist/mjs/core/engine.mjs +690 -513
- package/dist/mjs/core/engine.mjs.map +3 -3
- package/dist/mjs/core/managers/undo-redo-manager.mjs +69 -0
- package/dist/mjs/core/managers/undo-redo-manager.mjs.map +10 -0
- package/dist/mjs/core/managers/workbook-manager.mjs +91 -55
- package/dist/mjs/core/managers/workbook-manager.mjs.map +3 -3
- package/dist/mjs/core/types.mjs +4 -2
- package/dist/mjs/core/types.mjs.map +3 -3
- package/dist/mjs/package.json +1 -1
- package/dist/types/core/engine-snapshot.d.ts +13 -7
- package/dist/types/core/engine.d.ts +18 -3
- package/dist/types/core/managers/undo-redo-manager.d.ts +16 -0
- package/dist/types/core/managers/workbook-manager.d.ts +2 -0
- package/dist/types/core/types.d.ts +29 -0
- package/package.json +1 -1
package/dist/mjs/core/engine.mjs
CHANGED
|
@@ -17,6 +17,7 @@ import { StyleManager } from "./managers/style-manager.mjs";
|
|
|
17
17
|
import { CopyManager } from "./managers/copy-manager.mjs";
|
|
18
18
|
import { ReferenceManager } from "./managers/reference-manager.mjs";
|
|
19
19
|
import { RangeMetadataManager } from "./managers/range-metadata-manager.mjs";
|
|
20
|
+
import { UndoRedoManager } from "./managers/undo-redo-manager.mjs";
|
|
20
21
|
import {
|
|
21
22
|
ENGINE_SNAPSHOT_VERSION
|
|
22
23
|
} from "./engine-snapshot.mjs";
|
|
@@ -51,6 +52,8 @@ class FormulaEngine {
|
|
|
51
52
|
rangeMetadataManager;
|
|
52
53
|
copyManager;
|
|
53
54
|
referenceManager;
|
|
55
|
+
undoRedoManager;
|
|
56
|
+
historyCheckpointDepth = 0;
|
|
54
57
|
_workbookManager;
|
|
55
58
|
_namedExpressionManager;
|
|
56
59
|
_tableManager;
|
|
@@ -60,7 +63,8 @@ class FormulaEngine {
|
|
|
60
63
|
_dependencyManager;
|
|
61
64
|
_styleManager;
|
|
62
65
|
_rangeMetadataManager;
|
|
63
|
-
constructor() {
|
|
66
|
+
constructor(options = {}) {
|
|
67
|
+
this.undoRedoManager = new UndoRedoManager(options.undoRedo);
|
|
64
68
|
this.eventManager = new EventManager;
|
|
65
69
|
this.workbookManager = new WorkbookManager;
|
|
66
70
|
this.namedExpressionManager = new NamedExpressionManager;
|
|
@@ -84,8 +88,51 @@ class FormulaEngine {
|
|
|
84
88
|
this._styleManager = this.styleManager;
|
|
85
89
|
this._rangeMetadataManager = this.rangeMetadataManager;
|
|
86
90
|
}
|
|
87
|
-
static buildEmpty() {
|
|
88
|
-
return new FormulaEngine;
|
|
91
|
+
static buildEmpty(options) {
|
|
92
|
+
return new FormulaEngine(options);
|
|
93
|
+
}
|
|
94
|
+
undo() {
|
|
95
|
+
if (!this.undoRedoManager.canUndo()) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const target = this.undoRedoManager.popUndo();
|
|
99
|
+
if (!target) {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
const current = this.serializeHistorySnapshot();
|
|
103
|
+
this.restoreHistorySnapshot(target);
|
|
104
|
+
this.undoRedoManager.pushRedo(current);
|
|
105
|
+
this.emitUpdate();
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
redo() {
|
|
109
|
+
if (!this.undoRedoManager.canRedo()) {
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
const target = this.undoRedoManager.popRedo();
|
|
113
|
+
if (!target) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
const current = this.serializeHistorySnapshot();
|
|
117
|
+
this.restoreHistorySnapshot(target);
|
|
118
|
+
this.undoRedoManager.pushUndo(current);
|
|
119
|
+
this.emitUpdate();
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
canUndo() {
|
|
123
|
+
return this.undoRedoManager.canUndo();
|
|
124
|
+
}
|
|
125
|
+
canRedo() {
|
|
126
|
+
return this.undoRedoManager.canRedo();
|
|
127
|
+
}
|
|
128
|
+
getUndoRedoState() {
|
|
129
|
+
return this.undoRedoManager.getState();
|
|
130
|
+
}
|
|
131
|
+
clearUndoRedoHistory() {
|
|
132
|
+
this.undoRedoManager.clear();
|
|
133
|
+
}
|
|
134
|
+
transact(callback) {
|
|
135
|
+
return this.withUndoRedoCheckpoint(callback);
|
|
89
136
|
}
|
|
90
137
|
emitMutation(footprint) {
|
|
91
138
|
this.evaluationManager.invalidateFromMutation(footprint);
|
|
@@ -94,6 +141,21 @@ class FormulaEngine {
|
|
|
94
141
|
emitUpdate() {
|
|
95
142
|
this.eventManager.emitUpdate();
|
|
96
143
|
}
|
|
144
|
+
withUndoRedoCheckpoint(callback) {
|
|
145
|
+
if (this.historyCheckpointDepth > 0) {
|
|
146
|
+
return callback();
|
|
147
|
+
}
|
|
148
|
+
const before = this.serializeHistorySnapshot();
|
|
149
|
+
this.historyCheckpointDepth++;
|
|
150
|
+
try {
|
|
151
|
+
const result = callback();
|
|
152
|
+
const after = this.serializeHistorySnapshot();
|
|
153
|
+
this.undoRedoManager.recordMutation(before, after);
|
|
154
|
+
return result;
|
|
155
|
+
} finally {
|
|
156
|
+
this.historyCheckpointDepth--;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
97
159
|
getExistingSheetContent(opts) {
|
|
98
160
|
const sheet = this.workbookManager.getSheet(opts);
|
|
99
161
|
return sheet ? new Map(sheet.content) : undefined;
|
|
@@ -170,8 +232,10 @@ class FormulaEngine {
|
|
|
170
232
|
return this.evaluationManager.evaluationResultToSerializedValue(result, cellAddress, debug);
|
|
171
233
|
}
|
|
172
234
|
setCellMetadata(address, metadata) {
|
|
173
|
-
this.
|
|
174
|
-
|
|
235
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
236
|
+
this.workbookManager.setCellMetadata(address, metadata);
|
|
237
|
+
this.emitUpdate();
|
|
238
|
+
});
|
|
175
239
|
}
|
|
176
240
|
getCellMetadata(address) {
|
|
177
241
|
const metadata = this.workbookManager.getCellMetadata(address);
|
|
@@ -181,29 +245,37 @@ class FormulaEngine {
|
|
|
181
245
|
return this.workbookManager.getSheetMetadataSerialized(opts);
|
|
182
246
|
}
|
|
183
247
|
setSheetMetadata(opts, metadata) {
|
|
184
|
-
this.
|
|
185
|
-
|
|
248
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
249
|
+
this.workbookManager.setSheetMetadata(opts, metadata);
|
|
250
|
+
this.emitUpdate();
|
|
251
|
+
});
|
|
186
252
|
}
|
|
187
253
|
getSheetMetadata(opts) {
|
|
188
254
|
return this.workbookManager.getSheetMetadata(opts);
|
|
189
255
|
}
|
|
190
256
|
setWorkbookMetadata(workbookName, metadata) {
|
|
191
|
-
this.
|
|
192
|
-
|
|
257
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
258
|
+
this.workbookManager.setWorkbookMetadata(workbookName, metadata);
|
|
259
|
+
this.emitUpdate();
|
|
260
|
+
});
|
|
193
261
|
}
|
|
194
262
|
getWorkbookMetadata(workbookName) {
|
|
195
263
|
return this.workbookManager.getWorkbookMetadata(workbookName);
|
|
196
264
|
}
|
|
197
265
|
addRangeMetadata(metadata) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
266
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
267
|
+
const id = this.rangeMetadataManager.addRangeMetadata(metadata);
|
|
268
|
+
this.emitUpdate();
|
|
269
|
+
return id;
|
|
270
|
+
});
|
|
201
271
|
}
|
|
202
272
|
removeRangeMetadata(id) {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
273
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
274
|
+
const removed = this.rangeMetadataManager.removeRangeMetadata(id);
|
|
275
|
+
if (removed) {
|
|
276
|
+
this.emitUpdate();
|
|
277
|
+
}
|
|
278
|
+
});
|
|
207
279
|
}
|
|
208
280
|
getAllRangeMetadata() {
|
|
209
281
|
return this.rangeMetadataManager.getAllRangeMetadata();
|
|
@@ -215,17 +287,29 @@ class FormulaEngine {
|
|
|
215
287
|
return this.rangeMetadataManager.getRangeMetadataIntersectingWithRange(range);
|
|
216
288
|
}
|
|
217
289
|
clearRangeMetadata(range) {
|
|
218
|
-
this.
|
|
219
|
-
|
|
290
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
291
|
+
this.rangeMetadataManager.clearRangeMetadataInRange(range);
|
|
292
|
+
this.emitUpdate();
|
|
293
|
+
});
|
|
220
294
|
}
|
|
221
295
|
createRef(address) {
|
|
222
|
-
return this.
|
|
296
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
297
|
+
const id = this.referenceManager.createRef(address);
|
|
298
|
+
this.emitUpdate();
|
|
299
|
+
return id;
|
|
300
|
+
});
|
|
223
301
|
}
|
|
224
302
|
getRefAddress(refId) {
|
|
225
303
|
return this.referenceManager.getRefAddress(refId);
|
|
226
304
|
}
|
|
227
305
|
deleteRef(refId) {
|
|
228
|
-
return this.
|
|
306
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
307
|
+
const deleted = this.referenceManager.deleteRef(refId);
|
|
308
|
+
if (deleted) {
|
|
309
|
+
this.emitUpdate();
|
|
310
|
+
}
|
|
311
|
+
return deleted;
|
|
312
|
+
});
|
|
229
313
|
}
|
|
230
314
|
getInvalidRefs() {
|
|
231
315
|
return this.referenceManager.getInvalidRefs();
|
|
@@ -240,21 +324,25 @@ class FormulaEngine {
|
|
|
240
324
|
throw new Error("Not implemented");
|
|
241
325
|
}
|
|
242
326
|
addNamedExpression(opts) {
|
|
243
|
-
this.
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
touchedCells: [],
|
|
247
|
-
resourceKeys: [getNamedExpressionResourceKey(opts)]
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
removeNamedExpression(opts) {
|
|
251
|
-
const removed = this.namedExpressionManager.removeNamedExpression(opts);
|
|
252
|
-
if (removed) {
|
|
327
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
328
|
+
this.assertNamedExpressionScopeExists(opts);
|
|
329
|
+
this.namedExpressionManager.addNamedExpression(opts);
|
|
253
330
|
this.emitMutation({
|
|
254
331
|
touchedCells: [],
|
|
255
332
|
resourceKeys: [getNamedExpressionResourceKey(opts)]
|
|
256
333
|
});
|
|
257
|
-
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
removeNamedExpression(opts) {
|
|
337
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
338
|
+
const removed = this.namedExpressionManager.removeNamedExpression(opts);
|
|
339
|
+
if (removed) {
|
|
340
|
+
this.emitMutation({
|
|
341
|
+
touchedCells: [],
|
|
342
|
+
resourceKeys: [getNamedExpressionResourceKey(opts)]
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
});
|
|
258
346
|
}
|
|
259
347
|
hasNamedExpression(opts) {
|
|
260
348
|
const scope = opts.sheetName && opts.workbookName ? {
|
|
@@ -268,140 +356,130 @@ class FormulaEngine {
|
|
|
268
356
|
});
|
|
269
357
|
}
|
|
270
358
|
updateNamedExpression(opts) {
|
|
271
|
-
this.
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
359
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
360
|
+
this.namedExpressionManager.updateNamedExpression(opts);
|
|
361
|
+
this.emitMutation({
|
|
362
|
+
touchedCells: [],
|
|
363
|
+
resourceKeys: [getNamedExpressionResourceKey(opts)]
|
|
364
|
+
});
|
|
275
365
|
});
|
|
276
366
|
}
|
|
277
367
|
renameNamedExpression(opts) {
|
|
278
|
-
this.
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
368
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
369
|
+
this.namedExpressionManager.renameNamedExpression(opts);
|
|
370
|
+
const changedCells = this.workbookManager.updateAllFormulas((formula) => renameNamedExpressionInFormula(formula, opts.expressionName, opts.newName));
|
|
371
|
+
const changedNamedExpressions = this.namedExpressionManager.updateAllNamedExpressions((formula) => renameNamedExpressionInFormula(formula, opts.expressionName, opts.newName));
|
|
372
|
+
this.emitMutation({
|
|
373
|
+
touchedCells: buildFormulaTouchedCells(changedCells),
|
|
374
|
+
resourceKeys: [
|
|
375
|
+
getNamedExpressionResourceKey({
|
|
376
|
+
expressionName: opts.expressionName,
|
|
377
|
+
workbookName: opts.workbookName,
|
|
378
|
+
sheetName: opts.sheetName
|
|
379
|
+
}),
|
|
380
|
+
getNamedExpressionResourceKey({
|
|
381
|
+
expressionName: opts.newName,
|
|
382
|
+
workbookName: opts.workbookName,
|
|
383
|
+
sheetName: opts.sheetName
|
|
384
|
+
}),
|
|
385
|
+
...changedNamedExpressions
|
|
386
|
+
]
|
|
387
|
+
});
|
|
296
388
|
});
|
|
297
389
|
}
|
|
298
390
|
setNamedExpressions(opts) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
workbookName: opts.workbookName
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
391
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
392
|
+
const allExpressions = this.namedExpressionManager.getNamedExpressions();
|
|
393
|
+
let previousExpressions;
|
|
394
|
+
if (opts.type === "global") {
|
|
395
|
+
previousExpressions = new Map(allExpressions.globalExpressions);
|
|
396
|
+
} else if (opts.type === "workbook") {
|
|
397
|
+
previousExpressions = new Map(allExpressions.workbookExpressions.get(opts.workbookName) || []);
|
|
398
|
+
} else {
|
|
399
|
+
const sheetExpressions = allExpressions.sheetExpressions.get(opts.workbookName)?.get(opts.sheetName);
|
|
400
|
+
previousExpressions = new Map(sheetExpressions || []);
|
|
401
|
+
}
|
|
402
|
+
this.namedExpressionManager.setNamedExpressions(opts);
|
|
403
|
+
const scope = opts.type === "global" ? {} : opts.type === "workbook" ? { workbookName: opts.workbookName } : {
|
|
404
|
+
workbookName: opts.workbookName,
|
|
405
|
+
sheetName: opts.sheetName
|
|
406
|
+
};
|
|
407
|
+
this.emitMutation({
|
|
408
|
+
touchedCells: [],
|
|
409
|
+
resourceKeys: [
|
|
410
|
+
...getNamedExpressionScopeResourceKeys(previousExpressions.keys(), scope),
|
|
411
|
+
...getNamedExpressionScopeResourceKeys(opts.expressions.keys(), scope)
|
|
412
|
+
]
|
|
413
|
+
});
|
|
320
414
|
});
|
|
321
415
|
}
|
|
322
416
|
addTable(props) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
417
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
418
|
+
const table = this.tableManager.addTable({
|
|
419
|
+
...props,
|
|
420
|
+
getCellValue: (cellAddress) => this.getCellValue(cellAddress)
|
|
421
|
+
});
|
|
422
|
+
this.emitMutation({
|
|
423
|
+
touchedCells: buildTableTouchedCells(this.workbookManager, [table]),
|
|
424
|
+
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [table]),
|
|
425
|
+
resourceKeys: [
|
|
426
|
+
getTableResourceKey({
|
|
427
|
+
workbookName: props.workbookName,
|
|
428
|
+
tableName: props.tableName
|
|
429
|
+
})
|
|
430
|
+
]
|
|
431
|
+
});
|
|
336
432
|
});
|
|
337
433
|
}
|
|
338
434
|
renameTable(workbookName, names) {
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
435
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
436
|
+
const oldTable = this.tableManager.getTable({
|
|
437
|
+
workbookName,
|
|
438
|
+
name: names.oldName
|
|
439
|
+
});
|
|
440
|
+
const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
|
|
441
|
+
this.tableManager.renameTable(workbookName, names);
|
|
442
|
+
const changedCells = this.workbookManager.updateAllFormulas((formula) => renameTableInFormula(formula, names.oldName, names.newName));
|
|
443
|
+
const changedNamedExpressions = this.namedExpressionManager.updateAllNamedExpressions((formula) => renameTableInFormula(formula, names.oldName, names.newName));
|
|
444
|
+
const newTable = this.tableManager.getTable({
|
|
445
|
+
workbookName,
|
|
446
|
+
name: names.newName
|
|
447
|
+
});
|
|
448
|
+
this.emitMutation({
|
|
449
|
+
touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, [oldTableSnapshot]), buildTableTouchedCells(this.workbookManager, [newTable]), buildFormulaTouchedCells(changedCells)),
|
|
450
|
+
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot, newTable]),
|
|
451
|
+
resourceKeys: [
|
|
452
|
+
getTableResourceKey({
|
|
453
|
+
workbookName,
|
|
454
|
+
tableName: names.oldName
|
|
455
|
+
}),
|
|
456
|
+
getTableResourceKey({
|
|
457
|
+
workbookName,
|
|
458
|
+
tableName: names.newName
|
|
459
|
+
}),
|
|
460
|
+
...changedNamedExpressions
|
|
461
|
+
]
|
|
462
|
+
});
|
|
365
463
|
});
|
|
366
464
|
}
|
|
367
465
|
updateTable(opts) {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, [oldTableSnapshot]), buildTableTouchedCells(this.workbookManager, [newTable])),
|
|
383
|
-
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot, newTable]),
|
|
384
|
-
resourceKeys: [
|
|
385
|
-
getTableResourceKey({
|
|
386
|
-
workbookName: opts.workbookName,
|
|
387
|
-
tableName: opts.tableName
|
|
388
|
-
})
|
|
389
|
-
]
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
removeTable(opts) {
|
|
393
|
-
const oldTable = this.tableManager.getTable({
|
|
394
|
-
workbookName: opts.workbookName,
|
|
395
|
-
name: opts.tableName
|
|
396
|
-
});
|
|
397
|
-
const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
|
|
398
|
-
const found = this.tableManager.removeTable(opts);
|
|
399
|
-
if (found) {
|
|
466
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
467
|
+
const oldTable = this.tableManager.getTable({
|
|
468
|
+
workbookName: opts.workbookName,
|
|
469
|
+
name: opts.tableName
|
|
470
|
+
});
|
|
471
|
+
const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
|
|
472
|
+
this.tableManager.updateTable({
|
|
473
|
+
...opts,
|
|
474
|
+
getCellValue: (cellAddress) => this.getCellValue(cellAddress)
|
|
475
|
+
});
|
|
476
|
+
const newTable = this.tableManager.getTable({
|
|
477
|
+
workbookName: opts.workbookName,
|
|
478
|
+
name: opts.tableName
|
|
479
|
+
});
|
|
400
480
|
this.emitMutation({
|
|
401
|
-
touchedCells: buildTableTouchedCells(this.workbookManager, [
|
|
402
|
-
|
|
403
|
-
]),
|
|
404
|
-
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot]),
|
|
481
|
+
touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, [oldTableSnapshot]), buildTableTouchedCells(this.workbookManager, [newTable])),
|
|
482
|
+
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot, newTable]),
|
|
405
483
|
resourceKeys: [
|
|
406
484
|
getTableResourceKey({
|
|
407
485
|
workbookName: opts.workbookName,
|
|
@@ -409,7 +487,31 @@ class FormulaEngine {
|
|
|
409
487
|
})
|
|
410
488
|
]
|
|
411
489
|
});
|
|
412
|
-
}
|
|
490
|
+
});
|
|
491
|
+
}
|
|
492
|
+
removeTable(opts) {
|
|
493
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
494
|
+
const oldTable = this.tableManager.getTable({
|
|
495
|
+
workbookName: opts.workbookName,
|
|
496
|
+
name: opts.tableName
|
|
497
|
+
});
|
|
498
|
+
const oldTableSnapshot = oldTable ? { ...oldTable, headers: new Map(oldTable.headers) } : undefined;
|
|
499
|
+
const found = this.tableManager.removeTable(opts);
|
|
500
|
+
if (found) {
|
|
501
|
+
this.emitMutation({
|
|
502
|
+
touchedCells: buildTableTouchedCells(this.workbookManager, [
|
|
503
|
+
oldTableSnapshot
|
|
504
|
+
]),
|
|
505
|
+
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [oldTableSnapshot]),
|
|
506
|
+
resourceKeys: [
|
|
507
|
+
getTableResourceKey({
|
|
508
|
+
workbookName: opts.workbookName,
|
|
509
|
+
tableName: opts.tableName
|
|
510
|
+
})
|
|
511
|
+
]
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
});
|
|
413
515
|
}
|
|
414
516
|
getAllTables() {
|
|
415
517
|
return Array.from(this.tableManager.tables.values()).flatMap((tables) => Array.from(tables.values()).map((table) => ({
|
|
@@ -430,20 +532,22 @@ class FormulaEngine {
|
|
|
430
532
|
});
|
|
431
533
|
}
|
|
432
534
|
resetTables(tables) {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
535
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
536
|
+
const oldTables = this.getAllTables();
|
|
537
|
+
const newTables = Array.from(tables.values()).flatMap((workbookTables) => Array.from(workbookTables.values()));
|
|
538
|
+
const resourceKeys = new Set;
|
|
539
|
+
for (const table of [...oldTables, ...newTables]) {
|
|
540
|
+
resourceKeys.add(getTableResourceKey({
|
|
541
|
+
workbookName: table.workbookName,
|
|
542
|
+
tableName: table.name
|
|
543
|
+
}));
|
|
544
|
+
}
|
|
545
|
+
this.tableManager.resetTables(tables);
|
|
546
|
+
this.emitMutation({
|
|
547
|
+
touchedCells: mergeTouchedCells(buildTableTouchedCells(this.workbookManager, oldTables), buildTableTouchedCells(this.workbookManager, newTables)),
|
|
548
|
+
tableContextChangedCells: buildTableContextChangedCells(this.workbookManager, [...oldTables, ...newTables]),
|
|
549
|
+
resourceKeys: Array.from(resourceKeys)
|
|
550
|
+
});
|
|
447
551
|
});
|
|
448
552
|
}
|
|
449
553
|
getTables(workbookName) {
|
|
@@ -453,14 +557,18 @@ class FormulaEngine {
|
|
|
453
557
|
return this.tableManager.isCellInTable(cellAddress);
|
|
454
558
|
}
|
|
455
559
|
addConditionalStyle(style) {
|
|
456
|
-
this.
|
|
457
|
-
|
|
560
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
561
|
+
this.styleManager.addConditionalStyle(style);
|
|
562
|
+
this.emitUpdate();
|
|
563
|
+
});
|
|
458
564
|
}
|
|
459
565
|
removeConditionalStyle(workbookName, index) {
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
566
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
567
|
+
const removed = this.styleManager.removeConditionalStyle(workbookName, index);
|
|
568
|
+
if (removed) {
|
|
569
|
+
this.emitUpdate();
|
|
570
|
+
}
|
|
571
|
+
});
|
|
464
572
|
}
|
|
465
573
|
getConditionalStyleCount(workbookName) {
|
|
466
574
|
const allStyles = this.styleManager.getAllConditionalStyles();
|
|
@@ -479,14 +587,18 @@ class FormulaEngine {
|
|
|
479
587
|
return this.styleManager.getAllConditionalStyles();
|
|
480
588
|
}
|
|
481
589
|
addCellStyle(style) {
|
|
482
|
-
this.
|
|
483
|
-
|
|
590
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
591
|
+
this.styleManager.addCellStyle(style);
|
|
592
|
+
this.emitUpdate();
|
|
593
|
+
});
|
|
484
594
|
}
|
|
485
595
|
removeCellStyle(workbookName, index) {
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
596
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
597
|
+
const removed = this.styleManager.removeCellStyle(workbookName, index);
|
|
598
|
+
if (removed) {
|
|
599
|
+
this.emitUpdate();
|
|
600
|
+
}
|
|
601
|
+
});
|
|
490
602
|
}
|
|
491
603
|
getCellStyleCount(workbookName) {
|
|
492
604
|
const allStyles = this.styleManager.getAllCellStyles();
|
|
@@ -499,8 +611,10 @@ class FormulaEngine {
|
|
|
499
611
|
return this.styleManager.getStyleForRange(range);
|
|
500
612
|
}
|
|
501
613
|
clearCellStyles(range) {
|
|
502
|
-
this.
|
|
503
|
-
|
|
614
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
615
|
+
this.styleManager.clearCellStyles(range);
|
|
616
|
+
this.emitUpdate();
|
|
617
|
+
});
|
|
504
618
|
}
|
|
505
619
|
getTopLeftCell(cells) {
|
|
506
620
|
let topLeft = cells[0];
|
|
@@ -530,100 +644,106 @@ class FormulaEngine {
|
|
|
530
644
|
return this.dedupeAddresses(options.cut ? [...source, ...targetCells] : targetCells);
|
|
531
645
|
}
|
|
532
646
|
pasteCells(source, target, options) {
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
address
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
647
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
648
|
+
if (source.length === 0) {
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
const touchedAddresses = this.getPasteTouchedAddresses(source, target, options);
|
|
652
|
+
const before = captureCellContents(this.workbookManager, touchedAddresses);
|
|
653
|
+
this.copyManager.pasteCells(source, target, options);
|
|
654
|
+
const after = captureCellContents(this.workbookManager, touchedAddresses);
|
|
655
|
+
this.emitMutation({
|
|
656
|
+
touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
|
|
657
|
+
address,
|
|
658
|
+
before: before.get(getMutationAddressKey(address)),
|
|
659
|
+
after: after.get(getMutationAddressKey(address))
|
|
660
|
+
}))),
|
|
661
|
+
resourceKeys: []
|
|
662
|
+
});
|
|
547
663
|
});
|
|
548
664
|
}
|
|
549
665
|
fillAreas(seedRange, targetRanges, options) {
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
address
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
666
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
667
|
+
const touchedAddresses = this.dedupeAddresses([
|
|
668
|
+
...targetRanges.flatMap((targetRange) => getFiniteRangeAddresses(targetRange)),
|
|
669
|
+
...options.cut ? getFiniteRangeAddresses(seedRange) : []
|
|
670
|
+
]);
|
|
671
|
+
const before = captureCellContents(this.workbookManager, touchedAddresses);
|
|
672
|
+
this.copyManager.fillAreas(seedRange, targetRanges, options);
|
|
673
|
+
const after = captureCellContents(this.workbookManager, touchedAddresses);
|
|
674
|
+
this.emitMutation({
|
|
675
|
+
touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
|
|
676
|
+
address,
|
|
677
|
+
before: before.get(getMutationAddressKey(address)),
|
|
678
|
+
after: after.get(getMutationAddressKey(address))
|
|
679
|
+
}))),
|
|
680
|
+
resourceKeys: []
|
|
681
|
+
});
|
|
564
682
|
});
|
|
565
683
|
}
|
|
566
684
|
smartPaste(sourceCells, pasteSelection, options) {
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
if (options.cut === true) {
|
|
571
|
-
for (const area of pasteSelection.areas) {
|
|
572
|
-
const target = {
|
|
573
|
-
workbookName: pasteSelection.workbookName,
|
|
574
|
-
sheetName: pasteSelection.sheetName,
|
|
575
|
-
colIndex: area.start.col,
|
|
576
|
-
rowIndex: area.start.row
|
|
577
|
-
};
|
|
578
|
-
this.pasteCells(sourceCells, target, options);
|
|
685
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
686
|
+
if (sourceCells.length === 0) {
|
|
687
|
+
return;
|
|
579
688
|
}
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
start: { col: sourceBounds.minCol, row: sourceBounds.minRow },
|
|
590
|
-
end: {
|
|
591
|
-
col: { type: "number", value: sourceBounds.maxCol },
|
|
592
|
-
row: { type: "number", value: sourceBounds.maxRow }
|
|
689
|
+
if (options.cut === true) {
|
|
690
|
+
for (const area of pasteSelection.areas) {
|
|
691
|
+
const target = {
|
|
692
|
+
workbookName: pasteSelection.workbookName,
|
|
693
|
+
sheetName: pasteSelection.sheetName,
|
|
694
|
+
colIndex: area.start.col,
|
|
695
|
+
rowIndex: area.start.row
|
|
696
|
+
};
|
|
697
|
+
this.pasteCells(sourceCells, target, options);
|
|
593
698
|
}
|
|
699
|
+
return;
|
|
594
700
|
}
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
const
|
|
598
|
-
const
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
workbookName: pasteSelection.workbookName,
|
|
607
|
-
sheetName: pasteSelection.sheetName,
|
|
608
|
-
range: {
|
|
609
|
-
start: { col: pasteStartCol, row: pasteStartRow },
|
|
610
|
-
end: {
|
|
611
|
-
col: { type: "number", value: pasteEndCol },
|
|
612
|
-
row: { type: "number", value: pasteEndRow }
|
|
613
|
-
}
|
|
701
|
+
const sourceBounds = this.getBoundsFromCells(sourceCells);
|
|
702
|
+
const sourceWidth = sourceBounds.maxCol - sourceBounds.minCol + 1;
|
|
703
|
+
const sourceHeight = sourceBounds.maxRow - sourceBounds.minRow + 1;
|
|
704
|
+
const seedRange = {
|
|
705
|
+
workbookName: sourceCells[0].workbookName,
|
|
706
|
+
sheetName: sourceCells[0].sheetName,
|
|
707
|
+
range: {
|
|
708
|
+
start: { col: sourceBounds.minCol, row: sourceBounds.minRow },
|
|
709
|
+
end: {
|
|
710
|
+
col: { type: "number", value: sourceBounds.maxCol },
|
|
711
|
+
row: { type: "number", value: sourceBounds.maxRow }
|
|
614
712
|
}
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
for (const area of pasteSelection.areas) {
|
|
716
|
+
const pasteStartCol = area.start.col;
|
|
717
|
+
const pasteStartRow = area.start.row;
|
|
718
|
+
const pasteEndCol = area.end.col.type === "number" ? area.end.col.value : pasteStartCol;
|
|
719
|
+
const pasteEndRow = area.end.row.type === "number" ? area.end.row.value : pasteStartRow;
|
|
720
|
+
const pasteWidth = pasteEndCol - pasteStartCol + 1;
|
|
721
|
+
const pasteHeight = pasteEndRow - pasteStartRow + 1;
|
|
722
|
+
const shouldFill = pasteWidth > sourceWidth || pasteHeight > sourceHeight;
|
|
723
|
+
if (shouldFill) {
|
|
724
|
+
const targetRange = {
|
|
725
|
+
workbookName: pasteSelection.workbookName,
|
|
726
|
+
sheetName: pasteSelection.sheetName,
|
|
727
|
+
range: {
|
|
728
|
+
start: { col: pasteStartCol, row: pasteStartRow },
|
|
729
|
+
end: {
|
|
730
|
+
col: { type: "number", value: pasteEndCol },
|
|
731
|
+
row: { type: "number", value: pasteEndRow }
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
};
|
|
735
|
+
this.fillAreas(seedRange, [targetRange], options);
|
|
736
|
+
} else {
|
|
737
|
+
const target = {
|
|
738
|
+
workbookName: pasteSelection.workbookName,
|
|
739
|
+
sheetName: pasteSelection.sheetName,
|
|
740
|
+
colIndex: pasteStartCol,
|
|
741
|
+
rowIndex: pasteStartRow
|
|
742
|
+
};
|
|
743
|
+
this.pasteCells(sourceCells, target, options);
|
|
744
|
+
}
|
|
625
745
|
}
|
|
626
|
-
}
|
|
746
|
+
});
|
|
627
747
|
}
|
|
628
748
|
getBoundsFromCells(cells) {
|
|
629
749
|
if (cells.length === 0) {
|
|
@@ -642,72 +762,84 @@ class FormulaEngine {
|
|
|
642
762
|
return { minCol, minRow, maxCol, maxRow };
|
|
643
763
|
}
|
|
644
764
|
moveCell(source, target) {
|
|
645
|
-
this.
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
765
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
766
|
+
this.pasteCells([source], target, {
|
|
767
|
+
cut: true,
|
|
768
|
+
type: "formula",
|
|
769
|
+
include: "all"
|
|
770
|
+
});
|
|
649
771
|
});
|
|
650
772
|
}
|
|
651
773
|
moveRange(sourceRange, target) {
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
774
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
775
|
+
const cells = this.copyManager.expandRangeToCells(sourceRange);
|
|
776
|
+
this.pasteCells(cells, target, {
|
|
777
|
+
cut: true,
|
|
778
|
+
type: "formula",
|
|
779
|
+
include: "all"
|
|
780
|
+
});
|
|
657
781
|
});
|
|
658
782
|
}
|
|
659
783
|
addSheet(opts) {
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
784
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
785
|
+
const sheet = this.workbookManager.addSheet(opts);
|
|
786
|
+
this.namedExpressionManager.addSheet(opts);
|
|
787
|
+
this.emitMutation({
|
|
788
|
+
touchedCells: [],
|
|
789
|
+
resourceKeys: [getSheetResourceKey(opts)]
|
|
790
|
+
});
|
|
791
|
+
return sheet;
|
|
665
792
|
});
|
|
666
|
-
return sheet;
|
|
667
793
|
}
|
|
668
794
|
createSheet(opts) {
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
795
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
796
|
+
const sheetName = opts.sheetName ?? this.workbookManager.getNextAvailableSheetName(opts.workbookName, opts.baseName);
|
|
797
|
+
return this.addSheet({
|
|
798
|
+
workbookName: opts.workbookName,
|
|
799
|
+
sheetName
|
|
800
|
+
});
|
|
673
801
|
});
|
|
674
802
|
}
|
|
675
803
|
removeSheet(opts) {
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
804
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
805
|
+
const resourceKeys = this.getSheetResourceKeys(opts);
|
|
806
|
+
this.workbookManager.removeSheet(opts);
|
|
807
|
+
this.namedExpressionManager.removeSheet(opts);
|
|
808
|
+
this.tableManager.removeSheet(opts);
|
|
809
|
+
this.styleManager.removeSheetStyles(opts.workbookName, opts.sheetName);
|
|
810
|
+
this.rangeMetadataManager.removeSheetRangeMetadata(opts.workbookName, opts.sheetName);
|
|
811
|
+
this.referenceManager.invalidateSheet(opts.workbookName, opts.sheetName);
|
|
812
|
+
this.emitMutation({
|
|
813
|
+
touchedCells: [],
|
|
814
|
+
resourceKeys,
|
|
815
|
+
removedScopes: [{ type: "sheet", ...opts }]
|
|
816
|
+
});
|
|
687
817
|
});
|
|
688
818
|
}
|
|
689
819
|
renameSheet(opts) {
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
formula
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
820
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
821
|
+
const oldResourceKeys = this.getSheetResourceKeys(opts);
|
|
822
|
+
this.workbookManager.renameSheet(opts);
|
|
823
|
+
this.namedExpressionManager.renameSheet(opts);
|
|
824
|
+
this.tableManager.updateTablesForSheetRename(opts);
|
|
825
|
+
this.styleManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
|
|
826
|
+
this.rangeMetadataManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
|
|
827
|
+
const changedCells = this.workbookManager.updateAllFormulas((formula) => renameSheetInFormula({
|
|
828
|
+
formula,
|
|
829
|
+
oldSheetName: opts.sheetName,
|
|
830
|
+
newSheetName: opts.newSheetName
|
|
831
|
+
}));
|
|
832
|
+
this.referenceManager.updateSheetName(opts.workbookName, opts.sheetName, opts.newSheetName);
|
|
833
|
+
this.emitMutation({
|
|
834
|
+
touchedCells: buildFormulaTouchedCells(changedCells),
|
|
835
|
+
resourceKeys: Array.from(new Set([
|
|
836
|
+
...oldResourceKeys,
|
|
837
|
+
...this.getSheetResourceKeys({
|
|
838
|
+
workbookName: opts.workbookName,
|
|
839
|
+
sheetName: opts.newSheetName
|
|
840
|
+
})
|
|
841
|
+
]))
|
|
842
|
+
});
|
|
711
843
|
});
|
|
712
844
|
}
|
|
713
845
|
hasSheet(opts) {
|
|
@@ -738,239 +870,259 @@ class FormulaEngine {
|
|
|
738
870
|
return this.workbookManager.search(query, options);
|
|
739
871
|
}
|
|
740
872
|
replace(query, replacement, target, options) {
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
873
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
874
|
+
const prepared = this.workbookManager.prepareReplace(query, replacement, target, options);
|
|
875
|
+
this.workbookManager.setCellContent(prepared.address, prepared.afterContent);
|
|
876
|
+
this.emitMutation({
|
|
877
|
+
touchedCells: buildTouchedCells([
|
|
878
|
+
{
|
|
879
|
+
address: prepared.address,
|
|
880
|
+
before: prepared.beforeContent,
|
|
881
|
+
after: prepared.afterContent
|
|
882
|
+
}
|
|
883
|
+
]),
|
|
884
|
+
resourceKeys: []
|
|
885
|
+
});
|
|
886
|
+
return prepared.change;
|
|
752
887
|
});
|
|
753
|
-
return prepared.change;
|
|
754
888
|
}
|
|
755
889
|
replaceAll(query, replacement, options) {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
890
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
891
|
+
const preparedReplacements = this.workbookManager.prepareReplaceAll(query, replacement, options);
|
|
892
|
+
if (preparedReplacements.length === 0) {
|
|
893
|
+
return [];
|
|
894
|
+
}
|
|
895
|
+
for (const prepared of preparedReplacements) {
|
|
896
|
+
this.workbookManager.setCellContent(prepared.address, prepared.afterContent);
|
|
897
|
+
}
|
|
898
|
+
this.emitMutation({
|
|
899
|
+
touchedCells: buildTouchedCells(preparedReplacements.map((prepared) => ({
|
|
900
|
+
address: prepared.address,
|
|
901
|
+
before: prepared.beforeContent,
|
|
902
|
+
after: prepared.afterContent
|
|
903
|
+
}))),
|
|
904
|
+
resourceKeys: []
|
|
905
|
+
});
|
|
906
|
+
return preparedReplacements.flatMap((prepared) => prepared.changes);
|
|
770
907
|
});
|
|
771
|
-
return preparedReplacements.flatMap((prepared) => prepared.changes);
|
|
772
908
|
}
|
|
773
909
|
addWorkbook(workbookName) {
|
|
774
|
-
this.
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
910
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
911
|
+
this.workbookManager.addWorkbook(workbookName);
|
|
912
|
+
this.namedExpressionManager.addWorkbook(workbookName);
|
|
913
|
+
this.tableManager.addWorkbook(workbookName);
|
|
914
|
+
this.emitMutation({
|
|
915
|
+
touchedCells: [],
|
|
916
|
+
resourceKeys: [getWorkbookResourceKey(workbookName)]
|
|
917
|
+
});
|
|
780
918
|
});
|
|
781
919
|
}
|
|
782
920
|
removeWorkbook(workbookName) {
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
921
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
922
|
+
const resourceKeys = this.getWorkbookResourceKeys(workbookName);
|
|
923
|
+
this.workbookManager.removeWorkbook(workbookName);
|
|
924
|
+
this.namedExpressionManager.removeWorkbook(workbookName);
|
|
925
|
+
this.tableManager.removeWorkbook(workbookName);
|
|
926
|
+
this.styleManager.removeWorkbookStyles(workbookName);
|
|
927
|
+
this.rangeMetadataManager.removeWorkbookRangeMetadata(workbookName);
|
|
928
|
+
this.referenceManager.invalidateWorkbook(workbookName);
|
|
929
|
+
this.emitMutation({
|
|
930
|
+
touchedCells: [],
|
|
931
|
+
resourceKeys,
|
|
932
|
+
removedScopes: [{ type: "workbook", workbookName }]
|
|
933
|
+
});
|
|
794
934
|
});
|
|
795
935
|
}
|
|
796
936
|
hasWorkbook(workbookName) {
|
|
797
937
|
return this.workbookManager.getWorkbooks().has(workbookName);
|
|
798
938
|
}
|
|
799
939
|
cloneWorkbook(fromWorkbookName, toWorkbookName) {
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
if (this.workbookManager.getWorkbooks().has(toWorkbookName)) {
|
|
805
|
-
throw new Error(`Target workbook "${toWorkbookName}" already exists`);
|
|
806
|
-
}
|
|
807
|
-
this.workbookManager.addWorkbook(toWorkbookName);
|
|
808
|
-
this.namedExpressionManager.addWorkbook(toWorkbookName);
|
|
809
|
-
this.tableManager.addWorkbook(toWorkbookName);
|
|
810
|
-
for (const [sheetName, sheet] of sourceWorkbook.sheets) {
|
|
811
|
-
this.workbookManager.addSheet({
|
|
812
|
-
workbookName: toWorkbookName,
|
|
813
|
-
sheetName
|
|
814
|
-
});
|
|
815
|
-
this.namedExpressionManager.addSheet({
|
|
816
|
-
workbookName: toWorkbookName,
|
|
817
|
-
sheetName
|
|
818
|
-
});
|
|
819
|
-
this.workbookManager.setSheetContent({ workbookName: toWorkbookName, sheetName }, new Map(sheet.content));
|
|
820
|
-
const targetSheet = this.workbookManager.getSheet({
|
|
821
|
-
workbookName: toWorkbookName,
|
|
822
|
-
sheetName
|
|
823
|
-
});
|
|
824
|
-
if (targetSheet) {
|
|
825
|
-
targetSheet.metadata = new Map(sheet.metadata);
|
|
826
|
-
if (sheet.sheetMetadata !== undefined) {
|
|
827
|
-
targetSheet.sheetMetadata = structuredClone(sheet.sheetMetadata);
|
|
828
|
-
}
|
|
940
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
941
|
+
const sourceWorkbook = this.workbookManager.getWorkbooks().get(fromWorkbookName);
|
|
942
|
+
if (!sourceWorkbook) {
|
|
943
|
+
throw new Error(`Source workbook "${fromWorkbookName}" not found`);
|
|
829
944
|
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
workbookName: toWorkbookName
|
|
945
|
+
if (this.workbookManager.getWorkbooks().has(toWorkbookName)) {
|
|
946
|
+
throw new Error(`Target workbook "${toWorkbookName}" already exists`);
|
|
947
|
+
}
|
|
948
|
+
this.workbookManager.addWorkbook(toWorkbookName);
|
|
949
|
+
this.namedExpressionManager.addWorkbook(toWorkbookName);
|
|
950
|
+
this.tableManager.addWorkbook(toWorkbookName);
|
|
951
|
+
for (const [sheetName, sheet] of sourceWorkbook.sheets) {
|
|
952
|
+
this.workbookManager.addSheet({
|
|
953
|
+
workbookName: toWorkbookName,
|
|
954
|
+
sheetName
|
|
955
|
+
});
|
|
956
|
+
this.namedExpressionManager.addSheet({
|
|
957
|
+
workbookName: toWorkbookName,
|
|
958
|
+
sheetName
|
|
959
|
+
});
|
|
960
|
+
this.workbookManager.setSheetContent({ workbookName: toWorkbookName, sheetName }, new Map(sheet.content));
|
|
961
|
+
const targetSheet = this.workbookManager.getSheet({
|
|
962
|
+
workbookName: toWorkbookName,
|
|
963
|
+
sheetName
|
|
843
964
|
});
|
|
965
|
+
if (targetSheet) {
|
|
966
|
+
targetSheet.metadata = new Map(sheet.metadata);
|
|
967
|
+
if (sheet.sheetMetadata !== undefined) {
|
|
968
|
+
targetSheet.sheetMetadata = structuredClone(sheet.sheetMetadata);
|
|
969
|
+
}
|
|
970
|
+
}
|
|
844
971
|
}
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
972
|
+
const targetWorkbook = this.workbookManager.getWorkbooks().get(toWorkbookName);
|
|
973
|
+
if (targetWorkbook && sourceWorkbook.workbookMetadata !== undefined) {
|
|
974
|
+
targetWorkbook.workbookMetadata = structuredClone(sourceWorkbook.workbookMetadata);
|
|
975
|
+
}
|
|
976
|
+
const namedExpressions = this.namedExpressionManager.getNamedExpressions();
|
|
977
|
+
const sourceWorkbookExpressions = namedExpressions.workbookExpressions.get(fromWorkbookName);
|
|
978
|
+
if (sourceWorkbookExpressions) {
|
|
979
|
+
for (const [expressionName, expression] of sourceWorkbookExpressions) {
|
|
850
980
|
this.namedExpressionManager.addNamedExpression({
|
|
851
981
|
expressionName,
|
|
852
982
|
expression: expression.expression,
|
|
853
|
-
workbookName: toWorkbookName
|
|
854
|
-
sheetName
|
|
983
|
+
workbookName: toWorkbookName
|
|
855
984
|
});
|
|
856
985
|
}
|
|
857
986
|
}
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
987
|
+
const sourceSheetExpressions = namedExpressions.sheetExpressions.get(fromWorkbookName);
|
|
988
|
+
if (sourceSheetExpressions) {
|
|
989
|
+
for (const [sheetName, expressions] of sourceSheetExpressions) {
|
|
990
|
+
for (const [expressionName, expression] of expressions) {
|
|
991
|
+
this.namedExpressionManager.addNamedExpression({
|
|
992
|
+
expressionName,
|
|
993
|
+
expression: expression.expression,
|
|
994
|
+
workbookName: toWorkbookName,
|
|
995
|
+
sheetName
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
}
|
|
863
999
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
areas: style.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
|
|
870
|
-
});
|
|
1000
|
+
const sourceTables = this.tableManager.tables.get(fromWorkbookName);
|
|
1001
|
+
if (sourceTables) {
|
|
1002
|
+
for (const [tableName] of sourceTables) {
|
|
1003
|
+
this.tableManager.copyTable({ workbookName: fromWorkbookName, tableName }, { workbookName: toWorkbookName, tableName });
|
|
1004
|
+
}
|
|
871
1005
|
}
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
}
|
|
1006
|
+
for (const style of this.styleManager.getAllConditionalStyles()) {
|
|
1007
|
+
if (style.areas.some((area) => area.workbookName === fromWorkbookName)) {
|
|
1008
|
+
this.styleManager.addConditionalStyle({
|
|
1009
|
+
...style,
|
|
1010
|
+
areas: style.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
879
1013
|
}
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
}
|
|
1014
|
+
for (const style of this.styleManager.getAllCellStyles()) {
|
|
1015
|
+
if (style.areas.some((area) => area.workbookName === fromWorkbookName)) {
|
|
1016
|
+
this.styleManager.addCellStyle({
|
|
1017
|
+
...style,
|
|
1018
|
+
areas: style.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
887
1021
|
}
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
1022
|
+
for (const metadata of this.rangeMetadataManager.getAllRangeMetadata()) {
|
|
1023
|
+
if (metadata.areas.some((area) => area.workbookName === fromWorkbookName)) {
|
|
1024
|
+
this.rangeMetadataManager.addRangeMetadata({
|
|
1025
|
+
metadata: metadata.metadata,
|
|
1026
|
+
areas: metadata.areas.map((area) => area.workbookName === fromWorkbookName ? { ...area, workbookName: toWorkbookName } : area)
|
|
1027
|
+
});
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
this.workbookManager.updateFormulasForWorkbook(toWorkbookName, (formula) => renameWorkbookInFormula({
|
|
1031
|
+
formula,
|
|
1032
|
+
oldWorkbookName: fromWorkbookName,
|
|
1033
|
+
newWorkbookName: toWorkbookName
|
|
1034
|
+
}));
|
|
1035
|
+
this.emitMutation({
|
|
1036
|
+
touchedCells: [],
|
|
1037
|
+
resourceKeys: [getWorkbookResourceKey(toWorkbookName)]
|
|
1038
|
+
});
|
|
897
1039
|
});
|
|
898
1040
|
}
|
|
899
1041
|
renameWorkbook(opts) {
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
formula
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
1042
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
1043
|
+
const oldResourceKeys = this.getWorkbookResourceKeys(opts.workbookName);
|
|
1044
|
+
this.workbookManager.renameWorkbook(opts);
|
|
1045
|
+
this.namedExpressionManager.renameWorkbook(opts);
|
|
1046
|
+
this.tableManager.updateTablesForWorkbookRename(opts);
|
|
1047
|
+
this.styleManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
|
|
1048
|
+
this.rangeMetadataManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
|
|
1049
|
+
const changedCells = this.workbookManager.updateAllFormulas((formula) => renameWorkbookInFormula({
|
|
1050
|
+
formula,
|
|
1051
|
+
oldWorkbookName: opts.workbookName,
|
|
1052
|
+
newWorkbookName: opts.newWorkbookName
|
|
1053
|
+
}));
|
|
1054
|
+
this.referenceManager.updateWorkbookName(opts.workbookName, opts.newWorkbookName);
|
|
1055
|
+
this.emitMutation({
|
|
1056
|
+
touchedCells: buildFormulaTouchedCells(changedCells),
|
|
1057
|
+
resourceKeys: Array.from(new Set([
|
|
1058
|
+
...oldResourceKeys,
|
|
1059
|
+
...this.getWorkbookResourceKeys(opts.newWorkbookName)
|
|
1060
|
+
]))
|
|
1061
|
+
});
|
|
918
1062
|
});
|
|
919
1063
|
}
|
|
920
1064
|
getWorkbooks() {
|
|
921
1065
|
return this.workbookManager.getWorkbooks();
|
|
922
1066
|
}
|
|
923
1067
|
setSheetContent(opts, content) {
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1068
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
1069
|
+
const previousContent = this.getExistingSheetContent(opts);
|
|
1070
|
+
this.workbookManager.setSheetContent(opts, content);
|
|
1071
|
+
this.emitMutation({
|
|
1072
|
+
touchedCells: buildSheetContentTouchedCells(opts, previousContent, content),
|
|
1073
|
+
resourceKeys: []
|
|
1074
|
+
});
|
|
929
1075
|
});
|
|
930
1076
|
}
|
|
931
1077
|
setCellContent(address, content) {
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
1078
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
1079
|
+
const previousValue = this.workbookManager.getCellContent(address);
|
|
1080
|
+
this.workbookManager.setCellContent(address, content);
|
|
1081
|
+
this.emitMutation({
|
|
1082
|
+
touchedCells: buildTouchedCells([
|
|
1083
|
+
{
|
|
1084
|
+
address,
|
|
1085
|
+
before: previousValue,
|
|
1086
|
+
after: content
|
|
1087
|
+
}
|
|
1088
|
+
]),
|
|
1089
|
+
resourceKeys: []
|
|
1090
|
+
});
|
|
943
1091
|
});
|
|
944
1092
|
}
|
|
945
1093
|
autoFill(opts, seedRange, fillRanges, direction) {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
address
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
1094
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
1095
|
+
const touchedAddresses = this.dedupeAddresses(fillRanges.flatMap((range) => getFiniteRangeAddresses({
|
|
1096
|
+
workbookName: opts.workbookName,
|
|
1097
|
+
sheetName: opts.sheetName,
|
|
1098
|
+
range
|
|
1099
|
+
})));
|
|
1100
|
+
const before = captureCellContents(this.workbookManager, touchedAddresses);
|
|
1101
|
+
this.autoFillManager.fill(opts, seedRange, fillRanges, direction);
|
|
1102
|
+
const after = captureCellContents(this.workbookManager, touchedAddresses);
|
|
1103
|
+
this.emitMutation({
|
|
1104
|
+
touchedCells: buildTouchedCells(touchedAddresses.map((address) => ({
|
|
1105
|
+
address,
|
|
1106
|
+
before: before.get(getMutationAddressKey(address)),
|
|
1107
|
+
after: after.get(getMutationAddressKey(address))
|
|
1108
|
+
}))),
|
|
1109
|
+
resourceKeys: []
|
|
1110
|
+
});
|
|
961
1111
|
});
|
|
962
1112
|
}
|
|
963
1113
|
clearSpreadsheetRange(address) {
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1114
|
+
return this.withUndoRedoCheckpoint(() => {
|
|
1115
|
+
const clearedCells = Array.from(this.workbookManager.iterateCellsInRange(address));
|
|
1116
|
+
const before = captureCellContents(this.workbookManager, clearedCells);
|
|
1117
|
+
this.workbookManager.clearSpreadsheetRange(address);
|
|
1118
|
+
this.emitMutation({
|
|
1119
|
+
touchedCells: buildTouchedCells(clearedCells.map((cellAddress) => ({
|
|
1120
|
+
address: cellAddress,
|
|
1121
|
+
before: before.get(getMutationAddressKey(cellAddress)),
|
|
1122
|
+
after: undefined
|
|
1123
|
+
}))),
|
|
1124
|
+
resourceKeys: []
|
|
1125
|
+
});
|
|
974
1126
|
});
|
|
975
1127
|
}
|
|
976
1128
|
getState() {
|
|
@@ -989,6 +1141,17 @@ class FormulaEngine {
|
|
|
989
1141
|
}
|
|
990
1142
|
buildSerializedSnapshot() {
|
|
991
1143
|
const evaluationSnapshots = this.dependencyManager.toSnapshot(this.evaluationManager);
|
|
1144
|
+
const historySnapshot = this.buildHistorySnapshot();
|
|
1145
|
+
return {
|
|
1146
|
+
version: ENGINE_SNAPSHOT_VERSION,
|
|
1147
|
+
managers: {
|
|
1148
|
+
...historySnapshot.managers,
|
|
1149
|
+
dependency: evaluationSnapshots.dependency,
|
|
1150
|
+
cache: evaluationSnapshots.cache
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
buildHistorySnapshot() {
|
|
992
1155
|
const workbookSnapshot = this.workbookManager.toSnapshot();
|
|
993
1156
|
return {
|
|
994
1157
|
version: ENGINE_SNAPSHOT_VERSION,
|
|
@@ -998,12 +1161,13 @@ class FormulaEngine {
|
|
|
998
1161
|
table: this.tableManager.toSnapshot(),
|
|
999
1162
|
style: this.styleManager.toSnapshot(),
|
|
1000
1163
|
rangeMetadata: this.rangeMetadataManager.toSnapshot(),
|
|
1001
|
-
reference: this.referenceManager.toSnapshot()
|
|
1002
|
-
dependency: evaluationSnapshots.dependency,
|
|
1003
|
-
cache: evaluationSnapshots.cache
|
|
1164
|
+
reference: this.referenceManager.toSnapshot()
|
|
1004
1165
|
}
|
|
1005
1166
|
};
|
|
1006
1167
|
}
|
|
1168
|
+
serializeHistorySnapshot() {
|
|
1169
|
+
return serialize(this.buildHistorySnapshot());
|
|
1170
|
+
}
|
|
1007
1171
|
buildNamedExpressionSnapshot(workbookSnapshot) {
|
|
1008
1172
|
const namedExpressions = this.namedExpressionManager.toSnapshot();
|
|
1009
1173
|
const workbookExpressions = new Map;
|
|
@@ -1027,14 +1191,15 @@ class FormulaEngine {
|
|
|
1027
1191
|
serializeEngine() {
|
|
1028
1192
|
return serialize(this.buildSerializedSnapshot());
|
|
1029
1193
|
}
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
if (!deserialized || typeof deserialized !== "object" || !("version" in deserialized) || deserialized.version !== ENGINE_SNAPSHOT_VERSION || !deserialized.managers) {
|
|
1194
|
+
assertSupportedSnapshot(snapshot) {
|
|
1195
|
+
if (!snapshot || typeof snapshot !== "object" || !("version" in snapshot) || snapshot.version !== ENGINE_SNAPSHOT_VERSION || !snapshot.managers) {
|
|
1033
1196
|
throw new Error(`Unsupported serialized engine format. Expected EngineSnapshot version ${ENGINE_SNAPSHOT_VERSION}.`);
|
|
1034
1197
|
}
|
|
1198
|
+
}
|
|
1199
|
+
restoreDataManagersFromSnapshot(managers) {
|
|
1035
1200
|
this.namedExpressionManager.clear();
|
|
1036
|
-
this.workbookManager.restoreFromSnapshot(
|
|
1037
|
-
|
|
1201
|
+
this.workbookManager.restoreFromSnapshot(managers.workbook);
|
|
1202
|
+
managers.workbook.forEach((workbook) => {
|
|
1038
1203
|
this.namedExpressionManager.addWorkbook(workbook.name);
|
|
1039
1204
|
workbook.sheets.forEach((sheet) => {
|
|
1040
1205
|
this.namedExpressionManager.addSheet({
|
|
@@ -1043,15 +1208,27 @@ class FormulaEngine {
|
|
|
1043
1208
|
});
|
|
1044
1209
|
});
|
|
1045
1210
|
});
|
|
1046
|
-
this.namedExpressionManager.restoreFromSnapshot(
|
|
1047
|
-
this.tableManager.restoreFromSnapshot(
|
|
1048
|
-
this.styleManager.restoreFromSnapshot(
|
|
1049
|
-
this.rangeMetadataManager.restoreFromSnapshot(
|
|
1050
|
-
this.referenceManager.restoreFromSnapshot(
|
|
1211
|
+
this.namedExpressionManager.restoreFromSnapshot(managers.namedExpression);
|
|
1212
|
+
this.tableManager.restoreFromSnapshot(managers.table);
|
|
1213
|
+
this.styleManager.restoreFromSnapshot(managers.style);
|
|
1214
|
+
this.rangeMetadataManager.restoreFromSnapshot(managers.rangeMetadata);
|
|
1215
|
+
this.referenceManager.restoreFromSnapshot(managers.reference);
|
|
1216
|
+
}
|
|
1217
|
+
restoreHistorySnapshot(data) {
|
|
1218
|
+
const deserialized = deserialize(data);
|
|
1219
|
+
this.assertSupportedSnapshot(deserialized);
|
|
1220
|
+
this.restoreDataManagersFromSnapshot(deserialized.managers);
|
|
1221
|
+
this.evaluationManager.clearEvaluationCache();
|
|
1222
|
+
}
|
|
1223
|
+
resetToSerializedEngine(data) {
|
|
1224
|
+
const deserialized = deserialize(data);
|
|
1225
|
+
this.assertSupportedSnapshot(deserialized);
|
|
1226
|
+
this.restoreDataManagersFromSnapshot(deserialized.managers);
|
|
1051
1227
|
this.dependencyManager.restoreFromSnapshot({
|
|
1052
1228
|
dependency: deserialized.managers.dependency,
|
|
1053
1229
|
cache: deserialized.managers.cache
|
|
1054
1230
|
}, this.evaluationManager);
|
|
1231
|
+
this.clearUndoRedoHistory();
|
|
1055
1232
|
this.eventManager.emitUpdate();
|
|
1056
1233
|
}
|
|
1057
1234
|
}
|
|
@@ -1059,4 +1236,4 @@ export {
|
|
|
1059
1236
|
FormulaEngine
|
|
1060
1237
|
};
|
|
1061
1238
|
|
|
1062
|
-
//# debugId=
|
|
1239
|
+
//# debugId=D1ED50A99BB06C3D64756E2164756E21
|