diff --git a/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx b/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx index 362890244..937083a21 100644 --- a/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx +++ b/app/canvas/[id]/CanvasEditorLegacyPageClient.tsx @@ -5413,7 +5413,6 @@ export default function CanvasEditorLegacyPage({ const onVisibilityChange = () => { if (!canvasLeaveApprovedRef.current && document.visibilityState === "hidden" && hasUnsavedCanvasChanges()) { writeCanvasDraft(id, { base: savedCanvasSnapshotRef.current!.snapshot, snapshot: JSON.stringify({ canvasData: buildPersistedCanvasData() }) }); - retrySync(); } }; const retryTimer = window.setInterval(() => { diff --git a/tests/e2e/canvas-autosync.test.ts b/tests/e2e/canvas-autosync.test.ts index fbe4312e7..07c250689 100644 --- a/tests/e2e/canvas-autosync.test.ts +++ b/tests/e2e/canvas-autosync.test.ts @@ -143,6 +143,21 @@ test("only unsaved content blocks closing and beforeunload does not issue duplic expect(errors).toEqual([]); }); +test("pagehide and visibilitychange issue only one closing save", async ({ page }) => { + const { state, errors } = await setup(page); + state.failSave = true; + await moveImage(page); + const writes = state.writes.length; + await page.evaluate(() => { + window.dispatchEvent(new Event("pagehide")); + Object.defineProperty(document, "visibilityState", { value: "hidden", configurable: true }); + document.dispatchEvent(new Event("visibilitychange")); + }); + await expect.poll(() => state.writes.length).toBe(writes + 1); + expect(state.submissions).toHaveLength(0); + expect(errors).toEqual([]); +}); + test("leaving with pending changes can continue editing or save before navigating", async ({ page }) => { const { state, errors } = await setup(page); await page.route(url => url.pathname === "/", route => route.fulfill({ contentType: "text/html; charset=utf-8", body: "

已返回首页

" }));