• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5part of engine;
6
7/// Provides keyboard bindings, such as the `flutter/keyevent` channel.
8class Keyboard {
9  /// Initializes the [Keyboard] singleton.
10  ///
11  /// Use the [instance] getter to get the singleton after calling this method.
12  static void initialize() {
13    _instance ??= Keyboard._();
14  }
15
16  /// The [Keyboard] singleton.
17  static Keyboard get instance => _instance;
18  static Keyboard _instance;
19
20  html.EventListener _keydownListener;
21  html.EventListener _keyupListener;
22
23  Keyboard._() {
24    _keydownListener = (html.Event event) {
25      _handleHtmlEvent(event);
26    };
27    html.window.addEventListener('keydown', _keydownListener);
28
29    _keyupListener = (html.Event event) {
30      _handleHtmlEvent(event);
31    };
32    html.window.addEventListener('keyup', _keyupListener);
33    registerHotRestartListener(() {
34      dispose();
35    });
36  }
37
38  /// Uninitializes the [Keyboard] singleton.
39  ///
40  /// After calling this method this object becomes unusable and [instance]
41  /// becomes `null`. Call [initialize] again to initialize a new singleton.
42  void dispose() {
43    html.window.removeEventListener('keydown', _keydownListener);
44    html.window.removeEventListener('keyup', _keyupListener);
45    _keydownListener = null;
46    _keyupListener = null;
47    _instance = null;
48  }
49
50  static const JSONMessageCodec _messageCodec = JSONMessageCodec();
51
52  void _handleHtmlEvent(html.KeyboardEvent event) {
53    final Map<String, dynamic> eventData = <String, dynamic>{
54      'type': event.type,
55      // TODO(yjbanov): this emulates Android because that the only reasonable
56      //                thing to map to right now (the other choice is fuchsia).
57      //                However, eventually we need to have something that maps
58      //                better to Web.
59      'keymap': 'android',
60      'keyCode': event.keyCode,
61    };
62
63    // TODO(yjbanov): The browser does not report `charCode` for 'keydown' and
64    //                'keyup', only for 'keypress'. This restores the value
65    //                from the 'key' field. However, we need to verify how
66    //                many code units a single key can have. Right now it
67    //                assumes exactly one unit (that's what Flutter framework
68    //                expects). But we'll need a different strategy if other
69    //                code unit counts are possible.
70    if (event.key.codeUnits.length == 1) {
71      eventData['codePoint'] = event.key.codeUnits.first;
72    }
73
74    ui.window.onPlatformMessage('flutter/keyevent',
75        _messageCodec.encodeMessage(eventData), _noopCallback);
76  }
77}
78
79void _noopCallback(ByteData data) {}
80