Skip to content

Comments

Lib: fix onbeforeunload handler breaking navigation (#1436) #2159

Open
hhugo wants to merge 2 commits intomasterfrom
fixunloadevent
Open

Lib: fix onbeforeunload handler breaking navigation (#1436) #2159
hhugo wants to merge 2 commits intomasterfrom
fixunloadevent

Conversation

@hhugo
Copy link
Member

@hhugo hhugo commented Feb 3, 2026

Summary

Fixes #1436.

Dom.handler converts the OCaml bool t return value to a JavaScript return value. When a beforeunload handler returns Js._true (allow navigation), the JS value true is passed to the browser. Modern browsers interpret any non-null, non-undefined return value from a beforeunload handler as a request to show the "Leave page?" confirmation dialog. This means that even when the OCaml handler intended to allow navigation, the browser would show a blocking dialog.

Changes

The fix detects beforeunload events at runtime in Dom.handler and Dom.full_handler:

  • When the handler returns Js._true (allow navigation), return undefined to the browser instead of true, so no dialog is shown.
  • When the handler returns Js._false (block navigation), also set event.returnValue = "" for legacy browser compatibility.
  • In Dom.invoke_handler, normalize undefined back to Js._true so callers that chain handlers still see a proper bool t value.

Also adds Dom.beforeUnloadEvent and Dom_html.beforeUnloadEvent class types with the returnValue property, and types onbeforeunload to use beforeUnloadEvent instead of the generic event type.

hhugo and others added 2 commits February 4, 2026 17:19
All modern browsers show a confirmation dialog when the beforeunload
handler returns any value other than null or undefined. Dom.handler
returned Js._true as the JS value true, which incorrectly triggered
the dialog even when the handler intended to allow navigation.

Fix by detecting beforeunload events at runtime in Dom.handler and
Dom.full_handler: Js._true returns undefined to JS (allowing
navigation without a dialog), while Js._false continues to call
preventDefault and also sets event.returnValue for legacy browsers.
Dom.invoke_handler normalizes undefined back to Js._true.

Also adds Dom.beforeUnloadEvent and Dom_html.beforeUnloadEvent class
types with the returnValue property, and types onbeforeunload to use
beforeUnloadEvent instead of the generic event type.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@hhugo
Copy link
Member Author

hhugo commented Feb 5, 2026

@TyOverby, this PR breaks some virtual_dom tests. Can you comment maybe ?

@hhugo
Copy link
Member Author

hhugo commented Feb 13, 2026

@vouillon, any though ?

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.

[BUG] semantics of (onbeforeunload, Dom_html.handler) incompatible with major browsers

1 participant