Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

[web] Hide autofill overlay #39294

Merged
merged 6 commits into from
Feb 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions lib/web_ui/lib/src/engine/host_node.dart
Original file line number Diff line number Diff line change
Expand Up @@ -317,16 +317,16 @@ void applyGlobalCssRulesToSheet(
}
''', sheet.cssRules.length);

// This css prevents an autofill overlay brought by the browser during
// text field autofill by delaying the transition effect.
// See: https://github.com/flutter/flutter/issues/61132.
// This CSS makes the autofill overlay transparent in order to prevent it
// from overlaying on top of Flutter-rendered text inputs.
// See: https://github.com/flutter/flutter/issues/118337.
if (browserHasAutofillOverlay()) {
sheet.insertRule('''
$cssSelectorPrefix .transparentTextEditing:-webkit-autofill,
$cssSelectorPrefix .transparentTextEditing:-webkit-autofill:hover,
$cssSelectorPrefix .transparentTextEditing:-webkit-autofill:focus,
$cssSelectorPrefix .transparentTextEditing:-webkit-autofill:active {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we start targeting the standard :autofill pseudo-class as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does mention here https://developer.mozilla.org/en-US/docs/Web/CSS/:autofill to use both for best browser compatibility, but in manual testing:

  • I was able to use the CSSOM to read the above :-webkit-autofill style on every browser. Like you mentioned above, safari and firefox just read it internally as :autofill
  • Interestingly enough, Chrome wouldn't read it at all if we just used :autofill...chrome and edge both need the webkit prefix.

So we can certainly conditionally target the :autofill selector for Firefox and Safari for "completeness", but it works fine as is too. The one downside I see in targeting :autofill as well is that it won't work for older versions of those browsers.

What do you think?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that until firefox and safari break because they don't recognize -webkit-autofill, we're fine :P

-webkit-transition-delay: 99999s;
opacity: 0 !important;
}
''', sheet.cssRules.length);
}
Expand Down
25 changes: 25 additions & 0 deletions lib/web_ui/test/engine/host_node_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,31 @@ void testMain() {
expect(hidesRevealIcons, isFalse);
}, skip: isEdge);

test(
'Attaches styles to hide the autofill overlay for browsers that support it',
() {
final DomElement? style =
hostNode.querySelector('#flt-internals-stylesheet');
final String vendorPrefix = (isSafari || isFirefox) ? '' : '-webkit-';
final bool autofillOverlay = hasCssRule(style,
selector: '.transparentTextEditing:${vendorPrefix}autofill',
declaration: 'opacity: 0 !important');
final bool autofillOverlayHovered = hasCssRule(style,
selector: '.transparentTextEditing:${vendorPrefix}autofill:hover',
declaration: 'opacity: 0 !important');
final bool autofillOverlayFocused = hasCssRule(style,
selector: '.transparentTextEditing:${vendorPrefix}autofill:focus',
declaration: 'opacity: 0 !important');
final bool autofillOverlayActive = hasCssRule(style,
selector: '.transparentTextEditing:${vendorPrefix}autofill:active',
declaration: 'opacity: 0 !important');

expect(autofillOverlay, isTrue);
expect(autofillOverlayHovered, isTrue);
expect(autofillOverlayFocused, isTrue);
expect(autofillOverlayActive, isTrue);
}, skip: !browserHasAutofillOverlay());

_runDomTests(hostNode);
});

Expand Down