1effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Copyright 2014 The Chromium Authors. All rights reserved.
2effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch// found in the LICENSE file.
4effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch(function() {
6effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Flag values for ctrl, alt and shift as defined by EventFlags
8effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // in "event_constants.h".
9effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // @enum {number}
10effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  var Modifier = {
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    NONE: 0,
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ALT: 8,
13effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    CONTROL: 4,
14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SHIFT: 2
15effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  }
16effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
17effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Each virtual key event is assigned a unique ID.
18effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  var nextRequestID = 0;
19effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // Keycodes have been deprecated in the KeyEvent specification, but are
21effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // nonetheless required to support legacy web content.  The Keycodes in the
22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // following table are based on subset of US-EN 101-key keyboard. These
23effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // codes are used in the absence of explicit keycodes for kb-key and
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // kb-keysequence elements. Keyboard layout authors may explicitly set the
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // keyCode attribute for kb-key or kb-keysequence elements to refer to
26effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // indices in this table in order to emulate a physical keyboard with an
27effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // alternate layout.  Not all keys on a virtual keyboard are required to
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // have keyCodes. The shiftModifier specifies whether to always include or
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // exclude the shift modifer when sending key events for this key. If it's
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // undefined, it will defer to state of the keyboard.
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // TODO(rsadam): Correctly propagate shutdown keycode. This is currently
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  // ignored due to chromoting (crbug/146609)
33effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  var keyCodes = {
34effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '\b': {keyCode: 0x08, keyName: 'Backspace', shiftModifier: false},
35effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '\t': {keyCode: 0x09, keyName: 'Tab', shiftModifier: false},
36effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '\n': {keyCode: 0x0D, keyName: 'Enter', shiftModifier: false},
37effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Esc': {keyCode: 0x1B, keyName: 'Escape', shiftModifier: false},
38effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ' ': {keyCode: 0x20, keyName: 'Space', shiftModifier: false},
39effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Arrow-Left': {keyCode: 0x25, keyName: 'ArrowLeft',
40effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: undefined},
41effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Arrow-Up': {keyCode: 0x26, keyName: 'ArrowUp', shiftModifier: undefined},
42effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Arrow-Right': {keyCode: 0x27, keyName: 'ArrowRight',
43effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: undefined},
44effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Arrow-Down': {keyCode: 0x28, keyName: 'ArrowDown',
45effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: undefined},
46effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '0': {keyCode: 0x30, keyName: 'Digit0', shiftModifier: false},
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ')': {keyCode: 0x30, keyName: 'Digit0', shiftModifier: true},
48effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '1': {keyCode: 0x31, keyName: 'Digit1', shiftModifier: false},
49effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '!': {keyCode: 0x31, keyName: 'Digit1', shiftModifier: true},
50effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '2': {keyCode: 0x32, keyName: 'Digit2', shiftModifier: false},
51effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '@': {keyCode: 0x32, keyName: 'Digit2', shiftModifier: true},
52effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '3': {keyCode: 0x33, keyName: 'Digit3', shiftModifier: false},
53effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '#': {keyCode: 0x33, keyName: 'Digit3', shiftModifier: true},
54effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '4': {keyCode: 0x34, keyName: 'Digit4', shiftModifier: false},
55effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '$': {keyCode: 0x34, keyName: 'Digit4', shiftModifier: true},
56effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '5': {keyCode: 0x35, keyName: 'Digit5', shiftModifier: false},
57effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '%': {keyCode: 0x35, keyName: 'Digit5', shiftModifier: true},
58effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '6': {keyCode: 0x36, keyName: 'Digit6', shiftModifier: false},
59effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '^': {keyCode: 0x36, keyName: 'Digit6', shiftModifier: true},
60effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '7': {keyCode: 0x37, keyName: 'Digit7', shiftModifier: false},
61effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '&': {keyCode: 0x37, keyName: 'Digit7', shiftModifier: true},
62effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '8': {keyCode: 0x38, keyName: 'Digit8', shiftModifier: false},
63effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '*': {keyCode: 0x38, keyName: 'Digit8', shiftModifier: true},
64effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '9': {keyCode: 0x39, keyName: 'Digit9', shiftModifier: false},
65effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '(': {keyCode: 0x39, keyName: 'Digit9', shiftModifier: true},
66effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'a': {keyCode: 0x41, keyName: 'KeyA', shiftModifier: false},
67effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'A': {keyCode: 0x41, keyName: 'KeyA', shiftModifier: true},
68effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'b': {keyCode: 0x42, keyName: 'KeyB', shiftModifier: false},
69effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'B': {keyCode: 0x42, keyName: 'KeyB', shiftModifier: true},
70effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'c': {keyCode: 0x43, keyName: 'KeyC', shiftModifier: false},
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'C': {keyCode: 0x43, keyName: 'KeyC', shiftModifier: true},
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'd': {keyCode: 0x44, keyName: 'KeyD', shiftModifier: false},
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'D': {keyCode: 0x44, keyName: 'KeyD', shiftModifier: true},
74effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'e': {keyCode: 0x45, keyName: 'KeyE', shiftModifier: false},
75effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'E': {keyCode: 0x45, keyName: 'KeyE', shiftModifier: true},
76effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'f': {keyCode: 0x46, keyName: 'KeyF', shiftModifier: false},
77effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'F': {keyCode: 0x46, keyName: 'KeyF', shiftModifier: true},
78effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'g': {keyCode: 0x47, keyName: 'KeyG', shiftModifier: false},
79effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'G': {keyCode: 0x47, keyName: 'KeyG', shiftModifier: true},
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'h': {keyCode: 0x48, keyName: 'KeyH', shiftModifier: false},
81effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'H': {keyCode: 0x48, keyName: 'KeyH', shiftModifier: true},
82effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'i': {keyCode: 0x49, keyName: 'KeyI', shiftModifier: false},
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'I': {keyCode: 0x49, keyName: 'KeyI', shiftModifier: true},
84effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'j': {keyCode: 0x4A, keyName: 'KeyJ', shiftModifier: false},
85effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'J': {keyCode: 0x4A, keyName: 'KeyJ', shiftModifier: true},
86effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'k': {keyCode: 0x4B, keyName: 'KeyK', shiftModifier: false},
87effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'K': {keyCode: 0x4B, keyName: 'KeyK', shiftModifier: true},
88effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'l': {keyCode: 0x4C, keyName: 'KeyL', shiftModifier: false},
89effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'L': {keyCode: 0x4C, keyName: 'KeyL', shiftModifier: true},
90effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'm': {keyCode: 0x4D, keyName: 'KeyM', shiftModifier: false},
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'M': {keyCode: 0x4D, keyName: 'KeyM', shiftModifier: true},
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'n': {keyCode: 0x4E, keyName: 'KeyN', shiftModifier: false},
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'N': {keyCode: 0x4E, keyName: 'KeyN', shiftModifier: true},
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'o': {keyCode: 0x4F, keyName: 'KeyO', shiftModifier: false},
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'O': {keyCode: 0x4F, keyName: 'KeyO', shiftModifier: true},
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'p': {keyCode: 0x50, keyName: 'KeyP', shiftModifier: false},
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'P': {keyCode: 0x50, keyName: 'KeyP', shiftModifier: true},
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'q': {keyCode: 0x51, keyName: 'KeyQ', shiftModifier: false},
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Q': {keyCode: 0x51, keyName: 'KeyQ', shiftModifier: true},
100effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'r': {keyCode: 0x52, keyName: 'KeyR', shiftModifier: false},
101effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'R': {keyCode: 0x52, keyName: 'KeyR', shiftModifier: true},
102effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    's': {keyCode: 0x53, keyName: 'KeyS', shiftModifier: false},
103effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'S': {keyCode: 0x53, keyName: 'KeyS', shiftModifier: true},
104effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    't': {keyCode: 0x54, keyName: 'KeyT', shiftModifier: false},
105effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'T': {keyCode: 0x54, keyName: 'KeyT', shiftModifier: true},
106effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'u': {keyCode: 0x55, keyName: 'KeyU', shiftModifier: false},
107effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'U': {keyCode: 0x55, keyName: 'KeyU', shiftModifier: true},
108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'v': {keyCode: 0x56, keyName: 'KeyV', shiftModifier: false},
109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'V': {keyCode: 0x56, keyName: 'KeyV', shiftModifier: true},
110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'w': {keyCode: 0x57, keyName: 'KeyW', shiftModifier: false},
111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'W': {keyCode: 0x57, keyName: 'KeyW', shiftModifier: true},
112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'x': {keyCode: 0x58, keyName: 'KeyX', shiftModifier: false},
113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'X': {keyCode: 0x58, keyName: 'KeyX', shiftModifier: true},
114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'y': {keyCode: 0x59, keyName: 'KeyY', shiftModifier: false},
115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Y': {keyCode: 0x59, keyName: 'KeyY', shiftModifier: true},
116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'z': {keyCode: 0x5A, keyName: 'KeyZ', shiftModifier: false},
117effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Z': {keyCode: 0x5A, keyName: 'KeyZ', shiftModifier: true},
118effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Fullscreen': {keyCode: 0x7A, shiftModifier: false},
119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Shutdown': {keyCode: 0x98, shiftModifier: false},
120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Back': {keyCode: 0xA6, shiftModifier: false},
121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Forward': {keyCode: 0xA7, shiftModifier: false},
122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Reload': {keyCode: 0xA8, shiftModifier: false},
123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Search': {keyCode: 0xAA, shiftModifier: false},
124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Mute': {keyCode: 0xAD, keyName: 'VolumeMute', shiftModifier: false},
125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Volume-Down': {keyCode: 0xAE, keyName: 'VolumeDown',
126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: false},
127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Volume-Up': {keyCode: 0xAF, keyName: 'VolumeUp', shiftModifier: false},
128effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Change-Window': {keyCode: 0xB6, shiftModifier: false},
129effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ';': {keyCode: 0xBA, keyName: 'Semicolon', shiftModifier: false},
130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ':': {keyCode: 0xBA, keyName: 'Semicolon',shiftModifier: true},
131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '=': {keyCode: 0xBB, keyName: 'Equal', shiftModifier: false},
132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '+': {keyCode: 0xBB, keyName: 'Equal', shiftModifier: true},
133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ',': {keyCode: 0xBC, keyName: 'Comma', shiftModifier: false},
134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '<': {keyCode: 0xBC, keyName: 'Comma', shiftModifier: true},
135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '-': {keyCode: 0xBD, keyName: 'Minus', shiftModifier: false},
136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '_': {keyCode: 0xBD, keyName: 'Minus', shiftModifier: true},
137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '.': {keyCode: 0xBE, keyName: 'Period', shiftModifier: false},
138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '>': {keyCode: 0xBE, keyName: 'Period', shiftModifier: true},
139effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '/': {keyCode: 0xBF, keyName: 'Slash', shiftModifier: false},
140effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '?': {keyCode: 0xBF, keyName: 'Slash', shiftModifier: true},
141effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '`': {keyCode: 0xC0, keyName: 'Backquote', shiftModifier: false},
142effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '~': {keyCode: 0xC0, keyName: 'Backquote', shiftModifier: true},
143effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Brightness-Down': {keyCode: 0xD8, keyName: 'BrightnessDown',
144effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: false},
145effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    'Brightness-Up': {keyCode: 0xD9, keyName: 'BrightnessUp',
146effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: false},
147effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '[': {keyCode: 0xDB, keyName: 'BracketLeft', shiftModifier: false},
148effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '{': {keyCode: 0xDB, keyName: 'BracketLeft', shiftModifier: true},
149effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '\\': {keyCode: 0xDC, keyName: 'Backslash', shiftModifier: false},
150effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '|': {keyCode: 0xDC, keyName: 'Backslash', shiftModifier: true},
151effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    ']': {keyCode: 0xDD, keyName: 'BracketRight', shiftModifier: false},
152effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '}': {keyCode: 0xDD, keyName: 'BracketRight', shiftModifier: true},
153effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '\'': {keyCode: 0xDE, keyName: 'Quote', shiftModifier: false},
154effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    '"': {keyCode: 0xDE, keyName: 'Quote', shiftModifier: true},
155effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  };
156effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
157effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  Polymer('kb-key-codes', {
158effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    /**
159effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     * Retrieves the keyCode and status of the shift modifier.
160effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     * @param {string} id ID of an entry in the code table.
161effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     * @return {keyCode: numeric, shiftModifier: boolean}
162effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     */
163effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    GetKeyCodeAndModifiers: function(id) {
164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      var entry = keyCodes[id];
165effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (entry) {
166effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return {
167effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          keyCode: entry.keyCode,
168effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          keyName: entry.keyName || 'Unidentified',
169effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch          shiftModifier: entry.shiftModifier
170effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        };
171effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      }
172effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      if (id.length != 1)
173effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        return;
174effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      // Special case of accented characters.
175effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      return {
176effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        keyCode: 0,
177effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        keyName: 'Unidentified',
178effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        shiftModifier: false
179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      };
180effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    },
181effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
182effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   /**
183effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    * Creates a virtual key event for use with the keyboard extension API.
184effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    * See http://www.w3.org/TR/DOM-Level-3-Events/#events-KeyboardEvent.
185effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    * @param {Object} detail Attribute of the key being pressed or released.
186effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    * @param {string} type The type of key event, which may be keydown
187effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *     or keyup.
188effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    * @return {?KeyboardEvent} A KeyboardEvent object, or undefined on
189effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    *     failure.
190effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    */
191effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   createVirtualKeyEvent: function(detail, type) {
192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     var char = detail.char;
193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     var keyCode = detail.keyCode;
194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     var keyName = detail.keyName;
195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     // The shift modifier is handled specially. Some charactares like '+'
196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     // {keyCode: 0xBB, shiftModifier: true}, are available on non-upper
197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     // keysets, and so we rely on caching the correct shiftModifier. If
198effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     // the cached value of the shiftModifier is undefined, we defer to
199effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     // the shiftModifier in the detail.
200effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     var shiftModifier = detail.shiftModifier;
201effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     if (keyCode == undefined || keyName == undefined) {
202effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       var state = this.GetKeyCodeAndModifiers(char);
203effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       if (state) {
204effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         keyCode = keyCode || state.keyCode;
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         keyName = keyName || state.keyName;
206effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         shiftModifier = (state.shiftModifier == undefined) ?
207effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch             shiftModifier : state.shiftModifier;
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       } else {
209effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         // Keycode not defined.
210effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         return;
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       }
212effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     }
213effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     var modifiers = Modifier.NONE;
214effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     modifiers = shiftModifier ? modifiers | Modifier.SHIFT : modifiers;
215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     modifiers = detail.controlModifier ?
216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch         modifiers | Modifier.CONTROL : modifiers;
217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     modifiers = detail.altModifier ? modifiers | Modifier.ALT : modifiers;
218effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     return {
219effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       type: type,
220effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       charValue: char.charCodeAt(0),
221effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       keyCode: keyCode,
222effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       keyName: keyName,
223effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch       modifiers: modifiers
224effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch     };
225effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch   },
226effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  });
227effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch})();
228