| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * @fileoverview A JavaScript class that represents a sequence of keys entered | 6 * @fileoverview A JavaScript class that represents a sequence of keys entered |
| 7 * by the user. | 7 * by the user. |
| 8 */ | 8 */ |
| 9 | 9 |
| 10 | 10 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 * specified. We will also accept an event-shaped object. | 37 * specified. We will also accept an event-shaped object. |
| 38 * @param {boolean=} opt_cvoxModifier Whether or not the ChromeVox modifier key | 38 * @param {boolean=} opt_cvoxModifier Whether or not the ChromeVox modifier key |
| 39 * is active. If not specified, we will try to determine whether the modifier | 39 * is active. If not specified, we will try to determine whether the modifier |
| 40 * was active by looking at the originalEvent. | 40 * was active by looking at the originalEvent. |
| 41 * from key events when the cvox modifiers are set. Defaults to false. | 41 * from key events when the cvox modifiers are set. Defaults to false. |
| 42 * @param {boolean=} opt_doubleTap Whether this is triggered via double tap. | 42 * @param {boolean=} opt_doubleTap Whether this is triggered via double tap. |
| 43 * @param {boolean=} opt_skipStripping Whether to strip cvox modifiers. | 43 * @param {boolean=} opt_skipStripping Whether to strip cvox modifiers. |
| 44 * @param {boolean=} opt_requireStickyMode Whether to require sticky mode. | 44 * @param {boolean=} opt_requireStickyMode Whether to require sticky mode. |
| 45 * @constructor | 45 * @constructor |
| 46 */ | 46 */ |
| 47 cvox.KeySequence = function(originalEvent, opt_cvoxModifier, opt_doubleTap, | 47 cvox.KeySequence = function( |
| 48 opt_skipStripping, opt_requireStickyMode) { | 48 originalEvent, opt_cvoxModifier, opt_doubleTap, opt_skipStripping, |
| 49 opt_requireStickyMode) { |
| 49 /** @type {boolean} */ | 50 /** @type {boolean} */ |
| 50 this.doubleTap = !!opt_doubleTap; | 51 this.doubleTap = !!opt_doubleTap; |
| 51 | 52 |
| 52 /** @type {boolean} */ | 53 /** @type {boolean} */ |
| 53 this.requireStickyMode = !!opt_requireStickyMode; | 54 this.requireStickyMode = !!opt_requireStickyMode; |
| 54 | 55 |
| 55 /** @type {cvox.PlatformFilter} */ | 56 /** @type {cvox.PlatformFilter} */ |
| 56 this.platformFilter; | 57 this.platformFilter; |
| 57 /** @type {boolean} */ | 58 /** @type {boolean} */ |
| 58 this.skipStripping = !!opt_skipStripping; | 59 this.skipStripping = !!opt_skipStripping; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 167 | 168 |
| 168 if (this.doubleTap != rhs.doubleTap) { | 169 if (this.doubleTap != rhs.doubleTap) { |
| 169 return false; | 170 return false; |
| 170 } | 171 } |
| 171 | 172 |
| 172 // So now we know the actual keys are the same. | 173 // So now we know the actual keys are the same. |
| 173 | 174 |
| 174 // If one key sequence requires sticky mode, return early the strict | 175 // If one key sequence requires sticky mode, return early the strict |
| 175 // sticky mode state. | 176 // sticky mode state. |
| 176 if (this.requireStickyMode || rhs.requireStickyMode) { | 177 if (this.requireStickyMode || rhs.requireStickyMode) { |
| 177 return (this.stickyMode || rhs.stickyMode) && | 178 return (this.stickyMode || rhs.stickyMode) && !this.cvoxModifier && |
| 178 !this.cvoxModifier && !rhs.cvoxModifier; | 179 !rhs.cvoxModifier; |
| 179 } | 180 } |
| 180 | 181 |
| 181 // If they both have the ChromeVox modifier, or they both don't have the | 182 // If they both have the ChromeVox modifier, or they both don't have the |
| 182 // ChromeVox modifier, then they are considered equal. | 183 // ChromeVox modifier, then they are considered equal. |
| 183 if (this.cvoxModifier === rhs.cvoxModifier) { | 184 if (this.cvoxModifier === rhs.cvoxModifier) { |
| 184 return true; | 185 return true; |
| 185 } | 186 } |
| 186 | 187 |
| 187 // So only one of them has the ChromeVox modifier. If the one that doesn't | 188 // So only one of them has the ChromeVox modifier. If the one that doesn't |
| 188 // have the ChromeVox modifier has sticky mode or the prefix key then the | 189 // have the ChromeVox modifier has sticky mode or the prefix key then the |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 * keyEvent. | 349 * keyEvent. |
| 349 */ | 350 */ |
| 350 cvox.KeySequence.prototype.isCVoxModifierActive = function(keyEvent) { | 351 cvox.KeySequence.prototype.isCVoxModifierActive = function(keyEvent) { |
| 351 // TODO (rshearer): Update this when the modifier key becomes customizable | 352 // TODO (rshearer): Update this when the modifier key becomes customizable |
| 352 var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g); | 353 var modifierKeyCombo = cvox.ChromeVox.modKeyStr.split(/\+/g); |
| 353 | 354 |
| 354 // For each modifier that is held down, remove it from the combo. | 355 // For each modifier that is held down, remove it from the combo. |
| 355 // If the combo string becomes empty, then the user has activated the combo. | 356 // If the combo string becomes empty, then the user has activated the combo. |
| 356 if (this.isKeyModifierActive(keyEvent, 'ctrlKey')) { | 357 if (this.isKeyModifierActive(keyEvent, 'ctrlKey')) { |
| 357 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { | 358 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { |
| 358 return modifier != 'Ctrl'; | 359 return modifier != 'Ctrl'; |
| 359 }); | 360 }); |
| 360 } | 361 } |
| 361 if (this.isKeyModifierActive(keyEvent, 'altKey')) { | 362 if (this.isKeyModifierActive(keyEvent, 'altKey')) { |
| 362 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { | 363 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { |
| 363 return modifier != 'Alt'; | 364 return modifier != 'Alt'; |
| 364 }); | 365 }); |
| 365 } | 366 } |
| 366 if (this.isKeyModifierActive(keyEvent, 'shiftKey')) { | 367 if (this.isKeyModifierActive(keyEvent, 'shiftKey')) { |
| 367 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { | 368 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { |
| 368 return modifier != 'Shift'; | 369 return modifier != 'Shift'; |
| 369 }); | 370 }); |
| 370 } | 371 } |
| 371 if (this.isKeyModifierActive(keyEvent, 'metaKey') || | 372 if (this.isKeyModifierActive(keyEvent, 'metaKey') || |
| 372 this.isKeyModifierActive(keyEvent, 'searchKeyHeld')) { | 373 this.isKeyModifierActive(keyEvent, 'searchKeyHeld')) { |
| 373 var metaKeyName = this.getMetaKeyName_(); | 374 var metaKeyName = this.getMetaKeyName_(); |
| 374 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { | 375 modifierKeyCombo = modifierKeyCombo.filter(function(modifier) { |
| 375 return modifier != metaKeyName; | 376 return modifier != metaKeyName; |
| 376 }); | 377 }); |
| 377 } | 378 } |
| 378 return (modifierKeyCombo.length == 0); | 379 return (modifierKeyCombo.length == 0); |
| 379 }; | 380 }; |
| 380 | 381 |
| 381 | 382 |
| 382 /** | 383 /** |
| 383 * Determines whether a particular key modifier (for example, ctrl or alt) is | 384 * Determines whether a particular key modifier (for example, ctrl or alt) is |
| 384 * active during the keyEvent. | 385 * active during the keyEvent. |
| 385 * @param {Event|Object} keyEvent The keyEvent or Event-shaped object to check. | 386 * @param {Event|Object} keyEvent The keyEvent or Event-shaped object to check. |
| 386 * @param {string} modifier The modifier to check. | 387 * @param {string} modifier The modifier to check. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 398 case 'altKey': | 399 case 'altKey': |
| 399 return (keyEvent.altKey || (keyEvent.keyCode == 18)); | 400 return (keyEvent.altKey || (keyEvent.keyCode == 18)); |
| 400 break; | 401 break; |
| 401 case 'shiftKey': | 402 case 'shiftKey': |
| 402 return (keyEvent.shiftKey || (keyEvent.keyCode == 16)); | 403 return (keyEvent.shiftKey || (keyEvent.keyCode == 16)); |
| 403 break; | 404 break; |
| 404 case 'metaKey': | 405 case 'metaKey': |
| 405 return (keyEvent.metaKey || (keyEvent.keyCode == 91)); | 406 return (keyEvent.metaKey || (keyEvent.keyCode == 91)); |
| 406 break; | 407 break; |
| 407 case 'searchKeyHeld': | 408 case 'searchKeyHeld': |
| 408 return ((cvox.ChromeVox.isChromeOS && keyEvent.keyCode == 91) || | 409 return ( |
| 410 (cvox.ChromeVox.isChromeOS && keyEvent.keyCode == 91) || |
| 409 keyEvent['searchKeyHeld']); | 411 keyEvent['searchKeyHeld']); |
| 410 break; | 412 break; |
| 411 } | 413 } |
| 412 return false; | 414 return false; |
| 413 }; | 415 }; |
| 414 | 416 |
| 415 /** | 417 /** |
| 416 * Returns if any modifier is active in this sequence. | 418 * Returns if any modifier is active in this sequence. |
| 417 * @return {boolean} The result. | 419 * @return {boolean} The result. |
| 418 */ | 420 */ |
| (...skipping 11 matching lines...) Expand all Loading... |
| 430 | 432 |
| 431 /** | 433 /** |
| 432 * Creates a KeySequence event from a generic object. | 434 * Creates a KeySequence event from a generic object. |
| 433 * @param {Object} sequenceObject The object. | 435 * @param {Object} sequenceObject The object. |
| 434 * @return {cvox.KeySequence} The created KeySequence object. | 436 * @return {cvox.KeySequence} The created KeySequence object. |
| 435 */ | 437 */ |
| 436 cvox.KeySequence.deserialize = function(sequenceObject) { | 438 cvox.KeySequence.deserialize = function(sequenceObject) { |
| 437 var firstSequenceEvent = {}; | 439 var firstSequenceEvent = {}; |
| 438 | 440 |
| 439 firstSequenceEvent['stickyMode'] = (sequenceObject.stickyMode == undefined) ? | 441 firstSequenceEvent['stickyMode'] = (sequenceObject.stickyMode == undefined) ? |
| 440 false : sequenceObject.stickyMode; | 442 false : |
| 443 sequenceObject.stickyMode; |
| 441 firstSequenceEvent['prefixKey'] = (sequenceObject.prefixKey == undefined) ? | 444 firstSequenceEvent['prefixKey'] = (sequenceObject.prefixKey == undefined) ? |
| 442 false : sequenceObject.prefixKey; | 445 false : |
| 446 sequenceObject.prefixKey; |
| 443 | 447 |
| 444 var secondKeyPressed = sequenceObject.keys.keyCode.length > 1; | 448 var secondKeyPressed = sequenceObject.keys.keyCode.length > 1; |
| 445 var secondSequenceEvent = {}; | 449 var secondSequenceEvent = {}; |
| 446 | 450 |
| 447 for (var keyPressed in sequenceObject.keys) { | 451 for (var keyPressed in sequenceObject.keys) { |
| 448 firstSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][0]; | 452 firstSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][0]; |
| 449 if (secondKeyPressed) { | 453 if (secondKeyPressed) { |
| 450 secondSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][1]; | 454 secondSequenceEvent[keyPressed] = sequenceObject.keys[keyPressed][1]; |
| 451 } | 455 } |
| 452 } | 456 } |
| 453 var skipStripping = sequenceObject.skipStripping !== undefined ? | 457 var skipStripping = sequenceObject.skipStripping !== undefined ? |
| 454 sequenceObject.skipStripping : true; | 458 sequenceObject.skipStripping : |
| 455 var keySeq = new cvox.KeySequence(firstSequenceEvent, | 459 true; |
| 456 sequenceObject.cvoxModifier, | 460 var keySeq = new cvox.KeySequence( |
| 457 sequenceObject.doubleTap, | 461 firstSequenceEvent, sequenceObject.cvoxModifier, sequenceObject.doubleTap, |
| 458 skipStripping, | 462 skipStripping, sequenceObject.requireStickyMode); |
| 459 sequenceObject.requireStickyMode); | |
| 460 if (secondKeyPressed) { | 463 if (secondKeyPressed) { |
| 461 cvox.ChromeVox.sequenceSwitchKeyCodes.push( | 464 cvox.ChromeVox.sequenceSwitchKeyCodes.push( |
| 462 new cvox.KeySequence(firstSequenceEvent, sequenceObject.cvoxModifier)); | 465 new cvox.KeySequence(firstSequenceEvent, sequenceObject.cvoxModifier)); |
| 463 keySeq.addKeyEvent(secondSequenceEvent); | 466 keySeq.addKeyEvent(secondSequenceEvent); |
| 464 } | 467 } |
| 465 | 468 |
| 466 if (sequenceObject.doubleTap) { | 469 if (sequenceObject.doubleTap) { |
| 467 cvox.KeySequence.doubleTapCache.push(keySeq); | 470 cvox.KeySequence.doubleTapCache.push(keySeq); |
| 468 } | 471 } |
| 469 | 472 |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 } else if (keyName == 'Cmd') { | 564 } else if (keyName == 'Cmd') { |
| 562 seqEvent['metaKey'] = true; | 565 seqEvent['metaKey'] = true; |
| 563 seqEvent['keyCode'] = 91; | 566 seqEvent['keyCode'] = 91; |
| 564 } else if (keyName == 'Win') { | 567 } else if (keyName == 'Win') { |
| 565 seqEvent['metaKey'] = true; | 568 seqEvent['metaKey'] = true; |
| 566 seqEvent['keyCode'] = 91; | 569 seqEvent['keyCode'] = 91; |
| 567 } else if (keyName == 'Insert') { | 570 } else if (keyName == 'Insert') { |
| 568 seqEvent['keyCode'] = 45; | 571 seqEvent['keyCode'] = 45; |
| 569 } | 572 } |
| 570 }; | 573 }; |
| OLD | NEW |