• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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