From eb939028f90feebbb1b32da7ca1532a0e4aa044f Mon Sep 17 00:00:00 2001 From: nturgut Date: Thu, 8 Oct 2020 10:10:12 -0700 Subject: [PATCH] fixing the autofill overlay problem (blue area for chrome) (#21610) * fixing the autofill overlay problem (blue area for chrome) * addression comments --- lib/web_ui/lib/src/engine/dom_renderer.dart | 15 ++++++++++++ .../src/engine/text_editing/text_editing.dart | 20 +++++++++++++++- lib/web_ui/test/text_editing_test.dart | 23 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/web_ui/lib/src/engine/dom_renderer.dart b/lib/web_ui/lib/src/engine/dom_renderer.dart index 9e1a3b50f..415ea66c8 100644 --- a/lib/web_ui/lib/src/engine/dom_renderer.dart +++ b/lib/web_ui/lib/src/engine/dom_renderer.dart @@ -307,6 +307,21 @@ flt-glass-pane * { ''', 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. + if(browserHasAutofillOverlay()) { + sheet.insertRule(''' +.transparentTextEditing:-webkit-autofill, +.transparentTextEditing:-webkit-autofill:hover, +.transparentTextEditing:-webkit-autofill:focus, +.transparentTextEditing:-webkit-autofill:active { + -webkit-transition-delay: 99999s; +} +''', sheet.cssRules.length); + } + + final html.BodyElement bodyElement = html.document.body!; setElementStyle(bodyElement, 'position', 'fixed'); setElementStyle(bodyElement, 'top', '0'); diff --git a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart index 5d298bed3..ce8b31d5f 100644 --- a/lib/web_ui/lib/src/engine/text_editing/text_editing.dart +++ b/lib/web_ui/lib/src/engine/text_editing/text_editing.dart @@ -11,6 +11,16 @@ bool _debugVisibleTextEditing = false; /// The `keyCode` of the "Enter" key. const int _kReturnKeyCode = 13; +/// Blink and Webkit engines, bring an overlay on top of the text field when it +/// is autofilled. +bool browserHasAutofillOverlay() => + browserEngine == BrowserEngine.blink || + browserEngine == BrowserEngine.webkit; + +/// `transparentTextEditing` class is configured to make the autofill overlay +/// transparent. +const String transparentTextEditingClass = 'transparentTextEditing'; + void _emptyCallback(dynamic _) {} /// These style attributes are constant throughout the life time of an input @@ -39,7 +49,11 @@ void _setStaticStyleAttributes(html.HtmlElement domElement) { ..overflow = 'hidden' ..transformOrigin = '0 0 0'; - /// This property makes the input's blinking cursor transparent. + if (browserHasAutofillOverlay()) { + domElement.classes.add(transparentTextEditingClass); + } + + // This property makes the input's blinking cursor transparent. elementStyle.setProperty('caret-color', 'transparent'); if (_debugVisibleTextEditing) { @@ -80,6 +94,10 @@ void _hideAutofillElements(html.HtmlElement domElement, ..left = '-9999px'; } + if (browserHasAutofillOverlay()) { + domElement.classes.add(transparentTextEditingClass); + } + /// This property makes the input's blinking cursor transparent. elementStyle.setProperty('caret-color', 'transparent'); } diff --git a/lib/web_ui/test/text_editing_test.dart b/lib/web_ui/test/text_editing_test.dart index a5bc7fa21..c8efd8182 100644 --- a/lib/web_ui/test/text_editing_test.dart +++ b/lib/web_ui/test/text_editing_test.dart @@ -1343,6 +1343,18 @@ void testMain() { '500 12px sans-serif', ); + // For `blink` and `webkit` browser engines the overlay would be hidden. + if (browserEngine == BrowserEngine.blink || + browserEngine == BrowserEngine.webkit) { + expect(textEditing.editingElement.domElement.classes, + contains('transparentTextEditing')); + } else { + expect( + textEditing.editingElement.domElement.classes.any( + (element) => element.toString() == 'transparentTextEditing'), + isFalse); + } + const MethodCall clearClient = MethodCall('TextInput.clearClient'); sendFrameworkMessage(codec.encodeMethodCall(clearClient)); }, @@ -1806,6 +1818,17 @@ void testMain() { final CssStyleDeclaration css = firstElement.style; expect(css.color, 'transparent'); expect(css.backgroundColor, 'transparent'); + + // For `blink` and `webkit` browser engines the overlay would be hidden. + if (browserEngine == BrowserEngine.blink || + browserEngine == BrowserEngine.webkit) { + expect(firstElement.classes, contains('transparentTextEditing')); + } else { + expect( + firstElement.classes.any( + (element) => element.toString() == 'transparentTextEditing'), + isFalse); + } }); test('validate multi element form ids sorted for form id', () { -- GitLab