Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Sign in
Toggle navigation
F
Front-End
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
abdullh.alsoleman
Front-End
Commits
cc9b78fc
Unverified
Commit
cc9b78fc
authored
Feb 25, 2021
by
Ferhat
Committed by
GitHub
Feb 25, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[web] Treeshake keymaps for web (4% code size reduction in hello world) (#75945)
parent
3e77f5e4
Changes
4
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
309 additions
and
161 deletions
+309
-161
raw_keyboard.dart
packages/flutter/lib/src/services/raw_keyboard.dart
+95
-81
raw_keyboard_test.dart
packages/flutter/test/services/raw_keyboard_test.dart
+110
-27
raw_keyboard_listener_test.dart
...ages/flutter/test/widgets/raw_keyboard_listener_test.dart
+31
-0
event_simulation.dart
packages/flutter_test/lib/src/event_simulation.dart
+73
-53
No files found.
packages/flutter/lib/src/services/raw_keyboard.dart
View file @
cc9b78fc
...
...
@@ -267,92 +267,106 @@ abstract class RawKeyEvent with Diagnosticable {
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
?
??
''
,
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
?
??
''
,
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
);
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'
:
...
...
packages/flutter/test/services/raw_keyboard_test.dart
View file @
cc9b78fc
This diff is collapsed.
Click to expand it.
packages/flutter/test/widgets/raw_keyboard_listener_test.dart
View file @
cc9b78fc
...
...
@@ -42,6 +42,37 @@ void main() {
expect
(
typedData
.
modifiers
,
RawKeyEventDataFuchsia
.
modifierLeftMeta
);
expect
(
typedData
.
isModifierPressed
(
ModifierKey
.
metaModifier
,
side:
KeyboardSide
.
left
),
isTrue
);
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
();
});
...
...
packages/flutter_test/lib/src/event_simulation.dart
View file @
cc9b78fc
...
...
@@ -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 @@ class KeyEventSimulator {
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 @@ class KeyEventSimulator {
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 @@ class KeyEventSimulator {
'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
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment