Revert 268405 "Make sure that ScratchBuffer::Allocate() always r..."
[chromium-blink-merge.git] / ui / keyboard / resources / elements / kb-shift-key.js
blob4ebb633304d88f703a2aad690ac8835eaf0d2a5e
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.
5 (function () {
7 /**
8 * The possible states of the shift key.
9 * Unlocked is the default state. Locked for capslocked, pressed is a
10 * key-down and tapped for a key-down followed by an immediate key-up.
11 * @const
12 * @type {Enum}
14 var KEY_STATES = {
15 PRESSED: "pressed", // Key-down on shift key.
16 LOCKED: "locked", // Key is capslocked.
17 UNLOCKED: "unlocked", // Default state.
18 TAPPED: "tapped", // Key-down followed by key-up.
19 CHORDING: "chording" // Key-down followed by other keys.
22 /**
23 * The pointerdown event on shiftkey that may eventually trigger chording
24 * state. pointerId and eventTarget are the two fields that is used now.
25 * @type {PointerEvent}
27 var enterChordingEvent = undefined;
29 /**
30 * Uses a closure to define one long press timer among all shift keys
31 * regardless of the layout they are in.
32 * @type {function}
34 var shiftLongPressTimer = undefined;
36 /**
37 * The current state of the shift key.
38 * @type {Enum}
40 var state = KEY_STATES.UNLOCKED;
42 Polymer('kb-shift-key', {
43 /**
44 * Defines how capslock effects keyset transition. We always transition
45 * from the lowerCaseKeysetId to the upperCaseKeysetId if capslock is
46 * on.
47 * @type {string}
49 lowerCaseKeysetId: 'lower',
50 upperCaseKeysetId: 'upper',
52 up: function(event) {
53 if (state == KEY_STATES.CHORDING &&
54 event.pointerId != enterChordingEvent.pointerId) {
55 // Disables all other pointer events on shift keys when chording.
56 return;
58 switch (state) {
59 case KEY_STATES.PRESSED:
60 state = KEY_STATES.TAPPED;
61 break;
62 case KEY_STATES.CHORDING:
63 // Leaves chording only if the pointer that triggered it is
64 // released.
65 state = KEY_STATES.UNLOCKED;
66 break;
67 default:
68 break;
70 // When releasing the shift key, it is not the same shift key that was
71 // pressed. Updates the pointerId of the releasing shift key to make
72 // sure key-up event fires correctly in kb-key-base.
73 this.pointerId = enterChordingEvent.pointerId;
74 this.super([event]);
77 out: function(event) {
78 // Sliding off the shift key while chording is treated as a key-up.
79 // Note that we switch to a new keyset on shift keydown, and a finger
80 // movement on the new shift key will trigger this function being
81 // called on the old shift key. We should not end chording in that
82 // case.
83 if (state == KEY_STATES.CHORDING &&
84 event.pointerId == enterChordingEvent.pointerId &&
85 event.target != enterChordingEvent.target) {
86 state = KEY_STATES.UNLOCKED;
87 var detail = this.populateDetails('out');
88 this.fire("key-out", detail);
92 down: function(event) {
93 // First transition state so that populateDetails generates
94 // correct data.
95 switch (state) {
96 case KEY_STATES.UNLOCKED:
97 state = KEY_STATES.PRESSED;
98 break;
99 case KEY_STATES.TAPPED:
100 case KEY_STATES.LOCKED:
101 state = KEY_STATES.UNLOCKED;
102 break;
103 case KEY_STATES.PRESSED:
104 case KEY_STATES.CHORDING:
105 // We pressed another shift key at the same time,
106 // so ignore second press.
107 return;
108 default:
109 console.error("Undefined shift key state: " + state);
110 break;
112 enterChordingEvent = event;
113 // Trigger parent behaviour.
114 this.super([event]);
115 this.fire('enable-sel');
116 // Populate double click transition details.
117 var detail = {};
118 detail.char = this.char || this.textContent;
119 detail.toKeyset = this.upperCaseKeysetId;
120 detail.nextKeyset = undefined;
121 detail.callback = this.onDoubleClick;
122 this.fire('enable-dbl', detail);
125 generateLongPressTimer: function() {
126 return this.async(function() {
127 var detail = this.populateDetails();
128 if (state == KEY_STATES.LOCKED) {
129 // We don't care about the longpress if we are already
130 // capitalized.
131 return;
132 } else {
133 state = KEY_STATES.LOCKED;
134 detail.toKeyset = this.upperCaseKeysetId;
135 detail.nextKeyset = undefined;
137 this.fire('key-longpress', detail);
138 }, null, LONGPRESS_DELAY_MSEC);
141 // @return Whether the shift modifier is currently active.
142 isActive: function() {
143 return state != KEY_STATES.UNLOCKED;
147 * Callback function for when a double click is triggered.
149 onDoubleClick: function() {
150 state = KEY_STATES.LOCKED;
154 * Notifies shift key that a non-control key was pressed down.
155 * A control key is defined as one of shift, control or alt.
157 onNonControlKeyDown: function() {
158 switch (state) {
159 case (KEY_STATES.PRESSED):
160 state = KEY_STATES.CHORDING;
161 // Disable longpress timer.
162 clearTimeout(shiftLongPressTimer);
163 break;
164 default:
165 break;
170 * Notifies key that a non-control keyed was typed.
171 * A control key is defined as one of shift, control or alt.
173 onNonControlKeyTyped: function() {
174 if (state == KEY_STATES.TAPPED)
175 state = KEY_STATES.UNLOCKED;
179 * Callback function for when a space is pressed after punctuation.
180 * @return {Object} The keyset transitions the keyboard should make.
182 onSpaceAfterPunctuation: function() {
183 var detail = {};
184 detail.toKeyset = this.upperCaseKeysetId;
185 detail.nextKeyset = this.lowerCaseKeysetId;
186 state = KEY_STATES.TAPPED;
187 return detail;
190 populateDetails: function(caller) {
191 var detail = this.super([caller]);
192 switch(state) {
193 case(KEY_STATES.LOCKED):
194 detail.toKeyset = this.upperCaseKeysetId;
195 break;
196 case(KEY_STATES.UNLOCKED):
197 detail.toKeyset = this.lowerCaseKeysetId;
198 break;
199 case(KEY_STATES.PRESSED):
200 detail.toKeyset = this.upperCaseKeysetId;
201 break;
202 case(KEY_STATES.TAPPED):
203 detail.toKeyset = this.upperCaseKeysetId;
204 detail.nextKeyset = this.lowerCaseKeysetId;
205 break;
206 case(KEY_STATES.CHORDING):
207 detail.toKeyset = this.lowerCaseKeysetId;
208 break;
209 default:
210 break;
212 return detail;
216 * Resets the shift key state.
218 reset: function() {
219 state = KEY_STATES.UNLOCKED;
223 * Overrides longPressTimer for the shift key.
225 get longPressTimer() {
226 return shiftLongPressTimer;
229 set longPressTimer(timer) {
230 shiftLongPressTimer = timer;
233 get state() {
234 return state;
237 get textKeyset() {
238 switch (state) {
239 case KEY_STATES.UNLOCKED:
240 return this.lowerCaseKeysetId;
241 default:
242 return this.upperCaseKeysetId;
246 })();