浏览代码

fix: bindings do not survive history serialization (#5942)

David Luzar 2 年之前
父节点
当前提交
8b33ca3a1a
共有 2 个文件被更改,包括 43 次插入5 次删除
  1. 3 5
      src/element/newElement.ts
  2. 40 0
      src/element/textWysiwyg.test.tsx

+ 3 - 5
src/element/newElement.ts

@@ -366,14 +366,11 @@ export const deepCopyElement = (val: any, depth: number = 0) => {
         : {};
     for (const key in val) {
       if (val.hasOwnProperty(key)) {
-        // don't copy top-level shape property, which we want to regenerate
+        // don't copy non-serializable objects like these caches. They'll be
+        // populated when the element is rendered.
         if (depth === 0 && (key === "shape" || key === "canvas")) {
           continue;
         }
-        if (key === "boundElements") {
-          tmp[key] = null;
-          continue;
-        }
         tmp[key] = deepCopyElement(val[key], depth + 1);
       }
     }
@@ -427,6 +424,7 @@ export const duplicateElement = <TElement extends Mutable<ExcalidrawElement>>(
   } else {
     copy.id = randomId();
   }
+  copy.boundElements = null;
   copy.updated = getUpdatedTimestamp();
   copy.seed = randomInteger();
   copy.groupIds = getNewGroupIdsForDuplication(

+ 40 - 0
src/element/textWysiwyg.test.tsx

@@ -1156,5 +1156,45 @@ describe("textWysiwyg", () => {
 
       expect(duplicatedText.containerId).toBe(duplicatedRectangle.id);
     });
+
+    it("undo should work", async () => {
+      Keyboard.keyPress(KEYS.ENTER);
+      const editor = document.querySelector(
+        ".excalidraw-textEditorContainer > textarea",
+      ) as HTMLTextAreaElement;
+      await new Promise((r) => setTimeout(r, 0));
+      fireEvent.change(editor, { target: { value: "Hello" } });
+      editor.blur();
+      expect(rectangle.boundElements).toStrictEqual([
+        { id: h.elements[1].id, type: "text" },
+      ]);
+      let text = h.elements[1] as ExcalidrawTextElementWithContainer;
+      const originalRectX = rectangle.x;
+      const originalRectY = rectangle.y;
+      const originalTextX = text.x;
+      const originalTextY = text.y;
+
+      mouse.select(rectangle);
+      mouse.downAt(rectangle.x, rectangle.y);
+      mouse.moveTo(rectangle.x + 100, rectangle.y + 50);
+      mouse.up(rectangle.x + 100, rectangle.y + 50);
+      expect(rectangle.x).toBe(80);
+      expect(rectangle.y).toBe(85);
+      expect(text.x).toBe(89.5);
+      expect(text.y).toBe(90);
+
+      Keyboard.withModifierKeys({ ctrl: true }, () => {
+        Keyboard.keyPress(KEYS.Z);
+      });
+      expect(rectangle.x).toBe(originalRectX);
+      expect(rectangle.y).toBe(originalRectY);
+      text = h.elements[1] as ExcalidrawTextElementWithContainer;
+      expect(text.x).toBe(originalTextX);
+      expect(text.y).toBe(originalTextY);
+      expect(rectangle.boundElements).toStrictEqual([
+        { id: text.id, type: "text" },
+      ]);
+      expect(text.containerId).toBe(rectangle.id);
+    });
   });
 });