[web] Treeshake keymaps for web (4% code size reduction in hello world) (#75945)
diff --git a/packages/flutter/lib/src/services/raw_keyboard.dart b/packages/flutter/lib/src/services/raw_keyboard.dart
index 41e927a..bcddb0d 100644
--- a/packages/flutter/lib/src/services/raw_keyboard.dart
+++ b/packages/flutter/lib/src/services/raw_keyboard.dart
@@ -267,92 +267,106 @@
String? character;
final String keymap = message['keymap'] as String;
- switch (keymap) {
- case 'android':
- data = RawKeyEventDataAndroid(
- flags: message['flags'] as int? ?? 0,
- codePoint: message['codePoint'] as int? ?? 0,
- keyCode: message['keyCode'] as int? ?? 0,
- plainCodePoint: message['plainCodePoint'] as int? ?? 0,
- scanCode: message['scanCode'] as int? ?? 0,
- metaState: message['metaState'] as int? ?? 0,
- eventSource: message['source'] as int? ?? 0,
- vendorId: message['vendorId'] as int? ?? 0,
- productId: message['productId'] as int? ?? 0,
- deviceId: message['deviceId'] as int? ?? 0,
- repeatCount: message['repeatCount'] as int? ?? 0,
- );
- if (message.containsKey('character')) {
- character = message['character'] as String?;
- }
- break;
- case 'fuchsia':
- final int codePoint = message['codePoint'] as int? ?? 0;
- data = RawKeyEventDataFuchsia(
- hidUsage: message['hidUsage'] as int? ?? 0,
- codePoint: codePoint,
- modifiers: message['modifiers'] as int? ?? 0,
- );
- if (codePoint != 0) {
- character = String.fromCharCode(codePoint);
- }
- break;
- case 'macos':
- data = RawKeyEventDataMacOs(
- characters: message['characters'] as String? ?? '',
- charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
+ if (kIsWeb) {
+ final String? key = message['key'] as String?;
+ data = RawKeyEventDataWeb(
+ code: message['code'] as String? ?? '',
+ key: key ?? '',
+ metaState: message['metaState'] as int? ?? 0,
+ );
+ if (key != null && key.isNotEmpty) {
+ character = key;
+ }
+ } else {
+ switch (keymap) {
+ case 'android':
+ data = RawKeyEventDataAndroid(
+ flags: message['flags'] as int? ?? 0,
+ codePoint: message['codePoint'] as int? ?? 0,
keyCode: message['keyCode'] as int? ?? 0,
- modifiers: message['modifiers'] as int? ?? 0);
- character = message['characters'] as String?;
- break;
- case 'ios':
- data = RawKeyEventDataIos(
- characters: message['characters'] as String? ?? '',
- charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
- keyCode: message['keyCode'] as int? ?? 0,
- modifiers: message['modifiers'] as int? ?? 0);
- break;
- case 'linux':
- final int unicodeScalarValues = message['unicodeScalarValues'] as int? ?? 0;
- data = RawKeyEventDataLinux(
- keyHelper: KeyHelper(message['toolkit'] as String? ?? ''),
- unicodeScalarValues: unicodeScalarValues,
+ plainCodePoint: message['plainCodePoint'] as int? ?? 0,
+ scanCode: message['scanCode'] as int? ?? 0,
+ metaState: message['metaState'] as int? ?? 0,
+ eventSource: message['source'] as int? ?? 0,
+ vendorId: message['vendorId'] as int? ?? 0,
+ productId: message['productId'] as int? ?? 0,
+ deviceId: message['deviceId'] as int? ?? 0,
+ repeatCount: message['repeatCount'] as int? ?? 0,
+ );
+ if (message.containsKey('character')) {
+ character = message['character'] as String?;
+ }
+ break;
+ case 'fuchsia':
+ final int codePoint = message['codePoint'] as int? ?? 0;
+ data = RawKeyEventDataFuchsia(
+ hidUsage: message['hidUsage'] as int? ?? 0,
+ codePoint: codePoint,
+ modifiers: message['modifiers'] as int? ?? 0,
+ );
+ if (codePoint != 0) {
+ character = String.fromCharCode(codePoint);
+ }
+ break;
+ case 'macos':
+ data = RawKeyEventDataMacOs(
+ characters: message['characters'] as String? ?? '',
+ charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
+ keyCode: message['keyCode'] as int? ?? 0,
+ modifiers: message['modifiers'] as int? ?? 0);
+ character = message['characters'] as String?;
+ break;
+ case 'ios':
+ data = RawKeyEventDataIos(
+ characters: message['characters'] as String? ?? '',
+ charactersIgnoringModifiers: message['charactersIgnoringModifiers'] as String? ?? '',
+ keyCode: message['keyCode'] as int? ?? 0,
+ modifiers: message['modifiers'] as int? ?? 0);
+ break;
+ case 'linux':
+ final int unicodeScalarValues = message['unicodeScalarValues'] as int? ?? 0;
+ data = RawKeyEventDataLinux(
+ keyHelper: KeyHelper(message['toolkit'] as String? ?? ''),
+ unicodeScalarValues: unicodeScalarValues,
+ keyCode: message['keyCode'] as int? ?? 0,
+ scanCode: message['scanCode'] as int? ?? 0,
+ modifiers: message['modifiers'] as int? ?? 0,
+ isDown: message['type'] == 'keydown');
+ if (unicodeScalarValues != 0) {
+ character = String.fromCharCode(unicodeScalarValues);
+ }
+ break;
+ case 'windows':
+ final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
+ data = RawKeyEventDataWindows(
keyCode: message['keyCode'] as int? ?? 0,
scanCode: message['scanCode'] as int? ?? 0,
+ characterCodePoint: characterCodePoint,
modifiers: message['modifiers'] as int? ?? 0,
- isDown: message['type'] == 'keydown');
- if (unicodeScalarValues != 0) {
- character = String.fromCharCode(unicodeScalarValues);
- }
- break;
- case 'web':
- data = RawKeyEventDataWeb(
- code: message['code'] as String? ?? '',
- key: message['key'] as String? ?? '',
- metaState: message['metaState'] as int? ?? 0,
- );
- character = message['key'] as String?;
- break;
- case 'windows':
- final int characterCodePoint = message['characterCodePoint'] as int? ?? 0;
- data = RawKeyEventDataWindows(
- keyCode: message['keyCode'] as int? ?? 0,
- scanCode: message['scanCode'] as int? ?? 0,
- characterCodePoint: characterCodePoint,
- modifiers: message['modifiers'] as int? ?? 0,
- );
- if (characterCodePoint != 0) {
- character = String.fromCharCode(characterCodePoint);
- }
- break;
- default:
- /// This exception would only be hit on platforms that haven't yet
- /// implemented raw key events, but will only be triggered if the
- /// engine for those platforms sends raw key event messages in the
- /// first place.
- throw FlutterError('Unknown keymap for key events: $keymap');
+ );
+ if (characterCodePoint != 0) {
+ character = String.fromCharCode(characterCodePoint);
+ }
+ break;
+ case 'web':
+ final String? key = message['key'] as String?;
+ data = RawKeyEventDataWeb(
+ code: message['code'] as String? ?? '',
+ key: key ?? '',
+ metaState: message['metaState'] as int? ?? 0,
+ );
+ if (key != null && key.isNotEmpty) {
+ character = key;
+ }
+ break;
+ default:
+ /// This exception would only be hit on platforms that haven't yet
+ /// implemented raw key events, but will only be triggered if the
+ /// engine for those platforms sends raw key event messages in the
+ /// first place.
+ throw FlutterError('Unknown keymap for key events: $keymap');
+ }
}
-
final String type = message['type'] as String;
switch (type) {
case 'keydown':
diff --git a/packages/flutter/test/services/raw_keyboard_test.dart b/packages/flutter/test/services/raw_keyboard_test.dart
index 2e0b3ef..1b40acb 100644
--- a/packages/flutter/test/services/raw_keyboard_test.dart
+++ b/packages/flutter/test/services/raw_keyboard_test.dart
@@ -31,7 +31,7 @@
}
});
testWidgets('No character is produced for non-printables', (WidgetTester tester) async {
- for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows']) {
+ for (final String platform in <String>['linux', 'android', 'macos', 'fuchsia', 'windows', 'web']) {
void handleKey(RawKeyEvent event) {
expect(event.character, isNull, reason: 'on $platform');
}
@@ -194,7 +194,7 @@
await simulateKeyUpEvent(LogicalKeyboardKey.keyA, platform: platform, physicalKey: PhysicalKeyboardKey.keyA);
expect(RawKeyboard.instance.keysPressed, isEmpty, reason: 'on $platform');
}
- });
+ }, skip: isBrowser); // https://github.com/flutter/flutter/issues/76741
testWidgets('keysPressed modifiers are synchronized with key events on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -219,7 +219,7 @@
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
),
);
- });
+ }, skip: isBrowser); // This is a macOS-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on iOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -244,7 +244,7 @@
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
),
);
- });
+ }, skip: isBrowser); // This is an iOS-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on Windows', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -269,7 +269,7 @@
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
),
);
- });
+ }, skip: isBrowser); // This is a Windows-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on android', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -294,7 +294,7 @@
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
),
);
- });
+ }, skip: isBrowser); // This is an Android-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on fuchsia', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -319,7 +319,7 @@
<LogicalKeyboardKey>{LogicalKeyboardKey.shiftLeft, LogicalKeyboardKey.keyA},
),
);
- });
+ }, skip: isBrowser); // This is a Fuchsia-specific test.
testWidgets('keysPressed modifiers are synchronized with key events on Linux GLFW', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -350,6 +350,37 @@
},
),
);
+ }, skip: isBrowser); // This is a GLFW-specific test.
+
+ testWidgets('keysPressed modifiers are synchronized with key events on web', (WidgetTester tester) async {
+ expect(RawKeyboard.instance.keysPressed, isEmpty);
+ // Generate the data for a regular key down event.
+ final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
+ LogicalKeyboardKey.keyA,
+ platform: 'web',
+ isDown: true,
+ );
+ // Change the modifiers so that they show the shift key as already down
+ // when this event is received, but it's not in keysPressed yet.
+ data['metaState'] |= RawKeyEventDataWeb.modifierShift;
+ // dispatch the modified data.
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ SystemChannels.keyEvent.name,
+ SystemChannels.keyEvent.codec.encodeMessage(data),
+ (ByteData? data) {},
+ );
+ expect(
+ RawKeyboard.instance.keysPressed,
+ equals(
+ <LogicalKeyboardKey>{
+ LogicalKeyboardKey.shiftLeft,
+ // Web doesn't distinguish between left and right keys, so they're
+ // all shown as down when either is pressed.
+ LogicalKeyboardKey.shiftRight,
+ LogicalKeyboardKey.keyA,
+ },
+ ),
+ );
});
testWidgets('sided modifiers without a side set return all sides on Android', (WidgetTester tester) async {
@@ -388,7 +419,7 @@
},
),
);
- });
+ }, skip: isBrowser); // This is an Android-specific test.
testWidgets('sided modifiers without a side set return all sides on macOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -426,7 +457,7 @@
},
),
);
- });
+ }, skip: isBrowser); // This is a macOS-specific test.
testWidgets('sided modifiers without a side set return all sides on iOS', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -464,7 +495,7 @@
},
),
);
- });
+ }, skip: isBrowser); // This is an iOS-specific test.
testWidgets('sided modifiers without a side set return all sides on Windows', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -500,7 +531,7 @@
},
),
);
- });
+ }, skip: isBrowser); // This is a Windows-specific test.
testWidgets('sided modifiers without a side set return all sides on Linux GLFW', (WidgetTester tester) async {
expect(RawKeyboard.instance.keysPressed, isEmpty);
@@ -539,6 +570,44 @@
},
),
);
+ }, skip: isBrowser); // This is a GLFW-specific test.
+
+ testWidgets('sided modifiers without a side set return all sides on web', (WidgetTester tester) async {
+ expect(RawKeyboard.instance.keysPressed, isEmpty);
+ // Generate the data for a regular key down event.
+ final Map<String, dynamic> data = KeyEventSimulator.getKeyData(
+ LogicalKeyboardKey.keyA,
+ platform: 'web',
+ isDown: true,
+ );
+ // Set only the generic "shift down" modifier, without setting a side.
+ data['metaState'] |=
+ RawKeyEventDataWeb.modifierShift |
+ RawKeyEventDataWeb.modifierAlt |
+ RawKeyEventDataWeb.modifierControl |
+ RawKeyEventDataWeb.modifierMeta;
+ // dispatch the modified data.
+ await ServicesBinding.instance!.defaultBinaryMessenger.handlePlatformMessage(
+ SystemChannels.keyEvent.name,
+ SystemChannels.keyEvent.codec.encodeMessage(data),
+ (ByteData? data) {},
+ );
+ expect(
+ RawKeyboard.instance.keysPressed,
+ equals(
+ <LogicalKeyboardKey>{
+ LogicalKeyboardKey.shiftLeft,
+ LogicalKeyboardKey.shiftRight,
+ LogicalKeyboardKey.altLeft,
+ LogicalKeyboardKey.altRight,
+ LogicalKeyboardKey.controlLeft,
+ LogicalKeyboardKey.controlRight,
+ LogicalKeyboardKey.metaLeft,
+ LogicalKeyboardKey.metaRight,
+ LogicalKeyboardKey.keyA,
+ },
+ ),
+ );
});
testWidgets('RawKeyboard asserts if no keys are in keysPressed after receiving a key down event', (WidgetTester tester) async {
@@ -547,19 +616,32 @@
FlutterError.onError = (FlutterErrorDetails details) {
errorDetails = details;
};
+
+ final Map<String, dynamic> keyEventMessage;
+ if (kIsWeb) {
+ keyEventMessage = const <String, dynamic>{
+ 'type': 'keydown',
+ 'keymap': 'web',
+ 'code': 'ShiftLeft', // Left shift code
+ 'metaState': 0x0, // No shift key metaState set!
+ };
+ } else {
+ keyEventMessage = const <String, dynamic>{
+ 'type': 'keydown',
+ 'keymap': 'android',
+ 'keyCode': 0x3b, // Left shift key keyCode
+ 'scanCode': 0x2a,
+ 'metaState': 0x0, // No shift key metaState set!
+ 'source': 0x101,
+ 'deviceId': 1,
+ };
+ }
+
try {
await ServicesBinding.instance!.defaultBinaryMessenger
.handlePlatformMessage(
SystemChannels.keyEvent.name,
- SystemChannels.keyEvent.codec.encodeMessage(const <String, dynamic>{
- 'type': 'keydown',
- 'keymap': 'android',
- 'keyCode': 0x3b, // Left shift key keyCode
- 'scanCode': 0x2a,
- 'metaState': 0x0, // No shift key metaState set!
- 'source': 0x101,
- 'deviceId': 1,
- }),
+ SystemChannels.keyEvent.codec.encodeMessage(keyEventMessage),
(ByteData? data) {},
);
} finally {
@@ -837,7 +919,8 @@
expect(message, equals(<String, dynamic>{ 'handled': true }));
ServicesBinding.instance!.defaultBinaryMessenger.setMockMessageHandler(SystemChannels.keyEvent.name, null);
});
- });
+ }, skip: isBrowser); // This is an Android-specific group.
+
group('RawKeyEventDataFuchsia', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
RawKeyEventDataFuchsia.modifierAlt: _ModifierCheck(ModifierKey.altModifier, KeyboardSide.any),
@@ -951,7 +1034,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
- });
+ }, skip: isBrowser); // This is a Fuchsia-specific group.
group('RawKeyEventDataMacOs', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
@@ -1097,7 +1180,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
expect(data.logicalKey.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
- });
+ }, skip: isBrowser); // This is a macOS-specific group.
group('RawKeyEventDataIos', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
@@ -1243,7 +1326,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
expect(data.logicalKey.keyLabel, isEmpty);
}, skip: isBrowser); // https://github.com/flutter/flutter/issues/35347
- });
+ }, skip: isBrowser); // This is an iOS-specific group.
group('RawKeyEventDataWindows', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
@@ -1388,7 +1471,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.arrowLeft));
expect(data.logicalKey.keyLabel, isEmpty);
});
- });
+ }, skip: isBrowser); // This is a Windows-specific group.
group('RawKeyEventDataLinux-GFLW', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
@@ -1572,7 +1655,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
});
- });
+ }, skip: isBrowser); // This is a GLFW-specific group.
group('RawKeyEventDataLinux-GTK', () {
const Map<int, _ModifierCheck> modifierTests = <int, _ModifierCheck>{
@@ -1756,7 +1839,7 @@
expect(data.logicalKey, equals(LogicalKeyboardKey.shiftLeft));
expect(data.keyLabel, isEmpty);
});
- });
+ }, skip: isBrowser); // This is a GTK-specific group.
group('RawKeyEventDataWeb', () {
const Map<int, ModifierKey> modifierTests = <int, ModifierKey>{
diff --git a/packages/flutter/test/widgets/raw_keyboard_listener_test.dart b/packages/flutter/test/widgets/raw_keyboard_listener_test.dart
index bcac58d..3149e0d 100644
--- a/packages/flutter/test/widgets/raw_keyboard_listener_test.dart
+++ b/packages/flutter/test/widgets/raw_keyboard_listener_test.dart
@@ -44,6 +44,37 @@
await tester.pumpWidget(Container());
focusNode.dispose();
+ }, skip: isBrowser); // This is a Fuchsia-specific test.
+
+ testWidgets('Web key event', (WidgetTester tester) async {
+ final List<RawKeyEvent> events = <RawKeyEvent>[];
+
+ final FocusNode focusNode = FocusNode();
+
+ await tester.pumpWidget(
+ RawKeyboardListener(
+ focusNode: focusNode,
+ onKey: events.add,
+ child: Container(),
+ ),
+ );
+
+ focusNode.requestFocus();
+ await tester.idle();
+
+ await tester.sendKeyEvent(LogicalKeyboardKey.metaLeft, platform: 'web');
+ await tester.idle();
+
+ expect(events.length, 2);
+ expect(events[0].runtimeType, equals(RawKeyDownEvent));
+ expect(events[0].data, isA<RawKeyEventDataWeb>());
+ final RawKeyEventDataWeb typedData = events[0].data as RawKeyEventDataWeb;
+ expect(typedData.code, 'MetaLeft');
+ expect(typedData.metaState, RawKeyEventDataWeb.modifierMeta);
+ expect(typedData.isModifierPressed(ModifierKey.metaModifier, side: KeyboardSide.left), isTrue);
+
+ await tester.pumpWidget(Container());
+ focusNode.dispose();
});
testWidgets('Defunct listeners do not receive events', (WidgetTester tester) async {
diff --git a/packages/flutter_test/lib/src/event_simulation.dart b/packages/flutter_test/lib/src/event_simulation.dart
index 82451d2..b99dab8 100644
--- a/packages/flutter_test/lib/src/event_simulation.dart
+++ b/packages/flutter_test/lib/src/event_simulation.dart
@@ -4,6 +4,7 @@
import 'dart:io';
+import 'package:flutter/foundation.dart' show kIsWeb;
import 'package:flutter/services.dart';
import 'test_async_utils.dart';
@@ -85,40 +86,47 @@
static int _getKeyCode(LogicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
- late Map<int, LogicalKeyboardKey> map;
- switch (platform) {
- case 'android':
- map = kAndroidToLogicalKey;
- break;
- case 'fuchsia':
- map = kFuchsiaToLogicalKey;
- break;
- case 'macos':
- // macOS doesn't do key codes, just scan codes.
- return -1;
- case 'ios':
- // iOS doesn't do key codes, just scan codes.
- return -1;
- case 'web':
- // web doesn't have int type code
- return -1;
- case 'linux':
- map = kGlfwToLogicalKey;
- break;
- case 'windows':
- map = kWindowsToLogicalKey;
- break;
- }
- int? keyCode;
- for (final int code in map.keys) {
- if (key.keyId == map[code]!.keyId) {
- keyCode = code;
- break;
+ if (kIsWeb) {
+ // web doesn't have int type code. This check is used to treeshake
+ // keyboard map code.
+ return -1;
+ } else {
+ late Map<int, LogicalKeyboardKey> map;
+ switch (platform) {
+ case 'android':
+ map = kAndroidToLogicalKey;
+ break;
+ case 'fuchsia':
+ map = kFuchsiaToLogicalKey;
+ break;
+ case 'macos':
+ // macOS doesn't do key codes, just scan codes.
+ return -1;
+ case 'ios':
+ // iOS doesn't do key codes, just scan codes.
+ return -1;
+ case 'web':
+ // web doesn't have int type code.
+ return -1;
+ case 'linux':
+ map = kGlfwToLogicalKey;
+ break;
+ case 'windows':
+ map = kWindowsToLogicalKey;
+ break;
}
+ int? keyCode;
+ for (final int code in map.keys) {
+ if (key.keyId == map[code]!.keyId) {
+ keyCode = code;
+ break;
+ }
+ }
+ assert(keyCode != null, 'Key $key not found in $platform keyCode map');
+ return keyCode!;
}
- assert(keyCode != null, 'Key $key not found in $platform keyCode map');
- return keyCode!;
}
+
static String _getWebKeyCode(LogicalKeyboardKey key) {
String? result;
for (final String code in kWebToLogicalKey.keys) {
@@ -134,28 +142,33 @@
static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
late Map<dynamic, PhysicalKeyboardKey> map;
- switch (platform) {
- case 'android':
- map = kAndroidToPhysicalKey;
- break;
- case 'fuchsia':
- map = kFuchsiaToPhysicalKey;
- break;
- case 'macos':
- map = kMacOsToPhysicalKey;
- break;
- case 'ios':
- map = kIosToPhysicalKey;
- break;
- case 'linux':
- map = kLinuxToPhysicalKey;
- break;
- case 'web':
- map = kWebToPhysicalKey;
- break;
- case 'windows':
- map = kWindowsToPhysicalKey;
- break;
+ if (kIsWeb) {
+ // This check is used to treeshake keymap code.
+ map = kWebToPhysicalKey;
+ } else {
+ switch (platform) {
+ case 'android':
+ map = kAndroidToPhysicalKey;
+ break;
+ case 'fuchsia':
+ map = kFuchsiaToPhysicalKey;
+ break;
+ case 'macos':
+ map = kMacOsToPhysicalKey;
+ break;
+ case 'ios':
+ map = kIosToPhysicalKey;
+ break;
+ case 'linux':
+ map = kLinuxToPhysicalKey;
+ break;
+ case 'web':
+ map = kWebToPhysicalKey;
+ break;
+ case 'windows':
+ map = kWindowsToPhysicalKey;
+ break;
+ }
}
PhysicalKeyboardKey? result;
for (final PhysicalKeyboardKey physicalKey in map.values) {
@@ -191,6 +204,13 @@
'keymap': platform,
};
+ if (kIsWeb) {
+ result['code'] = _getWebKeyCode(key);
+ result['key'] = key.keyLabel;
+ result['metaState'] = _getWebModifierFlags(key, isDown);
+ return result;
+ }
+
switch (platform) {
case 'android':
result['keyCode'] = keyCode;