Browse Source

fix: wysiwyg left in undefined state on reload (#7123)

mazijian-pp 1 year ago
parent
commit
44d9d5fcac

+ 10 - 1
src/data/restore.ts

@@ -189,7 +189,7 @@ const restoreElement = (
         fontSize = parseFloat(fontPx);
         fontSize = parseFloat(fontPx);
         fontFamily = getFontFamilyByName(_fontFamily);
         fontFamily = getFontFamilyByName(_fontFamily);
       }
       }
-      const text = element.text ?? "";
+      const text = (typeof element.text === "string" && element.text) || "";
 
 
       // line-height might not be specified either when creating elements
       // line-height might not be specified either when creating elements
       // programmatically, or when importing old diagrams.
       // programmatically, or when importing old diagrams.
@@ -222,9 +222,17 @@ const restoreElement = (
         baseline,
         baseline,
       });
       });
 
 
+      // if empty text, mark as deleted. We keep in array
+      // for data integrity purposes (collab etc.)
+      if (!text && !element.isDeleted) {
+        element = { ...element, originalText: text, isDeleted: true };
+        element = bumpVersion(element);
+      }
+
       if (refreshDimensions) {
       if (refreshDimensions) {
         element = { ...element, ...refreshTextDimensions(element) };
         element = { ...element, ...refreshTextDimensions(element) };
       }
       }
+
       return element;
       return element;
     case "freedraw": {
     case "freedraw": {
       return restoreElementWithProperties(element, {
       return restoreElementWithProperties(element, {
@@ -299,6 +307,7 @@ const restoreElement = (
     // We also don't want to throw, but instead return void so we filter
     // We also don't want to throw, but instead return void so we filter
     // out these unsupported elements from the restored array.
     // out these unsupported elements from the restored array.
   }
   }
+  return null;
 };
 };
 
 
 /**
 /**

+ 2 - 2
src/element/mutateElement.ts

@@ -140,8 +140,8 @@ export const newElementWith = <TElement extends ExcalidrawElement>(
  *
  *
  * NOTE: does not trigger re-render.
  * NOTE: does not trigger re-render.
  */
  */
-export const bumpVersion = (
-  element: Mutable<ExcalidrawElement>,
+export const bumpVersion = <T extends Mutable<ExcalidrawElement>>(
+  element: T,
   version?: ExcalidrawElement["version"],
   version?: ExcalidrawElement["version"],
 ) => {
 ) => {
   element.version = (version ?? element.version) + 1;
   element.version = (version ?? element.version) + 1;

+ 2 - 1
src/element/textWysiwyg.tsx

@@ -584,7 +584,7 @@ export const textWysiwyg = ({
     window.removeEventListener("pointerdown", onPointerDown);
     window.removeEventListener("pointerdown", onPointerDown);
     window.removeEventListener("pointerup", bindBlurEvent);
     window.removeEventListener("pointerup", bindBlurEvent);
     window.removeEventListener("blur", handleSubmit);
     window.removeEventListener("blur", handleSubmit);
-
+    window.removeEventListener("beforeunload", handleSubmit);
     unbindUpdate();
     unbindUpdate();
 
 
     editable.remove();
     editable.remove();
@@ -701,6 +701,7 @@ export const textWysiwyg = ({
     passive: false,
     passive: false,
     capture: true,
     capture: true,
   });
   });
+  window.addEventListener("beforeunload", handleSubmit);
   excalidrawContainer
   excalidrawContainer
     ?.querySelector(".excalidraw-textEditorContainer")!
     ?.querySelector(".excalidraw-textEditorContainer")!
     .appendChild(editable);
     .appendChild(editable);

+ 4 - 4
src/tests/data/__snapshots__/restore.test.ts.snap

@@ -340,12 +340,12 @@ exports[`restoreElements > should restore text element correctly with unknown fo
   "groupIds": [],
   "groupIds": [],
   "height": 100,
   "height": 100,
   "id": "id-text01",
   "id": "id-text01",
-  "isDeleted": false,
+  "isDeleted": true,
   "lineHeight": 1.25,
   "lineHeight": 1.25,
   "link": null,
   "link": null,
   "locked": false,
   "locked": false,
   "opacity": 100,
   "opacity": 100,
-  "originalText": "test",
+  "originalText": "",
   "roughness": 1,
   "roughness": 1,
   "roundness": {
   "roundness": {
     "type": 3,
     "type": 3,
@@ -358,8 +358,8 @@ exports[`restoreElements > should restore text element correctly with unknown fo
   "textAlign": "left",
   "textAlign": "left",
   "type": "text",
   "type": "text",
   "updated": 1,
   "updated": 1,
-  "version": 1,
-  "versionNonce": 0,
+  "version": 2,
+  "versionNonce": Any<Number>,
   "verticalAlign": "top",
   "verticalAlign": "top",
   "width": 100,
   "width": 100,
   "x": 0,
   "x": 0,

+ 3 - 0
src/tests/data/restore.test.ts

@@ -86,12 +86,15 @@ describe("restoreElements", () => {
     textElement.text = null;
     textElement.text = null;
     textElement.font = "10 unknown";
     textElement.font = "10 unknown";
 
 
+    expect(textElement.isDeleted).toBe(false);
     const restoredText = restore.restoreElements(
     const restoredText = restore.restoreElements(
       [textElement],
       [textElement],
       null,
       null,
     )[0] as ExcalidrawTextElement;
     )[0] as ExcalidrawTextElement;
+    expect(restoredText.isDeleted).toBe(true);
     expect(restoredText).toMatchSnapshot({
     expect(restoredText).toMatchSnapshot({
       seed: expect.any(Number),
       seed: expect.any(Number),
+      versionNonce: expect.any(Number),
     });
     });
   });
   });