1
0
mirror of https://github.com/excalidraw/excalidraw.git synced 2025-02-18 13:29:36 +01:00

fix: Binding after duplicating is now applied for both the old and duplicate shapes (#8185)

Using ALT/OPT + drag to clone does not transfer the bindings (or leaves the duplicates in place of the old one , which are also not bound).

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Márk Tolmács 2024-06-28 15:28:48 +02:00 committed by GitHub
parent abbeed3d5f
commit 04668d8263
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 54 additions and 2 deletions

@ -707,6 +707,9 @@ export const fixBindingsAfterDuplication = (
const allBoundElementIds: Set<ExcalidrawElement["id"]> = new Set();
const allBindableElementIds: Set<ExcalidrawElement["id"]> = new Set();
const shouldReverseRoles = duplicatesServeAsOld === "duplicatesServeAsOld";
const duplicateIdToOldId = new Map(
[...oldIdToDuplicatedId].map(([key, value]) => [value, key]),
);
oldElements.forEach((oldElement) => {
const { boundElements } = oldElement;
if (boundElements != null && boundElements.length > 0) {
@ -756,7 +759,11 @@ export const fixBindingsAfterDuplication = (
sceneElements
.filter(({ id }) => allBindableElementIds.has(id))
.forEach((bindableElement) => {
const { boundElements } = bindableElement;
const oldElementId = duplicateIdToOldId.get(bindableElement.id);
const { boundElements } = sceneElements.find(
({ id }) => id === oldElementId,
)!;
if (boundElements != null && boundElements.length > 0) {
mutateElement(bindableElement, {
boundElements: boundElements.map((boundElement) =>

@ -1,5 +1,5 @@
import { fireEvent, render } from "./test-utils";
import { Excalidraw } from "../index";
import { Excalidraw, isLinearElement } from "../index";
import { UI, Pointer, Keyboard } from "./helpers/ui";
import { getTransformHandles } from "../element/transformHandles";
import { API } from "./helpers/api";
@ -433,4 +433,49 @@ describe("element binding", () => {
expect(arrow.startBinding).not.toBe(null);
expect(arrow.endBinding).toBe(null);
});
it("should not unbind when duplicating via selection group", () => {
const rectLeft = UI.createElement("rectangle", {
x: 0,
width: 200,
height: 500,
});
const rectRight = UI.createElement("rectangle", {
x: 400,
y: 200,
width: 200,
height: 500,
});
const arrow = UI.createElement("arrow", {
x: 210,
y: 250,
width: 177,
height: 1,
});
expect(arrow.startBinding?.elementId).toBe(rectLeft.id);
expect(arrow.endBinding?.elementId).toBe(rectRight.id);
mouse.downAt(-100, -100);
mouse.moveTo(650, 750);
mouse.up(0, 0);
expect(API.getSelectedElements().length).toBe(3);
mouse.moveTo(5, 5);
Keyboard.withModifierKeys({ alt: true }, () => {
mouse.downAt(5, 5);
mouse.moveTo(1000, 1000);
mouse.up(0, 0);
expect(window.h.elements.length).toBe(6);
window.h.elements.forEach((element) => {
if (isLinearElement(element)) {
expect(element.startBinding).not.toBe(null);
expect(element.endBinding).not.toBe(null);
} else {
expect(element.boundElements).not.toBe(null);
}
});
});
});
});