Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.js

Issue 2874303003: Fork PIN keyboard assets and create additional flag for lock screen (Closed)
Patch Set: Address comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 /**
6 * @fileoverview
7 * 'pin-keyboard' is a keyboard that can be used to enter PINs or more generally
8 * numeric values.
9 *
10 * Properties:
11 * value: The value of the PIN keyboard. Writing to this property will adjust
12 * the PIN keyboard's value.
13 *
14 * Events:
15 * pin-change: Fired when the PIN value has changed. The PIN is available at
16 * event.detail.pin.
17 * submit: Fired when the PIN is submitted. The PIN is available at
18 * event.detail.pin.
19 *
20 * Example:
21 * <pin-keyboard on-pin-change="onPinChange" on-submit="onPinSubmit">
22 * </pin-keyboard>
23 */
24
25 (function() {
26
27 /**
28 * Once auto backspace starts, the time between individual backspaces.
29 * @type {number}
30 * @const
31 */
32 var REPEAT_BACKSPACE_DELAY_MS = 150;
33
34 /**
35 * How long the backspace button must be held down before auto backspace
36 * starts.
37 * @type {number}
38 * @const
39 */
40 var INITIAL_BACKSPACE_DELAY_MS = 500;
41
42 /**
43 * The key codes of the keys allowed to be used on the pin input, in addition to
44 * number keys. Currently we allow backspace(8), tab(9), left(37) and right(39).
45 * @type {Array<number>}
46 * @const
47 */
48 var PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES = [8, 9, 37, 39];
49
50 Polymer({
51 is: 'pin-keyboard',
52
53 behaviors: [
54 I18nBehavior,
55 ],
56
57 properties: {
58 /**
59 * Whether or not the keyboard's input element should be numerical
60 * or password.
61 * @private
62 */
63 enablePassword: {
64 type: Boolean,
65 value: false,
66 },
67
68 /**
69 * The password element the pin keyboard is associated with. If this is not
70 * set, then a default input element is shown and used.
71 * @type {?Element}
72 * @private
73 */
74 passwordElement: {
75 type: Object,
76 value: function() {
77 return this.$.pinInput.inputElement;
78 },
79 observer: 'onPasswordElementAttached_',
80 },
81
82 /**
83 * The intervalID used for the backspace button set/clear interval.
84 * @private
85 */
86 repeatBackspaceIntervalId_: {
87 type: Number,
88 value: 0,
89 },
90
91 /**
92 * The timeoutID used for the auto backspace.
93 * @private
94 */
95 startAutoBackspaceId_: {
96 type: Number,
97 value: 0,
98 },
99
100 /**
101 * Whether or not to show the default pin input.
102 * @private
103 */
104 showPinInput_: {
105 type: Boolean,
106 value: false,
107 },
108
109 /**
110 * The value stored in the keyboard's input element.
111 * @private
112 */
113 value: {
114 type: String,
115 notify: true,
116 value: '',
117 observer: 'onPinValueChange_',
118 },
119 },
120
121 /**
122 * Called when a password element is attached to the pin keyboard.
123 * @param {HTMLInputElement} inputElement The PIN keyboard's input element.
124 * @private
125 */
126 onPasswordElementAttached_: function(inputElement) {
127 this.showPinInput_ = inputElement == this.$.pinInput.inputElement;
128 inputElement.addEventListener('input',
129 this.handleInputChanged_.bind(this));
130 },
131
132 /**
133 * Called when the user uses the keyboard to enter a value into the input
134 * element.
135 * @param {Event} event The event object.
136 * @private
137 */
138 handleInputChanged_: function(event) {
139 this.value = event.target.value;
140 },
141
142 /**
143 * Gets the selection start of the input field.
144 * @type {number}
145 * @private
146 */
147 get selectionStart_() {
148 return this.passwordElement.selectionStart;
149 },
150
151 /**
152 * Gets the selection end of the input field.
153 * @type {number}
154 * @private
155 */
156 get selectionEnd_() {
157 return this.passwordElement.selectionEnd;
158 },
159
160 /**
161 * Sets the selection start of the input field.
162 * @param {number} start The new selection start of the input element.
163 * @private
164 */
165 set selectionStart_(start) {
166 this.passwordElement.selectionStart = start;
167 },
168
169 /**
170 * Sets the selection end of the input field.
171 * @param {number} end The new selection end of the input element.
172 * @private
173 */
174 set selectionEnd_(end) {
175 this.passwordElement.selectionEnd = end;
176 },
177
178 /** Transfers focus to the input element. */
179 focus: function() {
180 this.passwordElement.focus();
181 },
182
183 /**
184 * Called when a keypad number has been tapped.
185 * @param {Event} event The event object.
186 * @private
187 */
188 onNumberTap_: function(event) {
189 var numberValue = event.target.getAttribute('value');
190
191 // Add the number where the caret is, then update the selection range of the
192 // input element.
193 var selectionStart = this.selectionStart_;
194 this.value = this.value.substring(0, this.selectionStart_) + numberValue +
195 this.value.substring(this.selectionEnd_);
196 this.selectionStart_ = selectionStart + 1;
197 this.selectionEnd_ = this.selectionStart_;
198
199 // If a number button is clicked, we do not want to switch focus to the
200 // button, therefore we transfer focus back to the input, but if a number
201 // button is tabbed into, it should keep focus, so users can use tab and
202 // spacebar/return to enter their PIN.
203 if (!event.target.receivedFocusFromKeyboard)
204 this.focus();
205 event.preventDefault();
206 },
207
208 /** Fires a submit event with the current PIN value. */
209 firePinSubmitEvent_: function() {
210 this.fire('submit', { pin: this.value });
211 },
212
213 /**
214 * Fires an update event with the current PIN value. The event will only be
215 * fired if the PIN value has actually changed.
216 * @param {string} value
217 * @param {string} previous
218 */
219 onPinValueChange_: function(value, previous) {
220 if (value != previous) {
221 this.passwordElement.value = this.value;
222 this.fire('pin-change', { pin: value });
223 }
224 },
225
226 /**
227 * Called when the user wants to erase the last character of the entered
228 * PIN value.
229 * @private
230 */
231 onPinClear_: function() {
232 // If the input is shown, clear the text based on the caret location or
233 // selected region of the input element. If it is just a caret, remove the
234 // character in front of the caret.
235 var selectionStart = this.selectionStart_;
236 var selectionEnd = this.selectionEnd_;
237 if (selectionStart == selectionEnd)
238 selectionStart--;
239
240 this.value = this.value.substring(0, selectionStart) +
241 this.value.substring(selectionEnd);
242
243 // Move the caret or selected region to the correct new place.
244 this.selectionStart_ = selectionStart;
245 this.selectionEnd_ = selectionStart;
246 },
247
248 /**
249 * Called when the user presses or touches the backspace button. Starts a
250 * timer which starts an interval to repeatedly backspace the pin value until
251 * the interval is cleared.
252 * @param {Event} event The event object.
253 * @private
254 */
255 onBackspacePointerDown_: function(event) {
256 this.startAutoBackspaceId_ = setTimeout(function() {
257 this.repeatBackspaceIntervalId_ = setInterval(
258 this.onPinClear_.bind(this), REPEAT_BACKSPACE_DELAY_MS);
259 }.bind(this), INITIAL_BACKSPACE_DELAY_MS);
260
261 if (!event.target.receivedFocusFromKeyboard)
262 this.focus();
263 event.preventDefault();
264 },
265
266 /**
267 * Helper function which clears the timer / interval ids and resets them.
268 * @private
269 */
270 clearAndReset_: function() {
271 clearInterval(this.repeatBackspaceIntervalId_);
272 this.repeatBackspaceIntervalId_ = 0;
273 clearTimeout(this.startAutoBackspaceId_);
274 this.startAutoBackspaceId_ = 0;
275 },
276
277 /**
278 * Called when the user exits the backspace button. Stops the interval
279 * callback.
280 * @param {Event} event The event object.
281 * @private
282 */
283 onBackspacePointerOut_: function(event) {
284 this.clearAndReset_();
285
286 if (!event.target.receivedFocusFromKeyboard)
287 this.focus();
288 event.preventDefault();
289 },
290
291 /**
292 * Called when the user unpresses or untouches the backspace button. Stops the
293 * interval callback and fires a backspace event if there is no interval
294 * running.
295 * @param {Event} event The event object.
296 * @private
297 */
298 onBackspacePointerUp_: function(event) {
299 // If an interval has started, do not fire event on pointer up.
300 if (!this.repeatBackspaceIntervalId_)
301 this.onPinClear_();
302 this.clearAndReset_();
303
304 if (!event.target.receivedFocusFromKeyboard)
305 this.focus();
306 event.preventDefault();
307 },
308
309 /**
310 * Helper function to check whether a given |event| should be processed by
311 * the numeric only input.
312 * @param {Event} event The event object.
313 * @private
314 */
315 isValidEventForInput_: function(event) {
316 // Valid if the key is a number, and shift is not pressed.
317 if ((event.keyCode >= 48 && event.keyCode <= 57) && !event.shiftKey)
318 return true;
319
320 // Valid if the key is one of the selected special keys defined in
321 // |PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES|.
322 if (PIN_INPUT_ALLOWED_NON_NUMBER_KEY_CODES.indexOf(event.keyCode) > -1)
323 return true;
324
325 // Valid if the key is CTRL+A to allow users to quickly select the entire
326 // PIN.
327 if (event.keyCode == 65 && event.ctrlKey)
328 return true;
329
330 // The rest of the keys are invalid.
331 return false;
332 },
333
334 /**
335 * Called when a key event is pressed while the input element has focus.
336 * @param {Event} event The event object.
337 * @private
338 */
339 onInputKeyDown_: function(event) {
340 // Up/down pressed, swallow the event to prevent the input value from
341 // being incremented or decremented.
342 if (event.keyCode == 38 || event.keyCode == 40) {
343 event.preventDefault();
344 return;
345 }
346
347 // Enter pressed.
348 if (event.keyCode == 13) {
349 this.firePinSubmitEvent_();
350 event.preventDefault();
351 return;
352 }
353
354 // Do not pass events that are not numbers or special keys we care about. We
355 // use this instead of input type number because there are several issues
356 // with input type number, such as no selectionStart/selectionEnd and
357 // entered non numbers causes the caret to jump to the left.
358 if (!this.isValidEventForInput_(event)) {
359 event.preventDefault();
360 return;
361 }
362 },
363
364 /**
365 * Disables the backspace button if nothing is entered.
366 * @param {string} value
367 * @private
368 */
369 hasInput_: function(value) {
370 return value.length > 0;
371 },
372
373 /**
374 * Computes the value of the pin input placeholder.
375 * @param {boolean} enablePassword
376 * @private
377 */
378 getInputPlaceholder_: function(enablePassword) {
379 return enablePassword ? this.i18n('pinKeyboardPlaceholderPinPassword') :
380 this.i18n('pinKeyboardPlaceholderPin');
381 },
382
383 /**
384 * Computes the direction of the pin input.
385 * @param {string} password
386 * @private
387 */
388 isInputRtl_: function(password) {
389 // +password will convert a string to a number or to NaN if that's not
390 // possible. Number.isInteger will verify the value is not a NaN and that it
391 // does not contain decimals.
392 // This heuristic will fail for inputs like '1.0'.
393 //
394 // Since we still support users entering their passwords through the PIN
395 // keyboard, we swap the input box to rtl when we think it is a password
396 // (just numbers), if the document direction is rtl.
397 return (document.dir == 'rtl') && !Number.isInteger(+password);
398 },
399 });
400 })();
OLDNEW
« no previous file with comments | « chrome/browser/resources/chromeos/quick_unlock/md_pin_keyboard.html ('k') | chrome/browser/ui/webui/chromeos/login/oobe_ui.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698