diff --git a/src/data/restore.ts b/src/data/restore.ts index bda6818f..d9ea999f 100644 --- a/src/data/restore.ts +++ b/src/data/restore.ts @@ -189,7 +189,7 @@ const restoreElement = ( fontSize = parseFloat(fontPx); 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 // programmatically, or when importing old diagrams. @@ -222,9 +222,17 @@ const restoreElement = ( 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) { element = { ...element, ...refreshTextDimensions(element) }; } + return element; case "freedraw": { return restoreElementWithProperties(element, { @@ -299,6 +307,7 @@ const restoreElement = ( // We also don't want to throw, but instead return void so we filter // out these unsupported elements from the restored array. } + return null; }; /** diff --git a/src/element/mutateElement.ts b/src/element/mutateElement.ts index 0e01a080..d4dbd8cd 100644 --- a/src/element/mutateElement.ts +++ b/src/element/mutateElement.ts @@ -140,8 +140,8 @@ export const newElementWith = ( * * NOTE: does not trigger re-render. */ -export const bumpVersion = ( - element: Mutable, +export const bumpVersion = >( + element: T, version?: ExcalidrawElement["version"], ) => { element.version = (version ?? element.version) + 1; diff --git a/src/element/textWysiwyg.tsx b/src/element/textWysiwyg.tsx index d7fed698..52f89e0b 100644 --- a/src/element/textWysiwyg.tsx +++ b/src/element/textWysiwyg.tsx @@ -584,7 +584,7 @@ export const textWysiwyg = ({ window.removeEventListener("pointerdown", onPointerDown); window.removeEventListener("pointerup", bindBlurEvent); window.removeEventListener("blur", handleSubmit); - + window.removeEventListener("beforeunload", handleSubmit); unbindUpdate(); editable.remove(); @@ -701,6 +701,7 @@ export const textWysiwyg = ({ passive: false, capture: true, }); + window.addEventListener("beforeunload", handleSubmit); excalidrawContainer ?.querySelector(".excalidraw-textEditorContainer")! .appendChild(editable); diff --git a/src/tests/data/__snapshots__/restore.test.ts.snap b/src/tests/data/__snapshots__/restore.test.ts.snap index 88194021..c5482c21 100644 --- a/src/tests/data/__snapshots__/restore.test.ts.snap +++ b/src/tests/data/__snapshots__/restore.test.ts.snap @@ -340,12 +340,12 @@ exports[`restoreElements > should restore text element correctly with unknown fo "groupIds": [], "height": 100, "id": "id-text01", - "isDeleted": false, + "isDeleted": true, "lineHeight": 1.25, "link": null, "locked": false, "opacity": 100, - "originalText": "test", + "originalText": "", "roughness": 1, "roundness": { "type": 3, @@ -358,8 +358,8 @@ exports[`restoreElements > should restore text element correctly with unknown fo "textAlign": "left", "type": "text", "updated": 1, - "version": 1, - "versionNonce": 0, + "version": 2, + "versionNonce": Any, "verticalAlign": "top", "width": 100, "x": 0, diff --git a/src/tests/data/restore.test.ts b/src/tests/data/restore.test.ts index 0019b0e8..0a0d9b15 100644 --- a/src/tests/data/restore.test.ts +++ b/src/tests/data/restore.test.ts @@ -86,12 +86,15 @@ describe("restoreElements", () => { textElement.text = null; textElement.font = "10 unknown"; + expect(textElement.isDeleted).toBe(false); const restoredText = restore.restoreElements( [textElement], null, )[0] as ExcalidrawTextElement; + expect(restoredText.isDeleted).toBe(true); expect(restoredText).toMatchSnapshot({ seed: expect.any(Number), + versionNonce: expect.any(Number), }); });