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 5 (function () { 6 7 /** 8 * The possible states of the key. 9 * @const 10 * @type {Enum} 11 */ 12 var KEY_STATES = { 13 PRESSED: "pressed", // Key-down. 14 UNLOCKED: "unlocked", // Default state. 15 TAPPED: "tapped", // Key-down followed by key-up. 16 CHORDING: "chording", // Chording mode. 17 }; 18 19 /** 20 * A map of the state of all modifier keys. 21 * @type {Object} 22 */ 23 var states = {}; 24 25 Polymer('kb-modifier-key', { 26 up: function(event) { 27 if (this.state == KEY_STATES.PRESSED) 28 this.state = KEY_STATES.TAPPED; 29 else 30 this.state = KEY_STATES.UNLOCKED; 31 this.super([event]); 32 }, 33 34 down: function(event) { 35 // First transition state so that populateDetails generates 36 // correct data. 37 switch (this.state) { 38 case KEY_STATES.UNLOCKED: 39 this.state = KEY_STATES.PRESSED; 40 break; 41 case KEY_STATES.TAPPED: 42 this.state = KEY_STATES.UNLOCKED; 43 break; 44 case KEY_STATES.PRESSED: 45 case KEY_STATES.CHORDING: 46 // We pressed another key at the same time, 47 // so ignore second press. 48 return; 49 default: 50 console.error("Undefined key state: " + state); 51 break; 52 } 53 this.super([event]); 54 }, 55 56 /** 57 * Returns whether the modifier for this key is active. 58 * @return {boolean} 59 */ 60 isActive: function() { 61 return this.state != KEY_STATES.UNLOCKED; 62 }, 63 64 /** 65 * Notifies key that a non-control keyed down. 66 * A control key is defined as one of shift, control or alt. 67 */ 68 onNonControlKeyDown: function() { 69 switch(this.state) { 70 case (KEY_STATES.PRESSED): 71 this.state = KEY_STATES.CHORDING; 72 break; 73 } 74 }, 75 76 /** 77 * Notifies key that a non-control keyed was typed. 78 * A control key is defined as one of shift, control or alt. 79 */ 80 onNonControlKeyTyped: function() { 81 switch(this.state) { 82 case (KEY_STATES.TAPPED): 83 this.state = KEY_STATES.UNLOCKED; 84 break; 85 } 86 }, 87 88 /** 89 * Called on a pointer-out event. Ends chording. 90 * @param {event} event The pointer-out event. 91 */ 92 out: function(event) { 93 // TODO(rsadam): Add chording event so that we don't reset 94 // when shift-chording. 95 if (this.state == KEY_STATES.CHORDING) { 96 this.state = KEY_STATES.UNLOCKED; 97 } 98 }, 99 100 /* 101 * Overrides the autoRelease function to enable chording. 102 */ 103 autoRelease: function() { 104 }, 105 106 populateDetails: function(caller) { 107 var detail = this.super([caller]); 108 if (this.state != KEY_STATES.UNLOCKED) 109 detail.activeModifier = this.charValue; 110 return detail; 111 }, 112 113 /** 114 * Resets the modifier key state. 115 */ 116 reset: function() { 117 this.state = KEY_STATES.UNLOCKED; 118 }, 119 120 get state() { 121 var key = this.charValue; 122 if (!key) 123 console.error("missing key for kb-modifier-key state: " + this); 124 // All keys default to the unlock state. 125 if (!(key in states)) 126 states[key] = KEY_STATES.UNLOCKED; 127 return states[key]; 128 }, 129 130 set state(value) { 131 var key = this.charValue; 132 states[key] = value; 133 } 134 }); 135 })(); 136