OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview User pod row implementation. | 6 * @fileoverview User pod row implementation. |
7 */ | 7 */ |
8 | 8 |
9 cr.define('login', function() { | 9 cr.define('login', function() { |
10 // Pod width. 170px Pod + 10px padding + 10px margin on both sides. | 10 // Pod width. 170px Pod + 10px padding + 10px margin on both sides. |
11 const POD_WIDTH = 170 + 2 * (10 + 10); | 11 const POD_WIDTH = 170 + 2 * (10 + 10); |
12 | 12 |
13 // Oauth token status. These must match UserManager::OAuthTokenStatus. | 13 // Oauth token status. These must match UserManager::OAuthTokenStatus. |
14 const OAUTH_TOKEN_STATUS_UNKNOWN = 0; | 14 const OAUTH_TOKEN_STATUS_UNKNOWN = 0; |
15 const OAUTH_TOKEN_STATUS_INVALID = 1; | 15 const OAUTH_TOKEN_STATUS_INVALID = 1; |
16 const OAUTH_TOKEN_STATUS_VALID = 2; | 16 const OAUTH_TOKEN_STATUS_VALID = 2; |
17 | 17 |
| 18 // Tab index for pods. Update these when adding new controls. |
| 19 const TAB_INDEX_POD_INPUT = 1; |
| 20 const TAB_INDEX_REMOVE_USER = 2; |
| 21 |
18 /** | 22 /** |
19 * Helper function to remove a class from given element. | 23 * Helper function to remove a class from given element. |
20 * @param {!HTMLElement} el Element whose class list to change. | 24 * @param {!HTMLElement} el Element whose class list to change. |
21 * @param {string} cl Class to remove. | 25 * @param {string} cl Class to remove. |
22 */ | 26 */ |
23 function removeClass(el, cl) { | 27 function removeClass(el, cl) { |
24 el.classList.remove(cl); | 28 el.classList.remove(cl); |
25 } | 29 } |
26 | 30 |
27 /** | 31 /** |
28 * Creates a user pod. | 32 * Creates a user pod. |
29 * @constructor | 33 * @constructor |
30 * @extends {HTMLDivElement} | 34 * @extends {HTMLDivElement} |
31 */ | 35 */ |
32 var UserPod = cr.ui.define(function() { | 36 var UserPod = cr.ui.define(function() { |
33 return $('user-pod-template').cloneNode(true); | 37 return $('user-pod-template').cloneNode(true); |
34 }); | 38 }); |
35 | 39 |
36 UserPod.prototype = { | 40 UserPod.prototype = { |
37 __proto__: HTMLDivElement.prototype, | 41 __proto__: HTMLDivElement.prototype, |
38 | 42 |
39 /** @inheritDoc */ | 43 /** @inheritDoc */ |
40 decorate: function() { | 44 decorate: function() { |
41 // Make this focusable | 45 // Make this focusable |
42 if (!this.hasAttribute('tabindex')) | 46 if (!this.hasAttribute('tabindex')) |
43 this.tabIndex = 0; | 47 this.tabIndex = TAB_INDEX_POD_INPUT; |
44 | 48 |
45 this.addEventListener('mousedown', | 49 this.addEventListener('mousedown', |
46 this.handleMouseDown_.bind(this)); | 50 this.handleMouseDown_.bind(this)); |
47 | 51 |
48 this.enterButtonElement.addEventListener('click', | 52 this.enterButtonElement.addEventListener('click', |
49 this.activate.bind(this)); | 53 this.activate.bind(this)); |
50 this.signinButtonElement.addEventListener('click', | 54 this.signinButtonElement.addEventListener('click', |
51 this.activate.bind(this)); | 55 this.activate.bind(this)); |
| 56 this.removeUserButtonElement.addEventListener('click', |
| 57 this.handleRemoveButtonClick_.bind(this)); |
52 this.removeUserButtonElement.addEventListener('mouseout', | 58 this.removeUserButtonElement.addEventListener('mouseout', |
53 this.handleRemoveButtonMouseOut_.bind(this)); | 59 this.handleRemoveButtonMouseOut_.bind(this)); |
54 }, | 60 }, |
55 | 61 |
56 /** | 62 /** |
57 * Initializes the pod after its properties set and added to a pod row. | 63 * Initializes the pod after its properties set and added to a pod row. |
58 */ | 64 */ |
59 initialize: function() { | 65 initialize: function() { |
60 if (!this.isGuest) { | 66 if (!this.isGuest) { |
61 this.passwordEmpty = true; | 67 this.passwordEmpty = true; |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 if (this.isGuest) { | 174 if (this.isGuest) { |
169 this.imageElement.title = userDict.name; | 175 this.imageElement.title = userDict.name; |
170 this.enterButtonElement.hidden = false; | 176 this.enterButtonElement.hidden = false; |
171 this.passwordElement.hidden = true; | 177 this.passwordElement.hidden = true; |
172 this.signinButtonElement.hidden = true; | 178 this.signinButtonElement.hidden = true; |
173 } else { | 179 } else { |
174 var needSignin = this.needGaiaSignin; | 180 var needSignin = this.needGaiaSignin; |
175 this.imageElement.title = userDict.emailAddress; | 181 this.imageElement.title = userDict.emailAddress; |
176 this.enterButtonElement.hidden = true; | 182 this.enterButtonElement.hidden = true; |
177 this.passwordElement.hidden = needSignin; | 183 this.passwordElement.hidden = needSignin; |
| 184 this.removeUserButtonElement.setAttribute( |
| 185 'aria-label', localStrings.getStringF('removeButtonAccessibleName', |
| 186 userDict.emailAddress)); |
178 this.passwordElement.setAttribute('aria-label', | 187 this.passwordElement.setAttribute('aria-label', |
179 localStrings.getStringF( | 188 localStrings.getStringF( |
180 'passwordFieldAccessibleName', | 189 'passwordFieldAccessibleName', |
181 userDict.emailAddress)); | 190 userDict.emailAddress)); |
182 this.signinButtonElement.hidden = !needSignin; | 191 this.signinButtonElement.hidden = !needSignin; |
183 } | 192 } |
184 }, | 193 }, |
185 | 194 |
186 /** | 195 /** |
187 * Whether we are a guest pod or not. | 196 * Whether we are a guest pod or not. |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
312 this.activeRemoveButton = true; | 321 this.activeRemoveButton = true; |
313 }, | 322 }, |
314 | 323 |
315 /** | 324 /** |
316 * Handles mousedown event. | 325 * Handles mousedown event. |
317 */ | 326 */ |
318 handleMouseDown_: function(e) { | 327 handleMouseDown_: function(e) { |
319 if (!this.parentNode.rowEnabled) | 328 if (!this.parentNode.rowEnabled) |
320 return; | 329 return; |
321 var handled = false; | 330 var handled = false; |
322 if (e.target == this.removeUserButtonElement) { | 331 if (!this.signinButtonElement.hidden) { |
323 this.handleRemoveButtonClick_(e); | |
324 handled = true; | |
325 } else if (!this.signinButtonElement.hidden) { | |
326 this.parentNode.showSigninUI(this.user.emailAddress); | 332 this.parentNode.showSigninUI(this.user.emailAddress); |
327 handled = true; | 333 handled = true; |
328 } | 334 } |
329 if (handled) { | 335 if (handled) { |
330 // Prevent default so that we don't trigger 'focus' event. | 336 // Prevent default so that we don't trigger 'focus' event. |
331 e.preventDefault(); | 337 e.preventDefault(); |
332 } | 338 } |
333 } | 339 } |
334 }; | 340 }; |
335 | 341 |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 */ | 402 */ |
397 addUserPod: function(user, animated) { | 403 addUserPod: function(user, animated) { |
398 var userPod = this.createUserPod(user); | 404 var userPod = this.createUserPod(user); |
399 if (animated) { | 405 if (animated) { |
400 userPod.classList.add('init'); | 406 userPod.classList.add('init'); |
401 userPod.nameElement.classList.add('init'); | 407 userPod.nameElement.classList.add('init'); |
402 } | 408 } |
403 | 409 |
404 this.appendChild(userPod); | 410 this.appendChild(userPod); |
405 userPod.initialize(); | 411 userPod.initialize(); |
| 412 var index = this.findIndex_(userPod); |
| 413 userPod.removeUserButtonElement.tabIndex = TAB_INDEX_REMOVE_USER; |
406 }, | 414 }, |
407 | 415 |
408 /** | 416 /** |
409 * Ensures the given pod is visible. | 417 * Ensures the given pod is visible. |
410 * @param {UserPod} pod Pod to scroll into view. | 418 * @param {UserPod} pod Pod to scroll into view. |
411 */ | 419 */ |
412 scrollPodIntoView: function(pod) { | 420 scrollPodIntoView: function(pod) { |
413 var podIndex = this.findIndex_(pod); | 421 var podIndex = this.findIndex_(pod); |
414 if (podIndex == -1) | 422 if (podIndex == -1) |
415 return; | 423 return; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 */ | 471 */ |
464 loadPods: function(users, animated) { | 472 loadPods: function(users, animated) { |
465 // Clear existing pods. | 473 // Clear existing pods. |
466 this.innerHTML = ''; | 474 this.innerHTML = ''; |
467 this.focusedPod_ = undefined; | 475 this.focusedPod_ = undefined; |
468 this.activatedPod_ = undefined; | 476 this.activatedPod_ = undefined; |
469 | 477 |
470 // Popoulate the pod row. | 478 // Popoulate the pod row. |
471 for (var i = 0; i < users.length; ++i) { | 479 for (var i = 0; i < users.length; ++i) { |
472 this.addUserPod(users[i], animated); | 480 this.addUserPod(users[i], animated); |
| 481 this.pods[i].tabIndex = TAB_INDEX_POD_INPUT; |
473 } | 482 } |
474 }, | 483 }, |
475 | 484 |
476 /** | 485 /** |
477 * Focuses a given user pod or clear focus when given null. | 486 * Focuses a given user pod or clear focus when given null. |
478 * @param {UserPod} pod User pod to focus or null to clear focus. | 487 * @param {UserPod} pod User pod to focus or null to clear focus. |
479 */ | 488 */ |
480 focusPod: function(pod) { | 489 focusPod: function(pod) { |
481 if (this.focusedPod_ == pod) | 490 if (this.focusedPod_ == pod) |
482 return; | 491 return; |
483 | 492 |
484 if (pod) { | 493 if (pod) { |
485 for (var i = 0; i < this.pods.length; ++i) { | 494 for (var i = 0; i < this.pods.length; ++i) { |
486 this.pods[i].activeRemoveButton = false; | 495 this.pods[i].activeRemoveButton = false; |
487 if (this.pods[i] == pod) { | 496 if (this.pods[i] == pod) { |
488 pod.classList.remove("faded"); | 497 pod.classList.remove("faded"); |
489 pod.classList.add("focused"); | 498 pod.classList.add("focused"); |
490 pod.tabIndex = -1; // Make it not keyboard focusable. | 499 pod.tabIndex = -1; // Make it not keyboard focusable. |
491 } else { | 500 } else { |
492 this.pods[i].classList.remove('focused'); | 501 this.pods[i].classList.remove('focused'); |
493 this.pods[i].classList.add('faded'); | 502 this.pods[i].classList.add('faded'); |
494 this.pods[i].tabIndex = 0; | 503 this.pods[i].tabIndex = TAB_INDEX_POD_INPUT; |
495 } | 504 } |
496 } | 505 } |
| 506 pod.mainInput.tabIndex = TAB_INDEX_POD_INPUT; |
497 pod.focusInput(); | 507 pod.focusInput(); |
498 | 508 |
499 this.focusedPod_ = pod; | 509 this.focusedPod_ = pod; |
500 this.scrollPodIntoView(pod); | 510 this.scrollPodIntoView(pod); |
501 } else { | 511 } else { |
502 for (var i = 0; i < this.pods.length; ++i) { | 512 for (var i = 0; i < this.pods.length; ++i) { |
503 this.pods[i].classList.remove('focused'); | 513 this.pods[i].classList.remove('focused'); |
504 this.pods[i].classList.remove('faded'); | 514 this.pods[i].classList.remove('faded'); |
505 this.pods[i].activeRemoveButton = false; | 515 this.pods[i].activeRemoveButton = false; |
506 this.pods[i].tabIndex = 0; | 516 this.pods[i].tabIndex = TAB_INDEX_POD_INPUT; |
507 } | 517 } |
508 this.focusedPod_ = undefined; | 518 this.focusedPod_ = undefined; |
509 } | 519 } |
510 }, | 520 }, |
511 | 521 |
512 /** | 522 /** |
513 * Returns the currently activated pod. | 523 * Returns the currently activated pod. |
514 */ | 524 */ |
515 get activated() { | 525 get activated() { |
516 return this.activatedPod_; | 526 return this.activatedPod_; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 this.ownerDocument.removeEventListener( | 680 this.ownerDocument.removeEventListener( |
671 event, this.listeners_[event][0], this.listeners_[event][1]); | 681 event, this.listeners_[event][0], this.listeners_[event][1]); |
672 } | 682 } |
673 } | 683 } |
674 }; | 684 }; |
675 | 685 |
676 return { | 686 return { |
677 PodRow: PodRow | 687 PodRow: PodRow |
678 }; | 688 }; |
679 }); | 689 }); |
OLD | NEW |