Repository navigation
fix: respect preventDefault from user click handlers - #627
Merged
Merged
Conversation
The i13n click listener cancels the native default action and redirects programmatically after the beacon, so a preventDefault() from a React onClick (which runs later, at the root) had no effect. Since #391 this caused I13nButton to submit its form (#569) and I13nAnchor to navigate even when an inner element's handler called preventDefault (#568). - Track preventDefault calls made before or after the i13n listener and skip the redirect/submit if any handler cancelled the click. - Defer the redirect until the click dispatch finishes, since the beacon callback can run synchronously when no plugin handles the event. - Submit forms with requestSubmit(submitter) when available so submit handlers and constraint validation run; fall back to form.submit(). Fixes #568 Fixes #569 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #568, fixes #569.
Problem
The i13n click listener is a native listener on the element, so it runs before React's
onClickhandlers (delegated to the root). For links and submit buttons it callede.preventDefault()itself, then navigated or submitted in code (location.assign/form.submit()) after the beacon. A laterpreventDefault()from user code had no effect.Since #391 (switch to
currentTarget), this means:I13nButtoninside a<form>submits even when itsonClickcallspreventDefault(). 2.x never touched buttons (nohref), so the browser handled submit natively.I13nAnchornavigates even when an inner button'sonClickcallspreventDefault(). 2.x avoided this by accident:e.targetwas the inner button, so it took the form-submit path with no form.Fix (
src/libs/clickHandler.js)e.defaultPrevented) or after the i13n listener (by wrappinge.preventDefaulton the event). Skip the redirect/submit if so. The click beacon still fires.setTimeout(…, 0). With no plugin handling the event, the beacon callback runs synchronously, before React's handlers.form.requestSubmit(submitter)when available, soonSubmithandlers and constraint validation run.form.submit()skips both. Falls back toform.submit().Behavior change to note
Redirects and submits now happen one macrotask later than before. In practice this is invisible, since they already waited for the beacon when plugins were registered.
Tests
src/libs/tests/clickHandler.test.js: unit tests for prevented-before, prevented-after (link and form), andrequestSubmit. The two_top/_parenttests now wait for the deferred redirect.src/components/tests/preventDefault.test.jsx: end-to-end tests that reproduce both issue scenarios with realI13nButton/I13nAnchorand React handlers, plus the unprevented happy paths.All 6 new tests fail on
masterand pass with this change. Full suite: 60 passed, 1 skipped.npm run lintis clean.🤖 Generated with Claude Code