1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// Use of this source code is governed by a BSD-style license that can be 3513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch// found in the LICENSE file. 4513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 5513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvar BASE_KEYBOARD = { 6513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch top: 0, 7513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch left: 0, 8513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch width: 1237, 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen height: 514 10513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 11513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 12513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvar BASE_INSTRUCTIONS = { 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen top: 194, 14513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch left: 370, 15513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch width: 498, 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen height: 112 17513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 18513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 19513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvar LABEL_TO_KEY_TEXT = { 20513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch alt: 'alt', 21513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch backspace: 'backspace', 22513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch ctrl: 'ctrl', 23513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch enter: 'enter', 24513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch esc: 'esc', 25513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_arrow_down: 'down', 26513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_arrow_left: 'left', 27513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_arrow_right: 'right', 28513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_arrow_up: 'up', 29513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_back: 'back', 30513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_backspace: 'backspace', 31513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_brightness_down: 'bright down', 32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_brightness_up: 'bright up', 33513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_enter: 'enter', 34513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_forward: 'forward', 35ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen glyph_fullscreen: 'full screen', 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen glyph_ime: 'ime', 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen glyph_lock: 'lock', 38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen glyph_overview: 'switch window', 39513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_power: 'power', 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen glyph_right: 'right', 41513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_reload: 'reload', 42513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_search: 'search', 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen glyph_shift: 'shift', 44513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_tab: 'tab', 45513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_tools: 'tools', 46513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_volume_down: 'vol. down', 47513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_volume_mute: 'mute', 48513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch glyph_volume_up: 'vol. up', 49513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shift: 'shift', 50513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch tab: 'tab' 51513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 52513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 53513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvar MODIFIER_TO_CLASS = { 54513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 'SHIFT': 'modifier-shift', 55513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 'CTRL': 'modifier-ctrl', 56513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 'ALT': 'modifier-alt' 57513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 58513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 59513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvar IDENTIFIER_TO_CLASS = { 60513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch '2A': 'is-shift', 61513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch '1D': 'is-ctrl', 62513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch '38': 'is-alt' 63513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}; 64513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 65201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvar keyboardOverlayId = 'en_US'; 66513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 67513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 68513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns layouts data. 69513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 70513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getLayouts() { 71513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return keyboardOverlayData['layouts']; 72513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 73513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 74513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 75513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns shortcut data. 76513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 77513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getShortcutData() { 78513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return keyboardOverlayData['shortcut']; 79513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 80513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 82201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch * Returns the keyboard overlay ID. 83513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 84201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochfunction getKeyboardOverlayId() { 85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return keyboardOverlayId 86513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 87513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 88513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 89513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns keyboard glyph data. 90513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 91513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getKeyboardGlyphData() { 92201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return keyboardOverlayData['keyboardGlyph'][getKeyboardOverlayId()]; 93513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 94513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 95513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 96513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Converts a single hex number to a character. 97513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction hex2char(hex) { 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!hex) { 100513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ''; 101513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 102513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var result = ''; 103513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var n = parseInt(hex, 16); 104513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (n <= 0xFFFF) { 105513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result += String.fromCharCode(n); 106513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else if (n <= 0x10FFFF) { 107513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch n -= 0x10000; 108513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch result += (String.fromCharCode(0xD800 | (n >> 10)) + 109513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch String.fromCharCode(0xDC00 | (n & 0x3FF))); 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch console.error('hex2Char error: Code point out of range :' + hex); 112513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 113513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return result; 114513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 115513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 116513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 117513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns a list of modifiers from the key event. 118513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 119513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getModifiers(e) { 120513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!e) { 121513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return []; 122513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var isKeyDown = (e.type == 'keydown'); 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var keyCodeToModifier = { 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 16: 'SHIFT', 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 17: 'CTRL', 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 18: 'ALT', 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 91: 'ALT', // left ALT pressed with SHIFT 129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 92: 'ALT', // right ALT pressed with SHIFT 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }; 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var modifierWithKeyCode = keyCodeToModifier[e.keyCode]; 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var isPressed = {'SHIFT': e.shiftKey, 'CTRL': e.ctrlKey, 'ALT': e.altKey}; 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // if e.keyCode is one of Shift, Ctrl and Alt, isPressed should 134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // be changed because the key currently pressed 135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // does not affect the values of e.shiftKey, e.ctrlKey and e.altKey 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if(modifierWithKeyCode){ 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen isPressed[modifierWithKeyCode] = isKeyDown; 138513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // make the result array 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return ['SHIFT', 'CTRL', 'ALT'].filter( 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen function(modifier) { 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return isPressed[modifier]; 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen }).sort(); 144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 146513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 147513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns an ID of the key. 148513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 149513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction keyId(identifier, i) { 150513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return identifier + '-key-' + i; 151513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 152513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 153513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 154513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns an ID of the text on the key. 155513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 156513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction keyTextId(identifier, i) { 157513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return identifier + '-key-text-' + i; 158513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 159513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 160513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns an ID of the shortcut text. 162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 163513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction shortcutTextId(identifier, i) { 164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return identifier + '-shortcut-text-' + i; 165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 167513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 168513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns true if |list| contains |e|. 169513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 170513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction contains(list, e) { 171513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return list.indexOf(e) != -1; 172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 174513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 175513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns a list of the class names corresponding to the identifier and 176513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * modifiers. 177513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 178513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getKeyClasses(identifier, modifiers) { 179513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var classes = ['keyboard-overlay-key']; 180513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (var i = 0; i < modifiers.length; ++i) { 181513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch classes.push(MODIFIER_TO_CLASS[modifiers[i]]); 182513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 183513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 184513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if ((identifier == '2A' && contains(modifiers, 'SHIFT')) || 185513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (identifier == '1D' && contains(modifiers, 'CTRL')) || 186513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch (identifier == '38' && contains(modifiers, 'ALT'))) { 187513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch classes.push('pressed'); 188513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch classes.push(IDENTIFIER_TO_CLASS[identifier]); 189513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 190513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return classes; 191513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 192513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 193513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 194513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns true if a character is a ASCII character. 195513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 196513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction isAscii(c) { 197513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var charCode = c.charCodeAt(0); 198513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return 0x00 <= charCode && charCode <= 0x7F; 199513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 200513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 201513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 202513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns a label of the key. 203513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 204513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getKeyLabel(keyData, modifiers) { 205513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!keyData) { 206513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return ''; 207513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 208513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (keyData.label in LABEL_TO_KEY_TEXT) { 209513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return LABEL_TO_KEY_TEXT[keyData.label]; 210513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 211513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyLabel = ''; 212513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (var j = 1; j <= 9; j++) { 213513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var pos = keyData['p' + j]; 214513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!pos) { 215513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; 216513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 217513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (LABEL_TO_KEY_TEXT[pos]) { 218513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return LABEL_TO_KEY_TEXT[pos]; 219513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 220513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyLabel = hex2char(pos); 221513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!keyLabel) { 222513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; 223513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 224513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (isAscii(keyLabel) && 225513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch getShortcutData()[getAction(keyLabel, modifiers)]) { 226513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch break; 227513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 228513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 229513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return keyLabel; 230513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 231513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 232513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 233513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns a normalized string used for a key of shortcutData. 234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * 235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * Examples: 236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * keycode: 'd', modifiers: ['CTRL', 'SHIFT'] => 'd<>CTRL<>SHIFT' 237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * keycode: 'alt', modifiers: ['ALT', 'SHIFT'] => 'ALT<>SHIFT' 238513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 239513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getAction(keycode, modifiers) { 240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const SEPARATOR = '<>'; 241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (keycode.toUpperCase() in MODIFIER_TO_CLASS) { 242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen keycode = keycode.toUpperCase(); 243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen if (keycode in modifiers) { 244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return modifiers.join(SEPARATOR); 245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } else { 246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var action = [keycode].concat(modifiers) 247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen action.sort(); 248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return action.join(SEPARATOR); 249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen } 251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen return [keycode].concat(modifiers).join(SEPARATOR); 252513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 253513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 254513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 255513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Returns a text which displayed on a key. 256513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 257513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction getKeyTextValue(keyData) { 258513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (LABEL_TO_KEY_TEXT[keyData.label]) { 259513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return LABEL_TO_KEY_TEXT[keyData.label]; 260513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 261513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var chars = []; 263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (var j = 1; j <= 9; ++j) { 264513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var pos = keyData['p' + j]; 265513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (LABEL_TO_KEY_TEXT[pos]) { 266513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return LABEL_TO_KEY_TEXT[pos]; 267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (pos && pos.length > 0) { 269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch chars.push(hex2char(pos)); 270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch return chars.join(' '); 273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Updates the whole keyboard. 277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 278ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenfunction update(modifiers) { 279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var instructions = document.getElementById('instructions'); 280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (modifiers.length == 0) { 281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.visibility = 'visible'; 282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 283513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.visibility = 'hidden'; 284513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 285513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 286513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyboardGlyphData = getKeyboardGlyphData(); 287513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var shortcutData = getShortcutData(); 288513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var layout = getLayouts()[keyboardGlyphData.layoutName]; 289513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (var i = 0; i < layout.length; ++i) { 290513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var identifier = layout[i][0]; 291513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyData = keyboardGlyphData.keys[identifier]; 292513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var classes = getKeyClasses(identifier, modifiers, keyData); 293513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyLabel = getKeyLabel(keyData, modifiers); 294513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var shortcutId = shortcutData[getAction(keyLabel, modifiers)]; 295513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (shortcutId) { 296513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch classes.push('is-shortcut'); 297513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 298513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 299513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var key = document.getElementById(keyId(identifier, i)); 300513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.className = classes.join(' '); 301513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 302513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (!keyData) { 303513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch continue; 304513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 305513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 306513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyText = document.getElementById(keyTextId(identifier, i)); 307513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyTextValue = getKeyTextValue(keyData); 308513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (keyTextValue) { 309513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.style.visibility = 'visible'; 310513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 311513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.style.visibility = 'hidden'; 312513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 313513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.textContent = keyTextValue; 314513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 315513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var shortcutText = document.getElementById(shortcutTextId(identifier, i)); 316513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (shortcutId) { 317513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.style.visibility = 'visible'; 318513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.textContent = templateData[shortcutId]; 319513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } else { 320513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.style.visibility = 'hidden'; 321513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 322513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 323513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (keyData.format) { 324513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var format = keyData.format; 325513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch if (format == 'left' || format == 'right') { 326513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.style.textAlign = format; 327513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.style.textAlign = format; 328513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 329513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 330513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 331513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 332513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 333513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 334ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen * A callback function for onkeydown and onkeyup events. 335513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 336ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenfunction handleKeyEvent(e){ 337ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen var modifiers = getModifiers(e); 338201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch if (!getKeyboardOverlayId()) { 339201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch return; 340201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 341ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen update(modifiers); 342513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 343513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 344513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 345513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * Initializes the layout of the keys. 346513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 347513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction initLayout() { 348513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var layout = getLayouts()[getKeyboardGlyphData().layoutName]; 349513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyboard = document.body; 350513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var minX = window.innerWidth; 351513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var maxX = 0; 352513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var minY = window.innerHeight; 353513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var maxY = 0; 354513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var multiplier = 1.38 * window.innerWidth / BASE_KEYBOARD.width; 355513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyMargin = 7; 356513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var offsetX = 10; 357513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var offsetY = 7; 358513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch for (var i = 0; i < layout.length; i++) { 359513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var array = layout[i]; 360513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var identifier = array[0]; 361513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var x = Math.round((array[1] + offsetX) * multiplier); 362513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var y = Math.round((array[2] + offsetY) * multiplier); 363513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var w = Math.round((array[3] - keyMargin) * multiplier); 364513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var h = Math.round((array[4] - keyMargin) * multiplier); 365513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 366513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var key = document.createElement('div'); 367513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.id = keyId(identifier, i); 368513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.className = 'keyboard-overlay-key'; 369513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.style.left = x + 'px'; 370513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.style.top = y + 'px'; 371513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.style.width = w + 'px'; 372513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.style.height = h + 'px'; 373513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 374513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var keyText = document.createElement('div'); 375513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.id = keyTextId(identifier, i); 376513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.className = 'keyboard-overlay-key-text'; 377513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyText.style.visibility = 'hidden'; 378513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.appendChild(keyText); 379513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 380513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var shortcutText = document.createElement('div'); 381513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.id = shortcutTextId(identifier, i); 382513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.className = 'keyboard-overlay-shortcut-text'; 383513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch shortcutText.style.visilibity = 'hidden'; 384513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch key.appendChild(shortcutText); 385513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyboard.appendChild(key); 386513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 387513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch minX = Math.min(minX, x); 388513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch maxX = Math.max(maxX, x + w); 389513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch minY = Math.min(minY, y); 390513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch maxY = Math.max(maxY, y + h); 391513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch } 392513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 393513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var width = maxX - minX + 1; 394513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch var height = maxY - minY + 1; 395513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyboard.style.width = (width + 2 * (minX + 1)) + 'px'; 396513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyboard.style.height = (height + 2 * (minY + 1)) + 'px'; 397513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 39872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var instructions = document.createElement('div'); 399513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.id = 'instructions'; 400513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.className = 'keyboard-overlay-instructions'; 401513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.left = ((BASE_INSTRUCTIONS.left - BASE_KEYBOARD.left) * 402513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch width / BASE_KEYBOARD.width + minX) + 'px'; 403513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.top = ((BASE_INSTRUCTIONS.top - BASE_KEYBOARD.top) * 404513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch height / BASE_KEYBOARD.height + minY) + 'px'; 405513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.width = (width * BASE_INSTRUCTIONS.width / 406513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch BASE_KEYBOARD.width) + 'px'; 407513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.style.height = (height * BASE_INSTRUCTIONS.height / 408513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch BASE_KEYBOARD.height) + 'px'; 409513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 41072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var instructionsText = document.createElement('div'); 411513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructionsText.id = 'instructions-text'; 412513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructionsText.className = 'keyboard-overlay-instructions-text'; 413513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructionsText.innerHTML = templateData.keyboardOverlayInstructions; 414513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch instructions.appendChild(instructionsText); 41572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen var instructionsHideText = document.createElement('div'); 41672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen instructionsHideText.id = 'instructions-hide-text'; 41772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen instructionsHideText.className = 'keyboard-overlay-instructions-hide-text'; 41872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen instructionsHideText.innerHTML = templateData.keyboardOverlayInstructionsHide; 41972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen instructions.appendChild(instructionsHideText); 420513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch keyboard.appendChild(instructions); 421513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 422513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 423513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch/** 424513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch * A callback function for the onload event of the body element. 425513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch */ 426513209b27ff55e2841eac0e4120199c23acce758Ben Murdochfunction init() { 427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen document.addEventListener('keydown', handleKeyEvent); 428ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen document.addEventListener('keyup', handleKeyEvent); 429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch chrome.send('getKeyboardOverlayId'); 430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch} 431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch 432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch/** 433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch * Initializes the global keyboad overlay ID and the layout of keys. 434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch * Called after sending the 'getKeyboardOverlayId' message. 435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch */ 436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochfunction initKeyboardOverlayId(overlayId) { 43772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Libcros returns an empty string when it cannot find the keyboard overlay ID 43872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // corresponding to the current input method. 43972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // In such a case, fallback to the default ID (en_US). 44072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (overlayId) { 44172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen keyboardOverlayId = overlayId; 44272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 443201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch while(document.body.firstChild) { 444201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch document.body.removeChild(document.body.firstChild); 445201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch } 446513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch initLayout(); 447513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch update(); 448513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch} 449513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch 450513209b27ff55e2841eac0e4120199c23acce758Ben Murdochdocument.addEventListener('DOMContentLoaded', init); 451