Repository navigation
[web] Preserve active autofill form across text input configuration updates - #193269
Conversation
There was a problem hiding this comment.
Code Review
This pull request updates the web text editing engine to preserve and reuse the active autofill form during configuration updates instead of replacing the DOM form. This is achieved by introducing updateFrameworkConfiguration on EngineAutofillForm and updating applyConfiguration in DefaultTextEditingStrategy to reuse the existing autofill group when identity properties match. Corresponding tests were added to verify this behavior. The review feedback suggests refactoring the duplicated identity checks into a helper method hasSameIdentity on EngineAutofillForm to improve maintainability.
There was a problem hiding this comment.
Code Review
This pull request modifies EditableTextState to schedule a text input connection restart on web when obscureTextChanged is true, instead of updating the configuration. It also updates the corresponding tests in editable_text_test.dart to verify this behavior specifically on web while skipping the standard configuration update test on web. I have no feedback to provide.
justinmc
left a comment
There was a problem hiding this comment.
LGTM 👍 . I tried this on my Mac using a composing Chinese Pinyin keyboard and I couldn't seem to find cause any bugs. Tapping to change obscureText while in the middle of composing just commits the text as-is, without converting to Chinese characters. This seems to be the same before before and after this PR.
Renzo-Olivares
left a comment
There was a problem hiding this comment.
Thanks for digging into this @simonpham!
I think the fix belongs in the web engine rather than in EditableText. The root cause is that #182024 made the autofill <form> lazily created and reused across connections, but TextInput.updateConfig still decodes a brand new EngineAutofillForm with no DOM form and swaps it in for the live one. On the next blur, disable() sees formElement == null and removes the <input> instead of letting the form go dormant. If the form went dormant earlier, wakeUp then calls replaceWith on a detached element, so the new <input> never makes it into the DOM.
Because of that, restarting the connection for obscureText only covers one of the callers. I tried this branch in Chrome and the same dead field still reproduces when keyboardType or readOnly changes while the field is focused (focus, blur, focus, change the property, blur, focus, type). The viewId change and any third-party TextInputClient that calls TextInputConnection.updateConfig go through the same path.
|
fyi @mdebbar @flutter-zl if y'all had any thoughts on the web diagnosis #193269 (review) |
Thanks for this insight. |
|
+1 I agree with @Renzo-Olivares's assessment to fixing this in the engine. |
Renzo-Olivares
left a comment
There was a problem hiding this comment.
LGTM, google testing failures need a rebase to fully verify. Analyzer failures seem unrelated.
…pdates When TextInput.updateConfig arrives while an autofill form is active, the newly decoded EngineAutofillForm has no associated DOM form. Preserve the active form so that on blur/disable the form goes dormant and remains reusable rather than incorrectly removing the live element. Fixes flutter#192102
SemanticsTextEditingStrategy never sets _appendedToForm, so the check skipped preserving the active autofill form in semantics mode. Rely on the active group's formElement alone.
Resolves the conflicts with flutter#187108, flutter#190942 and flutter#193269, and reformats the change for the Dart 3.13 formatter from flutter#192649.
…pdates (flutter#193269) Fixes flutter#192102 Fixes flutter#193267 ### Problem Toggling `TextField.obscureText` on Web sends `TextInput.updateConfig`, which decodes a new `EngineAutofillForm` lacking an associated DOM form (`formElement == null`). On blur (`TextInput.clearClient`), the web engine bypasses dormancy and tears down the active DOM input element. Refocusing the field leaves it unresponsive to keyboard events. ### Solution Preserve the active `EngineAutofillForm` across `TextInput.updateConfig` in `DefaultTextEditingStrategy.applyConfiguration`. This retains live DOM ownership so the form goes dormant on blur and wakes up cleanly on refocus. ### Testing Added engine unit tests in `text_editing_test.dart` for multi-field and single-field autofill forms, verifying dormancy and refocus reusability. | Issue | Result | | - | - | | flutter#192102: plain password field | https://github.com/user-attachments/assets/a8c98c15-7dbe-4d91-bf32-bbe90bfffc08 | | flutter#193267: password field with autofill hints | https://github.com/user-attachments/assets/7c57998f-4e80-42bc-bc3c-b7bdc49f27db | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] All existing and new tests are passing.
Fixes #192102
Fixes #193267
Problem
Toggling
TextField.obscureTexton Web sendsTextInput.updateConfig, which decodes a newEngineAutofillFormlacking an associated DOM form (formElement == null).On blur (
TextInput.clearClient), the web engine bypasses dormancy and tears down the active DOM input element. Refocusing the field leaves it unresponsive to keyboard events.Solution
Preserve the active
EngineAutofillFormacrossTextInput.updateConfiginDefaultTextEditingStrategy.applyConfiguration. This retains live DOM ownership so the form goes dormant on blur and wakes up cleanly on refocus.Testing
Added engine unit tests in
text_editing_test.dartfor multi-field and single-field autofill forms, verifying dormancy and refocus reusability.Screen.Recording.2026-09-24.at.15.42.06.mov
Screen.Recording.2026-09-24.at.15.42.42.mov
Pre-launch Checklist
///).