Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/extensions/key_identifier_conversion_views.h"
      6 
      7 #include <string.h>
      8 
      9 #include "base/basictypes.h"
     10 #include "base/hash_tables.h"
     11 #include "content/browser/browser_thread.h"
     12 #include "ui/base/keycodes/keyboard_codes.h"
     13 #include "views/events/event.h"
     14 
     15 namespace {
     16 
     17 static const int kNumIdentifierTypes = 3;
     18 
     19 typedef struct KeyIdentifier {
     20   // In order: key identifier, character and unicode codepoint.  They are
     21   // searched in that order as well.
     22   // These are all placed into a single array as they are treated uniformly and
     23   // we never refer to a specific type of identifier.  This reduces code
     24   // duplication below.
     25   const char* identifiers[kNumIdentifierTypes];
     26   const ui::KeyboardCode key_code;
     27   const int event_flags;
     28 } KeyIdentifier;
     29 
     30 // Taken from Section 6.3.3 here:
     31 // http://www.w3.org/TR/DOM-Level-3-Events/#keyset-keyidentifiers
     32 // TODO(bryeung): keycodes could be wrong: I took the keydown code only
     33 static const KeyIdentifier kKeyIdentifiers[] = {
     34   { {"Accept", "", ""}, ui::VKEY_ACCEPT, 0 },
     35   { {"Add", "", ""}, ui::VKEY_ADD, 0 },
     36   { {"Again", "", ""}, ui::VKEY_UNKNOWN, 0 },
     37   { {"AllCandidates", "", ""}, ui::VKEY_UNKNOWN, 0 },
     38   { {"Alphanumeric", "", ""}, ui::VKEY_UNKNOWN, 0 },
     39   { {"Alt", "", ""}, ui::VKEY_MENU, 0 },
     40   { {"AltGraph", "", ""}, ui::VKEY_UNKNOWN, 0 },
     41   { {"Apps", "", ""}, ui::VKEY_APPS, 0 },
     42   { {"Attn", "", ""}, ui::VKEY_ATTN, 0 },
     43   { {"BrowserBack", "", ""}, ui::VKEY_BROWSER_BACK, 0 },
     44   { {"BrowserFavorites", "", ""}, ui::VKEY_BROWSER_FAVORITES, 0 },
     45   { {"BrowserForward", "", ""}, ui::VKEY_BROWSER_FAVORITES, 0 },
     46   { {"BrowserHome", "", ""}, ui::VKEY_BROWSER_HOME, 0 },
     47   { {"BrowserRefresh", "", ""}, ui::VKEY_BROWSER_REFRESH, 0 },
     48   { {"BrowserSearch", "", ""}, ui::VKEY_BROWSER_SEARCH, 0 },
     49   { {"BrowserStop", "", ""}, ui::VKEY_BROWSER_STOP, 0 },
     50   { {"CapsLock", "", ""}, ui::VKEY_CAPITAL, 0 },
     51   { {"Clear", "", ""}, ui::VKEY_OEM_CLEAR, 0 },
     52   { {"CodeInput", "", ""}, ui::VKEY_UNKNOWN, 0 },
     53   { {"Compose", "", ""}, ui::VKEY_UNKNOWN, 0 },
     54   { {"Control", "", ""}, ui::VKEY_CONTROL, 0 },
     55   { {"Crsel", "", ""}, ui::VKEY_CRSEL, 0 },
     56   { {"Convert", "", ""}, ui::VKEY_CONVERT, 0 },
     57   { {"Copy", "", ""}, ui::VKEY_UNKNOWN, 0 },
     58   { {"Cut", "", ""}, ui::VKEY_UNKNOWN, 0 },
     59   { {"Decimal", "", ""}, ui::VKEY_DECIMAL, 0 },
     60   { {"Divide", "", ""}, ui::VKEY_DIVIDE, 0 },
     61   { {"Down", "", ""}, ui::VKEY_DOWN, 0 },
     62   { {"DownLeft", "", ""}, ui::VKEY_UNKNOWN, 0 },
     63   { {"DownRight", "", ""}, ui::VKEY_UNKNOWN, 0 },
     64   { {"End", "", ""}, ui::VKEY_END, 0 },
     65   { {"Enter", "", ""}, ui::VKEY_RETURN, 0 },
     66   { {"EraseEof", "", ""}, ui::VKEY_EREOF, 0 },
     67   { {"Execute", "", ""}, ui::VKEY_EXECUTE, 0 },
     68   { {"Exsel", "", ""}, ui::VKEY_EXSEL, 0 },
     69   { {"Fn", "", ""}, ui::VKEY_UNKNOWN, 0 },
     70   { {"F1", "", ""}, ui::VKEY_F1, 0 },
     71   { {"F2", "", ""}, ui::VKEY_F2, 0 },
     72   { {"F3", "", ""}, ui::VKEY_F3, 0 },
     73   { {"F4", "", ""}, ui::VKEY_F4, 0 },
     74   { {"F5", "", ""}, ui::VKEY_F5, 0 },
     75   { {"F6", "", ""}, ui::VKEY_F6, 0 },
     76   { {"F7", "", ""}, ui::VKEY_F7, 0 },
     77   { {"F8", "", ""}, ui::VKEY_F8, 0 },
     78   { {"F9", "", ""}, ui::VKEY_F9, 0 },
     79   { {"F10", "", ""}, ui::VKEY_F10, 0 },
     80   { {"F11", "", ""}, ui::VKEY_F11, 0 },
     81   { {"F12", "", ""}, ui::VKEY_F12, 0 },
     82   { {"F13", "", ""}, ui::VKEY_F13, 0 },
     83   { {"F14", "", ""}, ui::VKEY_F14, 0 },
     84   { {"F15", "", ""}, ui::VKEY_F15, 0 },
     85   { {"F16", "", ""}, ui::VKEY_F16, 0 },
     86   { {"F17", "", ""}, ui::VKEY_F17, 0 },
     87   { {"F18", "", ""}, ui::VKEY_F18, 0 },
     88   { {"F19", "", ""}, ui::VKEY_F19, 0 },
     89   { {"F20", "", ""}, ui::VKEY_F20, 0 },
     90   { {"F21", "", ""}, ui::VKEY_F21, 0 },
     91   { {"F22", "", ""}, ui::VKEY_F22, 0 },
     92   { {"F23", "", ""}, ui::VKEY_F23, 0 },
     93   { {"F24", "", ""}, ui::VKEY_F24, 0 },
     94   { {"FinalMode", "", ""}, ui::VKEY_FINAL, 0 },
     95   { {"Find", "", ""}, ui::VKEY_UNKNOWN, 0 },
     96   { {"FullWidth", "", ""}, ui::VKEY_UNKNOWN, 0 },
     97   { {"HalfWidth", "", ""}, ui::VKEY_UNKNOWN, 0 },
     98   { {"HangulMode", "", ""}, ui::VKEY_HANGUL, 0 },
     99   { {"HanjaMode", "", ""}, ui::VKEY_HANJA, 0 },
    100   { {"Help", "", ""}, ui::VKEY_HELP, 0 },
    101   { {"Hiragana", "", ""}, ui::VKEY_UNKNOWN, 0 },
    102   { {"Home", "", ""}, ui::VKEY_HOME, 0 },
    103   { {"Insert", "", ""}, ui::VKEY_INSERT, 0 },
    104   { {"JapaneseHiragana", "", ""}, ui::VKEY_UNKNOWN, 0 },
    105   { {"JapaneseKatakana", "", ""}, ui::VKEY_UNKNOWN, 0 },
    106   { {"JapaneseRomaji", "", ""}, ui::VKEY_UNKNOWN, 0 },
    107   { {"JunjaMode", "", ""}, ui::VKEY_JUNJA, 0 },
    108   { {"KanaMode", "", ""}, ui::VKEY_KANA, 0 },
    109   { {"KanjiMode", "", ""}, ui::VKEY_KANJI, 0 },
    110   { {"Katakana", "", ""}, ui::VKEY_UNKNOWN, 0 },
    111   { {"LaunchApplication1", "", ""}, ui::VKEY_MEDIA_LAUNCH_APP1, 0 },
    112   { {"LaunchApplication2", "", ""}, ui::VKEY_MEDIA_LAUNCH_APP2, 0 },
    113   { {"LaunchMail", "", ""}, ui::VKEY_MEDIA_LAUNCH_MAIL, 0 },
    114   { {"Left", "", ""}, ui::VKEY_LEFT, 0 },
    115   { {"Menu", "", ""}, ui::VKEY_MENU, 0 },
    116   { {"Meta", "", ""}, ui::VKEY_UNKNOWN, 0 },
    117   { {"MediaNextTrack", "", ""}, ui::VKEY_MEDIA_NEXT_TRACK, 0 },
    118   { {"MediaPlayPause", "", ""}, ui::VKEY_MEDIA_PLAY_PAUSE, 0 },
    119   { {"MediaPreviousTrack", "", ""}, ui::VKEY_MEDIA_PREV_TRACK, 0 },
    120   { {"MediaStop", "", ""}, ui::VKEY_MEDIA_STOP, 0 },
    121   { {"ModeChange", "", ""}, ui::VKEY_MODECHANGE, 0 },
    122   { {"Multiply", "", ""}, ui::VKEY_MULTIPLY, 0 },
    123   { {"NextCandidate", "", ""}, ui::VKEY_UNKNOWN, 0 },
    124   { {"Nonconvert", "", ""}, ui::VKEY_NONCONVERT, 0 },
    125   { {"NumLock", "", ""}, ui::VKEY_NUMLOCK, 0 },
    126   { {"PageDown", "", ""}, ui::VKEY_NEXT, 0 },
    127   { {"PageUp", "", ""}, ui::VKEY_PRIOR, 0 },
    128   { {"Paste", "", ""}, ui::VKEY_UNKNOWN, 0 },
    129   { {"Pause", "", ""}, ui::VKEY_PAUSE, 0 },
    130   { {"Play", "", ""}, ui::VKEY_PLAY, 0 },
    131   { {"PreviousCandidate", "", ""}, ui::VKEY_UNKNOWN, 0 },
    132   { {"PrintScreen", "", ""}, ui::VKEY_SNAPSHOT, 0 },
    133   { {"Process", "", ""}, ui::VKEY_PROCESSKEY, 0 },
    134   { {"Props", "", ""}, ui::VKEY_UNKNOWN, 0 },
    135   { {"Right", "", ""}, ui::VKEY_RIGHT, 0 },
    136   { {"RomanCharacters", "", ""}, ui::VKEY_UNKNOWN, 0 },
    137   { {"Scroll", "", ""}, ui::VKEY_SCROLL, 0 },
    138   { {"Select", "", ""}, ui::VKEY_SELECT, 0 },
    139   { {"SelectMedia", "", ""}, ui::VKEY_MEDIA_LAUNCH_MEDIA_SELECT, 0 },
    140   { {"Separator", "", ""}, ui::VKEY_SEPARATOR, 0 },
    141   { {"Shift", "", ""}, ui::VKEY_SHIFT, 0 },
    142   { {"Soft1", "", ""}, ui::VKEY_UNKNOWN, 0 },
    143   { {"Soft2", "", ""}, ui::VKEY_UNKNOWN, 0 },
    144   { {"Soft3", "", ""}, ui::VKEY_UNKNOWN, 0 },
    145   { {"Soft4", "", ""}, ui::VKEY_UNKNOWN, 0 },
    146   { {"Stop", "", ""}, ui::VKEY_UNKNOWN, 0 },
    147   { {"Subtract", "", ""}, ui::VKEY_SUBTRACT, 0 },
    148   { {"Up", "", ""}, ui::VKEY_UP, 0 },
    149   { {"UpLeft", "", ""}, ui::VKEY_UNKNOWN, 0 },
    150   { {"UpRight", "", ""}, ui::VKEY_UNKNOWN, 0 },
    151   { {"Undo", "", ""}, ui::VKEY_UNKNOWN, 0 },
    152   { {"VolumeDown", "", ""}, ui::VKEY_VOLUME_DOWN, 0 },
    153   { {"VolumeMute", "", ""}, ui::VKEY_VOLUME_MUTE, 0 },
    154   { {"VolumeUp", "", ""}, ui::VKEY_VOLUME_UP, 0 },
    155   { {"Win", "", ""}, ui::VKEY_LWIN, 0 },
    156   { {"Zoom", "", ""}, ui::VKEY_ZOOM, 0 },
    157   { {"Backspace", "", "U+0008"}, ui::VKEY_BACK, 0 },
    158   { {"Tab", "", "U+0009"}, ui::VKEY_TAB, 0 },
    159   { {"Cancel", "", "U+0018"}, ui::VKEY_UNKNOWN, 0 },
    160   { {"Esc", "", "U+001B"}, ui::VKEY_ESCAPE, 0 },
    161   { {"Spacebar", " ", "U+0020"}, ui::VKEY_SPACE, 0 },
    162   { {"Exclamation", "!", "U+0021"}, ui::VKEY_1, ui::EF_SHIFT_DOWN },
    163   { {"DoubleQuote", "\"", "U+0022"},
    164       ui::VKEY_OEM_7, ui::EF_SHIFT_DOWN },
    165   { {"Hash", "#", "U+0023"}, ui::VKEY_3, ui::EF_SHIFT_DOWN },
    166   { {"Dollar", "$", "U+0024"}, ui::VKEY_4, ui::EF_SHIFT_DOWN },
    167   { {"Ampersand", "&", "U+0026"}, ui::VKEY_7, ui::EF_SHIFT_DOWN },
    168   { {"Apostrophe", "\'", "U+0027"}, ui::VKEY_OEM_7, 0 },
    169   { {"LeftParen", "(", "U+0028"}, ui::VKEY_9, ui::EF_SHIFT_DOWN },
    170   { {"RightParen", ")", "U+0029"}, ui::VKEY_0, ui::EF_SHIFT_DOWN },
    171   { {"Asterisk", "*", "U+002A"}, ui::VKEY_8, ui::EF_SHIFT_DOWN },
    172   { {"Plus", "+", "U+002B"}, ui::VKEY_OEM_PLUS, ui::EF_SHIFT_DOWN },
    173   { {"Percent", "%", "U+0025"}, ui::VKEY_5, ui::EF_SHIFT_DOWN },
    174   { {"Comma", ",", "U+002C"}, ui::VKEY_OEM_COMMA, 0 },
    175   { {"HyphenMinus", "-", "U+002D"}, ui::VKEY_OEM_MINUS, 0 },
    176   { {"Period", ".", "U+002E"}, ui::VKEY_OEM_PERIOD, 0 },
    177   { {"Solidus", "/", "U+002F"}, ui::VKEY_OEM_2, 0 },
    178   { {"", "0", "U+0030"}, ui::VKEY_0, 0 },
    179   { {"", "1", "U+0031"}, ui::VKEY_1, 0 },
    180   { {"", "2", "U+0032"}, ui::VKEY_2, 0 },
    181   { {"", "3", "U+0033"}, ui::VKEY_3, 0 },
    182   { {"", "4", "U+0034"}, ui::VKEY_4, 0 },
    183   { {"", "5", "U+0035"}, ui::VKEY_5, 0 },
    184   { {"", "6", "U+0036"}, ui::VKEY_6, 0 },
    185   { {"", "7", "U+0037"}, ui::VKEY_7, 0 },
    186   { {"", "8", "U+0038"}, ui::VKEY_8, 0 },
    187   { {"", "9", "U+0039"}, ui::VKEY_9, 0 },
    188   { {"Colon", ":", "U+003A"}, ui::VKEY_OEM_1, ui::EF_SHIFT_DOWN },
    189   { {"Semicolon", ";", "U+003B"}, ui::VKEY_OEM_1, 0 },
    190   { {"LessThan", "<", "U+003C"},
    191       ui::VKEY_OEM_COMMA, ui::EF_SHIFT_DOWN },
    192   { {"Equals", "=", "U+003D"}, ui::VKEY_OEM_PLUS, 0 },
    193   { {"GreaterThan", ">", "U+003E"},
    194       ui::VKEY_OEM_PERIOD, ui::EF_SHIFT_DOWN },
    195   { {"QuestionMark", "?", "U+003F"},
    196       ui::VKEY_OEM_2, ui::EF_SHIFT_DOWN },
    197   { {"At", "@", "U+0040"}, ui::VKEY_2, ui::EF_SHIFT_DOWN },
    198   { {"", "A", "U+0041"}, ui::VKEY_A, 0 },
    199   { {"", "B", "U+0042"}, ui::VKEY_B, 0 },
    200   { {"", "C", "U+0043"}, ui::VKEY_C, 0 },
    201   { {"", "D", "U+0044"}, ui::VKEY_D, 0 },
    202   { {"", "E", "U+0045"}, ui::VKEY_E, 0 },
    203   { {"", "F", "U+0046"}, ui::VKEY_F, 0 },
    204   { {"", "G", "U+0047"}, ui::VKEY_G, 0 },
    205   { {"", "H", "U+0048"}, ui::VKEY_H, 0 },
    206   { {"", "I", "U+0049"}, ui::VKEY_I, 0 },
    207   { {"", "J", "U+004A"}, ui::VKEY_J, 0 },
    208   { {"", "K", "U+004B"}, ui::VKEY_K, 0 },
    209   { {"", "L", "U+004C"}, ui::VKEY_L, 0 },
    210   { {"", "M", "U+004D"}, ui::VKEY_M, 0 },
    211   { {"", "N", "U+004E"}, ui::VKEY_N, 0 },
    212   { {"", "O", "U+004F"}, ui::VKEY_O, 0 },
    213   { {"", "P", "U+0050"}, ui::VKEY_P, 0 },
    214   { {"", "Q", "U+0051"}, ui::VKEY_Q, 0 },
    215   { {"", "R", "U+0052"}, ui::VKEY_R, 0 },
    216   { {"", "S", "U+0053"}, ui::VKEY_S, 0 },
    217   { {"", "T", "U+0054"}, ui::VKEY_T, 0 },
    218   { {"", "U", "U+0055"}, ui::VKEY_U, 0 },
    219   { {"", "V", "U+0056"}, ui::VKEY_V, 0 },
    220   { {"", "W", "U+0057"}, ui::VKEY_W, 0 },
    221   { {"", "X", "U+0058"}, ui::VKEY_X, 0 },
    222   { {"", "Y", "U+0059"}, ui::VKEY_Y, 0 },
    223   { {"", "Z", "U+005A"}, ui::VKEY_Z, 0 },
    224   { {"", "a", "U+0061"}, ui::VKEY_A, 0 },
    225   { {"", "b", "U+0062"}, ui::VKEY_B, 0 },
    226   { {"", "c", "U+0063"}, ui::VKEY_C, 0 },
    227   { {"", "d", "U+0064"}, ui::VKEY_D, 0 },
    228   { {"", "e", "U+0065"}, ui::VKEY_E, 0 },
    229   { {"", "f", "U+0066"}, ui::VKEY_F, 0 },
    230   { {"", "g", "U+0067"}, ui::VKEY_G, 0 },
    231   { {"", "h", "U+0068"}, ui::VKEY_H, 0 },
    232   { {"", "i", "U+0069"}, ui::VKEY_I, 0 },
    233   { {"", "j", "U+006A"}, ui::VKEY_J, 0 },
    234   { {"", "k", "U+006B"}, ui::VKEY_K, 0 },
    235   { {"", "l", "U+006C"}, ui::VKEY_L, 0 },
    236   { {"", "m", "U+006D"}, ui::VKEY_M, 0 },
    237   { {"", "n", "U+006E"}, ui::VKEY_N, 0 },
    238   { {"", "o", "U+006F"}, ui::VKEY_O, 0 },
    239   { {"", "p", "U+0070"}, ui::VKEY_P, 0 },
    240   { {"", "q", "U+0071"}, ui::VKEY_Q, 0 },
    241   { {"", "r", "U+0072"}, ui::VKEY_R, 0 },
    242   { {"", "s", "U+0073"}, ui::VKEY_S, 0 },
    243   { {"", "t", "U+0074"}, ui::VKEY_T, 0 },
    244   { {"", "u", "U+0075"}, ui::VKEY_U, 0 },
    245   { {"", "v", "U+0076"}, ui::VKEY_V, 0 },
    246   { {"", "w", "U+0077"}, ui::VKEY_W, 0 },
    247   { {"", "x", "U+0078"}, ui::VKEY_X, 0 },
    248   { {"", "y", "U+0079"}, ui::VKEY_Y, 0 },
    249   { {"", "z", "U+007A"}, ui::VKEY_Z, 0 },
    250   { {"LeftSquareBracket", "[", "U+005B"}, ui::VKEY_OEM_4, 0 },
    251   { {"Backslash", "\\", "U+005C"}, ui::VKEY_OEM_5, 0 },
    252   { {"RightSquareBracket", "]", "U+005D"}, ui::VKEY_OEM_6, 0 },
    253   { {"Circumflex", "^", "U+005E"}, ui::VKEY_6, ui::EF_SHIFT_DOWN },
    254   { {"Underscore", "_", "U+005F"},
    255       ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN },
    256   { {"Grave", "`", "U+0060"}, ui::VKEY_OEM_3, 0 },
    257   { {"Tilde", "~", "U+007E"}, ui::VKEY_OEM_3, ui::EF_SHIFT_DOWN },
    258   { {"LeftCurlyBracket", "{", "U+007B"},
    259       ui::VKEY_OEM_4, ui::EF_SHIFT_DOWN },
    260   { {"Pipe", "|", "U+007C"}, ui::VKEY_OEM_5, ui::EF_SHIFT_DOWN },
    261   { {"RightCurlyBracket", "}", "U+007D"},
    262       ui::VKEY_OEM_6, ui::EF_SHIFT_DOWN },
    263   { {"Del", "", "U+007F"}, ui::VKEY_DELETE, 0 },
    264   { {"InvertedExclamation", "", "U+00A1"}, ui::VKEY_UNKNOWN, 0 },
    265   { {"DeadGrave", "", "U+0300"}, ui::VKEY_UNKNOWN, 0 },
    266   { {"DeadEacute", "", "U+0301"}, ui::VKEY_UNKNOWN, 0 },
    267   { {"DeadCircumflex", "", "U+0302"}, ui::VKEY_UNKNOWN, 0 },
    268   { {"DeadTilde", "", "U+0303"}, ui::VKEY_UNKNOWN, 0 },
    269   { {"DeadMacron", "", "U+0304"}, ui::VKEY_UNKNOWN, 0 },
    270   { {"DeadBreve", "", "U+0306"}, ui::VKEY_UNKNOWN, 0 },
    271   { {"DeadAboveDot", "", "U+0307"}, ui::VKEY_UNKNOWN, 0 },
    272   { {"DeadUmlaut", "", "U+0308"}, ui::VKEY_UNKNOWN, 0 },
    273   { {"DeadAboveRing", "", "U+030A"}, ui::VKEY_UNKNOWN, 0 },
    274   { {"DeadDoubleacute", "", "U+030B"}, ui::VKEY_UNKNOWN, 0 },
    275   { {"DeadCaron", "", "U+030C"}, ui::VKEY_UNKNOWN, 0 },
    276   { {"DeadCedilla", "", "U+0327"}, ui::VKEY_UNKNOWN, 0 },
    277   { {"DeadOgonek", "", "U+0328"}, ui::VKEY_UNKNOWN, 0 },
    278   { {"DeadIota", "", "U+0345"}, ui::VKEY_UNKNOWN, 0 },
    279   { {"Euro", "", "U+20AC"}, ui::VKEY_UNKNOWN, 0 },
    280   { {"DeadVoicedSound", "", "U+3099"}, ui::VKEY_UNKNOWN, 0 },
    281   { {"DeadSemivoicedSound", "", "U+309A"}, ui::VKEY_UNKNOWN, 0 }
    282 };
    283 
    284 static const int kNumKeyIdentifiers = arraysize(kKeyIdentifiers);
    285 
    286 typedef base::hash_map<std::string, const views::KeyEvent*> IdentifierMap;
    287 typedef std::pair<std::string, const views::KeyEvent*> IdentifierPair;
    288 static IdentifierMap* identifierMaps[kNumIdentifierTypes] = { NULL };
    289 
    290 static views::KeyEvent* kUnknownKeyEvent = NULL;
    291 
    292 static void InitializeMaps() {
    293   if (identifierMaps[0])
    294     return;
    295 
    296   kUnknownKeyEvent = new views::KeyEvent(
    297     ui::ET_KEY_PRESSED, ui::VKEY_UNKNOWN, 0);
    298 
    299   for (int i = 0; i < kNumIdentifierTypes; ++i)
    300     identifierMaps[i] = new IdentifierMap;
    301 
    302   for (int i = 0; i < kNumKeyIdentifiers; ++i) {
    303     const KeyIdentifier& key = kKeyIdentifiers[i];
    304 
    305     views::KeyEvent* event = new views::KeyEvent(
    306         ui::ET_KEY_PRESSED, key.key_code, key.event_flags);
    307 
    308     for (int j = 0; j < kNumIdentifierTypes; ++j) {
    309       if (key.identifiers[j][0] != '\0') {
    310         std::pair<IdentifierMap::iterator, bool> result =
    311             identifierMaps[j]->insert(
    312                 IdentifierPair(key.identifiers[j], event));
    313         DCHECK(result.second);
    314       }
    315     }
    316   }
    317 }
    318 
    319 }  // namespace
    320 
    321 
    322 const views::KeyEvent& KeyEventFromKeyIdentifier(
    323     const std::string& key_identifier) {
    324   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    325   InitializeMaps();
    326 
    327   for (int i = 0; i < kNumIdentifierTypes; ++i) {
    328     const IdentifierMap& map = *identifierMaps[i];
    329 
    330     IdentifierMap::const_iterator iter = map.find(key_identifier);
    331     if (iter != map.end())
    332       return *iter->second;
    333   }
    334 
    335   return *kUnknownKeyEvent;
    336 }
    337