summaryrefslogtreecommitdiff
path: root/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js')
-rw-r--r--chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js633
1 files changed, 0 insertions, 633 deletions
diff --git a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js b/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js
deleted file mode 100644
index 0a6f3d51c01..00000000000
--- a/chromium/chrome/browser/resources/chromeos/chromevox/common/key_sequence.js
+++ /dev/null
@@ -1,633 +0,0 @@
-// Copyright 2014 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.
-
-/**
- * @fileoverview A JavaScript class that represents a sequence of keys entered
- * by the user.
- */
-
-
-goog.provide('cvox.KeySequence');
-
-goog.require('cvox.ChromeVox');
-goog.require('cvox.PlatformFilter');
-
-
-/**
- * A class to represent a sequence of keys entered by a user or affiliated with
- * a ChromeVox command.
- * This class can represent the data from both types of key sequences:
- *
- * COMMAND KEYS SPECIFIED IN A KEYMAP:
- * - Two discrete keys (at most): [Down arrow], [A, A] or [O, W] etc. Can
- * specify one or both.
- * - Modifiers (like ctrl, alt, meta, etc)
- * - Whether or not the ChromeVox modifier key is required with the command.
- *
- * USER INPUT:
- * - Two discrete keys (at most): [Down arrow], [A, A] or [O, W] etc.
- * - Modifiers (like ctlr, alt, meta, etc)
- * - Whether or not the ChromeVox modifier key was active when the keys were
- * entered.
- * - Whether or not a prefix key was entered before the discrete keys.
- * - Whether sticky mode was active.
- * @param {Event|Object} originalEvent The original key event entered by a user.
- * The originalEvent may or may not have parameters stickyMode and keyPrefix
- * specified. We will also accept an event-shaped object.
- * @param {boolean=} opt_cvoxModifier Whether or not the ChromeVox modifier key
- * is active. If not specified, we will try to determine whether the modifier
- * was active by looking at the originalEvent.
- * @param {boolean=} opt_skipStripping Skips stripping of ChromeVox modifiers
- * from key events when the cvox modifiers are set. Defaults to false.
- * @param {boolean=} opt_doubleTap Whether this is triggered via double tap.
- * @constructor
- */
-cvox.KeySequence = function(
- originalEvent, opt_cvoxModifier, opt_skipStripping, opt_doubleTap) {
- /** @type {boolean} */
- this.doubleTap = !!opt_doubleTap;
-
- /** @type {cvox.PlatformFilter} */
- this.platformFilter;
-
- if (opt_cvoxModifier == undefined) {
- this.cvoxModifier = this.isCVoxModifierActive(originalEvent);
- } else {
- this.cvoxModifier = opt_cvoxModifier;
- }
- this.stickyMode = !!originalEvent['stickyMode'];
- this.prefixKey = !!originalEvent['keyPrefix'];
- this.skipStripping = !!opt_skipStripping;
-
- if (this.stickyMode && this.prefixKey) {
- throw 'Prefix key and sticky mode cannot both be enabled: ' + originalEvent;
- }
-
- var event = this.resolveChromeOSSpecialKeys_(originalEvent);
-
- // TODO (rshearer): We should take the user out of sticky mode if they
- // try to use the CVox modifier or prefix key.
-
- /**
- * Stores the key codes and modifiers for the keys in the key sequence.
- * TODO(rshearer): Consider making this structure an array of minimal
- * keyEvent-like objects instead so we don't have to worry about what happens
- * when ctrlKey.length is different from altKey.length.
- *
- * NOTE: If a modifier key is pressed by itself, we will store the keyCode
- * *and* set the appropriate modKey to be true. This mirrors the way key
- * events are created on Mac and Windows. For example, if the Meta key was
- * pressed by itself, the keys object will have:
- * {metaKey: [true], keyCode:[91]}
- *
- * @type {Object}
- */
- this.keys = {
- ctrlKey: [],
- searchKeyHeld: [],
- altKey: [],
- altGraphKey: [],
- shiftKey: [],
- metaKey: [],
- keyCode: []
- };
-
- this.extractKey_(event);
-};
-
-
-// TODO(dtseng): This is incomplete; pull once we have appropriate libs.
-/**
- * Maps a keypress keycode to a keydown or keyup keycode.
- * @type {Object<number, number>}
- */
-cvox.KeySequence.KEY_PRESS_CODE = {
- 39: 222,
- 44: 188,
- 45: 189,
- 46: 190,
- 47: 191,
- 59: 186,
- 91: 219,
- 92: 220,
- 93: 221
-};
-
-/**
- * A cache of all key sequences that have been set as double-tappable. We need
- * this cache because repeated key down computations causes ChromeVox to become
- * less responsive. This list is small so we currently use an array.
- * @type {!Array<cvox.KeySequence>}
- */
-cvox.KeySequence.doubleTapCache = [];
-
-
-/**
- * Adds an additional key onto the original sequence, for use when the user
- * is entering two shortcut keys. This happens when the user presses a key,
- * releases it, and then presses a second key. Those two keys together are
- * considered part of the sequence.
- * @param {Event|Object} additionalKeyEvent The additional key to be added to
- * the original event. Should be an event or an event-shaped object.
- * @return {boolean} Whether or not we were able to add a key. Returns false
- * if there are already two keys attached to this event.
- */
-cvox.KeySequence.prototype.addKeyEvent = function(additionalKeyEvent) {
- if (this.keys.keyCode.length > 1) {
- return false;
- }
- this.extractKey_(additionalKeyEvent);
- return true;
-};
-
-
-/**
- * Check for equality. Commands are matched based on the actual key codes
- * involved and on whether or not they both require a ChromeVox modifier key.
- *
- * If sticky mode or a prefix is active on one of the commands but not on
- * the other, then we try and match based on key code first.
- * - If both commands have the same key code and neither of them have the
- * ChromeVox modifier active then we have a match.
- * - Next we try and match with the ChromeVox modifier. If both commands have
- * the same key code, and one of them has the ChromeVox modifier and the other
- * has sticky mode or an active prefix, then we also have a match.
- * @param {!cvox.KeySequence} rhs The key sequence to compare against.
- * @return {boolean} True if equal.
- */
-cvox.KeySequence.prototype.equals = function(rhs) {
- // Check to make sure the same keys with the same modifiers were pressed.
- if (!this.checkKeyEquality_(rhs)) {
- return false;
- }
-
- if (this.doubleTap != rhs.doubleTap) {
- return false;
- }
-
- // So now we know the actual keys are the same.
- // If they both have the ChromeVox modifier, or they both don't have the
- // ChromeVox modifier, then they are considered equal.
- if (this.cvoxModifier === rhs.cvoxModifier) {
- return true;
- }
-
- // So only one of them has the ChromeVox modifier. If the one that doesn't
- // have the ChromeVox modifier has sticky mode or the prefix key then the
- // keys are still considered equal.
- var unmodified = this.cvoxModifier ? rhs : this;
- return unmodified.stickyMode || unmodified.prefixKey;
-};
-
-
-/**
- * Utility method that extracts the key code and any modifiers from a given
- * event and adds them to the object map.
- * @param {Event|Object} keyEvent The keyEvent or event-shaped object to extract
- * from.
- * @private
- */
-cvox.KeySequence.prototype.extractKey_ = function(keyEvent) {
- for (var prop in this.keys) {
- if (prop == 'keyCode') {
- var keyCode;
- // TODO (rshearer): This is temporary until we find a library that can
- // convert between ASCII charcodes and keycodes.
- if (keyEvent.type == 'keypress' && keyEvent[prop] >= 97 &&
- keyEvent[prop] <= 122) {
- // Alphabetic keypress. Convert to the upper case ASCII code.
- keyCode = keyEvent[prop] - 32;
- } else if (keyEvent.type == 'keypress') {
- keyCode = cvox.KeySequence.KEY_PRESS_CODE[keyEvent[prop]];
- }
- this.keys[prop].push(keyCode || keyEvent[prop]);
- } else {
- if (this.isKeyModifierActive(keyEvent, prop)) {
- this.keys[prop].push(true);
- } else {
- this.keys[prop].push(false);
- }
- }
- }
- if (this.cvoxModifier) {
- this.rationalizeKeys_();
- }
-};
-
-
-/**
- * Rationalizes the key codes and the ChromeVox modifier for this keySequence.
- * This means we strip out the key codes and key modifiers stored for this
- * KeySequence that are also present in the ChromeVox modifier. For example, if
- * the ChromeVox modifier keys are Ctrl+Alt, and we've determined that the
- * ChromeVox modifier is active (meaning the user has pressed Ctrl+Alt), we
- * don't want this.keys.ctrlKey = true also because that implies that this
- * KeySequence involves the ChromeVox modifier and the ctrl key being held down
- * together, which doesn't make any sense.
- * @private
- */
-cvox.KeySequence.prototype.rationalizeKeys_ = function() {
- if (this.skipStripping) {
- return;
- }
-
- // TODO (rshearer): This is a hack. When the modifier key becomes customizable
- // then we will not have to deal with strings here.
- var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g);
-
- var index = this.keys.keyCode.length - 1;
- // For each modifier that is part of the CVox modifier, remove it from keys.
- if (modifierKeyCombo.indexOf('Ctrl') != -1) {
- this.keys.ctrlKey[index] = false;
- }
- if (modifierKeyCombo.indexOf('Alt') != -1) {
- this.keys.altKey[index] = false;
- }
- if (modifierKeyCombo.indexOf('Shift') != -1) {
- this.keys.shiftKey[index] = false;
- }
- var metaKeyName = this.getMetaKeyName_();
- if (modifierKeyCombo.indexOf(metaKeyName) != -1) {
- if (metaKeyName == 'Search') {
- this.keys.searchKeyHeld[index] = false;
- // TODO(dmazzoni): http://crbug.com/404763 Get rid of the code that
- // tracks the search key and just use meta everywhere.
- this.keys.metaKey[index] = false;
- } else if (metaKeyName == 'Cmd' || metaKeyName == 'Win') {
- this.keys.metaKey[index] = false;
- }
- }
-};
-
-
-/**
- * Get the user-facing name for the meta key (keyCode = 91), which varies
- * depending on the platform.
- * @return {string} The user-facing string name for the meta key.
- * @private
- */
-cvox.KeySequence.prototype.getMetaKeyName_ = function() {
- if (cvox.ChromeVox.isChromeOS) {
- return 'Search';
- } else if (cvox.ChromeVox.isMac) {
- return 'Cmd';
- } else {
- return 'Win';
- }
-};
-
-
-/**
- * Utility method that checks for equality of the modifiers (like shift and alt)
- * and the equality of key codes.
- * @param {!cvox.KeySequence} rhs The key sequence to compare against.
- * @return {boolean} True if the modifiers and key codes in the key sequence are
- * the same.
- * @private
- */
-cvox.KeySequence.prototype.checkKeyEquality_ = function(rhs) {
- for (var i in this.keys) {
- for (var j = this.keys[i].length; j--;) {
- if (this.keys[i][j] !== rhs.keys[i][j])
- return false;
- }
- }
- return true;
-};
-
-
-/**
- * Gets first key code
- * @return {number} The first key code.
- */
-cvox.KeySequence.prototype.getFirstKeyCode = function() {
- return this.keys.keyCode[0];
-};
-
-
-/**
- * Gets the number of keys in the sequence. Should be 1 or 2.
- * @return {number} The number of keys in the sequence.
- */
-cvox.KeySequence.prototype.length = function() {
- return this.keys.keyCode.length;
-};
-
-
-
-/**
- * Checks if the specified key code represents a modifier key, i.e. Ctrl, Alt,
- * Shift, Search (on ChromeOS) or Meta.
- *
- * @param {number} keyCode key code.
- * @return {boolean} true if it is a modifier keycode, false otherwise.
- */
-cvox.KeySequence.prototype.isModifierKey = function(keyCode) {
- // Shift, Ctrl, Alt, Search/LWin
- return keyCode == 16 || keyCode == 17 || keyCode == 18 || keyCode == 91 ||
- keyCode == 93;
-};
-
-
-/**
- * Determines whether the Cvox modifier key is active during the keyEvent.
- * @param {Event|Object} keyEvent The keyEvent or event-shaped object to check.
- * @return {boolean} Whether or not the modifier key was active during the
- * keyEvent.
- */
-cvox.KeySequence.prototype.isCVoxModifierActive = function(keyEvent) {
- // TODO (rshearer): Update this when the modifier key becomes customizable
- var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g);
-
- // For each modifier that is held down, remove it from the combo.
- // If the combo string becomes empty, then the user has activated the combo.
- if (this.isKeyModifierActive(keyEvent, 'ctrlKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Ctrl';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'altKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Alt';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'shiftKey')) {
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != 'Shift';
- });
- }
- if (this.isKeyModifierActive(keyEvent, 'metaKey') ||
- this.isKeyModifierActive(keyEvent, 'searchKeyHeld')) {
- var metaKeyName = this.getMetaKeyName_();
- modifierKeyCombo = modifierKeyCombo.filter(function(modifier) {
- return modifier != metaKeyName;
- });
- }
- return (modifierKeyCombo.length == 0);
-};
-
-
-/**
- * Determines whether a particular key modifier (for example, ctrl or alt) is
- * active during the keyEvent.
- * @param {Event|Object} keyEvent The keyEvent or Event-shaped object to check.
- * @param {string} modifier The modifier to check.
- * @return {boolean} Whether or not the modifier key was active during the
- * keyEvent.
- */
-cvox.KeySequence.prototype.isKeyModifierActive = function(keyEvent, modifier) {
- // We need to check the key event modifier and the keyCode because Linux will
- // not set the keyEvent.modKey property if it is the modKey by itself.
- // This bug filed as crbug.com/74044
- switch (modifier) {
- case 'ctrlKey':
- return (keyEvent.ctrlKey || keyEvent.keyCode == 17);
- break;
- case 'altKey':
- return (keyEvent.altKey || (keyEvent.keyCode == 18));
- break;
- case 'shiftKey':
- return (keyEvent.shiftKey || (keyEvent.keyCode == 16));
- break;
- case 'metaKey':
- return (keyEvent.metaKey || (keyEvent.keyCode == 91));
- break;
- case 'searchKeyHeld':
- return ((cvox.ChromeVox.isChromeOS && keyEvent.keyCode == 91) ||
- keyEvent['searchKeyHeld']);
- break;
- }
- return false;
-};
-
-/**
- * Returns if any modifier is active in this sequence.
- * @return {boolean} The result.
- */
-cvox.KeySequence.prototype.isAnyModifierActive = function() {
- for (var modifierType in this.keys) {
- for (var i = 0; i < this.length(); i++) {
- if (this.keys[modifierType][i] && modifierType != 'keyCode') {
- return true;
- }
- }
- }
- return false;
-};
-
-
-/**
- * Creates a KeySequence event from a generic object.
- * @param {Object} sequenceObject The object.
- * @return {cvox.KeySequence} The created KeySequence object.
- */
-cvox.KeySequence.deserialize = function(sequenceObject) {
- var firstSequenceEvent = {};
-
- firstSequenceEvent['stickyMode'] = (sequenceObject.stickyMode == undefined) ?
- false : sequenceObject.stickyMode;
- firstSequenceEvent['prefixKey'] = (sequenceObject.prefixKey == undefined) ?
- false : sequenceObject.prefixKey;
-
-
- var secondKeyPressed = sequenceObject.keys.keyCode.length > 1;
- var secondSequenceEvent = {};
-
- for (var keyPressed in sequenceObject.keys) {
- firstSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][0];
- if (secondKeyPressed) {
- secondSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][1];
- }
- }
-
- var keySeq = new cvox.KeySequence(firstSequenceEvent,
- sequenceObject.cvoxModifier, true, sequenceObject.doubleTap);
- if (secondKeyPressed) {
- cvox.ChromeVox.sequenceSwitchKeyCodes.push(
- new cvox.KeySequence(firstSequenceEvent, sequenceObject.cvoxModifier));
- keySeq.addKeyEvent(secondSequenceEvent);
- }
-
- if (sequenceObject.doubleTap) {
- cvox.KeySequence.doubleTapCache.push(keySeq);
- }
-
- return keySeq;
-};
-
-
-/**
- * Creates a KeySequence event from a given string. The string should be in the
- * standard key sequence format described in keyUtil.keySequenceToString and
- * used in the key map JSON files.
- * @param {string} keyStr The string representation of a key sequence.
- * @return {!cvox.KeySequence} The created KeySequence object.
- */
-cvox.KeySequence.fromStr = function(keyStr) {
- var sequenceEvent = {};
- var secondSequenceEvent = {};
-
- var secondKeyPressed;
- if (keyStr.indexOf('>') == -1) {
- secondKeyPressed = false;
- } else {
- secondKeyPressed = true;
- }
-
- var cvoxPressed = false;
- sequenceEvent['stickyMode'] = false;
- sequenceEvent['prefixKey'] = false;
-
- var tokens = keyStr.split('+');
- for (var i = 0; i < tokens.length; i++) {
- var seqs = tokens[i].split('>');
- for (var j = 0; j < seqs.length; j++) {
- if (seqs[j].charAt(0) == '#') {
- var keyCode = parseInt(seqs[j].substr(1), 10);
- if (j > 0) {
- secondSequenceEvent['keyCode'] = keyCode;
- } else {
- sequenceEvent['keyCode'] = keyCode;
- }
- }
- var keyName = seqs[j];
- if (seqs[j].length == 1) {
- // Key is A/B/C...1/2/3 and we don't need to worry about setting
- // modifiers.
- if (j > 0) {
- secondSequenceEvent['keyCode'] = seqs[j].charCodeAt(0);
- } else {
- sequenceEvent['keyCode'] = seqs[j].charCodeAt(0);
- }
- } else {
- // Key is a modifier key
- if (j > 0) {
- cvox.KeySequence.setModifiersOnEvent_(keyName, secondSequenceEvent);
- if (keyName == 'Cvox') {
- cvoxPressed = true;
- }
- } else {
- cvox.KeySequence.setModifiersOnEvent_(keyName, sequenceEvent);
- if (keyName == 'Cvox') {
- cvoxPressed = true;
- }
- }
- }
- }
- }
- var keySeq = new cvox.KeySequence(sequenceEvent, cvoxPressed);
- if (secondKeyPressed) {
- keySeq.addKeyEvent(secondSequenceEvent);
- }
- return keySeq;
-};
-
-
-/**
- * Utility method for populating the modifiers on an event object that will be
- * used to create a KeySequence.
- * @param {string} keyName A particular modifier key name (such as 'Ctrl').
- * @param {Object} seqEvent The event to populate.
- * @private
- */
-cvox.KeySequence.setModifiersOnEvent_ = function(keyName, seqEvent) {
- if (keyName == 'Ctrl') {
- seqEvent['ctrlKey'] = true;
- seqEvent['keyCode'] = 17;
- } else if (keyName == 'Alt') {
- seqEvent['altKey'] = true;
- seqEvent['keyCode'] = 18;
- } else if (keyName == 'Shift') {
- seqEvent['shiftKey'] = true;
- seqEvent['keyCode'] = 16;
- } else if (keyName == 'Search') {
- seqEvent['searchKeyHeld'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Cmd') {
- seqEvent['metaKey'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Win') {
- seqEvent['metaKey'] = true;
- seqEvent['keyCode'] = 91;
- } else if (keyName == 'Insert') {
- seqEvent['keyCode'] = 45;
- }
-};
-
-
-/**
- * Used to resolve special ChromeOS keys (see link for more detail).
- * http://crbug.com/162268
- * @param {Object} originalEvent The event.
- * @return {Object} The resolved event.
- * @private
- */
-cvox.KeySequence.prototype.resolveChromeOSSpecialKeys_ =
- function(originalEvent) {
- if (!this.cvoxModifier || this.stickyMode || this.prefixKey ||
- !cvox.ChromeVox.isChromeOS) {
- return originalEvent;
- }
- var evt = {};
- for (var key in originalEvent) {
- evt[key] = originalEvent[key];
- }
- switch (evt['keyCode']) {
- case 33: // Page up.
- evt['keyCode'] = 38; // Up arrow.
- break;
- case 34: // Page down.
- evt['keyCode'] = 40; // Down arrow.
- break;
- case 35: // End.
- evt['keyCode'] = 39; // Right arrow.
- break;
- case 36: // Home.
- evt['keyCode'] = 37; // Left arrow.
- break;
- case 45: // Insert.
- evt['keyCode'] = 190; // Period.
- break;
- case 46: // Delete.
- evt['keyCode'] = 8; // Backspace.
- break;
- case 112: // F1.
- evt['keyCode'] = 49; // 1.
- break;
- case 113: // F2.
- evt['keyCode'] = 50; // 2.
- break;
- case 114: // F3.
- evt['keyCode'] = 51; // 3.
- break;
- case 115: // F4.
- evt['keyCode'] = 52; // 4.
- break;
- case 116: // F5.
- evt['keyCode'] = 53; // 5.
- break;
- case 117: // F6.
- evt['keyCode'] = 54; // 6.
- break;
- case 118: // F7.
- evt['keyCode'] = 55; // 7.
- break;
- case 119: // F8.
- evt['keyCode'] = 56; // 8.
- break;
- case 120: // F9.
- evt['keyCode'] = 57; // 9.
- break;
- case 121: // F10.
- evt['keyCode'] = 48; // 0.
- break;
- case 122: // F11
- evt['keyCode'] = 189; // Hyphen.
- break;
- case 123: // F12
- evt['keyCode'] = 187; // Equals.
- break;
- }
- return evt;
-};