summaryrefslogtreecommitdiffstats
path: root/chrome/browser/resources/chromeos/keyboard/keyboard_utils.js
blob: 931b5aa7b89627ad134cfbf7ff6248f114864e09 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * Namespace for keyboard utility functions.
 */
var keyboard = {};

/**
 * Swallows keypress and keyup events of arrow keys.
 * @param {KeyboardEvent} event Raised event.
 * @private
 */
keyboard.onKeyIgnore_ = function(event) {
  if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
    return;

  if (event.keyIdentifier == 'Left' ||
      event.keyIdentifier == 'Right' ||
      event.keyIdentifier == 'Up' ||
      event.keyIdentifier == 'Down') {
    event.stopPropagation();
    event.preventDefault();
  }
};

/**
 * Converts arrow keys into tab/shift-tab key events.
 * @param {KeyboardEvent} event Raised event.
 * @private
 */
keyboard.onKeyDown_ = function(event) {
   if (event.ctrlKey || event.shiftKey || event.altKey || event.metaKey)
     return;

   var needsUpDownKeys = event.target.classList.contains('needs-up-down-keys');

   if (event.keyIdentifier == 'Left' ||
       (!needsUpDownKeys && event.keyIdentifier == 'Up')) {
     keyboard.raiseKeyFocusPrevious(document.activeElement);
     event.stopPropagation();
     event.preventDefault();
   } else if (event.keyIdentifier == 'Right' ||
              (!needsUpDownKeys && event.keyIdentifier == 'Down')) {
     keyboard.raiseKeyFocusNext(document.activeElement);
     event.stopPropagation();
     event.preventDefault();
   }
};

/**
 * Raises tab/shift-tab keyboard events.
 * @param {HTMLElement} element Element that should receive the event.
 * @param {string} eventType Keyboard event type.
 * @param {boolean} shift True if shift should be on.
 * @private
 */
keyboard.raiseTabKeyEvent_ = function(element, eventType, shift) {
  var event = document.createEvent('KeyboardEvent');
  event.initKeyboardEvent(
      eventType,
      true,  // canBubble
      true,  // cancelable
      window,
      'U+0009',
      0,  // keyLocation
      false,  // ctrl
      false,  // alt
      shift,  // shift
      false);  // meta
  element.dispatchEvent(event);
};

/**
 * Raises shift+tab keyboard events to focus previous element.
 * @param {HTMLElement} element Element that should receive the event.
 */
keyboard.raiseKeyFocusPrevious = function(element) {
  keyboard.raiseTabKeyEvent_(element, 'keydown', true);
  keyboard.raiseTabKeyEvent_(element, 'keypress', true);
  keyboard.raiseTabKeyEvent_(element, 'keyup', true);
};

/**
 * Raises tab keyboard events to focus next element.
 * @param {HTMLElement} element Element that should receive the event.
 */
keyboard.raiseKeyFocusNext = function(element) {
  keyboard.raiseTabKeyEvent_(element, 'keydown', false);
  keyboard.raiseTabKeyEvent_(element, 'keypress', false);
  keyboard.raiseTabKeyEvent_(element, 'keyup', false);
};

/**
 * Initializes event handling for arrow keys driven focus flow.
 */
keyboard.initializeKeyboardFlow = function() {
  document.addEventListener('keydown',
      keyboard.onKeyDown_, true);
  document.addEventListener('keypress',
      keyboard.onKeyIgnore_, true);
  document.addEventListener('keyup',
      keyboard.onKeyIgnore_, true);
};