diff --git a/lib/web_ui/lib/src/engine/keyboard.dart b/lib/web_ui/lib/src/engine/keyboard.dart index 8779e095d552d..8307bbac369b6 100644 --- a/lib/web_ui/lib/src/engine/keyboard.dart +++ b/lib/web_ui/lib/src/engine/keyboard.dart @@ -80,11 +80,6 @@ class Keyboard { } final html.KeyboardEvent keyboardEvent = event; - - if (_shouldPreventDefault(event)) { - event.preventDefault(); - } - final String timerKey = keyboardEvent.code!; // Don't handle synthesizing a keyup event for modifier keys @@ -132,16 +127,17 @@ class Keyboard { }; EnginePlatformDispatcher.instance.invokeOnPlatformMessage('flutter/keyevent', - _messageCodec.encodeMessage(eventData), _noopCallback); - } - - bool _shouldPreventDefault(html.KeyboardEvent event) { - switch (event.key) { - case 'Tab': - return true; - default: - return false; - } + _messageCodec.encodeMessage(eventData), (ByteData? data) { + if (data == null) { + return; + } + final Map jsonResponse = _messageCodec.decodeMessage(data); + if (jsonResponse['handled'] as bool) { + // If the framework handled it, then don't propagate it any further. + event.preventDefault(); + } + }, + ); } void _synthesizeKeyup(html.KeyboardEvent event) { diff --git a/lib/web_ui/test/keyboard_test.dart b/lib/web_ui/test/keyboard_test.dart index c16fe89467b03..2b042b9fc1f87 100644 --- a/lib/web_ui/test/keyboard_test.dart +++ b/lib/web_ui/test/keyboard_test.dart @@ -226,13 +226,15 @@ void testMain() { expect(count, 2); }); - test('prevents default when "Tab" is pressed', () { + test('prevents default when key is handled by the framework', () { Keyboard.initialize(); int count = 0; ui.window.onPlatformMessage = (String channel, ByteData data, ui.PlatformMessageResponseCallback callback) { count += 1; + ByteData response = const JSONMessageCodec().encodeMessage({'handled': true}); + callback(response); }; final html.KeyboardEvent event = dispatchKeyboardEvent( @@ -247,6 +249,29 @@ void testMain() { Keyboard.instance.dispose(); }); + test("Doesn't prevent default when key is not handled by the framework", () { + Keyboard.initialize(); + + int count = 0; + ui.window.onPlatformMessage = (String channel, ByteData data, + ui.PlatformMessageResponseCallback callback) { + count += 1; + ByteData response = const JSONMessageCodec().encodeMessage({'handled': false}); + callback(response); + }; + + final html.KeyboardEvent event = dispatchKeyboardEvent( + 'keydown', + key: 'Tab', + code: 'Tab', + ); + + expect(event.defaultPrevented, isFalse); + expect(count, 1); + + Keyboard.instance.dispose(); + }); + test('keyboard events should be triggered on text fields', () { Keyboard.initialize(); @@ -278,6 +303,8 @@ void testMain() { ui.window.onPlatformMessage = (String channel, ByteData data, ui.PlatformMessageResponseCallback callback) { count += 1; + ByteData response = const JSONMessageCodec().encodeMessage({'handled': true}); + callback(response); }; useTextEditingElement((html.Element element) {