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

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

Issue 369893005: Implement new design for expanded public session pod design (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments. Made sure PS "enter" button cannot be tabbed to when PS pod is not expanded. Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 * @type {number} 42 * @type {number}
43 * @const 43 * @const
44 */ 44 */
45 var MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER = 2; 45 var MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER = 2;
46 46
47 /** 47 /**
48 * Variables used for pod placement processing. Width and height should be 48 * Variables used for pod placement processing. Width and height should be
49 * synced with computed CSS sizes of pods. 49 * synced with computed CSS sizes of pods.
50 */ 50 */
51 var POD_WIDTH = 180; 51 var POD_WIDTH = 180;
52 var PUBLIC_EXPANDED_WIDTH = 420; 52 var PUBLIC_EXPANDED_BASIC_WIDTH = 500;
53 var CROS_POD_HEIGHT = 213; 53 var CROS_POD_HEIGHT = 213;
54 var DESKTOP_POD_HEIGHT = 216; 54 var DESKTOP_POD_HEIGHT = 226;
55 var POD_ROW_PADDING = 10; 55 var POD_ROW_PADDING = 10;
56 var DESKTOP_ROW_PADDING = 15; 56 var DESKTOP_ROW_PADDING = 15;
57 57
58 /** 58 /**
59 * Minimal padding between user pod and virtual keyboard. 59 * Minimal padding between user pod and virtual keyboard.
60 * @type {number} 60 * @type {number}
61 * @const 61 * @const
62 */ 62 */
63 var USER_POD_KEYBOARD_MIN_PADDING = 20; 63 var USER_POD_KEYBOARD_MIN_PADDING = 20;
64 64
(...skipping 26 matching lines...) Expand all
91 */ 91 */
92 var UserPodTabOrder = { 92 var UserPodTabOrder = {
93 POD_INPUT: 1, // Password input fields (and whole pods themselves). 93 POD_INPUT: 1, // Password input fields (and whole pods themselves).
94 HEADER_BAR: 2, // Buttons on the header bar (Shutdown, Add User). 94 HEADER_BAR: 2, // Buttons on the header bar (Shutdown, Add User).
95 ACTION_BOX: 3, // Action box buttons. 95 ACTION_BOX: 3, // Action box buttons.
96 PAD_MENU_ITEM: 4 // User pad menu items (Remove this user). 96 PAD_MENU_ITEM: 4 // User pad menu items (Remove this user).
97 }; 97 };
98 98
99 /** 99 /**
100 * Supported authentication types. Keep in sync with the enum in 100 * Supported authentication types. Keep in sync with the enum in
101 * chrome/browser/chromeos/login/login_display.h 101 * chrome/browser/signin/screenlock_bridge.h
102 * @enum {number} 102 * @enum {number}
103 * @const 103 * @const
104 */ 104 */
105 var AUTH_TYPE = { 105 var AUTH_TYPE = {
106 OFFLINE_PASSWORD: 0, 106 OFFLINE_PASSWORD: 0,
107 ONLINE_SIGN_IN: 1, 107 ONLINE_SIGN_IN: 1,
108 NUMERIC_PIN: 2, 108 NUMERIC_PIN: 2,
109 USER_CLICK: 3, 109 USER_CLICK: 3,
110 EXPAND_THEN_USER_CLICK: 4,
110 }; 111 };
111 112
112 /** 113 /**
113 * Names of authentication types. 114 * Names of authentication types.
114 */ 115 */
115 var AUTH_TYPE_NAMES = { 116 var AUTH_TYPE_NAMES = {
116 0: 'offlinePassword', 117 0: 'offlinePassword',
117 1: 'onlineSignIn', 118 1: 'onlineSignIn',
118 2: 'numericPin', 119 2: 'numericPin',
119 3: 'userClick', 120 3: 'userClick',
121 4: 'expandThenUserClick',
120 }; 122 };
121 123
122 // Focus and tab order are organized as follows: 124 // Focus and tab order are organized as follows:
123 // 125 //
124 // (1) all user pods have tab index 1 so they are traversed first; 126 // (1) all user pods have tab index 1 so they are traversed first;
125 // (2) when a user pod is activated, its tab index is set to -1 and its 127 // (2) when a user pod is activated, its tab index is set to -1 and its
126 // main input field gets focus and tab index 1; 128 // main input field gets focus and tab index 1;
127 // (3) buttons on the header bar have tab index 2 so they follow user pods; 129 // (3) buttons on the header bar have tab index 2 so they follow user pods;
128 // (4) Action box buttons have tab index 3 and follow header bar buttons; 130 // (4) Action box buttons have tab index 3 and follow header bar buttons;
129 // (5) lastly, focus jumps to the Status Area and back to user pods. 131 // (5) lastly, focus jumps to the Status Area and back to user pods.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 this.handleActionAreaButtonClick_.bind(this)); 191 this.handleActionAreaButtonClick_.bind(this));
190 this.actionBoxAreaElement.addEventListener('keydown', 192 this.actionBoxAreaElement.addEventListener('keydown',
191 this.handleActionAreaButtonKeyDown_.bind(this)); 193 this.handleActionAreaButtonKeyDown_.bind(this));
192 194
193 this.actionBoxMenuRemoveElement.addEventListener('click', 195 this.actionBoxMenuRemoveElement.addEventListener('click',
194 this.handleRemoveCommandClick_.bind(this)); 196 this.handleRemoveCommandClick_.bind(this));
195 this.actionBoxMenuRemoveElement.addEventListener('keydown', 197 this.actionBoxMenuRemoveElement.addEventListener('keydown',
196 this.handleRemoveCommandKeyDown_.bind(this)); 198 this.handleRemoveCommandKeyDown_.bind(this));
197 this.actionBoxMenuRemoveElement.addEventListener('blur', 199 this.actionBoxMenuRemoveElement.addEventListener('blur',
198 this.handleRemoveCommandBlur_.bind(this)); 200 this.handleRemoveCommandBlur_.bind(this));
199 201 this.actionBoxRemoveUserWarningButtonElement.addEventListener(
200 if (this.actionBoxRemoveUserWarningButtonElement) { 202 'click',
Nikita (slow) 2014/07/10 15:56:22 nit: this guard is not needed?
bartfab (slow) 2014/07/10 15:59:24 |actionBoxRemoveUserWarningButtonElement| is the d
201 this.actionBoxRemoveUserWarningButtonElement.addEventListener( 203 this.handleRemoveUserConfirmationClick_.bind(this));
202 'click',
203 this.handleRemoveUserConfirmationClick_.bind(this));
204 this.actionBoxRemoveUserWarningButtonElement.addEventListener( 204 this.actionBoxRemoveUserWarningButtonElement.addEventListener(
205 'keydown', 205 'keydown',
206 this.handleRemoveUserConfirmationKeyDown_.bind(this)); 206 this.handleRemoveUserConfirmationKeyDown_.bind(this));
207 }
208 }, 207 },
209 208
210 /** 209 /**
211 * Initializes the pod after its properties set and added to a pod row. 210 * Initializes the pod after its properties set and added to a pod row.
212 */ 211 */
213 initialize: function() { 212 initialize: function() {
214 this.passwordElement.addEventListener('keydown', 213 this.passwordElement.addEventListener('keydown',
215 this.parentNode.handleKeyDown.bind(this.parentNode)); 214 this.parentNode.handleKeyDown.bind(this.parentNode));
216 this.passwordElement.addEventListener('keypress', 215 this.passwordElement.addEventListener('keypress',
217 this.handlePasswordKeyPress_.bind(this)); 216 this.handlePasswordKeyPress_.bind(this));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
278 }, 277 },
279 278
280 /** 279 /**
281 * Height number of pixels. 280 * Height number of pixels.
282 */ 281 */
283 get height() { 282 get height() {
284 return this.offsetHeight; 283 return this.offsetHeight;
285 }, 284 },
286 285
287 /** 286 /**
288 * Gets signed in indicator element.
289 * @type {!HTMLDivElement}
290 */
291 get signedInIndicatorElement() {
292 return this.querySelector('.signed-in-indicator');
293 },
294
295 /**
296 * Gets image element. 287 * Gets image element.
297 * @type {!HTMLImageElement} 288 * @type {!HTMLImageElement}
298 */ 289 */
299 get imageElement() { 290 get imageElement() {
300 return this.querySelector('.user-image'); 291 return this.querySelector('.user-image');
301 }, 292 },
302 293
303 /** 294 /**
304 * Gets name element. 295 * Gets name element.
305 * @type {!HTMLDivElement} 296 * @type {!HTMLDivElement}
306 */ 297 */
307 get nameElement() { 298 get nameElement() {
308 return this.querySelector('.name'); 299 return this.querySelector('.name');
309 }, 300 },
310 301
311 /** 302 /**
303 * Gets the container holding the password field.
304 * @type {!HTMLInputElement}
305 */
306 get passwordEntryContainerElement() {
307 return this.querySelector('.password-entry-container');
308 },
309
310 /**
312 * Gets password field. 311 * Gets password field.
313 * @type {!HTMLInputElement} 312 * @type {!HTMLInputElement}
314 */ 313 */
315 get passwordElement() { 314 get passwordElement() {
316 return this.querySelector('.password'); 315 return this.querySelector('.password');
317 }, 316 },
318 317
319 /** 318 /**
320 * Gets the password label, which is used to show a message where the 319 * Gets the password label, which is used to show a message where the
321 * password field is normally. 320 * password field is normally.
322 * @type {!HTMLInputElement} 321 * @type {!HTMLInputElement}
323 */ 322 */
324 get passwordLabelElement() { 323 get passwordLabelElement() {
325 return this.querySelector('.password-label'); 324 return this.querySelector('.password-label');
326 }, 325 },
327 326
328 /** 327 /**
329 * Gets Caps Lock hint image.
330 * @type {!HTMLImageElement}
331 */
332 get capslockHintElement() {
333 return this.querySelector('.capslock-hint');
334 },
335
336 /**
337 * Gets user sign in button. 328 * Gets user sign in button.
338 * @type {!HTMLButtonElement} 329 * @type {!HTMLButtonElement}
339 */ 330 */
340 get signinButtonElement() { 331 get signinButtonElement() {
341 return this.querySelector('.signin-button'); 332 return this.querySelector('.signin-button');
342 }, 333 },
343 334
344 /** 335 /**
336 * Gets the container holding the launch app button.
337 * @type {!HTMLButtonElement}
338 */
339 get launchAppButtonContainerElement() {
340 return this.querySelector('.launch-app-button-container');
341 },
342
343 /**
345 * Gets launch app button. 344 * Gets launch app button.
346 * @type {!HTMLButtonElement} 345 * @type {!HTMLButtonElement}
347 */ 346 */
348 get launchAppButtonElement() { 347 get launchAppButtonElement() {
349 return this.querySelector('.launch-app-button'); 348 return this.querySelector('.launch-app-button');
350 }, 349 },
351 350
352 /** 351 /**
353 * Gets action box area. 352 * Gets action box area.
354 * @type {!HTMLInputElement} 353 * @type {!HTMLInputElement}
(...skipping 12 matching lines...) Expand all
367 366
368 /** 367 /**
369 * Gets user type bubble like multi-profiles policy restriction message. 368 * Gets user type bubble like multi-profiles policy restriction message.
370 * @type {!HTMLDivElement} 369 * @type {!HTMLDivElement}
371 */ 370 */
372 get userTypeBubbleElement() { 371 get userTypeBubbleElement() {
373 return this.querySelector('.user-type-bubble'); 372 return this.querySelector('.user-type-bubble');
374 }, 373 },
375 374
376 /** 375 /**
377 * Gets user type icon.
378 * @type {!HTMLDivElement}
379 */
380 get userTypeIconElement() {
381 return this.querySelector('.user-type-icon-image');
382 },
383
384 /**
385 * Gets action box menu.
386 * @type {!HTMLInputElement}
387 */
388 get actionBoxMenuElement() {
389 return this.querySelector('.action-box-menu');
390 },
391
392 /**
393 * Gets action box menu title.
394 * @type {!HTMLInputElement}
395 */
396 get actionBoxMenuTitleElement() {
397 return this.querySelector('.action-box-menu-title');
398 },
399
400 /**
401 * Gets action box menu title, user name item. 376 * Gets action box menu title, user name item.
402 * @type {!HTMLInputElement} 377 * @type {!HTMLInputElement}
403 */ 378 */
404 get actionBoxMenuTitleNameElement() { 379 get actionBoxMenuTitleNameElement() {
405 return this.querySelector('.action-box-menu-title-name'); 380 return this.querySelector('.action-box-menu-title-name');
406 }, 381 },
407 382
408 /** 383 /**
409 * Gets action box menu title, user email item. 384 * Gets action box menu title, user email item.
410 * @type {!HTMLInputElement} 385 * @type {!HTMLInputElement}
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 431
457 /** 432 /**
458 * Gets action box menu, remove user command item div. 433 * Gets action box menu, remove user command item div.
459 * @type {!HTMLInputElement} 434 * @type {!HTMLInputElement}
460 */ 435 */
461 get actionBoxRemoveUserWarningButtonElement() { 436 get actionBoxRemoveUserWarningButtonElement() {
462 return this.querySelector('.remove-warning-button'); 437 return this.querySelector('.remove-warning-button');
463 }, 438 },
464 439
465 /** 440 /**
466 * Gets the locked user indicator box.
467 * @type {!HTMLInputElement}
468 */
469 get lockedIndicatorElement() {
470 return this.querySelector('.locked-indicator');
471 },
472
473 /**
474 * Gets the supervised user indicator box.
475 * @type {!HTMLInputElement}
476 */
477 get supervisedUserIndicatorElement() {
478 return this.querySelector('.supervised-indicator');
479 },
480
481 /**
482 * Gets the custom icon. This icon is normally hidden, but can be shown 441 * Gets the custom icon. This icon is normally hidden, but can be shown
483 * using the chrome.screenlockPrivate API. 442 * using the chrome.screenlockPrivate API.
484 * @type {!HTMLDivElement} 443 * @type {!HTMLDivElement}
485 */ 444 */
486 get customIconElement() { 445 get customIconElement() {
487 return this.querySelector('.custom-icon'); 446 return this.querySelector('.custom-icon');
488 }, 447 },
489 448
490 /** 449 /**
491 * Updates the user pod element. 450 * Updates the user pod element.
492 */ 451 */
493 update: function() { 452 update: function() {
494 this.imageElement.src = 'chrome://userimage/' + this.user.username + 453 this.imageElement.src = 'chrome://userimage/' + this.user.username +
495 '?id=' + UserPod.userImageSalt_[this.user.username]; 454 '?id=' + UserPod.userImageSalt_[this.user.username];
496 455
497 this.nameElement.textContent = this.user_.displayName; 456 this.nameElement.textContent = this.user_.displayName;
498 this.signedInIndicatorElement.hidden = !this.user_.signedIn; 457 this.classList.toggle('signed-in', this.user_.signedIn);
499 458
500 this.signinButtonElement.hidden = !this.isAuthTypeOnlineSignIn;
501 if (this.isAuthTypeUserClick) 459 if (this.isAuthTypeUserClick)
502 this.passwordLabelElement.textContent = this.authValue; 460 this.passwordLabelElement.textContent = this.authValue;
503 461
504 this.updateActionBoxArea(); 462 this.updateActionBoxArea();
505 463
506 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF( 464 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF(
507 'passwordFieldAccessibleName', this.user_.emailAddress)); 465 'passwordFieldAccessibleName', this.user_.emailAddress));
508 466
509 this.customizeUserPodPerUserType(); 467 this.customizeUserPodPerUserType();
510 }, 468 },
511 469
512 updateActionBoxArea: function() { 470 updateActionBoxArea: function() {
513 if (this.user_.publicAccount || this.user_.isApp) { 471 if (this.user_.publicAccount || this.user_.isApp) {
514 this.actionBoxAreaElement.hidden = true; 472 this.actionBoxAreaElement.hidden = true;
515 return; 473 return;
516 } 474 }
517 475
518 this.actionBoxAreaElement.hidden = false;
519 this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove; 476 this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
520 477
521 this.actionBoxAreaElement.setAttribute( 478 this.actionBoxAreaElement.setAttribute(
522 'aria-label', loadTimeData.getStringF( 479 'aria-label', loadTimeData.getStringF(
523 'podMenuButtonAccessibleName', this.user_.emailAddress)); 480 'podMenuButtonAccessibleName', this.user_.emailAddress));
524 this.actionBoxMenuRemoveElement.setAttribute( 481 this.actionBoxMenuRemoveElement.setAttribute(
525 'aria-label', loadTimeData.getString( 482 'aria-label', loadTimeData.getString(
526 'podMenuRemoveItemAccessibleName')); 483 'podMenuRemoveItemAccessibleName'));
527 this.actionBoxMenuTitleNameElement.textContent = this.user_.isOwner ? 484 this.actionBoxMenuTitleNameElement.textContent = this.user_.isOwner ?
528 loadTimeData.getStringF('ownerUserPattern', this.user_.displayName) : 485 loadTimeData.getStringF('ownerUserPattern', this.user_.displayName) :
529 this.user_.displayName; 486 this.user_.displayName;
530 this.actionBoxMenuTitleEmailElement.textContent = this.user_.emailAddress; 487 this.actionBoxMenuTitleEmailElement.textContent = this.user_.emailAddress;
531 this.actionBoxMenuTitleEmailElement.hidden = 488 this.actionBoxMenuTitleEmailElement.hidden =
532 this.user_.locallyManagedUser; 489 this.user_.locallyManagedUser;
533 490
534 this.actionBoxMenuCommandElement.textContent = 491 this.actionBoxMenuCommandElement.textContent =
535 loadTimeData.getString('removeUser'); 492 loadTimeData.getString('removeUser');
536 }, 493 },
537 494
538 customizeUserPodPerUserType: function() { 495 customizeUserPodPerUserType: function() {
539 if (this.user_.locallyManagedUser && !this.user_.isDesktopUser) { 496 if (this.user_.locallyManagedUser && !this.user_.isDesktopUser) {
540 this.setUserPodIconType('supervised'); 497 this.setUserPodIconType('supervised');
541 } else if (this.multiProfilesPolicyApplied) { 498 } else if (this.multiProfilesPolicyApplied) {
542 // Mark user pod as not focusable which in addition to the grayed out 499 // Mark user pod as not focusable which in addition to the grayed out
543 // filter makes it look in disabled state. 500 // filter makes it look in disabled state.
544 this.classList.add('multiprofiles-policy-applied'); 501 this.classList.add('multiprofiles-policy-applied');
545 this.setUserPodIconType('policy'); 502 this.setUserPodIconType('policy');
546 503
547 this.querySelector('.mp-policy-title').hidden = false;
548 if (this.user.multiProfilesPolicy == 'primary-only') 504 if (this.user.multiProfilesPolicy == 'primary-only')
549 this.querySelector('.mp-policy-primary-only-msg').hidden = false; 505 this.querySelector('.mp-policy-primary-only-msg').hidden = false;
550 else if (this.user.multiProfilesPolicy == 'owner-primary-only') 506 else if (this.user.multiProfilesPolicy == 'owner-primary-only')
551 this.querySelector('.mp-owner-primary-only-msg').hidden = false; 507 this.querySelector('.mp-owner-primary-only-msg').hidden = false;
552 else 508 else
553 this.querySelector('.mp-policy-not-allowed-msg').hidden = false; 509 this.querySelector('.mp-policy-not-allowed-msg').hidden = false;
554 } else if (this.user_.isApp) { 510 } else if (this.user_.isApp) {
555 this.setUserPodIconType('app'); 511 this.setUserPodIconType('app');
556 } 512 }
557 }, 513 },
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 */ 561 */
606 get isActionBoxMenuActive() { 562 get isActionBoxMenuActive() {
607 return this.actionBoxAreaElement.classList.contains('active'); 563 return this.actionBoxAreaElement.classList.contains('active');
608 }, 564 },
609 set isActionBoxMenuActive(active) { 565 set isActionBoxMenuActive(active) {
610 if (active == this.isActionBoxMenuActive) 566 if (active == this.isActionBoxMenuActive)
611 return; 567 return;
612 568
613 if (active) { 569 if (active) {
614 this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove; 570 this.actionBoxMenuRemoveElement.hidden = !this.user_.canRemove;
615 if (this.actionBoxRemoveUserWarningElement) 571 this.actionBoxRemoveUserWarningElement.hidden = true;
616 this.actionBoxRemoveUserWarningElement.hidden = true;
617 572
618 // Clear focus first if another pod is focused. 573 // Clear focus first if another pod is focused.
619 if (!this.parentNode.isFocused(this)) { 574 if (!this.parentNode.isFocused(this)) {
620 this.parentNode.focusPod(undefined, true); 575 this.parentNode.focusPod(undefined, true);
621 this.actionBoxAreaElement.focus(); 576 this.actionBoxAreaElement.focus();
622 } 577 }
623 578
624 // Hide user-type-bubble. 579 // Hide user-type-bubble.
625 this.userTypeBubbleElement.classList.remove('bubble-shown'); 580 this.userTypeBubbleElement.classList.remove('bubble-shown');
626 581
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 * Boolean flag of whether the pod is showing the side pane. The flag 982 * Boolean flag of whether the pod is showing the side pane. The flag
1028 * controls whether 'expanded' class is added to the pod's class list and 983 * controls whether 'expanded' class is added to the pod's class list and
1029 * resets tab order because main input element changes when the 'expanded' 984 * resets tab order because main input element changes when the 'expanded'
1030 * state changes. 985 * state changes.
1031 * @type {boolean} 986 * @type {boolean}
1032 */ 987 */
1033 get expanded() { 988 get expanded() {
1034 return this.classList.contains('expanded'); 989 return this.classList.contains('expanded');
1035 }, 990 },
1036 991
1037 /**
1038 * During transition final height of pod is not available because of
1039 * flexbox layout. That's why we have to calculate
1040 * the final height manually.
1041 */
1042 get expandedHeight_() {
1043 function getTopAndBottomPadding(domElement) {
1044 return parseInt(window.getComputedStyle(
1045 domElement).getPropertyValue('padding-top')) +
1046 parseInt(window.getComputedStyle(
1047 domElement).getPropertyValue('padding-bottom'));
1048 };
1049 var height =
1050 this.getElementsByClassName('side-pane-contents')[0].offsetHeight +
1051 this.getElementsByClassName('enter-button')[0].offsetHeight +
1052 getTopAndBottomPadding(
1053 this.getElementsByClassName('enter-button')[0]) +
1054 getTopAndBottomPadding(
1055 this.getElementsByClassName('side-pane-container')[0]) +
1056 getTopAndBottomPadding(this);
1057 return height;
1058 },
1059
1060 set expanded(expanded) { 992 set expanded(expanded) {
1061 if (this.expanded == expanded) 993 if (this.expanded == expanded)
1062 return; 994 return;
1063 995
1064 this.resetTabOrder(); 996 this.resetTabOrder();
1065 this.classList.toggle('expanded', expanded); 997 this.classList.toggle('expanded', expanded);
1066 if (expanded) { 998 if (expanded) {
1067 var isDesktopUserManager = Oobe.getInstance().displayType == 999 var isDesktopUserManager = Oobe.getInstance().displayType ==
1068 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 1000 DISPLAY_TYPE.DESKTOP_USER_MANAGER;
1069 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : 1001 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING :
1070 POD_ROW_PADDING; 1002 POD_ROW_PADDING;
1071 this.usualLeft = this.left; 1003 this.usualLeft = this.left;
1072 this.usualTop = this.top; 1004 this.usualTop = this.top;
1073 if (this.left + PUBLIC_EXPANDED_WIDTH > 1005 if (this.left + PUBLIC_EXPANDED_BASIC_WIDTH >
1074 $('pod-row').offsetWidth - rowPadding) 1006 $('pod-row').offsetWidth - rowPadding)
1075 this.left = $('pod-row').offsetWidth - rowPadding - 1007 this.left = $('pod-row').offsetWidth - rowPadding -
1076 PUBLIC_EXPANDED_WIDTH; 1008 PUBLIC_EXPANDED_BASIC_WIDTH;
1077 var expandedHeight = this.expandedHeight_;
1078 if (this.top + expandedHeight > $('pod-row').offsetHeight)
1079 this.top = $('pod-row').offsetHeight - expandedHeight;
1080 } else { 1009 } else {
1081 if (typeof(this.usualLeft) != 'undefined') 1010 if (typeof(this.usualLeft) != 'undefined')
1082 this.left = this.usualLeft; 1011 this.left = this.usualLeft;
1083 if (typeof(this.usualTop) != 'undefined') 1012 if (typeof(this.usualTop) != 'undefined')
1084 this.top = this.usualTop; 1013 this.top = this.usualTop;
1085 } 1014 }
1086 1015
1087 var self = this; 1016 var self = this;
1088 this.classList.add('animating'); 1017 this.classList.add('animating');
1089 this.addEventListener('webkitTransitionEnd', function f(e) { 1018 this.addEventListener('webkitTransitionEnd', function f(e) {
(...skipping 13 matching lines...) Expand all
1103 if (this.expanded) 1032 if (this.expanded)
1104 return this.enterButtonElement; 1033 return this.enterButtonElement;
1105 else 1034 else
1106 return this.nameElement; 1035 return this.nameElement;
1107 }, 1036 },
1108 1037
1109 /** @override */ 1038 /** @override */
1110 decorate: function() { 1039 decorate: function() {
1111 UserPod.prototype.decorate.call(this); 1040 UserPod.prototype.decorate.call(this);
1112 1041
1113 this.classList.remove('need-password');
1114 this.classList.add('public-account'); 1042 this.classList.add('public-account');
1115 1043
1116 this.nameElement.addEventListener('keydown', (function(e) { 1044 this.nameElement.addEventListener('keydown', (function(e) {
1117 if (e.keyIdentifier == 'Enter') { 1045 if (e.keyIdentifier == 'Enter') {
1118 this.parentNode.setActivatedPod(this, e); 1046 this.parentNode.setActivatedPod(this, e);
1119 // Stop this keydown event from bubbling up to PodRow handler. 1047 // Stop this keydown event from bubbling up to PodRow handler.
1120 e.stopPropagation(); 1048 e.stopPropagation();
1121 // Prevent default so that we don't trigger a 'click' event on the 1049 // Prevent default so that we don't trigger a 'click' event on the
1122 // newly focused "Enter" button. 1050 // newly focused "Enter" button.
1123 e.preventDefault(); 1051 e.preventDefault();
1124 } 1052 }
1125 }).bind(this)); 1053 }).bind(this));
1126 1054
1127 var learnMore = this.querySelector('.learn-more'); 1055 var learnMore = this.querySelector('.learn-more');
1128 learnMore.addEventListener('mousedown', stopEventPropagation); 1056 learnMore.addEventListener('mousedown', stopEventPropagation);
1129 learnMore.addEventListener('click', this.handleLearnMoreEvent); 1057 learnMore.addEventListener('click', this.handleLearnMoreEvent);
1130 learnMore.addEventListener('keydown', this.handleLearnMoreEvent); 1058 learnMore.addEventListener('keydown', this.handleLearnMoreEvent);
1131 1059
1132 learnMore = this.querySelector('.side-pane-learn-more'); 1060 learnMore = this.querySelector('.expanded-pane-learn-more');
1133 learnMore.addEventListener('click', this.handleLearnMoreEvent); 1061 learnMore.addEventListener('click', this.handleLearnMoreEvent);
1134 learnMore.addEventListener('keydown', this.handleLearnMoreEvent); 1062 learnMore.addEventListener('keydown', this.handleLearnMoreEvent);
1135 1063
1136 this.enterButtonElement.addEventListener('click', (function(e) { 1064 this.enterButtonElement.addEventListener('click', (function(e) {
1137 this.enterButtonElement.disabled = true; 1065 this.enterButtonElement.disabled = true;
1138 chrome.send('launchPublicAccount', [this.user.username]); 1066 chrome.send('launchPublicAccount', [this.user.username]);
1139 }).bind(this)); 1067 }).bind(this));
1140 }, 1068 },
1141 1069
1142 /** @override **/ 1070 /** @override **/
1143 update: function() { 1071 update: function() {
1144 UserPod.prototype.update.call(this); 1072 UserPod.prototype.update.call(this);
1145 this.querySelector('.side-pane-name').textContent = 1073 this.querySelector('.expanded-pane-name').textContent =
1146 this.user_.displayName; 1074 this.user_.displayName;
1147 this.querySelector('.info').textContent = 1075 this.querySelector('.info').textContent =
1148 loadTimeData.getStringF('publicAccountInfoFormat', 1076 loadTimeData.getStringF('publicAccountInfoFormat',
1149 this.user_.enterpriseDomain); 1077 this.user_.enterpriseDomain);
1150 }, 1078 },
1151 1079
1152 /** @override */ 1080 /** @override */
1153 focusInput: function() { 1081 focusInput: function() {
1154 // Move tabIndex from the whole pod to the main input. 1082 // Move tabIndex from the whole pod to the main input.
1155 this.tabIndex = -1; 1083 this.tabIndex = -1;
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 var node = $('user-pod-template').cloneNode(true); 1151 var node = $('user-pod-template').cloneNode(true);
1224 node.removeAttribute('id'); 1152 node.removeAttribute('id');
1225 return node; 1153 return node;
1226 }); 1154 });
1227 1155
1228 DesktopUserPod.prototype = { 1156 DesktopUserPod.prototype = {
1229 __proto__: UserPod.prototype, 1157 __proto__: UserPod.prototype,
1230 1158
1231 /** @override */ 1159 /** @override */
1232 get mainInput() { 1160 get mainInput() {
1233 if (!this.passwordElement.hidden) 1161 if (this.user.needsSignin)
1234 return this.passwordElement; 1162 return this.passwordElement;
1235 else 1163 else
1236 return this.nameElement; 1164 return this.nameElement;
1237 }, 1165 },
1238 1166
1239 /** @override */ 1167 /** @override */
1240 decorate: function() {
1241 UserPod.prototype.decorate.call(this);
1242 },
1243
1244 /** @override */
1245 update: function() { 1168 update: function() {
1246 this.imageElement.src = this.user.userImage; 1169 this.imageElement.src = this.user.userImage;
1247 this.nameElement.textContent = this.user.displayName; 1170 this.nameElement.textContent = this.user.displayName;
1248 1171
1249 var isLockedUser = this.user.needsSignin; 1172 var isLockedUser = this.user.needsSignin;
1250 var isSupervisedUser = this.user.locallyManagedUser; 1173 var isSupervisedUser = this.user.locallyManagedUser;
1251 this.signinButtonElement.hidden = true; 1174 this.classList.toggle('locked', isLockedUser);
1252 this.lockedIndicatorElement.hidden = !isLockedUser; 1175 this.classList.toggle('supervised-user', isSupervisedUser);
1253 this.supervisedUserIndicatorElement.hidden = !isSupervisedUser;
1254 this.passwordElement.hidden = !isLockedUser;
1255 this.nameElement.hidden = isLockedUser;
1256 1176
1257 if (this.isAuthTypeUserClick) 1177 if (this.isAuthTypeUserClick)
1258 this.passwordLabelElement.textContent = this.authValue; 1178 this.passwordLabelElement.textContent = this.authValue;
1259 1179
1260 this.actionBoxRemoveUserWarningTextElement.hidden = isSupervisedUser; 1180 this.actionBoxRemoveUserWarningTextElement.hidden = isSupervisedUser;
1261 this.actionBoxRemoveSupervisedUserWarningTextElement.hidden = 1181 this.actionBoxRemoveSupervisedUserWarningTextElement.hidden =
1262 !isSupervisedUser; 1182 !isSupervisedUser;
1263 1183
1264 UserPod.prototype.updateActionBoxArea.call(this); 1184 UserPod.prototype.updateActionBoxArea.call(this);
1265 }, 1185 },
1266 1186
1267 /** @override */ 1187 /** @override */
1268 focusInput: function() { 1188 focusInput: function() {
1269 // For focused pods, display the name unless the pod is locked.
1270 var isLockedUser = this.user.needsSignin;
1271 var isSupervisedUser = this.user.locallyManagedUser;
1272 this.signinButtonElement.hidden = true;
1273 this.lockedIndicatorElement.hidden = !isLockedUser;
1274 this.supervisedUserIndicatorElement.hidden = !isSupervisedUser;
1275 this.passwordElement.hidden = !isLockedUser;
1276 this.nameElement.hidden = isLockedUser;
1277
1278 // Move tabIndex from the whole pod to the main input. 1189 // Move tabIndex from the whole pod to the main input.
1279 this.tabIndex = -1; 1190 this.tabIndex = -1;
1280 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT; 1191 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT;
1281 this.mainInput.focus(); 1192 this.mainInput.focus();
1282 }, 1193 },
1283 1194
1284 /** @override */ 1195 /** @override */
1285 reset: function(takeFocus) {
1286 // Always display the user's name for unfocused pods.
1287 if (!takeFocus)
1288 this.nameElement.hidden = false;
1289 UserPod.prototype.reset.call(this, takeFocus);
1290 },
1291
1292 /** @override */
1293 activate: function(e) { 1196 activate: function(e) {
1294 if (this.passwordElement.hidden) { 1197 if (!this.user.needsSignin) {
1295 Oobe.launchUser(this.user.emailAddress, this.user.displayName); 1198 Oobe.launchUser(this.user.emailAddress, this.user.displayName);
1296 } else if (!this.passwordElement.value) { 1199 } else if (!this.passwordElement.value) {
1297 return false; 1200 return false;
1298 } else { 1201 } else {
1299 chrome.send('authenticatedLaunchUser', 1202 chrome.send('authenticatedLaunchUser',
1300 [this.user.emailAddress, 1203 [this.user.emailAddress,
1301 this.user.displayName, 1204 this.user.displayName,
1302 this.passwordElement.value]); 1205 this.passwordElement.value]);
1303 } 1206 }
1304 this.passwordElement.value = ''; 1207 this.passwordElement.value = '';
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 /** @override */ 1242 /** @override */
1340 decorate: function() { 1243 decorate: function() {
1341 UserPod.prototype.decorate.call(this); 1244 UserPod.prototype.decorate.call(this);
1342 this.launchAppButtonElement.addEventListener('click', 1245 this.launchAppButtonElement.addEventListener('click',
1343 this.activate.bind(this)); 1246 this.activate.bind(this));
1344 }, 1247 },
1345 1248
1346 /** @override */ 1249 /** @override */
1347 update: function() { 1250 update: function() {
1348 this.imageElement.src = this.user.iconUrl; 1251 this.imageElement.src = this.user.iconUrl;
1349 if (this.user.iconHeight && this.user.iconWidth) {
1350 this.imageElement.style.height = this.user.iconHeight;
1351 this.imageElement.style.width = this.user.iconWidth;
1352 }
1353 this.imageElement.alt = this.user.label; 1252 this.imageElement.alt = this.user.label;
1354 this.imageElement.title = this.user.label; 1253 this.imageElement.title = this.user.label;
1355 this.passwordElement.hidden = true; 1254 this.passwordEntryContainerElement.hidden = true;
1356 this.signinButtonElement.hidden = true; 1255 this.launchAppButtonContainerElement.hidden = false;
1357 this.launchAppButtonElement.hidden = false;
1358 this.signedInIndicatorElement.hidden = true;
1359 this.nameElement.textContent = this.user.label; 1256 this.nameElement.textContent = this.user.label;
1360 1257
1361 UserPod.prototype.updateActionBoxArea.call(this); 1258 UserPod.prototype.updateActionBoxArea.call(this);
1362 UserPod.prototype.customizeUserPodPerUserType.call(this); 1259 UserPod.prototype.customizeUserPodPerUserType.call(this);
1363 }, 1260 },
1364 1261
1365 /** @override */ 1262 /** @override */
1366 get mainInput() { 1263 get mainInput() {
1367 return this.launchAppButtonElement; 1264 return this.launchAppButtonElement;
1368 }, 1265 },
1369 1266
1370 /** @override */ 1267 /** @override */
1371 focusInput: function() { 1268 focusInput: function() {
1372 this.signinButtonElement.hidden = true;
1373 this.launchAppButtonElement.hidden = false;
1374 this.passwordElement.hidden = true;
1375
1376 // Move tabIndex from the whole pod to the main input. 1269 // Move tabIndex from the whole pod to the main input.
1377 this.tabIndex = -1; 1270 this.tabIndex = -1;
1378 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT; 1271 this.mainInput.tabIndex = UserPodTabOrder.POD_INPUT;
1379 this.mainInput.focus(); 1272 this.mainInput.focus();
1380 }, 1273 },
1381 1274
1382 /** @override */ 1275 /** @override */
1383 get forceOnlineSignin() { 1276 get forceOnlineSignin() {
1384 return false; 1277 return false;
1385 }, 1278 },
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 1346
1454 // Activated pod, i.e. the pod of current login attempt. 1347 // Activated pod, i.e. the pod of current login attempt.
1455 activatedPod_: undefined, 1348 activatedPod_: undefined,
1456 1349
1457 // Pod that was most recently focused, if any. 1350 // Pod that was most recently focused, if any.
1458 lastFocusedPod_: undefined, 1351 lastFocusedPod_: undefined,
1459 1352
1460 // Pods whose initial images haven't been loaded yet. 1353 // Pods whose initial images haven't been loaded yet.
1461 podsWithPendingImages_: [], 1354 podsWithPendingImages_: [],
1462 1355
1463 // Whether pod creation is animated.
1464 userAddIsAnimated_: false,
1465
1466 // Whether pod placement has been postponed. 1356 // Whether pod placement has been postponed.
1467 podPlacementPostponed_: false, 1357 podPlacementPostponed_: false,
1468 1358
1469 // Standard user pod height/width. 1359 // Standard user pod height/width.
1470 userPodHeight_: 0, 1360 userPodHeight_: 0,
1471 userPodWidth_: 0, 1361 userPodWidth_: 0,
1472 1362
1473 // Array of apps that are shown in addition to other user pods. 1363 // Array of apps that are shown in addition to other user pods.
1474 apps_: [], 1364 apps_: [],
1475 1365
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1577 else 1467 else
1578 userPod = new UserPod({user: user}); 1468 userPod = new UserPod({user: user});
1579 1469
1580 userPod.hidden = false; 1470 userPod.hidden = false;
1581 return userPod; 1471 return userPod;
1582 }, 1472 },
1583 1473
1584 /** 1474 /**
1585 * Add an existing user pod to this pod row. 1475 * Add an existing user pod to this pod row.
1586 * @param {!Object} user User info dictionary. 1476 * @param {!Object} user User info dictionary.
1587 * @param {boolean} animated Whether to use init animation.
1588 */ 1477 */
1589 addUserPod: function(user, animated) { 1478 addUserPod: function(user) {
1590 var userPod = this.createUserPod(user); 1479 var userPod = this.createUserPod(user);
1591 if (animated) {
1592 userPod.classList.add('init');
1593 userPod.nameElement.classList.add('init');
1594 }
1595
1596 this.appendChild(userPod); 1480 this.appendChild(userPod);
1597 userPod.initialize(); 1481 userPod.initialize();
1598 }, 1482 },
1599 1483
1600 /** 1484 /**
1601 * Runs app with a given id from the list of loaded apps. 1485 * Runs app with a given id from the list of loaded apps.
1602 * @param {!string} app_id of an app to run. 1486 * @param {!string} app_id of an app to run.
1603 * @param {boolean=} opt_diagnostic_mode Whether to run the app in 1487 * @param {boolean=} opt_diagnostic_mode Whether to run the app in
1604 * diagnostic mode. Default is false. 1488 * diagnostic mode. Default is false.
1605 */ 1489 */
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 */ 1521 */
1638 indexOf_: function(pod) { 1522 indexOf_: function(pod) {
1639 for (var i = 0; i < this.pods.length; ++i) { 1523 for (var i = 0; i < this.pods.length; ++i) {
1640 if (pod == this.pods[i]) 1524 if (pod == this.pods[i])
1641 return i; 1525 return i;
1642 } 1526 }
1643 return -1; 1527 return -1;
1644 }, 1528 },
1645 1529
1646 /** 1530 /**
1647 * Start first time show animation.
1648 */
1649 startInitAnimation: function() {
1650 // Schedule init animation.
1651 for (var i = 0, pod; pod = this.pods[i]; ++i) {
1652 window.setTimeout(removeClass, 500 + i * 70, pod, 'init');
1653 window.setTimeout(removeClass, 700 + i * 70, pod.nameElement, 'init');
1654 }
1655 },
1656
1657 /**
1658 * Start login success animation.
1659 */
1660 startAuthenticatedAnimation: function() {
1661 var activated = this.indexOf_(this.activatedPod_);
1662 if (activated == -1)
1663 return;
1664
1665 for (var i = 0, pod; pod = this.pods[i]; ++i) {
1666 if (i < activated)
1667 pod.classList.add('left');
1668 else if (i > activated)
1669 pod.classList.add('right');
1670 else
1671 pod.classList.add('zoom');
1672 }
1673 },
1674
1675 /**
1676 * Populates pod row with given existing users and start init animation. 1531 * Populates pod row with given existing users and start init animation.
1677 * @param {array} users Array of existing user emails. 1532 * @param {array} users Array of existing user emails.
1678 * @param {boolean} animated Whether to use init animation.
1679 */ 1533 */
1680 loadPods: function(users, animated) { 1534 loadPods: function(users) {
1681 this.users_ = users; 1535 this.users_ = users;
1682 this.userAddIsAnimated_ = animated;
1683 1536
1684 this.rebuildPods(); 1537 this.rebuildPods();
1685 }, 1538 },
1686 1539
1687 /** 1540 /**
1688 * Scrolls focused user pod into view. 1541 * Scrolls focused user pod into view.
1689 */ 1542 */
1690 scrollFocusedPodIntoView: function() { 1543 scrollFocusedPodIntoView: function() {
1691 var pod = this.focusedPod_; 1544 var pod = this.focusedPod_;
1692 if (!pod) 1545 if (!pod)
(...skipping 25 matching lines...) Expand all
1718 this.innerHTML = ''; 1571 this.innerHTML = '';
1719 this.focusedPod_ = undefined; 1572 this.focusedPod_ = undefined;
1720 this.activatedPod_ = undefined; 1573 this.activatedPod_ = undefined;
1721 this.lastFocusedPod_ = undefined; 1574 this.lastFocusedPod_ = undefined;
1722 1575
1723 // Switch off animation 1576 // Switch off animation
1724 Oobe.getInstance().toggleClass('flying-pods', false); 1577 Oobe.getInstance().toggleClass('flying-pods', false);
1725 1578
1726 // Populate the pod row. 1579 // Populate the pod row.
1727 for (var i = 0; i < this.users_.length; ++i) 1580 for (var i = 0; i < this.users_.length; ++i)
1728 this.addUserPod(this.users_[i], this.userAddIsAnimated_); 1581 this.addUserPod(this.users_[i]);
1729 1582
1730 for (var i = 0, pod; pod = this.pods[i]; ++i) 1583 for (var i = 0, pod; pod = this.pods[i]; ++i)
1731 this.podsWithPendingImages_.push(pod); 1584 this.podsWithPendingImages_.push(pod);
1732 1585
1733 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. 1586 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting.
1734 if (this.shouldShowApps_) { 1587 if (this.shouldShowApps_) {
1735 for (var i = 0; i < this.apps_.length; ++i) 1588 for (var i = 0; i < this.apps_.length; ++i)
1736 this.addUserPod(this.apps_[i], this.userAddIsAnimated_); 1589 this.addUserPod(this.apps_[i]);
1737 } 1590 }
1738 1591
1739 // Make sure we eventually show the pod row, even if some image is stuck. 1592 // Make sure we eventually show the pod row, even if some image is stuck.
1740 setTimeout(function() { 1593 setTimeout(function() {
1741 $('pod-row').classList.remove('images-loading'); 1594 $('pod-row').classList.remove('images-loading');
1742 }, POD_ROW_IMAGES_LOAD_TIMEOUT_MS); 1595 }, POD_ROW_IMAGES_LOAD_TIMEOUT_MS);
1743 1596
1744 var isCrosAccountPicker = $('login-header-bar').signinUIState == 1597 var isCrosAccountPicker = $('login-header-bar').signinUIState ==
1745 SIGNIN_UI_STATE.ACCOUNT_PICKER; 1598 SIGNIN_UI_STATE.ACCOUNT_PICKER;
1746 var isDesktopUserManager = Oobe.getInstance().displayType == 1599 var isDesktopUserManager = Oobe.getInstance().displayType ==
(...skipping 693 matching lines...) Expand 10 before | Expand all | Expand 10 after
2440 if (this.podsWithPendingImages_.length == 0) { 2293 if (this.podsWithPendingImages_.length == 0) {
2441 this.classList.remove('images-loading'); 2294 this.classList.remove('images-loading');
2442 } 2295 }
2443 } 2296 }
2444 }; 2297 };
2445 2298
2446 return { 2299 return {
2447 PodRow: PodRow 2300 PodRow: PodRow
2448 }; 2301 };
2449 }); 2302 });
OLDNEW
« no previous file with comments | « chrome/browser/resources/login/user_pod_row.css ('k') | chrome/browser/resources/login/user_pod_template.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698