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