Unverified Commit d62c7ecc authored by cjng96's avatar cjng96 Committed by GitHub

Ignore key events on edit control on web platform (#52656) (#52661)

parent 2a649b16
......@@ -473,6 +473,11 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
// string using Unicode scalar values, rather than using the number of
// extended grapheme clusters (a.k.a. "characters" in the end user's mind).
void _handleKeyEvent(RawKeyEvent keyEvent) {
if(kIsWeb) {
// On web platform, we should ignore the key because it's processed already.
return;
}
if (keyEvent is! RawKeyDownEvent || onSelectionChanged == null)
return;
final Set<LogicalKeyboardKey> keysPressed = LogicalKeyboardKey.collapseSynonyms(RawKeyboard.instance.keysPressed);
......
......@@ -368,6 +368,58 @@ void main() {
expect(editable, paintsExactlyCountTimes(#drawRect, 1));
}, skip: isBrowser);
test('ignore key event from web platform', () async {
final TextSelectionDelegate delegate = FakeEditableTextState();
final ViewportOffset viewportOffset = ViewportOffset.zero();
TextSelection currentSelection;
final RenderEditable editable = RenderEditable(
backgroundCursorColor: Colors.grey,
selectionColor: Colors.black,
textDirection: TextDirection.ltr,
cursorColor: Colors.red,
offset: viewportOffset,
// This makes the scroll axis vertical.
maxLines: 2,
textSelectionDelegate: delegate,
onSelectionChanged: (TextSelection selection, RenderEditable renderObject, SelectionChangedCause cause) {
currentSelection = selection;
},
startHandleLayerLink: LayerLink(),
endHandleLayerLink: LayerLink(),
text: const TextSpan(
text: 'test\ntest',
style: TextStyle(
height: 1.0, fontSize: 10.0, fontFamily: 'Ahem',
),
),
selection: const TextSelection.collapsed(
offset: 4,
),
);
layout(editable);
editable.hasFocus = true;
expect(
editable,
paints..paragraph(offset: Offset.zero),
);
editable.selectPositionAt(from: const Offset(0, 0), cause: SelectionChangedCause.tap);
editable.selection = const TextSelection.collapsed(offset: 0);
pumpFrame();
if(kIsWeb) {
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight, platform: 'web');
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 0);
} else {
await simulateKeyDownEvent(LogicalKeyboardKey.arrowRight, platform: 'android');
expect(currentSelection.isCollapsed, true);
expect(currentSelection.baseOffset, 1);
}
});
test('selects correct place with offsets', () {
final TextSelectionDelegate delegate = FakeEditableTextState();
final ViewportOffset viewportOffset = ViewportOffset.zero();
......
......@@ -39,6 +39,7 @@ class KeyEventSimulator {
case 'fuchsia':
case 'macos':
case 'linux':
case 'web':
return true;
}
return false;
......@@ -61,6 +62,9 @@ class KeyEventSimulator {
case 'linux':
map = kLinuxToPhysicalKey;
break;
case 'web':
// web doesn't have int type code
return null;
}
for (final int code in map.keys) {
if (key.usbHidUsage == map[code].usbHidUsage) {
......@@ -85,6 +89,9 @@ class KeyEventSimulator {
case 'macos':
// macOS doesn't do key codes, just scan codes.
return null;
case 'web':
// web doesn't have int type code
return null;
case 'linux':
map = kGlfwToLogicalKey;
break;
......@@ -97,10 +104,18 @@ class KeyEventSimulator {
}
return keyCode;
}
static String _getWebKeyCode(LogicalKeyboardKey key) {
for (final String code in kWebToLogicalKey.keys) {
if (key.keyId == kWebToLogicalKey[code].keyId) {
return code;
}
}
return null;
}
static PhysicalKeyboardKey _findPhysicalKey(LogicalKeyboardKey key, String platform) {
assert(_osIsSupported(platform), 'Platform $platform not supported for key simulation');
Map<int, PhysicalKeyboardKey> map;
Map<dynamic, PhysicalKeyboardKey> map;
switch (platform) {
case 'android':
map = kAndroidToPhysicalKey;
......@@ -114,6 +129,9 @@ class KeyEventSimulator {
case 'linux':
map = kLinuxToPhysicalKey;
break;
case 'web':
map = kWebToPhysicalKey;
break;
}
for (final PhysicalKeyboardKey physicalKey in map.values) {
if (key.debugName == physicalKey.debugName) {
......@@ -138,10 +156,10 @@ class KeyEventSimulator {
physicalKey ??= _findPhysicalKey(key, platform);
assert(key.debugName != null);
final int keyCode = platform == 'macos' ? -1 : _getKeyCode(key, platform);
assert(platform == 'macos' || keyCode != null, 'Key $key not found in $platform keyCode map');
final int scanCode = _getScanCode(physicalKey, platform);
assert(scanCode != null, 'Physical key for $key not found in $platform scanCode map');
final int keyCode = platform == 'macos' || platform == 'web' ? -1 : _getKeyCode(key, platform);
assert(platform == 'macos' || platform == 'web' || keyCode != null, 'Key $key not found in $platform keyCode map');
final int scanCode = platform == 'web' ? -1 : _getScanCode(physicalKey, platform);
assert(platform == 'web' || scanCode != null, 'Physical key for $key not found in $platform scanCode map');
final Map<String, dynamic> result = <String, dynamic>{
'type': isDown ? 'keydown' : 'keyup',
......@@ -173,6 +191,10 @@ class KeyEventSimulator {
result['charactersIgnoringModifiers'] = key.keyLabel;
result['modifiers'] = _getMacOsModifierFlags(key, isDown);
break;
case 'web':
result['code'] = _getWebKeyCode(key);
result['key'] = '';
result['metaState'] = _getWebModifierFlags(key, isDown);
}
return result;
}
......@@ -288,6 +310,50 @@ class KeyEventSimulator {
return result;
}
static int _getWebModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
int result = 0;
final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
if (isDown) {
pressed.add(newKey);
} else {
pressed.remove(newKey);
}
if (pressed.contains(LogicalKeyboardKey.shiftLeft)) {
result |= RawKeyEventDataWeb.modifierShift;
}
if (pressed.contains(LogicalKeyboardKey.shiftRight)) {
result |= RawKeyEventDataWeb.modifierShift;
}
if (pressed.contains(LogicalKeyboardKey.metaLeft)) {
result |= RawKeyEventDataWeb.modifierMeta;
}
if (pressed.contains(LogicalKeyboardKey.metaRight)) {
result |= RawKeyEventDataWeb.modifierMeta;
}
if (pressed.contains(LogicalKeyboardKey.controlLeft)) {
result |= RawKeyEventDataWeb.modifierControl;
}
if (pressed.contains(LogicalKeyboardKey.controlRight)) {
result |= RawKeyEventDataWeb.modifierControl;
}
if (pressed.contains(LogicalKeyboardKey.altLeft)) {
result |= RawKeyEventDataWeb.modifierAlt;
}
if (pressed.contains(LogicalKeyboardKey.altRight)) {
result |= RawKeyEventDataWeb.modifierAlt;
}
if (pressed.contains(LogicalKeyboardKey.capsLock)) {
result |= RawKeyEventDataWeb.modifierCapsLock;
}
if (pressed.contains(LogicalKeyboardKey.numLock)) {
result |= RawKeyEventDataWeb.modifierNumLock;
}
if (pressed.contains(LogicalKeyboardKey.scrollLock)) {
result |= RawKeyEventDataWeb.modifierScrollLock;
}
return result;
}
static int _getMacOsModifierFlags(LogicalKeyboardKey newKey, bool isDown) {
int result = 0;
final Set<LogicalKeyboardKey> pressed = RawKeyboard.instance.keysPressed;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment