// 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. (function () { /** * The possible states of the key. * @const * @type {Enum} */ var KEY_STATES = { PRESSED: "pressed", // Key-down. UNLOCKED: "unlocked", // Default state. TAPPED: "tapped", // Key-down followed by key-up. CHORDING: "chording", // Chording mode. }; /** * A map of the state of all modifier keys. * @type {Object} */ var states = {}; Polymer('kb-modifier-key', { up: function(event) { if (this.state == KEY_STATES.PRESSED) this.state = KEY_STATES.TAPPED; else this.state = KEY_STATES.UNLOCKED; this.super([event]); }, down: function(event) { // First transition state so that populateDetails generates // correct data. switch (this.state) { case KEY_STATES.UNLOCKED: this.state = KEY_STATES.PRESSED; break; case KEY_STATES.TAPPED: this.state = KEY_STATES.UNLOCKED; break; case KEY_STATES.PRESSED: case KEY_STATES.CHORDING: // We pressed another key at the same time, // so ignore second press. return; default: console.error("Undefined key state: " + state); break; } this.super([event]); }, /** * Returns whether the modifier for this key is active. * @return {boolean} */ isActive: function() { return this.state != KEY_STATES.UNLOCKED; }, /** * Notifies key that a non-control keyed down. * A control key is defined as one of shift, control or alt. */ onNonControlKeyDown: function() { switch(this.state) { case (KEY_STATES.PRESSED): this.state = KEY_STATES.CHORDING; break; } }, /** * Notifies key that a non-control keyed was typed. * A control key is defined as one of shift, control or alt. */ onNonControlKeyTyped: function() { switch(this.state) { case (KEY_STATES.TAPPED): this.state = KEY_STATES.UNLOCKED; break; } }, /** * Called on a pointer-out event. Ends chording. * @param {event} event The pointer-out event. */ out: function(event) { // TODO(rsadam): Add chording event so that we don't reset // when shift-chording. if (this.state == KEY_STATES.CHORDING) { this.state = KEY_STATES.UNLOCKED; } }, /* * Overrides the autoRelease function to enable chording. */ autoRelease: function() { }, populateDetails: function(caller) { var detail = this.super([caller]); if (this.state != KEY_STATES.UNLOCKED) detail.activeModifier = this.charValue; return detail; }, /** * Resets the modifier key state. */ reset: function() { this.state = KEY_STATES.UNLOCKED; }, get state() { var key = this.charValue; if (!key) console.error("missing key for kb-modifier-key state: " + this); // All keys default to the unlock state. if (!(key in states)) states[key] = KEY_STATES.UNLOCKED; return states[key]; }, set state(value) { var key = this.charValue; states[key] = value; } }); })();