fix: duplicating/removing frame while children selected (#9079)

This commit is contained in:
David Luzar 2025-02-04 19:23:47 +01:00 committed by GitHub
parent 302664e500
commit 424e94a403
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 3160 additions and 2065 deletions

View file

@ -45,6 +45,7 @@ import {
DEFAULT_FONT_SIZE,
DEFAULT_TEXT_ALIGN,
DEFAULT_VERTICAL_ALIGN,
ORIG_ID,
VERTICAL_ALIGN,
} from "../constants";
import type { MarkOptional, Merge, Mutable } from "../utility-types";
@ -592,26 +593,18 @@ export const deepCopyElement = <T extends ExcalidrawElement>(
return _deepCopyElement(val);
};
const __test__defineOrigId = (clonedObj: object, origId: string) => {
Object.defineProperty(clonedObj, ORIG_ID, {
value: origId,
writable: false,
enumerable: false,
});
};
/**
* utility wrapper to generate new id. In test env it reuses the old + postfix
* for test assertions.
* utility wrapper to generate new id.
*/
export const regenerateId = (
/** supply null if no previous id exists */
previousId: string | null,
) => {
if (isTestEnv() && previousId) {
let nextId = `${previousId}_copy`;
// `window.h` may not be defined in some unit tests
if (
window.h?.app
?.getSceneElementsIncludingDeleted()
.find((el: ExcalidrawElement) => el.id === nextId)
) {
nextId += "_copy";
}
return nextId;
}
const regenerateId = () => {
return randomId();
};
@ -637,7 +630,11 @@ export const duplicateElement = <TElement extends ExcalidrawElement>(
): Readonly<TElement> => {
let copy = deepCopyElement(element);
copy.id = regenerateId(copy.id);
if (isTestEnv()) {
__test__defineOrigId(copy, element.id);
}
copy.id = regenerateId();
copy.boundElements = null;
copy.updated = getUpdatedTimestamp();
copy.seed = randomInteger();
@ -646,7 +643,7 @@ export const duplicateElement = <TElement extends ExcalidrawElement>(
editingGroupId,
(groupId) => {
if (!groupIdMapForOperation.has(groupId)) {
groupIdMapForOperation.set(groupId, regenerateId(groupId));
groupIdMapForOperation.set(groupId, regenerateId());
}
return groupIdMapForOperation.get(groupId)!;
},
@ -692,7 +689,7 @@ export const duplicateElements = (
// if we haven't migrated the element id, but an old element with the same
// id exists, generate a new id for it and return it
if (origElementsMap.has(id)) {
const newId = regenerateId(id);
const newId = regenerateId();
elementNewIdsMap.set(id, newId);
return newId;
}
@ -706,6 +703,9 @@ export const duplicateElements = (
const clonedElement: Mutable<ExcalidrawElement> = _deepCopyElement(element);
clonedElement.id = maybeGetNewId(element.id)!;
if (isTestEnv()) {
__test__defineOrigId(clonedElement, element.id);
}
if (opts?.randomizeSeed) {
clonedElement.seed = randomInteger();
@ -715,7 +715,7 @@ export const duplicateElements = (
if (clonedElement.groupIds) {
clonedElement.groupIds = clonedElement.groupIds.map((groupId) => {
if (!groupNewIdsMap.has(groupId)) {
groupNewIdsMap.set(groupId, regenerateId(groupId));
groupNewIdsMap.set(groupId, regenerateId());
}
return groupNewIdsMap.get(groupId)!;
});

View file

@ -116,8 +116,5 @@ const normalizeBoundElementsOrder = (
export const normalizeElementOrder = (
elements: readonly ExcalidrawElement[],
) => {
// console.time();
const ret = normalizeBoundElementsOrder(normalizeGroupElementOrder(elements));
// console.timeEnd();
return ret;
return normalizeBoundElementsOrder(normalizeGroupElementOrder(elements));
};