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