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