Skip to content

PDForm: disarm beforeunload prompt on dispose (fixes #86) - #87

Merged
rolandbanks merged 1 commit into
mainfrom
fix/issue-86-pdform-beforeunload-dispose-leak
Aug 8, 2026
Merged

PDForm: disarm beforeunload prompt on dispose (fixes #86)#87
rolandbanks merged 1 commit into
mainfrom
fix/issue-86-pdform-beforeunload-dispose-leak

Conversation

@rolandbanks

Copy link
Copy Markdown
Contributor

Summary

Fixes #86: PDForm registers a browser beforeunload prompt when the form becomes dirty (ConfirmOnUnload, default true), but DisposeAsync never unregistered it. Any page that disposed a dirty PDForm (for example by internal navigation) left the unconditional "Exit and lose changes?" prompt installed on the whole browser tab until a full page reload.

Change

DisposeAsync now calls setUnloadListener(Id, false) before disposing the JS module, guarded by ConfirmOnUnload, catching JSDisconnectedException for the case where the browser or circuit is already gone. This matches the teardown idiom already used by PDModal. Removing an id that was never armed is a no-op in the JS module, so the call is safe unconditionally.

The issue's optional belt-and-braces suggestion (path-aware JS listener) was deliberately not taken: it would suppress legitimate prompts for a form that survives navigation, for example one hosted in a shared layout, which is a behaviour change beyond the bug.

Verification

Reproduced and verified in the PanoramicData.Blazor.Web Blazor Server host:

  1. Instrumented window.addEventListener/removeEventListener to log beforeunload handler changes by function name.
  2. Edited a field on /pdform4 (default ConfirmOnUnload): logged add:beforeUnloadListener.
  3. Navigated internally away via a plain anchor (bypassing PDNavLink's NavigationCancelService confirm): with this fix the disposal logged remove:beforeUnloadListener, and a synthetic beforeunload dispatch confirmed no prompt remains armed.

Library builds clean (0 warnings, 0 errors).

🤖 Generated with Claude Code

A dirty PDForm arms the shared "Exit and lose changes?" beforeunload
listener via setUnloadListener, but DisposeAsync never removed the
form's id, so internal navigation away from a dirty form left the
prompt installed on the whole tab until a full page reload.

DisposeAsync now best-effort disarms the listener before disposing the
JS module, swallowing JSDisconnectedException for the case where the
browser or circuit is already gone (matching the PDModal teardown
idiom).

Verified in the Blazor Server demo host on /pdform4: the listener is
added on first edit and now removed when navigation disposes the form,
with no stale prompt remaining.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity · 0 duplication

Metric Results
Complexity 0
Duplication 0

View in Codacy

AI Reviewer: run a review on demand. To trigger the first review automatically, go to your organization or repository integration settings. AI can make mistakes. Always validate suggestions.

Run reviewer

TIP This summary will be updated as you push new changes.

@rolandbanks
rolandbanks merged commit 3f67018 into main Aug 8, 2026
4 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PDForm never unregisters its beforeunload prompt on dispose, leaving a stale 'Exit and lose changes?' prompt after navigation

1 participant