OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 /** | 10 /** |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 function removeClass(el, cl) { | 86 function removeClass(el, cl) { |
87 el.classList.remove(cl); | 87 el.classList.remove(cl); |
88 } | 88 } |
89 | 89 |
90 /** | 90 /** |
91 * Creates a user pod. | 91 * Creates a user pod. |
92 * @constructor | 92 * @constructor |
93 * @extends {HTMLDivElement} | 93 * @extends {HTMLDivElement} |
94 */ | 94 */ |
95 var UserPod = cr.ui.define(function() { | 95 var UserPod = cr.ui.define(function() { |
96 return $('user-pod-template').cloneNode(true); | 96 var dom = $('user-pod-template').cloneNode(true); |
| 97 dom.id = ''; |
| 98 return dom; |
97 }); | 99 }); |
98 | 100 |
99 UserPod.prototype = { | 101 UserPod.prototype = { |
100 __proto__: HTMLDivElement.prototype, | 102 __proto__: HTMLDivElement.prototype, |
101 | 103 |
102 /** @override */ | 104 /** @override */ |
103 decorate: function() { | 105 decorate: function() { |
104 this.tabIndex = UserPodTabOrder.POD_INPUT; | 106 this.tabIndex = UserPodTabOrder.POD_INPUT; |
105 this.removeUserButtonElement.tabIndex = UserPodTabOrder.REMOVE_USER; | 107 this.removeUserButtonElement.tabIndex = UserPodTabOrder.REMOVE_USER; |
106 | 108 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
161 e.preventDefault(); | 163 e.preventDefault(); |
162 return; | 164 return; |
163 } | 165 } |
164 }, | 166 }, |
165 | 167 |
166 /** | 168 /** |
167 * Gets signed in indicator element. | 169 * Gets signed in indicator element. |
168 * @type {!HTMLDivElement} | 170 * @type {!HTMLDivElement} |
169 */ | 171 */ |
170 get signedInIndicatorElement() { | 172 get signedInIndicatorElement() { |
171 return this.firstElementChild; | 173 return this.querySelector('.signed-in-indicator'); |
172 }, | 174 }, |
173 | 175 |
174 /** | 176 /** |
175 * Gets image element. | 177 * Gets image element. |
176 * @type {!HTMLImageElement} | 178 * @type {!HTMLImageElement} |
177 */ | 179 */ |
178 get imageElement() { | 180 get imageElement() { |
179 return this.signedInIndicatorElement.nextElementSibling; | 181 return this.querySelector('.user-image'); |
180 }, | 182 }, |
181 | 183 |
182 /** | 184 /** |
183 * Gets name element. | 185 * Gets name element. |
184 * @type {!HTMLDivElement} | 186 * @type {!HTMLDivElement} |
185 */ | 187 */ |
186 get nameElement() { | 188 get nameElement() { |
187 return this.imageElement.nextElementSibling; | 189 return this.querySelector('.name'); |
188 }, | 190 }, |
189 | 191 |
190 /** | 192 /** |
191 * Gets password field. | 193 * Gets password field. |
192 * @type {!HTMLInputElement} | 194 * @type {!HTMLInputElement} |
193 */ | 195 */ |
194 get passwordElement() { | 196 get passwordElement() { |
195 return this.nameElement.nextElementSibling; | 197 return this.querySelector('.password'); |
196 }, | 198 }, |
197 | 199 |
198 /** | 200 /** |
199 * Gets Caps Lock hint image. | 201 * Gets Caps Lock hint image. |
200 * @type {!HTMLImageElement} | 202 * @type {!HTMLImageElement} |
201 */ | 203 */ |
202 get capslockHintElement() { | 204 get capslockHintElement() { |
203 return this.signinButtonElement.previousElementSibling; | 205 return this.querySelector('.capslock-hint'); |
204 }, | 206 }, |
205 | 207 |
206 /** | 208 /** |
207 * Gets user signin button. | 209 * Gets user signin button. |
208 * @type {!HTMLInputElement} | 210 * @type {!HTMLInputElement} |
209 */ | 211 */ |
210 get signinButtonElement() { | 212 get signinButtonElement() { |
211 return this.removeUserButtonElement.previousElementSibling; | 213 return this.querySelector('.signin-button'); |
212 }, | 214 }, |
213 | 215 |
214 /** | 216 /** |
215 * Gets remove user button. | 217 * Gets remove user button. |
216 * @type {!HTMLInputElement} | 218 * @type {!HTMLInputElement} |
217 */ | 219 */ |
218 get removeUserButtonElement() { | 220 get removeUserButtonElement() { |
219 return this.lastElementChild; | 221 return this.querySelector('.remove-user-button'); |
220 }, | 222 }, |
221 | 223 |
222 /** | 224 /** |
223 * Updates the user pod element. | 225 * Updates the user pod element. |
224 */ | 226 */ |
225 update: function() { | 227 update: function() { |
226 this.updateUserImage(); | 228 this.updateUserImage(); |
227 | 229 |
228 this.nameElement.textContent = this.user_.displayName; | 230 this.nameElement.textContent = this.user_.displayName; |
229 this.removeUserButtonElement.hidden = !this.user_.canRemove; | 231 this.removeUserButtonElement.hidden = !this.user_.canRemove; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 if (this.parentNode.disabled) | 390 if (this.parentNode.disabled) |
389 return; | 391 return; |
390 if (!this.signinButtonElement.hidden) { | 392 if (!this.signinButtonElement.hidden) { |
391 this.showSigninUI(); | 393 this.showSigninUI(); |
392 // Prevent default so that we don't trigger 'focus' event. | 394 // Prevent default so that we don't trigger 'focus' event. |
393 e.preventDefault(); | 395 e.preventDefault(); |
394 } | 396 } |
395 } | 397 } |
396 }; | 398 }; |
397 | 399 |
| 400 /** |
| 401 * Creates a public account user pod. |
| 402 * @constructor |
| 403 * @extends {UserPod} |
| 404 */ |
| 405 var PublicAccountUserPod = cr.ui.define(function() { |
| 406 var dom = UserPod(); |
| 407 |
| 408 var extras = $('public-account-user-pod-extras-template').children; |
| 409 for (var i = 0; i < extras.length; ++i) { |
| 410 var el = extras[i].cloneNode(true); |
| 411 dom.appendChild(el); |
| 412 } |
| 413 |
| 414 return dom; |
| 415 }); |
| 416 |
| 417 PublicAccountUserPod.prototype = { |
| 418 __proto__: UserPod.prototype, |
| 419 |
| 420 /** |
| 421 * "Enter" button in expanded side pane. |
| 422 * @type {!HTMLButtonElement} |
| 423 */ |
| 424 get enterButtonElement() { |
| 425 return this.querySelector('.enter-button'); |
| 426 }, |
| 427 |
| 428 /** |
| 429 * Boolean flag of whether the pod is showing the side pane. The flag |
| 430 * controls whether 'expanded' class is added to the pod's class list and |
| 431 * resets tab order because main input element changes when the 'expanded' |
| 432 * state changes. |
| 433 * @type {boolean} |
| 434 */ |
| 435 get expanded() { |
| 436 return this.classList.contains('expanded'); |
| 437 }, |
| 438 set expanded(expanded) { |
| 439 if (this.expanded == expanded) |
| 440 return; |
| 441 |
| 442 this.resetTabOrder(); |
| 443 this.classList.toggle('expanded', expanded); |
| 444 |
| 445 var self = this; |
| 446 this.classList.add('animating'); |
| 447 this.addEventListener('webkitTransitionEnd', function f(e) { |
| 448 self.removeEventListener('webkitTransitionEnd', f); |
| 449 self.classList.remove('animating'); |
| 450 }); |
| 451 }, |
| 452 |
| 453 /** @override */ |
| 454 get needGaiaSignin() { |
| 455 return false; |
| 456 }, |
| 457 |
| 458 /** @override */ |
| 459 get mainInput() { |
| 460 if (this.expanded) |
| 461 return this.enterButtonElement; |
| 462 else |
| 463 return this.nameElement; |
| 464 }, |
| 465 |
| 466 /** @override */ |
| 467 decorate: function() { |
| 468 UserPod.prototype.decorate.call(this); |
| 469 |
| 470 this.classList.remove('need-password'); |
| 471 this.classList.add('public-account'); |
| 472 |
| 473 this.nameElement.addEventListener('keydown', (function(e) { |
| 474 if (e.keyIdentifier == 'Enter') { |
| 475 this.parentNode.activatedPod = this; |
| 476 // Stop this keydown event from bubbling up to PodRow handler. |
| 477 e.stopPropagation(); |
| 478 // Prevent default so that we don't trigger a 'click' event on the |
| 479 // newly focused "Enter" button. |
| 480 e.preventDefault(); |
| 481 } |
| 482 }).bind(this)); |
| 483 |
| 484 this.enterButtonElement.addEventListener('click', (function(e) { |
| 485 chrome.send('launchPublicAccount', [this.user.username]); |
| 486 }).bind(this)); |
| 487 }, |
| 488 |
| 489 /** |
| 490 * Updates the user pod element. |
| 491 */ |
| 492 update: function() { |
| 493 UserPod.prototype.update.call(this); |
| 494 this.querySelector('.side-pane-name').textContent = |
| 495 this.user_.displayName; |
| 496 this.querySelector('.info').textContent = |
| 497 localStrings.getStringF('publicAccountInfoFormat', |
| 498 this.user_.enterpriseDomain); |
| 499 }, |
| 500 |
| 501 /** @override */ |
| 502 focusInput: function() { |
| 503 // Move tabIndex from the whole pod to the main input. |
| 504 this.tabIndex = -1; |
| 505 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT; |
| 506 this.mainInput.focus(); |
| 507 }, |
| 508 |
| 509 /** @override */ |
| 510 reset: function(takeFocus) { |
| 511 if (!takeFocus) |
| 512 this.expanded = false; |
| 513 UserPod.prototype.reset.call(this, takeFocus); |
| 514 }, |
| 515 |
| 516 /** @override */ |
| 517 activate: function() { |
| 518 this.expanded = true; |
| 519 this.focusInput(); |
| 520 return true; |
| 521 }, |
| 522 |
| 523 /** @override */ |
| 524 handleMouseDown_: function(e) { |
| 525 if (this.parentNode.disabled) |
| 526 return; |
| 527 |
| 528 this.parentNode.focusPod(this); |
| 529 this.parentNode.activatedPod = this; |
| 530 // Prevent default so that we don't trigger 'focus' event. |
| 531 e.preventDefault(); |
| 532 } |
| 533 }; |
398 | 534 |
399 /** | 535 /** |
400 * Creates a new pod row element. | 536 * Creates a new pod row element. |
401 * @constructor | 537 * @constructor |
402 * @extends {HTMLDivElement} | 538 * @extends {HTMLDivElement} |
403 */ | 539 */ |
404 var PodRow = cr.ui.define('podrow'); | 540 var PodRow = cr.ui.define('podrow'); |
405 | 541 |
406 PodRow.prototype = { | 542 PodRow.prototype = { |
407 __proto__: HTMLDivElement.prototype, | 543 __proto__: HTMLDivElement.prototype, |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
504 for (var i = 0, control; control = controls[i]; ++i) { | 640 for (var i = 0, control; control = controls[i]; ++i) { |
505 control.disabled = value; | 641 control.disabled = value; |
506 } | 642 } |
507 }, | 643 }, |
508 | 644 |
509 /** | 645 /** |
510 * Creates a user pod from given email. | 646 * Creates a user pod from given email. |
511 * @param {string} email User's email. | 647 * @param {string} email User's email. |
512 */ | 648 */ |
513 createUserPod: function(user) { | 649 createUserPod: function(user) { |
514 var userPod = new UserPod({user: user}); | 650 var userPod; |
| 651 if (user.publicAccount) |
| 652 userPod = new PublicAccountUserPod({user: user}); |
| 653 else |
| 654 userPod = new UserPod({user: user}); |
| 655 |
515 userPod.hidden = false; | 656 userPod.hidden = false; |
516 return userPod; | 657 return userPod; |
517 }, | 658 }, |
518 | 659 |
519 /** | 660 /** |
520 * Add an existing user pod to this pod row. | 661 * Add an existing user pod to this pod row. |
521 * @param {!Object} user User info dictionary. | 662 * @param {!Object} user User info dictionary. |
522 * @param {boolean} animated Whether to use init animation. | 663 * @param {boolean} animated Whether to use init animation. |
523 */ | 664 */ |
524 addUserPod: function(user, animated) { | 665 addUserPod: function(user, animated) { |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 | 930 |
790 /** | 931 /** |
791 * Handler of click event. | 932 * Handler of click event. |
792 * @param {Event} e Click Event object. | 933 * @param {Event} e Click Event object. |
793 * @private | 934 * @private |
794 */ | 935 */ |
795 handleClick_: function(e) { | 936 handleClick_: function(e) { |
796 if (this.disabled) | 937 if (this.disabled) |
797 return; | 938 return; |
798 // Clears focus if not clicked on a pod and if there's more than one pod. | 939 // Clears focus if not clicked on a pod and if there's more than one pod. |
799 if (e.target.parentNode != this && | 940 var pod = findAncestorByClass(e.target, 'pod'); |
800 e.target.parentNode.parentNode != this && | 941 if ((!pod || pod.parentNode != this) && !this.isSinglePod) { |
801 !this.isSinglePod) { | |
802 this.focusPod(); | 942 this.focusPod(); |
803 } | 943 } |
804 | 944 |
805 // Return focus back to single pod. | 945 // Return focus back to single pod. |
806 if (this.isSinglePod) { | 946 if (this.isSinglePod) { |
807 this.focusPod(this.focusedPod_, true /* force */); | 947 this.focusPod(this.focusedPod_, true /* force */); |
808 } | 948 } |
809 }, | 949 }, |
810 | 950 |
811 /** | 951 /** |
812 * Handles focus event. | 952 * Handles focus event. |
813 * @param {Event} e Focus Event object. | 953 * @param {Event} e Focus Event object. |
814 * @private | 954 * @private |
815 */ | 955 */ |
816 handleFocus_: function(e) { | 956 handleFocus_: function(e) { |
817 if (this.disabled) | 957 if (this.disabled) |
818 return; | 958 return; |
819 if (e.target.parentNode == this) { | 959 if (e.target.parentNode == this) { |
820 // Focus on a pod | 960 // Focus on a pod |
821 if (e.target.classList.contains('focused')) | 961 if (e.target.classList.contains('focused')) |
822 e.target.focusInput(); | 962 e.target.focusInput(); |
823 else | 963 else |
824 this.focusPod(e.target); | 964 this.focusPod(e.target); |
825 } else if (e.target.parentNode.parentNode == this) { | 965 return; |
| 966 } |
| 967 |
| 968 var pod = findAncestorByClass(e.target, 'pod'); |
| 969 if (pod && pod.parentNode == this) { |
826 // Focus on a control of a pod but not on the Remove button. | 970 // Focus on a control of a pod but not on the Remove button. |
827 if (!e.target.parentNode.classList.contains('focused') && | 971 if (!pod.classList.contains('focused') && |
828 !e.target.classList.contains('remove-user-button')) { | 972 !e.target.classList.contains('remove-user-button')) { |
829 this.focusPod(e.target.parentNode); | 973 this.focusPod(pod); |
830 e.target.focus(); | 974 e.target.focus(); |
831 } | 975 } |
832 } else { | 976 return; |
833 // Clears pod focus when we reach here. It means new focus is neither | |
834 // on a pod nor on a button/input for a pod. | |
835 // Do not "defocus" user pod when it is a single pod. | |
836 // That means that 'focused' class will not be removed and | |
837 // input field/button will always be visible. | |
838 if (!this.isSinglePod) | |
839 this.focusPod(); | |
840 } | 977 } |
| 978 |
| 979 // Clears pod focus when we reach here. It means new focus is neither |
| 980 // on a pod nor on a button/input for a pod. |
| 981 // Do not "defocus" user pod when it is a single pod. |
| 982 // That means that 'focused' class will not be removed and |
| 983 // input field/button will always be visible. |
| 984 if (!this.isSinglePod) |
| 985 this.focusPod(); |
841 }, | 986 }, |
842 | 987 |
843 /** | 988 /** |
844 * Handler of keydown event. | 989 * Handler of keydown event. |
845 * @param {Event} e KeyDown Event object. | 990 * @param {Event} e KeyDown Event object. |
846 */ | 991 */ |
847 handleKeyDown: function(e) { | 992 handleKeyDown: function(e) { |
848 if (this.disabled) | 993 if (this.disabled) |
849 return; | 994 return; |
850 var editing = e.target.tagName == 'INPUT' && e.target.value; | 995 var editing = e.target.tagName == 'INPUT' && e.target.value; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 this.classList.remove('images-loading'); | 1094 this.classList.remove('images-loading'); |
950 chrome.send('userImagesLoaded'); | 1095 chrome.send('userImagesLoaded'); |
951 } | 1096 } |
952 } | 1097 } |
953 }; | 1098 }; |
954 | 1099 |
955 return { | 1100 return { |
956 PodRow: PodRow | 1101 PodRow: PodRow |
957 }; | 1102 }; |
958 }); | 1103 }); |
OLD | NEW |