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