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

Commit 53d66aa

Browse files
authored
[web] Add styling in CSS reset to remove Edge password reveal icon (#38011)
* Add pseudoelement css to remove password reveal * Add comments * Add changes to inject style tag to shadow root on Edge browsers * Remove print statement * Dart lint * Whitespace * Fix comments * Change to getter
1 parent d82c8ad commit 53d66aa

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

lib/web_ui/lib/src/engine/browser_detection.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ bool get isSafari => browserEngine == BrowserEngine.webkit;
223223
/// Whether the current browser is Firefox.
224224
bool get isFirefox => browserEngine == BrowserEngine.firefox;
225225

226+
/// Whether the current browser is Edge.
227+
bool get isEdge => domWindow.navigator.userAgent.contains('Edg/');
228+
226229
/// Use in tests to simulate the detection of iOS 15.
227230
bool? debugIsIOS15;
228231

lib/web_ui/lib/src/engine/dom.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ extension DomNodeExtension on DomNode {
212212
external String? get baseUri;
213213
external DomNode? get firstChild;
214214
external String get innerText;
215+
external set innerText(String text);
215216
external DomNode? get lastChild;
216217
external DomNode appendChild(DomNode node);
217218
DomElement? get parent => js_util.getProperty(this, 'parentElement');

lib/web_ui/lib/src/engine/host_node.dart

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ class ShadowDomHostNode implements HostNode {
9191
/// This also calls [applyGlobalCssRulesToSheet], defined in dom_renderer.
9292
ShadowDomHostNode(DomElement root) :
9393
assert(
94-
root.isConnected ?? true,
95-
'The `root` of a ShadowDomHostNode must be connected to the Document object or a ShadowRoot.',
96-
) {
94+
root.isConnected ?? true,
95+
'The `root` of a ShadowDomHostNode must be connected to the Document object or a ShadowRoot.',
96+
) {
9797
_shadow = root.attachShadow(<String, dynamic>{
9898
'mode': 'open',
9999
// This needs to stay false to prevent issues like this:
@@ -111,6 +111,19 @@ class ShadowDomHostNode implements HostNode {
111111
browserEngine: browserEngine,
112112
hasAutofillOverlay: browserHasAutofillOverlay(),
113113
);
114+
115+
// Removes password reveal icon for text inputs in Edge browsers.
116+
// Style tag needs to be injected into DOM because non-Edge
117+
// browsers will crash trying to parse -ms-reveal CSS selectors if added via
118+
// sheet.insertRule().
119+
// See: https://github.com/flutter/flutter/issues/83695
120+
if (isEdge) {
121+
final DomHTMLStyleElement edgeStyleElement = createDomHTMLStyleElement();
122+
123+
edgeStyleElement.id = 'ms-reveal';
124+
edgeStyleElement.innerText = 'input::-ms-reveal {display: none;}';
125+
_shadow.appendChild(edgeStyleElement);
126+
}
114127
}
115128

116129
late DomShadowRoot _shadow;

lib/web_ui/test/engine/host_node_test.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ void testMain() {
3939
expect(firstChild.tagName, equalsIgnoringCase('style'));
4040
});
4141

42+
test('Attaches styling to remove password reveal icons on Edge', () {
43+
final DomElement? edgeStyleElement = hostNode.querySelector('#ms-reveal');
44+
45+
expect(edgeStyleElement, isNotNull);
46+
expect(edgeStyleElement!.innerText, 'input::-ms-reveal {display: none;}');
47+
}, skip: !isEdge);
48+
49+
test('Does not attach the Edge-specific style tag on non-Edge browsers',
50+
() {
51+
final DomElement? edgeStyleElement = hostNode.querySelector('#ms-reveal');
52+
expect(edgeStyleElement, isNull);
53+
}, skip: isEdge);
54+
4255
_runDomTests(hostNode);
4356
});
4457

0 commit comments

Comments
 (0)