15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<include src="keyboard_overlay_data.js"/>
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)<include src="keyboard_overlay_accessibility_helper.js"/>
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var BASE_KEYBOARD = {
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top: 0,
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left: 0,
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width: 1237,
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height: 514
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var BASE_INSTRUCTIONS = {
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top: 194,
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  left: 370,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  width: 498,
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  height: 142
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var MODIFIER_TO_CLASS = {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'SHIFT': 'modifier-shift',
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'CTRL': 'modifier-ctrl',
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  'ALT': 'modifier-alt',
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  'SEARCH': 'modifier-search'
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var IDENTIFIER_TO_CLASS = {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  '2A': 'is-shift',
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  '1D': 'is-ctrl',
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  '38': 'is-alt',
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  'E0 5B': 'is-search'
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var LABEL_TO_IDENTIFIER = {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'search': 'E0 5B',
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'ctrl': '1D',
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'alt': '38',
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'caps lock': '3A',
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  'disabled': 'DISABLED'
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var KEYCODE_TO_LABEL = {
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  8: 'backspace',
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  9: 'tab',
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  13: 'enter',
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  27: 'esc',
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  32: 'space',
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  33: 'pageup',
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  34: 'pagedown',
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  35: 'end',
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  36: 'home',
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  37: 'left',
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  38: 'up',
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  39: 'right',
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  40: 'down',
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  46: 'delete',
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  91: 'search',
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  92: 'search',
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  96: '0',
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  97: '1',
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  98: '2',
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  99: '3',
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  100: '4',
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  101: '5',
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  102: '6',
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  103: '7',
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  104: '8',
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  105: '9',
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  106: '*',
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  107: '+',
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  109: '-',
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  110: '.',
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  111: '/',
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  112: 'back',
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  113: 'forward',
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  114: 'reload',
79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)  115: 'full screen',
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  116: 'switch window',
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  117: 'bright down',
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  118: 'bright up',
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  119: 'mute',
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  120: 'vol. down',
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  121: 'vol. up',
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  186: ';',
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  187: '+',
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  188: ',',
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  189: '-',
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  190: '.',
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  191: '/',
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  192: '`',
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  219: '[',
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  220: '\\',
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  221: ']',
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  222: '\'',
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var keyboardOverlayId = 'en_US';
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)var identifierMap = {};
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns the layout name.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {string} layout name.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function getLayoutName() {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return getKeyboardGlyphData().layoutName;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns layout data.
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {Array} Keyboard layout data.
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function getLayout() {
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return keyboardOverlayData['layouts'][getLayoutName()];
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Cache the shortcut data after it is constructed.
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var shortcutDataCache;
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns shortcut data.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Object} Keyboard shortcut data.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getShortcutData() {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (shortcutDataCache)
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return shortcutDataCache;
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shortcutDataCache = keyboardOverlayData['shortcut'];
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!isDisplayRotationEnabled()) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Rotate screen
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete shortcutDataCache['reload<>CTRL<>SHIFT'];
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!isDisplayUIScalingEnabled()) {
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Zoom screen in
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete shortcutDataCache['+<>CTRL<>SHIFT'];
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Zoom screen out
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete shortcutDataCache['-<>CTRL<>SHIFT'];
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Reset screen zoom
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    delete shortcutDataCache['0<>CTRL<>SHIFT'];
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return shortcutDataCache;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the keyboard overlay ID.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Keyboard overlay ID.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getKeyboardOverlayId() {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return keyboardOverlayId;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns keyboard glyph data.
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Object} Keyboard glyph data.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getKeyboardGlyphData() {
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return keyboardOverlayData['keyboardGlyph'][getKeyboardOverlayId()];
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Converts a single hex number to a character.
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} hex Hexadecimal string.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Unicode values of hexadecimal string.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function hex2char(hex) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!hex) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '';
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var result = '';
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var n = parseInt(hex, 16);
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (n <= 0xFFFF) {
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result += String.fromCharCode(n);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (n <= 0x10FFFF) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    n -= 0x10000;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result += (String.fromCharCode(0xD800 | (n >> 10)) +
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               String.fromCharCode(0xDC00 | (n & 0x3FF)));
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    console.error('hex2Char error: Code point out of range :' + hex);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)var searchIsPressed = false;
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a list of modifiers from the key event.
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e The key event.
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Array} List of modifiers based on key event.
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getModifiers(e) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!e)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return [];
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var isKeyDown = (e.type == 'keydown');
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keyCodeToModifier = {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    16: 'SHIFT',
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    17: 'CTRL',
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    18: 'ALT',
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    91: 'SEARCH',
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var modifierWithKeyCode = keyCodeToModifier[e.keyCode];
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var isPressed = {
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'SHIFT': e.shiftKey,
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'CTRL': e.ctrlKey,
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'ALT': e.altKey,
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      'SEARCH': searchIsPressed
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifierWithKeyCode)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    isPressed[modifierWithKeyCode] = isKeyDown;
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  searchIsPressed = isPressed['SEARCH'];
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // make the result array
2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return ['SHIFT', 'CTRL', 'ALT', 'SEARCH'].filter(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      function(modifier) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return isPressed[modifier];
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }).sort();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an ID of the key.
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} identifier Key identifier.
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} i Key number.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Key ID.
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function keyId(identifier, i) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return identifier + '-key-' + i;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an ID of the text on the key.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} identifier Key identifier.
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} i Key number.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Key text ID.
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function keyTextId(identifier, i) {
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return identifier + '-key-text-' + i;
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an ID of the shortcut text.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} identifier Key identifier.
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {number} i Key number.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Key shortcut text ID.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function shortcutTextId(identifier, i) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return identifier + '-shortcut-text-' + i;
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns true if |list| contains |e|.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array} list Container list.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} e Element string.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} Returns true if the list contains the element.
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function contains(list, e) {
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return list.indexOf(e) != -1;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a list of the class names corresponding to the identifier and
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * modifiers.
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} identifier Key identifier.
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array} modifiers List of key modifiers.
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {Array} List of class names corresponding to specified params.
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getKeyClasses(identifier, modifiers) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var classes = ['keyboard-overlay-key'];
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var i = 0; i < modifiers.length; ++i) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    classes.push(MODIFIER_TO_CLASS[modifiers[i]]);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if ((identifier == '2A' && contains(modifiers, 'SHIFT')) ||
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (identifier == '1D' && contains(modifiers, 'CTRL')) ||
2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (identifier == '38' && contains(modifiers, 'ALT')) ||
2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      (identifier == 'E0 5B' && contains(modifiers, 'SEARCH'))) {
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    classes.push('pressed');
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    classes.push(IDENTIFIER_TO_CLASS[identifier]);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return classes;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns true if a character is a ASCII character.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} c A character to be checked.
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {boolean} True if the character is an ASCII character.
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function isAscii(c) {
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var charCode = c.charCodeAt(0);
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0x00 <= charCode && charCode <= 0x7F;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a remapped identiifer based on the preference.
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} identifier Key identifier.
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Remapped identifier.
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function remapIdentifier(identifier) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return identifierMap[identifier] || identifier;
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a label of the key.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} keyData Key glyph data.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array} modifiers Key Modifier list.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Label of the key.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getKeyLabel(keyData, modifiers) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!keyData) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return '';
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (keyData.label) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return keyData.label;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keyLabel = '';
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var j = 1; j <= 9; j++) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var pos = keyData['p' + j];
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!pos) {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyLabel = hex2char(pos);
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!keyLabel) {
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     }
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (isAscii(keyLabel) &&
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        getShortcutData()[getAction(keyLabel, modifiers)]) {
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return keyLabel;
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a normalized string used for a key of shortcutData.
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Examples:
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   keyCode: 'd', modifiers: ['CTRL', 'SHIFT'] => 'd<>CTRL<>SHIFT'
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   keyCode: 'alt', modifiers: ['ALT', 'SHIFT'] => 'ALT<>SHIFT'
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} keyCode Key code.
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array} modifiers Key Modifier list.
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Normalized key shortcut data string.
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getAction(keyCode, modifiers) {
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  /** @const */ var separatorStr = '<>';
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (keyCode.toUpperCase() in MODIFIER_TO_CLASS) {
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyCode = keyCode.toUpperCase();
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (keyCode in modifiers) {
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return modifiers.join(separatorStr);
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var action = [keyCode].concat(modifiers);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      action.sort();
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return action.join(separatorStr);
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return [keyCode].concat(modifiers).join(separatorStr);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a text which displayed on a key.
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {string} keyData Key glyph data.
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @return {string} Key text value.
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function getKeyTextValue(keyData) {
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (keyData.label) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Do not show text on the space key.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (keyData.label == 'space') {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return '';
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return keyData.label;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var chars = [];
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var j = 1; j <= 9; ++j) {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var pos = keyData['p' + j];
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pos && pos.length > 0) {
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chars.push(hex2char(pos));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return chars.join(' ');
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Updates the whole keyboard.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Array} modifiers Key Modifier list.
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function update(modifiers) {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var instructions = $('instructions');
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (modifiers.length == 0) {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instructions.style.visibility = 'visible';
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    instructions.style.visibility = 'hidden';
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keyboardGlyphData = getKeyboardGlyphData();
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var shortcutData = getShortcutData();
4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var layout = getLayout();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var i = 0; i < layout.length; ++i) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var identifier = remapIdentifier(layout[i][0]);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var keyData = keyboardGlyphData.keys[identifier];
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var classes = getKeyClasses(identifier, modifiers, keyData);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var keyLabel = getKeyLabel(keyData, modifiers);
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var shortcutId = shortcutData[getAction(keyLabel, modifiers)];
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (modifiers.length == 1 && modifiers[0] == 'SHIFT' &&
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        identifier == '2A') {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Currently there is no way to identify whether the left shift or the
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // right shift is preesed from the key event, so I assume the left shift
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // key is pressed here and do not show keyboard shortcut description for
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // 'Shift - Shift' (Toggle caps lock) on the left shift key, the
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // identifier of which is '2A'.
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // TODO(mazda): Remove this workaround (http://crosbug.com/18047)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcutId = null;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shortcutId) {
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classes.push('is-shortcut');
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var key = $(keyId(identifier, i));
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.className = classes.join(' ');
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!keyData) {
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var keyText = $(keyTextId(identifier, i));
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var keyTextValue = getKeyTextValue(keyData);
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (keyTextValue) {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       keyText.style.visibility = 'visible';
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       keyText.style.visibility = 'hidden';
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyText.textContent = keyTextValue;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var shortcutText = $(shortcutTextId(identifier, i));
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (shortcutId) {
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcutText.style.visibility = 'visible';
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcutText.textContent = loadTimeData.getString(shortcutId);
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcutText.style.visibility = 'hidden';
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (keyData.format) {
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      var format = keyData.format;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (format == 'left' || format == 'right') {
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shortcutText.style.textAlign = format;
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        keyText.style.textAlign = format;
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A callback function for onkeydown and onkeyup events.
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e Key event.
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function handleKeyEvent(e) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!getKeyboardOverlayId()) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var modifiers = getModifiers(e);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update(modifiers);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  KeyboardOverlayAccessibilityHelper.maybeSpeakAllShortcuts(modifiers);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  e.preventDefault();
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initializes the layout of the keys.
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function initLayout() {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add data for the caps lock key
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keys = getKeyboardGlyphData().keys;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!('3A' in keys)) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keys['3A'] = {label: 'caps lock', format: 'left'};
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Add data for the special key representing a disabled key
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keys['DISABLED'] = {label: 'disabled', format: 'left'};
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var layout = getLayout();
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keyboard = document.body;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var minX = window.innerWidth;
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var maxX = 0;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var minY = window.innerHeight;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var maxY = 0;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var multiplier = 1.38 * window.innerWidth / BASE_KEYBOARD.width;
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var keyMargin = 7;
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var offsetX = 10;
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var offsetY = 7;
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var i = 0; i < layout.length; i++) {
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var array = layout[i];
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var identifier = remapIdentifier(array[0]);
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var x = Math.round((array[1] + offsetX) * multiplier);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var y = Math.round((array[2] + offsetY) * multiplier);
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var w = Math.round((array[3] - keyMargin) * multiplier);
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var h = Math.round((array[4] - keyMargin) * multiplier);
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var key = document.createElement('div');
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.id = keyId(identifier, i);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.className = 'keyboard-overlay-key';
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.style.left = x + 'px';
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.style.top = y + 'px';
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.style.width = w + 'px';
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.style.height = h + 'px';
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var keyText = document.createElement('div');
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyText.id = keyTextId(identifier, i);
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyText.className = 'keyboard-overlay-key-text';
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyText.style.visibility = 'hidden';
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.appendChild(keyText);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var shortcutText = document.createElement('div');
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcutText.id = shortcutTextId(identifier, i);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcutText.className = 'keyboard-overlay-shortcut-text';
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcutText.style.visilibity = 'hidden';
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    key.appendChild(shortcutText);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyboard.appendChild(key);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    minX = Math.min(minX, x);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    maxX = Math.max(maxX, x + w);
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    minY = Math.min(minY, y);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    maxY = Math.max(maxY, y + h);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var width = maxX - minX + 1;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var height = maxY - minY + 1;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyboard.style.width = (width + 2 * (minX + 1)) + 'px';
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyboard.style.height = (height + 2 * (minY + 1)) + 'px';
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var instructions = document.createElement('div');
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.id = 'instructions';
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.className = 'keyboard-overlay-instructions';
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.style.left = ((BASE_INSTRUCTIONS.left - BASE_KEYBOARD.left) *
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             width / BASE_KEYBOARD.width + minX) + 'px';
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.style.top = ((BASE_INSTRUCTIONS.top - BASE_KEYBOARD.top) *
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            height / BASE_KEYBOARD.height + minY) + 'px';
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.style.width = (width * BASE_INSTRUCTIONS.width /
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              BASE_KEYBOARD.width) + 'px';
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.style.height = (height * BASE_INSTRUCTIONS.height /
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               BASE_KEYBOARD.height) + 'px';
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var instructionsText = document.createElement('div');
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsText.id = 'instructions-text';
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsText.className = 'keyboard-overlay-instructions-text';
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsText.innerHTML =
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loadTimeData.getString('keyboardOverlayInstructions');
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.appendChild(instructionsText);
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var instructionsHideText = document.createElement('div');
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsHideText.id = 'instructions-hide-text';
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsHideText.className = 'keyboard-overlay-instructions-hide-text';
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructionsHideText.innerHTML =
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loadTimeData.getString('keyboardOverlayInstructionsHide');
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.appendChild(instructionsHideText);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var learnMoreLinkText = document.createElement('div');
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkText.id = 'learn-more-text';
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkText.className = 'keyboard-overlay-learn-more-text';
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkText.addEventListener('click', learnMoreClicked);
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var learnMoreLinkAnchor = document.createElement('a');
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkAnchor.href =
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loadTimeData.getString('keyboardOverlayLearnMoreURL');
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkAnchor.textContent =
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      loadTimeData.getString('keyboardOverlayLearnMore');
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  learnMoreLinkText.appendChild(learnMoreLinkAnchor);
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  instructions.appendChild(learnMoreLinkText);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  keyboard.appendChild(instructions);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns true if the device has a diamond key.
5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} Returns true if the device has a diamond key.
5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function hasDiamondKey() {
5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return loadTimeData.getBoolean('keyboardOverlayHasChromeOSDiamondKey');
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
5782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns true if display rotation feature is enabled.
5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} True if display rotation feature is enabled.
5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isDisplayRotationEnabled() {
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return loadTimeData.getBoolean('keyboardOverlayIsDisplayRotationEnabled');
5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Returns true if display scaling feature is enabled.
5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * @return {boolean} True if display scaling feature is enabled.
5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function isDisplayUIScalingEnabled() {
5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return loadTimeData.getBoolean('keyboardOverlayIsDisplayUIScalingEnabled');
5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Initializes the layout and the key labels for the keyboard that has a diamond
5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * key.
5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) */
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)function initDiamondKey() {
5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var newLayoutData = {
5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '1D': [65.0, 287.0, 60.0, 60.0],  // left Ctrl
6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '38': [185.0, 287.0, 60.0, 60.0],  // left Alt
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    'E0 5B': [125.0, 287.0, 60.0, 60.0],  // search
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '3A': [5.0, 167.0, 105.0, 60.0],  // caps lock
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '5B': [803.0, 6.0, 72.0, 35.0],  // lock key
6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '5D': [5.0, 287.0, 60.0, 60.0]  // diamond key
6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var layout = getLayout();
6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var powerKeyIndex = -1;
6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var powerKeyId = '00';
6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var i = 0; i < layout.length; i++) {
6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    var keyId = layout[i][0];
6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (keyId in newLayoutData) {
6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      layout[i] = [keyId].concat(newLayoutData[keyId]);
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      delete newLayoutData[keyId];
6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (keyId == powerKeyId)
6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      powerKeyIndex = i;
6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var keyId in newLayoutData)
6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layout.push([keyId].concat(newLayoutData[keyId]));
6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remove the power key.
6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (powerKeyIndex != -1)
6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    layout.splice(powerKeyIndex, 1);
6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var keyData = getKeyboardGlyphData()['keys'];
6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  var newKeyData = {
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '3A': {'label': 'caps lock', 'format': 'left'},
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '5B': {'label': 'lock'},
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    '5D': {'label': 'diamond', 'format': 'left'}
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (var keyId in newKeyData)
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    keyData[keyId] = newKeyData[keyId];
6342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/**
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A callback function for the onload event of the body element.
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function init() {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document.addEventListener('keydown', handleKeyEvent);
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  document.addEventListener('keyup', handleKeyEvent);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome.send('getLabelMap');
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initializes the global map for remapping identifiers of modifier keys based
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * on the preference.
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called after sending the 'getLabelMap' message.
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Object} remap Identifier map.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function initIdentifierMap(remap) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (var key in remap) {
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    var val = remap[key];
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((key in LABEL_TO_IDENTIFIER) &&
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        (val in LABEL_TO_IDENTIFIER)) {
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      identifierMap[LABEL_TO_IDENTIFIER[key]] =
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          LABEL_TO_IDENTIFIER[val];
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      console.error('Invalid label map element: ' + key + ', ' + val);
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome.send('getInputMethodId');
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Initializes the global keyboad overlay ID and the layout of keys.
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Called after sending the 'getInputMethodId' message.
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {inputMethodId} inputMethodId Input Method Identifier.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function initKeyboardOverlayId(inputMethodId) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Libcros returns an empty string when it cannot find the keyboard overlay ID
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // corresponding to the current input method.
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In such a case, fallback to the default ID (en_US).
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  var inputMethodIdToOverlayId =
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      keyboardOverlayData['inputMethodIdToOverlayId'];
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (inputMethodId) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyboardOverlayId = inputMethodIdToOverlayId[inputMethodId];
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!keyboardOverlayId) {
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    console.error('No keyboard overlay ID for ' + inputMethodId);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    keyboardOverlayId = 'en_US';
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (document.body.firstChild) {
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    document.body.removeChild(document.body.firstChild);
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // We show Japanese layout as-is because the user has chosen the layout
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // that is quite diffrent from the physical layout that has a diamond key.
6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (hasDiamondKey() && getLayoutName() != 'J')
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    initDiamondKey();
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  initLayout();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  update([]);
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window.webkitRequestAnimationFrame(function() {
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome.send('didPaint');
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  });
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handles click events of the learn more link.
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @param {Event} e Mouse click event.
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)function learnMoreClicked(e) {
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome.send('openLearnMorePage');
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  chrome.send('DialogClose');
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  e.preventDefault();
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)document.addEventListener('DOMContentLoaded', init);
708