feat: various delta improvements (#9571)
This commit is contained in:
@@ -103,6 +103,7 @@ import {
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import {
|
||||
getObservedAppState,
|
||||
getCommonBounds,
|
||||
getElementAbsoluteCoords,
|
||||
bindOrUnbindLinearElements,
|
||||
@@ -260,7 +261,6 @@ import type {
|
||||
ExcalidrawNonSelectionElement,
|
||||
ExcalidrawArrowElement,
|
||||
ExcalidrawElbowArrowElement,
|
||||
SceneElementsMap,
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import type { Mutable, ValueOf } from "@excalidraw/common/utility-types";
|
||||
@@ -702,6 +702,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
addFiles: this.addFiles,
|
||||
resetScene: this.resetScene,
|
||||
getSceneElementsIncludingDeleted: this.getSceneElementsIncludingDeleted,
|
||||
getSceneElementsMapIncludingDeleted:
|
||||
this.getSceneElementsMapIncludingDeleted,
|
||||
history: {
|
||||
clear: this.resetHistory,
|
||||
},
|
||||
@@ -3909,22 +3911,18 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}) => {
|
||||
const { elements, appState, collaborators, captureUpdate } = sceneData;
|
||||
|
||||
const nextElements = elements ? syncInvalidIndices(elements) : undefined;
|
||||
|
||||
if (captureUpdate) {
|
||||
const nextElementsMap = elements
|
||||
? (arrayToMap(nextElements ?? []) as SceneElementsMap)
|
||||
: undefined;
|
||||
|
||||
const nextAppState = appState
|
||||
? // new instance, with partial appstate applied to previously captured one, including hidden prop inside `prevCommittedAppState`
|
||||
Object.assign({}, this.store.snapshot.appState, appState)
|
||||
const observedAppState = appState
|
||||
? getObservedAppState({
|
||||
...this.store.snapshot.appState,
|
||||
...appState,
|
||||
})
|
||||
: undefined;
|
||||
|
||||
this.store.scheduleMicroAction({
|
||||
action: captureUpdate,
|
||||
elements: nextElementsMap,
|
||||
appState: nextAppState,
|
||||
elements: elements ?? [],
|
||||
appState: observedAppState,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3932,8 +3930,8 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.setState(appState);
|
||||
}
|
||||
|
||||
if (nextElements) {
|
||||
this.scene.replaceAllElements(nextElements);
|
||||
if (elements) {
|
||||
this.scene.replaceAllElements(elements);
|
||||
}
|
||||
|
||||
if (collaborators) {
|
||||
@@ -10550,7 +10548,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// otherwise we would end up with duplicated fractional indices on undo
|
||||
this.store.scheduleMicroAction({
|
||||
action: CaptureUpdateAction.NEVER,
|
||||
elements: arrayToMap(elements) as SceneElementsMap,
|
||||
elements,
|
||||
appState: undefined,
|
||||
});
|
||||
|
||||
|
||||
+108
-45
@@ -4,14 +4,81 @@ import {
|
||||
CaptureUpdateAction,
|
||||
StoreChange,
|
||||
StoreDelta,
|
||||
type Store,
|
||||
} from "@excalidraw/element";
|
||||
|
||||
import type { StoreSnapshot, Store } from "@excalidraw/element";
|
||||
|
||||
import type { SceneElementsMap } from "@excalidraw/element/types";
|
||||
|
||||
import type { AppState } from "./types";
|
||||
|
||||
class HistoryEntry extends StoreDelta {}
|
||||
export class HistoryDelta extends StoreDelta {
|
||||
/**
|
||||
* Apply the delta to the passed elements and appState, does not modify the snapshot.
|
||||
*/
|
||||
public applyTo(
|
||||
elements: SceneElementsMap,
|
||||
appState: AppState,
|
||||
snapshot: StoreSnapshot,
|
||||
): [SceneElementsMap, AppState, boolean] {
|
||||
const [nextElements, elementsContainVisibleChange] = this.elements.applyTo(
|
||||
elements,
|
||||
// used to fallback into local snapshot in case we couldn't apply the delta
|
||||
// due to a missing (force deleted) elements in the scene
|
||||
snapshot.elements,
|
||||
// we don't want to apply the `version` and `versionNonce` properties for history
|
||||
// as we always need to end up with a new version due to collaboration,
|
||||
// approaching each undo / redo as a new user action
|
||||
{
|
||||
excludedProperties: new Set(["version", "versionNonce"]),
|
||||
},
|
||||
);
|
||||
|
||||
const [nextAppState, appStateContainsVisibleChange] = this.appState.applyTo(
|
||||
appState,
|
||||
nextElements,
|
||||
);
|
||||
|
||||
const appliedVisibleChanges =
|
||||
elementsContainVisibleChange || appStateContainsVisibleChange;
|
||||
|
||||
return [nextElements, nextAppState, appliedVisibleChanges];
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriding once to avoid type casting everywhere.
|
||||
*/
|
||||
public static override calculate(
|
||||
prevSnapshot: StoreSnapshot,
|
||||
nextSnapshot: StoreSnapshot,
|
||||
) {
|
||||
return super.calculate(prevSnapshot, nextSnapshot) as HistoryDelta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriding once to avoid type casting everywhere.
|
||||
*/
|
||||
public static override inverse(delta: StoreDelta): HistoryDelta {
|
||||
return super.inverse(delta) as HistoryDelta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overriding once to avoid type casting everywhere.
|
||||
*/
|
||||
public static override applyLatestChanges(
|
||||
delta: StoreDelta,
|
||||
prevElements: SceneElementsMap,
|
||||
nextElements: SceneElementsMap,
|
||||
modifierOptions?: "deleted" | "inserted",
|
||||
) {
|
||||
return super.applyLatestChanges(
|
||||
delta,
|
||||
prevElements,
|
||||
nextElements,
|
||||
modifierOptions,
|
||||
) as HistoryDelta;
|
||||
}
|
||||
}
|
||||
|
||||
export class HistoryChangedEvent {
|
||||
constructor(
|
||||
@@ -25,8 +92,8 @@ export class History {
|
||||
[HistoryChangedEvent]
|
||||
>();
|
||||
|
||||
public readonly undoStack: HistoryEntry[] = [];
|
||||
public readonly redoStack: HistoryEntry[] = [];
|
||||
public readonly undoStack: HistoryDelta[] = [];
|
||||
public readonly redoStack: HistoryDelta[] = [];
|
||||
|
||||
public get isUndoStackEmpty() {
|
||||
return this.undoStack.length === 0;
|
||||
@@ -48,16 +115,16 @@ export class History {
|
||||
* Do not re-record history entries, which were already pushed to undo / redo stack, as part of history action.
|
||||
*/
|
||||
public record(delta: StoreDelta) {
|
||||
if (delta.isEmpty() || delta instanceof HistoryEntry) {
|
||||
if (delta.isEmpty() || delta instanceof HistoryDelta) {
|
||||
return;
|
||||
}
|
||||
|
||||
// construct history entry, so once it's emitted, it's not recorded again
|
||||
const entry = HistoryEntry.inverse(delta);
|
||||
const historyDelta = HistoryDelta.inverse(delta);
|
||||
|
||||
this.undoStack.push(entry);
|
||||
this.undoStack.push(historyDelta);
|
||||
|
||||
if (!entry.elements.isEmpty()) {
|
||||
if (!historyDelta.elements.isEmpty()) {
|
||||
// don't reset redo stack on local appState changes,
|
||||
// as a simple click (unselect) could lead to losing all the redo entries
|
||||
// only reset on non empty elements changes!
|
||||
@@ -74,7 +141,7 @@ export class History {
|
||||
elements,
|
||||
appState,
|
||||
() => History.pop(this.undoStack),
|
||||
(entry: HistoryEntry) => History.push(this.redoStack, entry, elements),
|
||||
(entry: HistoryDelta) => History.push(this.redoStack, entry),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -83,20 +150,20 @@ export class History {
|
||||
elements,
|
||||
appState,
|
||||
() => History.pop(this.redoStack),
|
||||
(entry: HistoryEntry) => History.push(this.undoStack, entry, elements),
|
||||
(entry: HistoryDelta) => History.push(this.undoStack, entry),
|
||||
);
|
||||
}
|
||||
|
||||
private perform(
|
||||
elements: SceneElementsMap,
|
||||
appState: AppState,
|
||||
pop: () => HistoryEntry | null,
|
||||
push: (entry: HistoryEntry) => void,
|
||||
pop: () => HistoryDelta | null,
|
||||
push: (entry: HistoryDelta) => void,
|
||||
): [SceneElementsMap, AppState] | void {
|
||||
try {
|
||||
let historyEntry = pop();
|
||||
let historyDelta = pop();
|
||||
|
||||
if (historyEntry === null) {
|
||||
if (historyDelta === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -108,41 +175,47 @@ export class History {
|
||||
let nextAppState = appState;
|
||||
let containsVisibleChange = false;
|
||||
|
||||
// iterate through the history entries in case they result in no visible changes
|
||||
while (historyEntry) {
|
||||
// iterate through the history entries in case ;they result in no visible changes
|
||||
while (historyDelta) {
|
||||
try {
|
||||
[nextElements, nextAppState, containsVisibleChange] =
|
||||
StoreDelta.applyTo(
|
||||
historyEntry,
|
||||
nextElements,
|
||||
nextAppState,
|
||||
prevSnapshot,
|
||||
);
|
||||
historyDelta.applyTo(nextElements, nextAppState, prevSnapshot);
|
||||
|
||||
const prevElements = prevSnapshot.elements;
|
||||
const nextSnapshot = prevSnapshot.maybeClone(
|
||||
action,
|
||||
nextElements,
|
||||
nextAppState,
|
||||
);
|
||||
|
||||
// schedule immediate capture, so that it's emitted for the sync purposes
|
||||
this.store.scheduleMicroAction({
|
||||
action,
|
||||
change: StoreChange.create(prevSnapshot, nextSnapshot),
|
||||
delta: historyEntry,
|
||||
});
|
||||
const change = StoreChange.create(prevSnapshot, nextSnapshot);
|
||||
const delta = HistoryDelta.applyLatestChanges(
|
||||
historyDelta,
|
||||
prevElements,
|
||||
nextElements,
|
||||
);
|
||||
|
||||
if (!delta.isEmpty()) {
|
||||
// schedule immediate capture, so that it's emitted for the sync purposes
|
||||
this.store.scheduleMicroAction({
|
||||
action,
|
||||
change,
|
||||
delta,
|
||||
});
|
||||
|
||||
historyDelta = delta;
|
||||
}
|
||||
|
||||
prevSnapshot = nextSnapshot;
|
||||
} finally {
|
||||
// make sure to always push, even if the delta is corrupted
|
||||
push(historyEntry);
|
||||
push(historyDelta);
|
||||
}
|
||||
|
||||
if (containsVisibleChange) {
|
||||
break;
|
||||
}
|
||||
|
||||
historyEntry = pop();
|
||||
historyDelta = pop();
|
||||
}
|
||||
|
||||
return [nextElements, nextAppState];
|
||||
@@ -155,7 +228,7 @@ export class History {
|
||||
}
|
||||
}
|
||||
|
||||
private static pop(stack: HistoryEntry[]): HistoryEntry | null {
|
||||
private static pop(stack: HistoryDelta[]): HistoryDelta | null {
|
||||
if (!stack.length) {
|
||||
return null;
|
||||
}
|
||||
@@ -169,18 +242,8 @@ export class History {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static push(
|
||||
stack: HistoryEntry[],
|
||||
entry: HistoryEntry,
|
||||
prevElements: SceneElementsMap,
|
||||
) {
|
||||
const inversedEntry = HistoryEntry.inverse(entry);
|
||||
const updatedEntry = HistoryEntry.applyLatestChanges(
|
||||
inversedEntry,
|
||||
prevElements,
|
||||
"inserted",
|
||||
);
|
||||
|
||||
return stack.push(updatedEntry);
|
||||
private static push(stack: HistoryDelta[], entry: HistoryDelta) {
|
||||
const inversedEntry = HistoryDelta.inverse(entry);
|
||||
return stack.push(inversedEntry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1269,12 +1269,14 @@ exports[`contextMenu element > selecting 'Add to library' in context menu adds e
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1420,14 +1422,14 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1014066025,
|
||||
"seed": 238820263,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 3,
|
||||
"versionNonce": 1604849351,
|
||||
"versionNonce": 1505387817,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -1459,7 +1461,7 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 23633383,
|
||||
"versionNonce": 915032327,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -1511,12 +1513,14 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1563,12 +1567,14 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1598,9 +1604,11 @@ exports[`contextMenu element > selecting 'Bring forward' in context menu brings
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"index": "a2",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"index": "a0",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1745,14 +1753,14 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1014066025,
|
||||
"seed": 238820263,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 3,
|
||||
"versionNonce": 1604849351,
|
||||
"versionNonce": 1505387817,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -1784,7 +1792,7 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 23633383,
|
||||
"versionNonce": 915032327,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -1836,12 +1844,14 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1888,12 +1898,14 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1923,9 +1935,11 @@ exports[`contextMenu element > selecting 'Bring to front' in context menu brings
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"index": "a2",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"index": "a0",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2131,12 +2145,14 @@ exports[`contextMenu element > selecting 'Copy styles' in context menu copies st
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2287,7 +2303,7 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 1116226695,
|
||||
"versionNonce": 1014066025,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
@@ -2339,12 +2355,14 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2370,9 +2388,11 @@ exports[`contextMenu element > selecting 'Delete' in context menu deletes elemen
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"isDeleted": true,
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": false,
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2551,14 +2571,14 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1014066025,
|
||||
"seed": 238820263,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 5,
|
||||
"versionNonce": 400692809,
|
||||
"versionNonce": 1604849351,
|
||||
"width": 10,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -2610,12 +2630,14 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2662,12 +2684,14 @@ exports[`contextMenu element > selecting 'Duplicate' in context menu duplicates
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 5,
|
||||
"width": 10,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2827,7 +2851,7 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 493213705,
|
||||
"versionNonce": 81784553,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -2854,14 +2878,14 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1014066025,
|
||||
"seed": 238820263,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 915032327,
|
||||
"versionNonce": 747212839,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -2913,12 +2937,14 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -2965,12 +2991,14 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3020,9 +3048,11 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
"id3": {
|
||||
@@ -3030,9 +3060,11 @@ exports[`contextMenu element > selecting 'Group selection' in context menu group
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3186,7 +3218,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 908564423,
|
||||
"versionNonce": 1359939303,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -3211,14 +3243,14 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"opacity": 60,
|
||||
"roughness": 2,
|
||||
"roundness": null,
|
||||
"seed": 1315507081,
|
||||
"seed": 640725609,
|
||||
"strokeColor": "#e03131",
|
||||
"strokeStyle": "dotted",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 9,
|
||||
"versionNonce": 406373543,
|
||||
"versionNonce": 908564423,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -3270,12 +3302,14 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3322,12 +3356,14 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3349,9 +3385,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"strokeColor": "#e03131",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"strokeColor": "#1e1e1e",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3372,9 +3410,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"backgroundColor": "#a5d8ff",
|
||||
"version": 5,
|
||||
},
|
||||
"inserted": {
|
||||
"backgroundColor": "transparent",
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3395,9 +3435,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"fillStyle": "cross-hatch",
|
||||
"version": 6,
|
||||
},
|
||||
"inserted": {
|
||||
"fillStyle": "solid",
|
||||
"version": 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3418,9 +3460,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"strokeStyle": "dotted",
|
||||
"version": 7,
|
||||
},
|
||||
"inserted": {
|
||||
"strokeStyle": "solid",
|
||||
"version": 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3441,9 +3485,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"roughness": 2,
|
||||
"version": 8,
|
||||
},
|
||||
"inserted": {
|
||||
"roughness": 1,
|
||||
"version": 7,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3464,9 +3510,11 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"opacity": 60,
|
||||
"version": 9,
|
||||
},
|
||||
"inserted": {
|
||||
"opacity": 100,
|
||||
"version": 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3500,6 +3548,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"roughness": 2,
|
||||
"strokeColor": "#e03131",
|
||||
"strokeStyle": "dotted",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"backgroundColor": "transparent",
|
||||
@@ -3508,6 +3557,7 @@ exports[`contextMenu element > selecting 'Paste styles' in context menu pastes s
|
||||
"roughness": 1,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3652,14 +3702,14 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1150084233,
|
||||
"seed": 1116226695,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 1604849351,
|
||||
"versionNonce": 23633383,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -3743,12 +3793,14 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3795,12 +3847,14 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3822,9 +3876,11 @@ exports[`contextMenu element > selecting 'Send backward' in context menu sends e
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"index": "Zz",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"index": "a1",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -3969,14 +4025,14 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1014066025,
|
||||
"seed": 238820263,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 23633383,
|
||||
"versionNonce": 915032327,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -4060,12 +4116,14 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4112,12 +4170,14 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4139,9 +4199,11 @@ exports[`contextMenu element > selecting 'Send to back' in context menu sends el
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"index": "Zz",
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"index": "a1",
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4296,7 +4358,7 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 5,
|
||||
"versionNonce": 1723083209,
|
||||
"versionNonce": 1006504105,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -4321,14 +4383,14 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 238820263,
|
||||
"seed": 400692809,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 5,
|
||||
"versionNonce": 760410951,
|
||||
"versionNonce": 289600103,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
@@ -4380,12 +4442,14 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4432,12 +4496,14 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 20,
|
||||
"x": 20,
|
||||
"y": 30,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4487,9 +4553,11 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
"id3": {
|
||||
@@ -4497,9 +4565,11 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -4526,21 +4596,25 @@ exports[`contextMenu element > selecting 'Ungroup selection' in context menu ung
|
||||
"id0": {
|
||||
"deleted": {
|
||||
"groupIds": [],
|
||||
"version": 5,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
"id3": {
|
||||
"deleted": {
|
||||
"groupIds": [],
|
||||
"version": 5,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [
|
||||
"id9",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -5594,14 +5668,14 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1604849351,
|
||||
"seed": 1505387817,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 3,
|
||||
"versionNonce": 493213705,
|
||||
"versionNonce": 915032327,
|
||||
"width": 10,
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
@@ -5653,12 +5727,14 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -5705,12 +5781,14 @@ exports[`contextMenu element > shows 'Group selection' in context menu for multi
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -6786,7 +6864,7 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 81784553,
|
||||
"versionNonce": 1723083209,
|
||||
"width": 10,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
@@ -6813,14 +6891,14 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 238820263,
|
||||
"seed": 400692809,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 747212839,
|
||||
"versionNonce": 760410951,
|
||||
"width": 10,
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
@@ -6872,12 +6950,14 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -10,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -6924,12 +7004,14 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": 12,
|
||||
"y": 0,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -7001,9 +7083,11 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"groupIds": [
|
||||
"id12",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
"id3": {
|
||||
@@ -7011,9 +7095,11 @@ exports[`contextMenu element > shows 'Ungroup selection' in context menu for gro
|
||||
"groupIds": [
|
||||
"id12",
|
||||
],
|
||||
"version": 4,
|
||||
},
|
||||
"inserted": {
|
||||
"groupIds": [],
|
||||
"version": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -9822,12 +9908,14 @@ exports[`contextMenu element > shows context menu for element > [end of test] un
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"version": 3,
|
||||
"width": 10,
|
||||
"x": -20,
|
||||
"y": -10,
|
||||
},
|
||||
"inserted": {
|
||||
"isDeleted": true,
|
||||
"version": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,7 +25,7 @@ exports[`duplicate element on move when ALT is clicked > rectangle 5`] = `
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 5,
|
||||
"versionNonce": 1505387817,
|
||||
"versionNonce": 23633383,
|
||||
"width": 30,
|
||||
"x": 30,
|
||||
"y": 20,
|
||||
@@ -50,14 +50,14 @@ exports[`duplicate element on move when ALT is clicked > rectangle 6`] = `
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1604849351,
|
||||
"seed": 1505387817,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 7,
|
||||
"versionNonce": 915032327,
|
||||
"versionNonce": 81784553,
|
||||
"width": 30,
|
||||
"x": -10,
|
||||
"y": 60,
|
||||
@@ -89,7 +89,7 @@ exports[`move element > rectangle 5`] = `
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 1116226695,
|
||||
"versionNonce": 1014066025,
|
||||
"width": 30,
|
||||
"x": 0,
|
||||
"y": 40,
|
||||
@@ -126,7 +126,7 @@ exports[`move element > rectangles with binding arrow 5`] = `
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 4,
|
||||
"versionNonce": 1723083209,
|
||||
"versionNonce": 1006504105,
|
||||
"width": 100,
|
||||
"x": 0,
|
||||
"y": 0,
|
||||
@@ -156,14 +156,14 @@ exports[`move element > rectangles with binding arrow 6`] = `
|
||||
"opacity": 100,
|
||||
"roughness": 1,
|
||||
"roundness": null,
|
||||
"seed": 1150084233,
|
||||
"seed": 1116226695,
|
||||
"strokeColor": "#1e1e1e",
|
||||
"strokeStyle": "solid",
|
||||
"strokeWidth": 2,
|
||||
"type": "rectangle",
|
||||
"updated": 1,
|
||||
"version": 7,
|
||||
"versionNonce": 1051383431,
|
||||
"versionNonce": 1984422985,
|
||||
"width": 300,
|
||||
"x": 201,
|
||||
"y": 2,
|
||||
@@ -208,7 +208,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"roundness": {
|
||||
"type": 2,
|
||||
},
|
||||
"seed": 1604849351,
|
||||
"seed": 23633383,
|
||||
"startArrowhead": null,
|
||||
"startBinding": {
|
||||
"elementId": "id0",
|
||||
@@ -221,7 +221,7 @@ exports[`move element > rectangles with binding arrow 7`] = `
|
||||
"type": "arrow",
|
||||
"updated": 1,
|
||||
"version": 11,
|
||||
"versionNonce": 1996028265,
|
||||
"versionNonce": 1573789895,
|
||||
"width": "81.00000",
|
||||
"x": "110.00000",
|
||||
"y": 50,
|
||||
|
||||
@@ -50,7 +50,7 @@ exports[`multi point mode in linear elements > arrow 3`] = `
|
||||
"type": "arrow",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"versionNonce": 400692809,
|
||||
"versionNonce": 1604849351,
|
||||
"width": 70,
|
||||
"x": 30,
|
||||
"y": 30,
|
||||
@@ -105,7 +105,7 @@ exports[`multi point mode in linear elements > line 3`] = `
|
||||
"type": "line",
|
||||
"updated": 1,
|
||||
"version": 8,
|
||||
"versionNonce": 400692809,
|
||||
"versionNonce": 1604849351,
|
||||
"width": 70,
|
||||
"x": 30,
|
||||
"y": 30,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -431,12 +431,17 @@ export const assertElements = <T extends AllPossibleKeys<ExcalidrawElement>>(
|
||||
expect(h.state.selectedElementIds).toEqual(selectedElementIds);
|
||||
};
|
||||
|
||||
const stripSeed = (deltas: Record<string, { deleted: any; inserted: any }>) =>
|
||||
const stripProps = (
|
||||
deltas: Record<string, { deleted: any; inserted: any }>,
|
||||
props: string[],
|
||||
) =>
|
||||
Object.entries(deltas).reduce((acc, curr) => {
|
||||
const { inserted, deleted, ...rest } = curr[1];
|
||||
|
||||
delete inserted.seed;
|
||||
delete deleted.seed;
|
||||
for (const prop of props) {
|
||||
delete inserted[prop];
|
||||
delete deleted[prop];
|
||||
}
|
||||
|
||||
acc[curr[0]] = {
|
||||
inserted,
|
||||
@@ -453,9 +458,9 @@ export const checkpointHistory = (history: History, name: string) => {
|
||||
...x,
|
||||
elements: {
|
||||
...x.elements,
|
||||
added: stripSeed(x.elements.added),
|
||||
removed: stripSeed(x.elements.removed),
|
||||
updated: stripSeed(x.elements.updated),
|
||||
added: stripProps(x.elements.added, ["seed", "versionNonce"]),
|
||||
removed: stripProps(x.elements.removed, ["seed", "versionNonce"]),
|
||||
updated: stripProps(x.elements.updated, ["seed", "versionNonce"]),
|
||||
},
|
||||
})),
|
||||
).toMatchSnapshot(`[${name}] undo stack`);
|
||||
@@ -465,9 +470,9 @@ export const checkpointHistory = (history: History, name: string) => {
|
||||
...x,
|
||||
elements: {
|
||||
...x.elements,
|
||||
added: stripSeed(x.elements.added),
|
||||
removed: stripSeed(x.elements.removed),
|
||||
updated: stripSeed(x.elements.updated),
|
||||
added: stripProps(x.elements.added, ["seed", "versionNonce"]),
|
||||
removed: stripProps(x.elements.removed, ["seed", "versionNonce"]),
|
||||
updated: stripProps(x.elements.updated, ["seed", "versionNonce"]),
|
||||
},
|
||||
})),
|
||||
).toMatchSnapshot(`[${name}] redo stack`);
|
||||
|
||||
@@ -813,6 +813,9 @@ export interface ExcalidrawImperativeAPI {
|
||||
getSceneElementsIncludingDeleted: InstanceType<
|
||||
typeof App
|
||||
>["getSceneElementsIncludingDeleted"];
|
||||
getSceneElementsMapIncludingDeleted: InstanceType<
|
||||
typeof App
|
||||
>["getSceneElementsMapIncludingDeleted"];
|
||||
history: {
|
||||
clear: InstanceType<typeof App>["resetHistory"];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user