Home | History | Annotate | Download | only in keyboard
      1 // Copyright (c) 2013 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 /**
      6  * Namespace for keyboard utility functions.
      7  */
      8 var keyboard = {};
      9 
     10 /**
     11  * Swallows keypress and keyup events of arrow keys.
     12  * @param {KeyboardEvent} event Raised event.
     13  * @private
     14  */
     15 keyboard.onKeyIgnore_ = function(event) {
     16   if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
     17     return;
     18 
     19   if (event.keyIdentifier == 'Left' ||
     20       event.keyIdentifier == 'Right' ||
     21       event.keyIdentifier == 'Up' ||
     22       event.keyIdentifier == 'Down') {
     23     event.stopPropagation();
     24     event.preventDefault();
     25   }
     26 };
     27 
     28 /**
     29  * Converts arrow keys into tab/shift-tab key events.
     30  * @param {KeyboardEvent} event Raised event.
     31  * @private
     32  */
     33 keyboard.onKeyDown_ = function(event) {
     34    if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
     35      return;
     36 
     37    var needsUpDownKeys = event.target.classList.contains('needs-up-down-keys');
     38 
     39    if (event.keyIdentifier == 'Left' ||
     40        (!needsUpDownKeys && event.keyIdentifier == 'Up')) {
     41      keyboard.raiseKeyFocusPrevious(document.activeElement);
     42      event.stopPropagation();
     43      event.preventDefault();
     44    } else if (event.keyIdentifier == 'Right' ||
     45               (!needsUpDownKeys && event.keyIdentifier == 'Down')) {
     46      keyboard.raiseKeyFocusNext(document.activeElement);
     47      event.stopPropagation();
     48      event.preventDefault();
     49    }
     50 };
     51 
     52 /**
     53  * Raises tab/shift-tab keyboard events.
     54  * @param {HTMLElement} element Element that should receive the event.
     55  * @param {string} eventType Keyboard event type.
     56  * @param {boolean} shift True if shift should be on.
     57  * @private
     58  */
     59 keyboard.raiseTabKeyEvent_ = function(element, eventType, shift) {
     60   var event = document.createEvent('KeyboardEvent');
     61   event.initKeyboardEvent(
     62       eventType,
     63       true,  // canBubble
     64       true,  // cancelable
     65       window,
     66       'U+0009',
     67       0,  // keyLocation
     68       false,  // ctrl
     69       false,  // alt
     70       shift,  // shift
     71       false);  // meta
     72   element.dispatchEvent(event);
     73 };
     74 
     75 /**
     76  * Raises shift+tab keyboard events to focus previous element.
     77  * @param {HTMLElement} element Element that should receive the event.
     78  */
     79 keyboard.raiseKeyFocusPrevious = function(element) {
     80   keyboard.raiseTabKeyEvent_(element, 'keydown', true);
     81   keyboard.raiseTabKeyEvent_(element, 'keypress', true);
     82   keyboard.raiseTabKeyEvent_(element, 'keyup', true);
     83 };
     84 
     85 /**
     86  * Raises tab keyboard events to focus next element.
     87  * @param {HTMLElement} element Element that should receive the event.
     88  */
     89 keyboard.raiseKeyFocusNext = function(element) {
     90   keyboard.raiseTabKeyEvent_(element, 'keydown', false);
     91   keyboard.raiseTabKeyEvent_(element, 'keypress', false);
     92   keyboard.raiseTabKeyEvent_(element, 'keyup', false);
     93 };
     94 
     95 /**
     96  * Initializes event handling for arrow keys driven focus flow.
     97  */
     98 keyboard.initializeKeyboardFlow = function() {
     99   document.addEventListener('keydown',
    100       keyboard.onKeyDown_, true);
    101   document.addEventListener('keypress',
    102       keyboard.onKeyIgnore_, true);
    103   document.addEventListener('keyup',
    104       keyboard.onKeyIgnore_, true);
    105 };
    106