keyboard_handler.js revision cedac228d2dd51db4b79ea1e72c7f249408ee061
1// Copyright 2014 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
5goog.provide('cvox.ChromeVoxKbHandler');
6
7goog.require('cvox.ChromeVox');
8goog.require('cvox.ChromeVoxUserCommands');
9goog.require('cvox.History');
10goog.require('cvox.KeyMap');
11goog.require('cvox.KeySequence');
12goog.require('cvox.KeyUtil');
13goog.require('cvox.KeyboardHelpWidget');
14
15/**
16 * @fileoverview Handles user keyboard input events.
17 *
18 */
19cvox.ChromeVoxKbHandler = {};
20
21/**
22 * The key map
23 *
24 * @type {cvox.KeyMap}
25 */
26cvox.ChromeVoxKbHandler.handlerKeyMap;
27
28/**
29 * Loads the key bindings into the keyToFunctionsTable.
30 *
31 * @param {string} keyToFunctionsTable The key bindings table in JSON form.
32 */
33cvox.ChromeVoxKbHandler.loadKeyToFunctionsTable = function(
34    keyToFunctionsTable) {
35  if (!window.JSON) {
36    return;
37  }
38
39  cvox.ChromeVoxKbHandler.handlerKeyMap =
40      cvox.KeyMap.fromJSON(keyToFunctionsTable);
41};
42
43/**
44 * Converts the key bindings table into an array that is sorted by the lengths
45 * of the key bindings. After the sort, the key bindings that describe single
46 * keys will come before the key bindings that describe multiple keys.
47 * @param {Object.<string, string>} keyToFunctionsTable Contains each key
48 * binding and its associated function name.
49 * @return {Array.<Array.<string>>} The sorted key bindings table in
50 * array form. Each entry in the array is itself an array containing the
51 * key binding and its associated function name.
52 * @private
53 */
54cvox.ChromeVoxKbHandler.sortKeyToFunctionsTable_ = function(
55    keyToFunctionsTable) {
56  var sortingArray = [];
57
58  for (var keySeqStr in keyToFunctionsTable) {
59    sortingArray.push([keySeqStr, keyToFunctionsTable[keySeqStr]]);
60  }
61
62  function compareKeyStr(a, b) {
63    // Compare the lengths of the key bindings.
64    if (a[0].length < b[0].length) {
65      return -1;
66    } else if (b[0].length < a[0].length) {
67      return 1;
68    } else {
69      // The keys are the same length. Sort lexicographically.
70      return a[0].localeCompare(b[0]);
71    }
72  };
73
74  sortingArray.sort(compareKeyStr);
75  return sortingArray;
76};
77
78
79/**
80 * Handles key down events.
81 *
82 * @param {Event} evt The key down event to process.
83 * @return {boolean} True if the default action should be performed.
84 */
85cvox.ChromeVoxKbHandler.basicKeyDownActionsListener = function(evt) {
86  var keySequence = cvox.KeyUtil.keyEventToKeySequence(evt);
87  var functionName;
88  if (cvox.ChromeVoxKbHandler.handlerKeyMap != undefined) {
89    functionName =
90        cvox.ChromeVoxKbHandler.handlerKeyMap.commandForKey(keySequence);
91  } else {
92    functionName = null;
93  }
94
95  // TODO (clchen): Disambiguate why functions are null. If the user pressed
96  // something that is not a valid combination, make an error noise so there
97  // is some feedback.
98
99  if (!functionName) {
100    return !cvox.KeyUtil.sequencing;
101  }
102
103  // If ChromeVox isn't active, ignore every command except the one
104  // to toggle ChromeVox active again.
105  if (!cvox.ChromeVox.isActive && functionName != 'toggleChromeVox') {
106    return true;
107  }
108
109  // This is the key event handler return value - true if the event should
110  // propagate and the default action should be performed, false if we eat
111  // the key.
112  var returnValue = true;
113
114  var func = cvox.ChromeVoxUserCommands.commands[functionName];
115  if (func) {
116    var history = cvox.History.getInstance();
117    history.enterUserCommand(functionName);
118    returnValue = func();
119    history.exitUserCommand(functionName);
120  } else if (keySequence.cvoxModifier) {
121    // Modifier/prefix is active -- prevent default action
122    returnValue = false;
123  }
124
125  // If the whole document is hidden from screen readers, let the app
126  // catch keys as well.
127  if (cvox.ChromeVox.entireDocumentIsHidden) {
128    returnValue = true;
129  }
130  return returnValue;
131};
132