Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
e9edb8e1
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
e9edb8e1
编写于
10月 02, 2019
作者:
M
Mouad Debbar
提交者:
GitHub
10月 02, 2019
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support correct keymap for web (#12712)
上级
73c0397d
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
169 addition
and
38 deletion
+169
-38
lib/web_ui/lib/src/engine/keyboard.dart
lib/web_ui/lib/src/engine/keyboard.dart
+40
-17
lib/web_ui/test/keyboard_test.dart
lib/web_ui/test/keyboard_test.dart
+129
-21
未找到文件。
lib/web_ui/lib/src/engine/keyboard.dart
浏览文件 @
e9edb8e1
...
...
@@ -52,28 +52,51 @@ class Keyboard {
void
_handleHtmlEvent
(
html
.
KeyboardEvent
event
)
{
final
Map
<
String
,
dynamic
>
eventData
=
<
String
,
dynamic
>{
'type'
:
event
.
type
,
// TODO(yjbanov): this emulates Android because that the only reasonable
// thing to map to right now (the other choice is fuchsia).
// However, eventually we need to have something that maps
// better to Web.
'keymap'
:
'android'
,
'keyCode'
:
event
.
keyCode
,
'keymap'
:
'web'
,
'code'
:
event
.
code
,
'key'
:
event
.
key
,
'metaState'
:
_getMetaState
(
event
),
};
// TODO(yjbanov): The browser does not report `charCode` for 'keydown' and
// 'keyup', only for 'keypress'. This restores the value
// from the 'key' field. However, we need to verify how
// many code units a single key can have. Right now it
// assumes exactly one unit (that's what Flutter framework
// expects). But we'll need a different strategy if other
// code unit counts are possible.
if
(
event
.
key
.
codeUnits
.
length
==
1
)
{
eventData
[
'codePoint'
]
=
event
.
key
.
codeUnits
.
first
;
}
ui
.
window
.
onPlatformMessage
(
'flutter/keyevent'
,
_messageCodec
.
encodeMessage
(
eventData
),
_noopCallback
);
}
}
const
int
_modifierNone
=
0x00
;
const
int
_modifierShift
=
0x01
;
const
int
_modifierAlt
=
0x02
;
const
int
_modifierControl
=
0x04
;
const
int
_modifierMeta
=
0x08
;
const
int
_modifierNumLock
=
0x10
;
const
int
_modifierCapsLock
=
0x20
;
const
int
_modifierScrollLock
=
0x40
;
/// Creates a bitmask representing the meta state of the [event].
int
_getMetaState
(
html
.
KeyboardEvent
event
)
{
int
metaState
=
_modifierNone
;
if
(
event
.
getModifierState
(
'Shift'
))
{
metaState
|=
_modifierShift
;
}
if
(
event
.
getModifierState
(
'Alt'
))
{
metaState
|=
_modifierAlt
;
}
if
(
event
.
getModifierState
(
'Control'
))
{
metaState
|=
_modifierControl
;
}
if
(
event
.
getModifierState
(
'Meta'
))
{
metaState
|=
_modifierMeta
;
}
if
(
event
.
getModifierState
(
'NumLock'
))
{
metaState
|=
_modifierNumLock
;
}
if
(
event
.
getModifierState
(
'CapsLock'
))
{
metaState
|=
_modifierCapsLock
;
}
if
(
event
.
getModifierState
(
'ScrollLock'
))
{
metaState
|=
_modifierScrollLock
;
}
return
metaState
;
}
void
_noopCallback
(
ByteData
data
)
{}
lib/web_ui/test/keyboard_test.dart
浏览文件 @
e9edb8e1
...
...
@@ -3,6 +3,7 @@
// found in the LICENSE file.
import
'dart:html'
as
html
;
import
'dart:js_util'
as
js_util
;
import
'dart:typed_data'
;
import
'package:ui/src/engine.dart'
;
...
...
@@ -15,7 +16,7 @@ void main() {
test
(
'initializes'
,
()
{
expect
(
Keyboard
.
instance
,
isNull
);
Keyboard
.
initialize
();
expect
(
Keyboard
.
instance
,
is
NotNull
);
expect
(
Keyboard
.
instance
,
is
A
<
Keyboard
>()
);
});
test
(
'dispatches keyup to flutter/keyevent channel'
,
()
{
...
...
@@ -27,17 +28,16 @@ void main() {
dataReceived
=
const
JSONMessageCodec
().
decodeMessage
(
data
);
};
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keyup'
)
);
dispatchKeyboardEvent
(
'keyup'
,
key:
'SomeKey'
,
code:
'SomeCode'
);
expect
(
channelReceived
,
'flutter/keyevent'
);
expect
(
dataReceived
[
'type'
],
'keyup'
);
expect
(
dataReceived
[
'keymap'
],
'android'
);
// Unfortunately there's no way to fake `keyCode`.
expect
(
dataReceived
[
'keyCode'
],
0
);
// Unfortunately there's no way to fake `key`.
expect
(
dataReceived
,
isNot
(
contains
(
'codePoint'
)));
expect
(
dataReceived
,
<
String
,
dynamic
>{
'type'
:
'keyup'
,
'keymap'
:
'web'
,
'code'
:
'SomeCode'
,
'key'
:
'SomeKey'
,
'metaState'
:
0x0
,
});
});
test
(
'dispatches keydown to flutter/keyevent channel'
,
()
{
...
...
@@ -49,17 +49,96 @@ void main() {
dataReceived
=
const
JSONMessageCodec
().
decodeMessage
(
data
);
};
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keydown'
)
);
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
);
expect
(
channelReceived
,
'flutter/keyevent'
);
expect
(
dataReceived
[
'type'
],
'keydown'
);
expect
(
dataReceived
[
'keymap'
],
'android'
);
expect
(
dataReceived
,
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'web'
,
'code'
:
'SomeCode'
,
'key'
:
'SomeKey'
,
'metaState'
:
0x0
,
});
});
// Unfortunately there's no way to fake `keyCode`.
expect
(
dataReceived
[
'keyCode'
],
0
);
test
(
'dispatches correct meta state'
,
()
{
Map
<
String
,
dynamic
>
dataReceived
;
ui
.
window
.
onPlatformMessage
=
(
String
channel
,
ByteData
data
,
ui
.
PlatformMessageResponseCallback
callback
)
{
dataReceived
=
const
JSONMessageCodec
().
decodeMessage
(
data
);
};
// Unfortunately there's no way to fake `key`.
expect
(
dataReceived
,
isNot
(
contains
(
'codePoint'
)));
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
,
isControlPressed:
true
,
);
expect
(
dataReceived
,
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'web'
,
'code'
:
'SomeCode'
,
'key'
:
'SomeKey'
,
// ctrl
'metaState'
:
0x4
,
});
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
,
isShiftPressed:
true
,
isAltPressed:
true
,
isMetaPressed:
true
,
);
expect
(
dataReceived
,
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'web'
,
'code'
:
'SomeCode'
,
'key'
:
'SomeKey'
,
// shift alt meta
'metaState'
:
0x1
|
0x2
|
0x8
,
});
});
test
(
'dispatches repeat events'
,
()
{
List
<
Map
<
String
,
dynamic
>>
messages
=
<
Map
<
String
,
dynamic
>>[];
ui
.
window
.
onPlatformMessage
=
(
String
channel
,
ByteData
data
,
ui
.
PlatformMessageResponseCallback
callback
)
{
messages
.
add
(
const
JSONMessageCodec
().
decodeMessage
(
data
));
};
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
,
repeat:
true
,
);
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
,
repeat:
true
,
);
dispatchKeyboardEvent
(
'keydown'
,
key:
'SomeKey'
,
code:
'SomeCode'
,
repeat:
true
,
);
final
Map
<
String
,
dynamic
>
expectedMessage
=
<
String
,
dynamic
>{
'type'
:
'keydown'
,
'keymap'
:
'web'
,
'code'
:
'SomeCode'
,
'key'
:
'SomeKey'
,
'metaState'
:
0
,
};
expect
(
messages
,
<
Map
<
String
,
dynamic
>>[
expectedMessage
,
expectedMessage
,
expectedMessage
,
]);
});
test
(
'stops dispatching events after dispose'
,
()
{
...
...
@@ -69,19 +148,48 @@ void main() {
count
+=
1
;
};
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keydown'
)
);
dispatchKeyboardEvent
(
'keydown'
);
expect
(
count
,
1
);
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keyup'
)
);
dispatchKeyboardEvent
(
'keyup'
);
expect
(
count
,
2
);
Keyboard
.
instance
.
dispose
();
expect
(
Keyboard
.
instance
,
isNull
);
// No more event dispatching.
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keydown'
)
);
dispatchKeyboardEvent
(
'keydown'
);
expect
(
count
,
2
);
html
.
window
.
dispatchEvent
(
html
.
KeyboardEvent
(
'keyup'
)
);
dispatchKeyboardEvent
(
'keyup'
);
expect
(
count
,
2
);
});
});
}
void
dispatchKeyboardEvent
(
String
type
,
{
String
key
,
String
code
,
bool
repeat
=
false
,
bool
isShiftPressed
=
false
,
bool
isAltPressed
=
false
,
bool
isControlPressed
=
false
,
bool
isMetaPressed
=
false
,
})
{
final
Function
jsKeyboardEvent
=
js_util
.
getProperty
(
html
.
window
,
'KeyboardEvent'
);
final
List
<
dynamic
>
eventArgs
=
<
dynamic
>[
type
,
<
String
,
dynamic
>{
'key'
:
key
,
'code'
:
code
,
'repeat'
:
repeat
,
'shiftKey'
:
isShiftPressed
,
'altKey'
:
isAltPressed
,
'ctrlKey'
:
isControlPressed
,
'metaKey'
:
isMetaPressed
,
}
];
final
event
=
js_util
.
callConstructor
(
jsKeyboardEvent
,
js_util
.
jsify
(
eventArgs
));
html
.
window
.
dispatchEvent
(
event
);
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录