1
0
mirror of https://github.com/excalidraw/excalidraw.git synced 2024-11-10 11:35:52 +01:00

fix: keep binding for attached arrows after changing text (#3754)

Co-authored-by: David Luzar <luzar.david@gmail.com>
This commit is contained in:
connorhanafee 2021-06-21 08:31:49 -04:00 committed by GitHub
parent 5cd921549a
commit 969d3c694a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 6 deletions

@ -1747,7 +1747,8 @@ class App extends React.Component<AppProps, AppState> {
[element.id]: true, [element.id]: true,
}, },
})); }));
} else { }
if (isDeleted) {
fixBindingsAfterDeletion(this.scene.getElements(), [element]); fixBindingsAfterDeletion(this.scene.getElements(), [element]);
} }
if (!isDeleted || isExistingElement) { if (!isDeleted || isExistingElement) {

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { render } from "./test-utils"; import { fireEvent, render } from "./test-utils";
import ExcalidrawApp from "../excalidraw-app"; import ExcalidrawApp from "../excalidraw-app";
import { UI, Pointer, Keyboard } from "./helpers/ui"; import { UI, Pointer, Keyboard } from "./helpers/ui";
import { getTransformHandles } from "../element/transformHandles"; import { getTransformHandles } from "../element/transformHandles";
@ -104,4 +104,113 @@ describe("element binding", () => {
Keyboard.keyPress(KEYS.ARROW_LEFT); Keyboard.keyPress(KEYS.ARROW_LEFT);
expect(arrow.endBinding).toBe(null); expect(arrow.endBinding).toBe(null);
}); });
it("should unbind on bound element deletion", () => {
const rectangle = UI.createElement("rectangle", {
x: 60,
y: 0,
size: 100,
});
const arrow = UI.createElement("arrow", {
x: 0,
y: 0,
size: 50,
});
expect(arrow.endBinding?.elementId).toBe(rectangle.id);
mouse.select(rectangle);
expect(API.getSelectedElement().type).toBe("rectangle");
Keyboard.keyDown(KEYS.DELETE);
expect(arrow.endBinding).toBe(null);
});
it("should unbind on text element deletion by submitting empty text", async () => {
const text = API.createElement({
type: "text",
text: "ola",
x: 60,
y: 0,
width: 100,
height: 100,
});
h.elements = [text];
const arrow = UI.createElement("arrow", {
x: 0,
y: 0,
size: 50,
});
expect(arrow.endBinding?.elementId).toBe(text.id);
// edit text element and submit
// -------------------------------------------------------------------------
UI.clickTool("text");
mouse.clickAt(text.x + 50, text.y + 50);
const editor = document.querySelector(
".excalidraw-textEditorContainer > textarea",
) as HTMLTextAreaElement;
expect(editor).not.toBe(null);
// we defer binding blur event on wysiwyg, hence wait a bit
await new Promise((r) => setTimeout(r, 30));
fireEvent.change(editor, { target: { value: "" } });
editor.blur();
expect(
document.querySelector(".excalidraw-textEditorContainer > textarea"),
).toBe(null);
expect(arrow.endBinding).toBe(null);
});
it("should keep binding on text update", async () => {
const text = API.createElement({
type: "text",
text: "ola",
x: 60,
y: 0,
width: 100,
height: 100,
});
h.elements = [text];
const arrow = UI.createElement("arrow", {
x: 0,
y: 0,
size: 50,
});
expect(arrow.endBinding?.elementId).toBe(text.id);
// delete text element by submitting empty text
// -------------------------------------------------------------------------
UI.clickTool("text");
mouse.clickAt(text.x + 50, text.y + 50);
const editor = document.querySelector(
".excalidraw-textEditorContainer > textarea",
) as HTMLTextAreaElement;
expect(editor).not.toBe(null);
// we defer binding blur event on wysiwyg, hence wait a bit
await new Promise((r) => setTimeout(r, 30));
fireEvent.change(editor, { target: { value: "asdasdasdasdas" } });
editor.blur();
expect(
document.querySelector(".excalidraw-textEditorContainer > textarea"),
).toBe(null);
expect(arrow.endBinding?.elementId).toBe(text.id);
});
}); });

@ -253,7 +253,7 @@ Object {
"fontFamily": 1, "fontFamily": 1,
"fontSize": 14, "fontSize": 14,
"groupIds": Array [], "groupIds": Array [],
"height": 0, "height": 100,
"id": "id-text01", "id": "id-text01",
"isDeleted": false, "isDeleted": false,
"opacity": 100, "opacity": 100,
@ -269,7 +269,7 @@ Object {
"version": 1, "version": 1,
"versionNonce": 0, "versionNonce": 0,
"verticalAlign": "middle", "verticalAlign": "middle",
"width": 0, "width": 100,
"x": 0, "x": 0,
"y": 0, "y": 0,
} }
@ -285,7 +285,7 @@ Object {
"fontFamily": 1, "fontFamily": 1,
"fontSize": 10, "fontSize": 10,
"groupIds": Array [], "groupIds": Array [],
"height": 0, "height": 100,
"id": "id-text01", "id": "id-text01",
"isDeleted": false, "isDeleted": false,
"opacity": 100, "opacity": 100,
@ -301,7 +301,7 @@ Object {
"version": 1, "version": 1,
"versionNonce": 0, "versionNonce": 0,
"verticalAlign": "top", "verticalAlign": "top",
"width": 0, "width": 100,
"x": 0, "x": 0,
"y": 0, "y": 0,
} }

@ -139,6 +139,8 @@ export class API {
textAlign: rest.textAlign ?? appState.currentItemTextAlign, textAlign: rest.textAlign ?? appState.currentItemTextAlign,
verticalAlign: rest.verticalAlign ?? DEFAULT_VERTICAL_ALIGN, verticalAlign: rest.verticalAlign ?? DEFAULT_VERTICAL_ALIGN,
}); });
element.width = width;
element.height = height;
break; break;
case "freedraw": case "freedraw":
element = newFreeDrawElement({ element = newFreeDrawElement({