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

Side by Side Diff: chrome/browser/resources/chromeos/login/user_pod_row.js

Issue 11308081: cros: Account picker UI for public account. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: for comments in #3 Created 8 years 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 | Annotate | Revision Log
OLDNEW
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
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
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');
bartfab (slow) 2012/12/05 18:49:51 Nice drive-by clean-up in these methods.
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
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 if (expanded) {
bartfab (slow) 2012/12/05 18:49:51 As I was just told in another code review, webkit
xiyuan 2012/12/05 19:38:49 Good to know. Thanks for the tip.
444 this.classList.add('expanded');
445 } else {
446 this.classList.remove('expanded');
447 }
448
449 this.classList.add('animating');
450 this.addEventListener('webkitTransitionEnd', function f(e) {
451 this.removeEventListener('webkitTransitionEnd', f);
Ivan Korotkov 2012/12/05 18:57:33 I think it's not gonna work since you add f.bind(.
xiyuan 2012/12/05 19:38:49 You are right. I missed that.
452 this.classList.remove('animating');
453 }.bind(this));
454 },
455
456 /** @override */
457 get needGaiaSignin() {
458 return false;
459 },
460
461 /** @override */
462 get mainInput() {
463 if (this.expanded)
464 return this.enterButtonElement;
465 else
466 return this.nameElement;
467 },
468
469 /** @override */
470 decorate: function() {
471 UserPod.prototype.decorate.call(this);
472
473 this.classList.remove('need-password');
474 this.classList.add('public-account');
475
476 this.nameElement.addEventListener('keydown', (function(e) {
477 if (e.keyIdentifier == 'Enter') {
478 this.parentNode.activatedPod = this;
479 // Stop this keydown event from bubbling up to PodRow handler.
480 e.stopPropagation();
481 // Prevent default so that we don't trigger a 'click' event on the
482 // newly focused "Enter" button.
483 e.preventDefault();
484 }
485 }).bind(this));
486
487 this.enterButtonElement.addEventListener('click', (function(e) {
488 chrome.send('launchPublicAccount', [this.user.username]);
489 }).bind(this));
490 },
491
492 /**
493 * Updates the user pod element.
494 */
495 update: function() {
496 UserPod.prototype.update.call(this);
497 this.querySelector('.side-pane-name').textContent =
498 this.user_.displayName;
499 this.querySelector('.info').textContent =
500 localStrings.getStringF('publicAccountInfoFormat',
501 this.user_.enterpriseDomain);
502 },
503
504 /** @override */
505 focusInput: function() {
506 // Move tabIndex from the whole pod to the main input.
507 this.tabIndex = -1;
508 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT;
509 this.mainInput.focus();
510 },
511
512 /** @override */
513 reset: function(takeFocus) {
514 if (!takeFocus)
515 this.expanded = false;
516 UserPod.prototype.reset.call(this, takeFocus);
517 },
518
519 /** @override */
520 activate: function() {
521 this.expanded = true;
522 this.focusInput();
523 return true;
524 },
525
526 /** @override */
527 handleMouseDown_: function(e) {
528 if (this.parentNode.disabled)
529 return;
530
531 this.parentNode.focusPod(this);
532 this.parentNode.activatedPod = this;
533 // Prevent default so that we don't trigger 'focus' event.
534 e.preventDefault();
535 }
536 };
398 537
399 /** 538 /**
400 * Creates a new pod row element. 539 * Creates a new pod row element.
401 * @constructor 540 * @constructor
402 * @extends {HTMLDivElement} 541 * @extends {HTMLDivElement}
403 */ 542 */
404 var PodRow = cr.ui.define('podrow'); 543 var PodRow = cr.ui.define('podrow');
405 544
406 PodRow.prototype = { 545 PodRow.prototype = {
407 __proto__: HTMLDivElement.prototype, 546 __proto__: HTMLDivElement.prototype,
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 for (var i = 0, control; control = controls[i]; ++i) { 643 for (var i = 0, control; control = controls[i]; ++i) {
505 control.disabled = value; 644 control.disabled = value;
506 } 645 }
507 }, 646 },
508 647
509 /** 648 /**
510 * Creates a user pod from given email. 649 * Creates a user pod from given email.
511 * @param {string} email User's email. 650 * @param {string} email User's email.
512 */ 651 */
513 createUserPod: function(user) { 652 createUserPod: function(user) {
514 var userPod = new UserPod({user: user}); 653 var userPod;
654 if (user.publicAccount)
655 userPod = new PublicAccountUserPod({user: user});
656 else
657 userPod = new UserPod({user: user});
658
515 userPod.hidden = false; 659 userPod.hidden = false;
516 return userPod; 660 return userPod;
517 }, 661 },
518 662
519 /** 663 /**
520 * Add an existing user pod to this pod row. 664 * Add an existing user pod to this pod row.
521 * @param {!Object} user User info dictionary. 665 * @param {!Object} user User info dictionary.
522 * @param {boolean} animated Whether to use init animation. 666 * @param {boolean} animated Whether to use init animation.
523 */ 667 */
524 addUserPod: function(user, animated) { 668 addUserPod: function(user, animated) {
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 933
790 /** 934 /**
791 * Handler of click event. 935 * Handler of click event.
792 * @param {Event} e Click Event object. 936 * @param {Event} e Click Event object.
793 * @private 937 * @private
794 */ 938 */
795 handleClick_: function(e) { 939 handleClick_: function(e) {
796 if (this.disabled) 940 if (this.disabled)
797 return; 941 return;
798 // Clears focus if not clicked on a pod and if there's more than one pod. 942 // Clears focus if not clicked on a pod and if there's more than one pod.
799 if (e.target.parentNode != this && 943 var pod = findAncestorByClass(e.target, 'pod');
800 e.target.parentNode.parentNode != this && 944 if ((!pod || pod.parentNode != this) && !this.isSinglePod) {
801 !this.isSinglePod) {
802 this.focusPod(); 945 this.focusPod();
803 } 946 }
804 947
805 // Return focus back to single pod. 948 // Return focus back to single pod.
806 if (this.isSinglePod) { 949 if (this.isSinglePod) {
807 this.focusPod(this.focusedPod_, true /* force */); 950 this.focusPod(this.focusedPod_, true /* force */);
808 } 951 }
809 }, 952 },
810 953
811 /** 954 /**
812 * Handles focus event. 955 * Handles focus event.
813 * @param {Event} e Focus Event object. 956 * @param {Event} e Focus Event object.
814 * @private 957 * @private
815 */ 958 */
816 handleFocus_: function(e) { 959 handleFocus_: function(e) {
817 if (this.disabled) 960 if (this.disabled)
818 return; 961 return;
819 if (e.target.parentNode == this) { 962 if (e.target.parentNode == this) {
820 // Focus on a pod 963 // Focus on a pod
821 if (e.target.classList.contains('focused')) 964 if (e.target.classList.contains('focused'))
822 e.target.focusInput(); 965 e.target.focusInput();
823 else 966 else
824 this.focusPod(e.target); 967 this.focusPod(e.target);
825 } else if (e.target.parentNode.parentNode == this) { 968 return;
969 }
970
971 var pod = findAncestorByClass(e.target, 'pod');
972 if (pod && pod.parentNode == this) {
826 // Focus on a control of a pod but not on the Remove button. 973 // Focus on a control of a pod but not on the Remove button.
827 if (!e.target.parentNode.classList.contains('focused') && 974 if (!pod.classList.contains('focused') &&
828 !e.target.classList.contains('remove-user-button')) { 975 !e.target.classList.contains('remove-user-button')) {
829 this.focusPod(e.target.parentNode); 976 this.focusPod(pod);
830 e.target.focus(); 977 e.target.focus();
831 } 978 }
832 } else { 979 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 } 980 }
981
982 // Clears pod focus when we reach here. It means new focus is neither
983 // on a pod nor on a button/input for a pod.
984 // Do not "defocus" user pod when it is a single pod.
985 // That means that 'focused' class will not be removed and
986 // input field/button will always be visible.
987 if (!this.isSinglePod)
988 this.focusPod();
841 }, 989 },
842 990
843 /** 991 /**
844 * Handler of keydown event. 992 * Handler of keydown event.
845 * @param {Event} e KeyDown Event object. 993 * @param {Event} e KeyDown Event object.
846 */ 994 */
847 handleKeyDown: function(e) { 995 handleKeyDown: function(e) {
848 if (this.disabled) 996 if (this.disabled)
849 return; 997 return;
850 var editing = e.target.tagName == 'INPUT' && e.target.value; 998 var editing = e.target.tagName == 'INPUT' && e.target.value;
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
949 this.classList.remove('images-loading'); 1097 this.classList.remove('images-loading');
950 chrome.send('userImagesLoaded'); 1098 chrome.send('userImagesLoaded');
951 } 1099 }
952 } 1100 }
953 }; 1101 };
954 1102
955 return { 1103 return {
956 PodRow: PodRow 1104 PodRow: PodRow
957 }; 1105 };
958 }); 1106 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698