Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 /** |
| 11 * Number of displayed columns depending on user pod count. | |
| 12 * @type {Array<number>} | |
| 13 * @const | |
| 14 */ | |
| 15 var COLUMNS = [0, 1, 2, 3, 4, 5, 4, 4, 4, 5, 5, 6, 6, 5, 5, 6, 6, 6, 6]; | |
| 16 | |
| 17 /** | |
| 18 * Mapping between number of columns in pod-row and margin between user pods | |
| 19 * for such layout. | |
| 20 * @type {Array<number>} | |
| 21 * @const | |
| 22 */ | |
| 23 var MARGIN_BY_COLUMNS = [undefined, 40, 40, 40, 40, 40, 12]; | |
| 24 | |
| 25 /** | |
| 26 * Mapping between number of columns in the desktop pod-row and margin | |
| 27 * between user pods for such layout. | |
| 28 * @type {Array<number>} | |
| 29 * @const | |
| 30 */ | |
| 31 var DESKTOP_MARGIN_BY_COLUMNS = [undefined, 32, 32, 32, 32, 32, 32]; | |
| 32 | |
| 33 /** | |
| 34 * Maximal number of columns currently supported by pod-row. | |
| 35 * @type {number} | |
| 36 * @const | |
| 37 */ | |
| 38 var MAX_NUMBER_OF_COLUMNS = 6; | |
| 39 | |
| 40 /** | |
| 41 * Maximal number of rows if sign-in banner is displayed alonside. | |
| 42 * @type {number} | |
| 43 * @const | |
| 44 */ | |
| 45 var MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER = 2; | |
| 46 | |
| 47 /** | |
| 48 * Variables used for pod placement processing. Width and height should be | 11 * Variables used for pod placement processing. Width and height should be |
| 49 * synced with computed CSS sizes of pods. | 12 * synced with computed CSS sizes of pods. |
| 50 */ | 13 */ |
| 51 var CROS_POD_WIDTH = 306; | 14 var CROS_POD_WIDTH = 306; |
| 52 var CROS_SMALL_POD_WIDTH = 304; | 15 var CROS_SMALL_POD_WIDTH = 304; |
| 53 var CROS_EXTRA_SMALL_POD_WIDTH = 282; | 16 var CROS_EXTRA_SMALL_POD_WIDTH = 282; |
| 54 var DESKTOP_POD_WIDTH = 180; | 17 var DESKTOP_POD_WIDTH = 180; |
| 55 var MD_DESKTOP_POD_WIDTH = 160; | 18 var MD_DESKTOP_POD_WIDTH = 160; |
| 56 var PUBLIC_EXPANDED_BASIC_WIDTH = 500; | 19 var PUBLIC_EXPANDED_BASIC_WIDTH = 500; |
| 57 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610; | 20 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610; |
| 58 var CROS_POD_HEIGHT = 346; | 21 var CROS_POD_HEIGHT = 346; |
| 59 var CROS_SMALL_POD_HEIGHT = 74; | 22 var CROS_SMALL_POD_HEIGHT = 74; |
| 60 var CROS_EXTRA_SMALL_POD_HEIGHT = 60; | 23 var CROS_EXTRA_SMALL_POD_HEIGHT = 60; |
| 61 var DESKTOP_POD_HEIGHT = 226; | 24 var DESKTOP_POD_HEIGHT = 226; |
| 62 var MD_DESKTOP_POD_HEIGHT = 200; | 25 var MD_DESKTOP_POD_HEIGHT = 200; |
| 63 var POD_ROW_PADDING = 10; | 26 var POD_ROW_PADDING = 10; |
| 64 var DESKTOP_ROW_PADDING = 32; | 27 var DESKTOP_ROW_PADDING = 32; |
| 65 var CUSTOM_ICON_CONTAINER_SIZE = 40; | 28 var CUSTOM_ICON_CONTAINER_SIZE = 40; |
| 66 var CROS_PIN_POD_HEIGHT = 417; | 29 var CROS_PIN_POD_HEIGHT = 417; |
| 67 var SCROLL_MASK_HEIGHT = 112; | 30 var SCROLL_MASK_HEIGHT = 112; |
| 31 var BANNER_MESSAGE_WIDTH = 520; | |
| 68 | 32 |
| 69 /** | 33 /** |
| 70 * The maximum number of users that each pod placement method can handle. | 34 * The maximum number of users that each pod placement method can handle. |
| 71 */ | 35 */ |
| 72 var POD_ROW_LIMIT = 2; | 36 var POD_ROW_LIMIT = 2; |
| 73 var LANDSCAPE_MODE_LIMIT = 6; | 37 var LANDSCAPE_MODE_LIMIT = 6; |
| 74 var PORTRAIT_MODE_LIMIT = 9; | 38 var PORTRAIT_MODE_LIMIT = 9; |
| 75 | 39 |
| 76 /** | 40 /** |
| 77 * Minimal padding between user pod and virtual keyboard. | 41 * Minimal padding between user pod and virtual keyboard. |
| (...skipping 899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 977 */ | 941 */ |
| 978 get nameElement() { | 942 get nameElement() { |
| 979 return this.querySelector('.name'); | 943 return this.querySelector('.name'); |
| 980 }, | 944 }, |
| 981 | 945 |
| 982 /** | 946 /** |
| 983 * Gets image element of the small pod. | 947 * Gets image element of the small pod. |
| 984 * @type {!HTMLImageElement} | 948 * @type {!HTMLImageElement} |
| 985 */ | 949 */ |
| 986 get smallPodImageElement() { | 950 get smallPodImageElement() { |
| 987 return this.querySelector('.small-pod-image'); | 951 return this.querySelector('.user-image.small-pod-image'); |
| 988 }, | 952 }, |
| 989 | 953 |
| 990 /** | 954 /** |
| 991 * Gets name element of the small pod. | 955 * Gets name element of the small pod. |
| 992 * @type {!HTMLDivElement} | 956 * @type {!HTMLDivElement} |
| 993 */ | 957 */ |
| 994 get smallPodNameElement() { | 958 get smallPodNameElement() { |
| 995 return this.querySelector('.small-pod-name'); | 959 return this.querySelector('.small-pod-name'); |
| 996 }, | 960 }, |
| 997 | 961 |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1409 } | 1373 } |
| 1410 | 1374 |
| 1411 // Hide user-type-bubble. | 1375 // Hide user-type-bubble. |
| 1412 this.userTypeBubbleElement.classList.remove('bubble-shown'); | 1376 this.userTypeBubbleElement.classList.remove('bubble-shown'); |
| 1413 | 1377 |
| 1414 this.actionBoxAreaElement.classList.add('active'); | 1378 this.actionBoxAreaElement.classList.add('active'); |
| 1415 | 1379 |
| 1416 // Invisible focus causes ChromeVox to read user name and email. | 1380 // Invisible focus causes ChromeVox to read user name and email. |
| 1417 this.actionBoxMenuTitleElement.tabIndex = UserPodTabOrder.POD_MENU_ITEM; | 1381 this.actionBoxMenuTitleElement.tabIndex = UserPodTabOrder.POD_MENU_ITEM; |
| 1418 this.actionBoxMenuTitleElement.focus(); | 1382 this.actionBoxMenuTitleElement.focus(); |
| 1419 | |
| 1420 // If the user pod is on either edge of the screen, then the menu | |
| 1421 // could be displayed partially ofscreen. | |
| 1422 this.actionBoxMenu.classList.remove('left-edge-offset'); | |
| 1423 this.actionBoxMenu.classList.remove('right-edge-offset'); | |
| 1424 | |
| 1425 var offsetLeft = | |
| 1426 cr.ui.login.DisplayManager.getOffset(this.actionBoxMenu).left; | |
| 1427 var menuWidth = this.actionBoxMenu.offsetWidth; | |
| 1428 if (offsetLeft < 0) | |
| 1429 this.actionBoxMenu.classList.add('left-edge-offset'); | |
| 1430 else if (offsetLeft + menuWidth > window.innerWidth) | |
| 1431 this.actionBoxMenu.classList.add('right-edge-offset'); | |
| 1432 } else { | 1383 } else { |
| 1433 this.actionBoxAreaElement.classList.remove('active'); | 1384 this.actionBoxAreaElement.classList.remove('active'); |
| 1434 this.actionBoxAreaElement.classList.remove('menu-moved-up'); | 1385 this.actionBoxAreaElement.classList.remove('menu-moved-up'); |
| 1435 this.actionBoxMenu.classList.remove('menu-moved-up'); | 1386 this.actionBoxMenu.classList.remove('menu-moved-up'); |
| 1436 } | 1387 } |
| 1437 }, | 1388 }, |
| 1438 | 1389 |
| 1439 /** | 1390 /** |
| 1440 * Whether action box button is in hovered state. | 1391 * Whether action box button is in hovered state. |
| 1441 * @type {boolean} | 1392 * @type {boolean} |
| (...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2128 * @param {Event} e Click event. | 2079 * @param {Event} e Click event. |
| 2129 */ | 2080 */ |
| 2130 handleClickOnPod_: function(e) { | 2081 handleClickOnPod_: function(e) { |
| 2131 if (this.parentNode.disabled) | 2082 if (this.parentNode.disabled) |
| 2132 return; | 2083 return; |
| 2133 | 2084 |
| 2134 if (this.getPodStyle() != UserPod.Style.LARGE) { | 2085 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2135 $('pod-row').switchMainPod(this); | 2086 $('pod-row').switchMainPod(this); |
| 2136 return; | 2087 return; |
| 2137 } | 2088 } |
| 2089 Oobe.clearErrors(); | |
| 2138 | 2090 |
| 2139 if (!this.isActionBoxMenuActive) { | 2091 if (!this.isActionBoxMenuActive) { |
| 2140 if (this.isAuthTypeOnlineSignIn) { | 2092 if (this.isAuthTypeOnlineSignIn) { |
| 2141 this.showSigninUI(); | 2093 this.showSigninUI(); |
| 2142 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { | 2094 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { |
| 2143 // Note that this.userClickAuthAllowed_ is set in mouse down event | 2095 // Note that this.userClickAuthAllowed_ is set in mouse down event |
| 2144 // handler. | 2096 // handler. |
| 2145 this.parentNode.setActivatedPod(this); | 2097 this.parentNode.setActivatedPod(this); |
| 2146 } else if (this.pinKeyboard && | 2098 } else if (this.pinKeyboard && |
| 2147 e.target == this.pinKeyboard.submitButton) { | 2099 e.target == this.pinKeyboard.submitButton) { |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2400 | 2352 |
| 2401 /** @override */ | 2353 /** @override */ |
| 2402 handleClickOnPod_: function(e) { | 2354 handleClickOnPod_: function(e) { |
| 2403 if (this.parentNode.disabled) | 2355 if (this.parentNode.disabled) |
| 2404 return; | 2356 return; |
| 2405 | 2357 |
| 2406 if (this.getPodStyle() != UserPod.Style.LARGE) { | 2358 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2407 $('pod-row').switchMainPod(this); | 2359 $('pod-row').switchMainPod(this); |
| 2408 return; | 2360 return; |
| 2409 } | 2361 } |
| 2362 Oobe.clearErrors(); | |
| 2410 | 2363 |
| 2411 this.parentNode.focusPod(this); | 2364 this.parentNode.focusPod(this); |
| 2412 this.parentNode.setActivatedPod(this, e); | 2365 this.parentNode.setActivatedPod(this, e); |
| 2413 // Prevent default so that we don't trigger 'focus' event. | 2366 // Prevent default so that we don't trigger 'focus' event. |
| 2414 e.preventDefault(); | 2367 e.preventDefault(); |
| 2415 }, | 2368 }, |
| 2416 | 2369 |
| 2417 /** | 2370 /** |
| 2418 * Updates the display name shown on the pod. | 2371 * Updates the display name shown on the pod. |
| 2419 * @param {string} displayName The new display name | 2372 * @param {string} displayName The new display name |
| (...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2861 | 2814 |
| 2862 // True to show app pods along with user pods. | 2815 // True to show app pods along with user pods. |
| 2863 shouldShowApps_: true, | 2816 shouldShowApps_: true, |
| 2864 | 2817 |
| 2865 // Array of users that are shown (public/supervised/regular). | 2818 // Array of users that are shown (public/supervised/regular). |
| 2866 users_: [], | 2819 users_: [], |
| 2867 | 2820 |
| 2868 // If we're in Touch View mode. | 2821 // If we're in Touch View mode. |
| 2869 touchViewEnabled_: false, | 2822 touchViewEnabled_: false, |
| 2870 | 2823 |
| 2824 // If testing mode is enabled. | |
| 2825 testingModeEnabled_: false, | |
| 2826 | |
| 2871 /** @override */ | 2827 /** @override */ |
| 2872 decorate: function() { | 2828 decorate: function() { |
| 2873 // Event listeners that are installed for the time period during which | 2829 // Event listeners that are installed for the time period during which |
| 2874 // the element is visible. | 2830 // the element is visible. |
| 2875 this.listeners_ = { | 2831 this.listeners_ = { |
| 2876 focus: [this.handleFocus_.bind(this), true /* useCapture */], | 2832 focus: [this.handleFocus_.bind(this), true /* useCapture */], |
| 2877 click: [this.handleClick_.bind(this), true], | 2833 click: [this.handleClick_.bind(this), true], |
| 2878 mousemove: [this.handleMouseMove_.bind(this), false], | 2834 mousemove: [this.handleMouseMove_.bind(this), false], |
| 2879 keydown: [this.handleKeyDown.bind(this), false] | 2835 keydown: [this.handleKeyDown.bind(this), false] |
| 2880 }; | 2836 }; |
| (...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3496 var pod = this.getPodWithUsername_(userID); | 3452 var pod = this.getPodWithUsername_(userID); |
| 3497 if (pod != null) | 3453 if (pod != null) |
| 3498 pod.populateKeyboardSelect(locale, list); | 3454 pod.populateKeyboardSelect(locale, list); |
| 3499 }, | 3455 }, |
| 3500 | 3456 |
| 3501 /** | 3457 /** |
| 3502 * Called when window was resized. The two common use cases are changing | 3458 * Called when window was resized. The two common use cases are changing |
| 3503 * screen orientation and showing the virtual keyboard. | 3459 * screen orientation and showing the virtual keyboard. |
| 3504 */ | 3460 */ |
| 3505 onWindowResize: function() { | 3461 onWindowResize: function() { |
| 3506 var screen = document.querySelector('#scroll-container'); | |
| 3507 var clientArea = document.querySelector('#inner-container'); | |
| 3508 if (Oobe.getInstance().virtualKeyboardShown) { | |
| 3509 // Edge case: when virtual keyboard is shown, although the screen size | |
| 3510 // is reduced properly, the size of the outer container remains the | |
| 3511 // same because its min-height is applied. Users can scroll the screen | |
| 3512 // upward and see empty areas beyond the pod row and the scroll bar, | |
| 3513 // which should be avoided. | |
| 3514 // This is a hacky solution: we can make the scroll container hide | |
| 3515 // the overflow area and manully position the client area. | |
| 3516 screen.style.overflowY = "hidden"; | |
| 3517 clientArea.style.position = "absolute"; | |
| 3518 clientArea.style.left = cr.ui.toCssPx(0); | |
| 3519 clientArea.style.top = cr.ui.toCssPx(0); | |
| 3520 } else { | |
| 3521 // Sets the values to default when virtual keyboard is not shown. | |
| 3522 screen.style.overflowY = "auto"; | |
| 3523 clientArea.style.position = "relative"; | |
| 3524 } | |
| 3525 this.placePods_(); | 3462 this.placePods_(); |
| 3526 }, | 3463 }, |
| 3527 | 3464 |
| 3528 /** | 3465 /** |
| 3529 * Returns width of podrow having |columns| number of columns. | |
| 3530 * @private | |
| 3531 */ | |
| 3532 columnsToWidth_: function(columns) { | |
| 3533 var isDesktopUserManager = Oobe.getInstance().displayType == | |
| 3534 DISPLAY_TYPE.DESKTOP_USER_MANAGER; | |
| 3535 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : | |
| 3536 MARGIN_BY_COLUMNS[columns]; | |
| 3537 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : | |
| 3538 POD_ROW_PADDING; | |
| 3539 return 2 * rowPadding + columns * this.userPodWidth_ + | |
| 3540 (columns - 1) * margin; | |
| 3541 }, | |
| 3542 | |
| 3543 /** | |
| 3544 * Returns height of podrow having |rows| number of rows. | |
| 3545 * @private | |
| 3546 */ | |
| 3547 rowsToHeight_: function(rows) { | |
| 3548 var isDesktopUserManager = Oobe.getInstance().displayType == | |
| 3549 DISPLAY_TYPE.DESKTOP_USER_MANAGER; | |
| 3550 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : | |
| 3551 POD_ROW_PADDING; | |
| 3552 return 2 * rowPadding + rows * this.userPodHeight_; | |
| 3553 }, | |
| 3554 | |
| 3555 /** | |
| 3556 * Calculates number of columns and rows that podrow should have in order to | |
| 3557 * hold as much its pods as possible for current screen size. Also it tries | |
| 3558 * to choose layout that looks good. | |
| 3559 * @return {{columns: number, rows: number}} | |
| 3560 */ | |
| 3561 calculateLayout_: function() { | |
| 3562 var preferredColumns = this.pods.length < COLUMNS.length ? | |
| 3563 COLUMNS[this.pods.length] : COLUMNS[COLUMNS.length - 1]; | |
| 3564 var maxWidth = Oobe.getInstance().clientAreaSize.width; | |
| 3565 var columns = preferredColumns; | |
| 3566 while (maxWidth < this.columnsToWidth_(columns) && columns > 1) | |
| 3567 --columns; | |
| 3568 var rows = Math.floor((this.pods.length - 1) / columns) + 1; | |
| 3569 if (getComputedStyle( | |
| 3570 $('signin-banner'), null).getPropertyValue('display') != 'none') { | |
| 3571 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER); | |
| 3572 } | |
| 3573 if (!Oobe.getInstance().newDesktopUserManager) { | |
| 3574 var maxHeigth = Oobe.getInstance().clientAreaSize.height; | |
| 3575 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1) | |
| 3576 --rows; | |
| 3577 } | |
| 3578 // One more iteration if it's not enough cells to place all pods. | |
| 3579 while (maxWidth >= this.columnsToWidth_(columns + 1) && | |
| 3580 columns * rows < this.pods.length && | |
| 3581 columns < MAX_NUMBER_OF_COLUMNS) { | |
| 3582 ++columns; | |
| 3583 } | |
| 3584 return {columns: columns, rows: rows}; | |
| 3585 }, | |
| 3586 | |
| 3587 /** | |
| 3588 * Places pods onto their positions in pod grid matching the new design. | 3466 * Places pods onto their positions in pod grid matching the new design. |
| 3589 * @private | 3467 * @private |
| 3590 */ | 3468 */ |
| 3591 placePods_: function() { | 3469 placePods_: function() { |
| 3592 var pods = this.pods; | 3470 var pods = this.pods; |
| 3593 if (pods.length == 0) { | 3471 if (pods.length == 0) { |
| 3594 console.error('Attempt to place pods for an empty pod list.'); | 3472 console.error('Attempt to place pods for an empty pod list.'); |
| 3595 return; | 3473 return; |
| 3596 } | 3474 } |
| 3597 // Append all pods to their proper parents. Small pods have parent other | 3475 // Appends all pods to their proper parents. Small pods have parent other |
| 3598 // than the pod row. The pods were all initialized with the pow row as a | 3476 // than the pod row. The pods were all initialized with the pow row as a |
| 3599 // temporary parent, which is intended to ensure that all event listeners | 3477 // temporary parent, which is intended to ensure that all event listeners |
| 3600 // work properly. If the main pod already exists, it means we are in the | 3478 // work properly. If the main pod already exists, it means we are in the |
| 3601 // process of resizing the window, then there is no need to change parents | 3479 // process of resizing the window, then there is no need to change parents |
| 3602 // of any pod. | 3480 // of any pod. |
| 3603 if (!this.mainPod_) { | 3481 if (!this.mainPod_) { |
| 3604 this.mainPod_ = this.preselectedPod; | 3482 this.mainPod_ = this.preselectedPod; |
| 3605 this.appendPodsToParents(); | 3483 this.appendPodsToParents_(); |
| 3606 } | 3484 } |
| 3607 this.restoreInitialStates_(); | 3485 this.restoreInitialStates_(); |
| 3608 if (Oobe.getInstance().virtualKeyboardShown) { | 3486 this.hideEmptyArea_(); |
| 3487 // Clear error bubbles whenever pod placement is happening, i.e., after | |
| 3488 // orientation change, showing or hiding virtual keyboard, and user | |
| 3489 // removal. | |
| 3490 Oobe.clearErrors(); | |
| 3491 | |
| 3492 if (this.isScreenShrinked_()) { | |
| 3609 // When virtual keyboard is shown, the account picker should occupy | 3493 // When virtual keyboard is shown, the account picker should occupy |
| 3610 // all the remaining screen. Screen size was already updated to exclude | 3494 // all the remaining screen. Screen size was already updated to exclude |
| 3611 // the virtual keyboard. | 3495 // the virtual keyboard. |
| 3612 this.parentNode.setPreferredSize( | 3496 this.parentNode.setPreferredSize(this.screenSize.width, |
| 3613 this.screenSize.width, | 3497 this.screenSize.height); |
| 3614 this.screenSize.height); | |
| 3615 } else { | 3498 } else { |
| 3616 // Make sure not to block the header bar when virtual keyboard is absent . | 3499 // Make sure not to block the header bar when virtual keyboard is absent . |
| 3617 this.parentNode.setPreferredSize( | 3500 this.parentNode.setPreferredSize( |
| 3618 Oobe.getInstance().clientAreaSize.width, | 3501 Oobe.getInstance().clientAreaSize.width, |
| 3619 Oobe.getInstance().clientAreaSize.height); | 3502 Oobe.getInstance().clientAreaSize.height); |
| 3620 } | 3503 } |
|
jdufault
2017/05/31 17:13:21
nit: drop whitespace
Wenzhao (Colin) Zang
2017/05/31 18:50:16
Done.
| |
| 3621 | 3504 |
| 3622 if (pods.length == 1) { | 3505 if (pods.length == 1) { |
| 3623 this.placeSinglePod_(); | 3506 this.placeSinglePod_(); |
| 3624 } else if (pods.length == POD_ROW_LIMIT) { | 3507 } else if (pods.length == POD_ROW_LIMIT) { |
| 3625 this.placePodsOnPodRow_(); | 3508 this.placePodsOnPodRow_(); |
| 3626 } else { | 3509 } else { |
| 3627 this.placePodsOnContainer_(); | 3510 this.placePodsOnContainer_(); |
| 3628 } | 3511 } |
| 3629 Oobe.getInstance().updateScreenSize(this.parentNode); | 3512 Oobe.getInstance().updateScreenSize(this.parentNode); |
| 3630 this.updatePodNameArea(); | 3513 this.updatePodNameArea_(); |
| 3631 }, | 3514 }, |
| 3632 | 3515 |
| 3633 /** | 3516 /** |
| 3634 * Append pods to proper parents. Called each time before pod placement. | 3517 * Appends pods to proper parents. Called each time before pod placement. |
| 3635 * @private | 3518 * @private |
| 3636 */ | 3519 */ |
| 3637 appendPodsToParents: function() { | 3520 appendPodsToParents_: function() { |
| 3638 var pods = this.pods; | 3521 var pods = this.pods; |
| 3639 // Pod count may have changed, so the placement method may change | 3522 // Pod count may have changed, so the placement method may change |
| 3640 // accordingly. Therefore, always remove all pods from their current | 3523 // accordingly. Therefore, always remove all pods from their current |
| 3641 // parents first. | 3524 // parents first. |
| 3642 for (var pod of pods) { | 3525 for (var pod of pods) { |
| 3643 pod.parentNode.removeChild(pod); | 3526 pod.parentNode.removeChild(pod); |
| 3644 } | 3527 } |
| 3645 if (pods.length <= POD_ROW_LIMIT) { | 3528 if (pods.length <= POD_ROW_LIMIT) { |
| 3646 for (var pod of pods) { | 3529 for (var pod of pods) { |
| 3647 this.appendChild(pod); | 3530 this.appendChild(pod); |
| 3648 } | 3531 } |
| 3649 } else { | 3532 } else { |
| 3650 // When the user count exceeds the limit (currently set to 2), only the | 3533 // When the user count exceeds the limit (currently set to 2), only the |
| 3651 // main pod still has pow row as parent, all other pods should be | 3534 // main pod still has pow row as parent, all other pods should be |
| 3652 // appended to the container with scroll bar. | 3535 // appended to the container with scroll bar. |
| 3653 for (var pod of pods) { | 3536 for (var pod of pods) { |
| 3654 if (pod == this.mainPod_) { | 3537 if (pod == this.mainPod_) |
| 3655 this.appendChild(pod); | 3538 this.appendChild(pod); |
| 3656 } else { | 3539 else |
| 3657 this.smallPodsContainer.appendChild(pod); | 3540 this.smallPodsContainer.appendChild(pod); |
| 3658 } | |
| 3659 } | 3541 } |
| 3660 } | 3542 } |
| 3661 }, | 3543 }, |
| 3662 | 3544 |
| 3663 /** | 3545 /** |
| 3546 * Makes inner container unscrollable and hides the bottom empty area | |
| 3547 * when virtual keyboard is shown. | |
| 3548 * @private | |
| 3549 */ | |
| 3550 hideEmptyArea_: function() { | |
| 3551 var screen = document.querySelector('#scroll-container'); | |
| 3552 var clientArea = document.querySelector('#inner-container'); | |
| 3553 if (this.isScreenShrinked_()) { | |
| 3554 // When virtual keyboard is shown, although the screen size | |
| 3555 // is reduced properly, the size of the outer container remains the | |
|
jdufault
2017/05/31 17:13:21
Do we need the min-height on the outer container?
Wenzhao (Colin) Zang
2017/05/31 18:50:16
According to previous comments I found, the min-he
jdufault
2017/05/31 19:02:36
I'd be surprised if we ever want to enable that. T
| |
| 3556 // same because its min-height is applied. Users can scroll the screen | |
| 3557 // upward and see empty areas beyond the pod row and the scroll bar, | |
| 3558 // which should be avoided. | |
| 3559 // This is a hacky solution: we can make the scroll container hide | |
| 3560 // the overflow area and manully position the client area. | |
| 3561 // We used to check Oobe.getInstance().virtualKeyboardShown directly | |
| 3562 // instead of the screen size, but there were occasional bugs because | |
| 3563 // that value may not be updated yet when we reach here. | |
| 3564 screen.style.overflowY = "hidden"; | |
| 3565 clientArea.style.position = "absolute"; | |
| 3566 clientArea.style.left = cr.ui.toCssPx(0); | |
| 3567 clientArea.style.top = cr.ui.toCssPx(0); | |
| 3568 } else { | |
| 3569 // Sets the values to default when virtual keyboard is not shown. | |
| 3570 screen.style.overflowY = "auto"; | |
| 3571 clientArea.style.position = "relative"; | |
| 3572 } | |
| 3573 }, | |
| 3574 | |
| 3575 /** | |
| 3664 * Called when there is one user pod. | 3576 * Called when there is one user pod. |
| 3665 * @private | 3577 * @private |
| 3666 */ | 3578 */ |
| 3667 placeSinglePod_: function() { | 3579 placeSinglePod_: function() { |
| 3668 this.mainPod_.setPodStyle(UserPod.Style.LARGE); | 3580 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3669 this.mainPod_.left = (this.screenSize.width - CROS_POD_WIDTH) / 2; | 3581 this.mainPod_.left = (this.screenSize.width - CROS_POD_WIDTH) / 2; |
| 3670 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; | 3582 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3671 }, | 3583 }, |
| 3672 | 3584 |
| 3673 /** | 3585 /** |
| 3674 * Called when there are two users pods. | 3586 * Called when there are two users pods. |
| 3675 * @private | 3587 * @private |
| 3676 */ | 3588 */ |
| 3677 placePodsOnPodRow_: function() { | 3589 placePodsOnPodRow_: function() { |
| 3678 // Both pods have large size and are placed adjacently. | 3590 // Both pods have large size and are placed adjacently. |
| 3679 var secondPod = | 3591 var secondPod = |
| 3680 this.pods[0] == this.mainPod_ ? this.pods[1] : this.pods[0]; | 3592 this.pods[0] == this.mainPod_ ? this.pods[1] : this.pods[0]; |
| 3681 this.mainPod_.setPodStyle(UserPod.Style.LARGE); | 3593 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3682 secondPod.setPodStyle(UserPod.Style.LARGE); | 3594 secondPod.setPodStyle(UserPod.Style.LARGE); |
| 3683 | 3595 |
| 3684 var DOUBLE_PODS_PADDING = this.isPortraitMode() ? 32 : 118; | 3596 var DOUBLE_PODS_PADDING = this.isPortraitMode_() ? 32 : 118; |
| 3685 var leftPadding = (this.screenSize.width - (CROS_POD_WIDTH * 2 + DOUBLE_PO DS_PADDING)) / 2; | 3597 var leftPadding = (this.screenSize.width - (CROS_POD_WIDTH * 2 + DOUBLE_PO DS_PADDING)) / 2; |
| 3686 // Start actual positioning. | 3598 // Start actual positioning. |
| 3687 this.mainPod_.left = leftPadding; | 3599 this.mainPod_.left = leftPadding; |
| 3688 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; | 3600 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3689 secondPod.left = leftPadding + CROS_POD_WIDTH + DOUBLE_PODS_PADDING; | 3601 secondPod.left = leftPadding + CROS_POD_WIDTH + DOUBLE_PODS_PADDING; |
| 3690 secondPod.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; | 3602 secondPod.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3691 }, | 3603 }, |
| 3692 | 3604 |
| 3693 /** | 3605 /** |
| 3694 * Called when there are more than two user pods. | 3606 * Called when there are more than two user pods. |
| 3695 * @private | 3607 * @private |
| 3696 */ | 3608 */ |
| 3697 placePodsOnContainer_: function() { | 3609 placePodsOnContainer_: function() { |
| 3698 this.smallPodsContainer.hidden = false; | 3610 this.smallPodsContainer.hidden = false; |
| 3699 var pods = this.pods; | 3611 var pods = this.pods; |
| 3700 if ((pods.length > LANDSCAPE_MODE_LIMIT && !this.isPortraitMode()) || | 3612 if ((pods.length > LANDSCAPE_MODE_LIMIT && !this.isPortraitMode_()) || |
| 3701 (pods.length > PORTRAIT_MODE_LIMIT && this.isPortraitMode())) { | 3613 (pods.length > PORTRAIT_MODE_LIMIT && this.isPortraitMode_())) { |
| 3702 // If the pod count exceeds limits, they should be in extra small size | 3614 // If the pod count exceeds limits, they should be in extra small size |
| 3703 // and the container will become scrollable. | 3615 // and the container will become scrollable. |
| 3704 this.placePodsOnScrollableContainer_(); | 3616 this.placePodsOnScrollableContainer_(); |
| 3705 return; | 3617 return; |
| 3706 } | 3618 } |
| 3707 this.mainPod_.setPodStyle(UserPod.Style.LARGE); | 3619 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3708 for (var pod of pods) { | 3620 for (var pod of pods) { |
| 3709 if (pod != this.mainPod_) { | 3621 if (pod != this.mainPod_) { |
| 3710 // All pods except the main one must be set to the small style. | 3622 // All pods except the main one must be set to the small style. |
| 3711 pod.setPodStyle(UserPod.Style.SMALL); | 3623 pod.setPodStyle(UserPod.Style.SMALL); |
| 3712 } | 3624 } |
| 3713 } | 3625 } |
| 3714 // The size of the smallPodsContainer must be updated to avoid overflow, | 3626 // The size of the smallPodsContainer must be updated to avoid overflow, |
| 3715 // otherwise unnecessary scroll bar will show up. | 3627 // otherwise unnecessary scroll bar will show up. |
| 3716 this.smallPodsContainer.style.height = | 3628 this.smallPodsContainer.style.height = |
| 3717 cr.ui.toCssPx(this.screenSize.height); | 3629 cr.ui.toCssPx(this.screenSize.height); |
| 3718 this.smallPodsContainer.style.width = cr.ui.toCssPx(CROS_SMALL_POD_WIDTH); | 3630 this.smallPodsContainer.style.width = cr.ui.toCssPx(CROS_SMALL_POD_WIDTH); |
| 3719 | 3631 |
| 3720 var LEFT_PADDING = this.isPortraitMode() ? 0 : 98; | 3632 var LEFT_PADDING = this.isPortraitMode_() ? 0 : 98; |
| 3721 var MIDDLE_PADDING = this.isPortraitMode() ? 84 : 220; | 3633 var MIDDLE_PADDING = this.isPortraitMode_() ? 84 : 220; |
| 3722 var contentsWidth = LEFT_PADDING + | 3634 var contentsWidth = LEFT_PADDING + |
| 3723 CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH; | 3635 CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH; |
| 3724 var blankWidth = this.screenSize.width - contentsWidth; | 3636 var blankWidth = this.screenSize.width - contentsWidth; |
| 3725 var actualLeftPadding = LEFT_PADDING; | 3637 var actualLeftPadding = LEFT_PADDING; |
| 3726 actualLeftPadding += this.isPortraitMode() ? blankWidth * 2 / 3: | 3638 actualLeftPadding += this.isPortraitMode_() ? blankWidth * 2 / 3: |
| 3727 blankWidth / 2; | 3639 blankWidth / 2; |
| 3728 var SMALL_POD_PADDING = 54; | 3640 var SMALL_POD_PADDING = 54; |
| 3729 var actualSmallPodPadding = SMALL_POD_PADDING; | 3641 var actualSmallPodPadding = SMALL_POD_PADDING; |
| 3730 var smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + | 3642 var smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + |
| 3731 (pods.length - 2) * actualSmallPodPadding; | 3643 (pods.length - 2) * actualSmallPodPadding; |
| 3732 if (smallPodsTotalHeight > this.screenSize.height) { | 3644 if (smallPodsTotalHeight > this.screenSize.height) { |
| 3733 // Edge case: when the virtual keyboard is present, the total height of | 3645 // Edge case: when the virtual keyboard is present, the total height of |
| 3734 // the smallPodsContainer may exceed the screen height. Decrease the | 3646 // the smallPodsContainer may exceed the screen height. Decrease the |
| 3735 // padding among small pods according to the design spec. | 3647 // padding among small pods according to the design spec. |
| 3736 actualSmallPodPadding = 32; | 3648 actualSmallPodPadding = 32; |
| 3737 smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + | 3649 smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 3767 this.smallPodsContainer.classList.add('scroll'); | 3679 this.smallPodsContainer.classList.add('scroll'); |
| 3768 var pods = this.pods; | 3680 var pods = this.pods; |
| 3769 this.mainPod_.setPodStyle(UserPod.Style.LARGE); | 3681 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3770 for (var pod of pods) { | 3682 for (var pod of pods) { |
| 3771 if (pod != this.mainPod_) { | 3683 if (pod != this.mainPod_) { |
| 3772 // All pods except the main one must be set to the extra small style. | 3684 // All pods except the main one must be set to the extra small style. |
| 3773 pod.setPodStyle(UserPod.Style.EXTRA_SMALL); | 3685 pod.setPodStyle(UserPod.Style.EXTRA_SMALL); |
| 3774 } | 3686 } |
| 3775 } | 3687 } |
| 3776 | 3688 |
| 3777 var SCROLL_LEFT_PADDING = this.isPortraitMode() ? 46 : 72; | 3689 var SCROLL_LEFT_PADDING = this.isPortraitMode_() ? 46 : 72; |
| 3778 var SCROLL_RIGHT_PADDING = this.isPortraitMode() ? 12 : 72; | 3690 var SCROLL_RIGHT_PADDING = this.isPortraitMode_() ? 12 : 72; |
| 3779 // The offsetWidth of the smallPodsContainer. | 3691 // The offsetWidth of the smallPodsContainer. |
| 3780 var scrollAreaWidth = SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH + | 3692 var scrollAreaWidth = SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH + |
| 3781 SCROLL_RIGHT_PADDING; | 3693 SCROLL_RIGHT_PADDING; |
| 3782 var mainPodPadding = (this.screenSize.width - | 3694 var mainPodPadding = (this.screenSize.width - |
| 3783 scrollAreaWidth - CROS_POD_WIDTH) / 2; | 3695 scrollAreaWidth - CROS_POD_WIDTH) / 2; |
| 3784 var SCROLL_TOP_PADDING = this.isPortraitMode() ? 66 : 72; | 3696 var SCROLL_TOP_PADDING = this.isPortraitMode_() ? 66 : 72; |
| 3785 var EXTRA_SMALL_POD_PADDING = 32; | 3697 var EXTRA_SMALL_POD_PADDING = 32; |
| 3786 // Start positioning of the main pod and the smallPodsContainer. | 3698 // Start positioning of the main pod and the smallPodsContainer. |
| 3787 this.mainPod_.left = mainPodPadding; | 3699 this.mainPod_.left = mainPodPadding; |
| 3788 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; | 3700 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3789 this.smallPodsContainer.style.left = | 3701 this.smallPodsContainer.style.left = |
| 3790 cr.ui.toCssPx(mainPodPadding * 2 + CROS_POD_WIDTH); | 3702 cr.ui.toCssPx(mainPodPadding * 2 + CROS_POD_WIDTH); |
| 3791 this.smallPodsContainer.style.top = cr.ui.toCssPx(0); | 3703 this.smallPodsContainer.style.top = cr.ui.toCssPx(0); |
| 3792 | 3704 |
| 3793 // Precalculate the total height of the scrollable container and check if | 3705 // Precalculate the total height of the scrollable container and check if |
| 3794 // it indeed exceeds the screen height. | 3706 // it indeed exceeds the screen height. |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 3810 // before allowing the container to overflow and show the scroll bar. | 3722 // before allowing the container to overflow and show the scroll bar. |
| 3811 var actualTopPadding = SCROLL_TOP_PADDING; | 3723 var actualTopPadding = SCROLL_TOP_PADDING; |
| 3812 if ((this.screenSize.height - scrollHeight) / 2 > actualTopPadding) { | 3724 if ((this.screenSize.height - scrollHeight) / 2 > actualTopPadding) { |
| 3813 // Edge case: the total height of the scrollable container does not | 3725 // Edge case: the total height of the scrollable container does not |
| 3814 // exceed the screen height (minus the neceesary padding), so the | 3726 // exceed the screen height (minus the neceesary padding), so the |
| 3815 // scroll bar will not appear. | 3727 // scroll bar will not appear. |
| 3816 // In this case, we still want to keep the extra small pod size and | 3728 // In this case, we still want to keep the extra small pod size and |
| 3817 // the overlay, but the top and bottom padding should be adjusted | 3729 // the overlay, but the top and bottom padding should be adjusted |
| 3818 // to ensure a symmetric layout. | 3730 // to ensure a symmetric layout. |
| 3819 actualTopPadding = (this.screenSize.height - scrollHeight) / 2; | 3731 actualTopPadding = (this.screenSize.height - scrollHeight) / 2; |
| 3820 } else if (!Oobe.getInstance().virtualKeyboardShown) { | 3732 } else if (!this.isScreenShrinked_()) { |
| 3821 // The scroll bar will definitely be shown if we reach here. A gradient | 3733 // The scroll bar will definitely be shown if we reach here. A gradient |
| 3822 // mask is applied to avoid blocking the header bar if the virtual | 3734 // mask is applied to avoid blocking the header bar if the virtual |
| 3823 // keyboard is not shown. When the keyboard is shown, there's no need | 3735 // keyboard is not shown. When the keyboard is shown, there's no need |
| 3824 // to add the mask and the original top padding value should be kept. | 3736 // to add the mask and the original top padding value should be kept. |
| 3825 actualTopPadding = SCROLL_MASK_HEIGHT; | 3737 actualTopPadding = SCROLL_MASK_HEIGHT; |
| 3826 this.showScrollMask(); | 3738 this.showScrollMask_(); |
| 3827 } | 3739 } |
| 3828 | 3740 |
| 3829 // Start positioning of the small pods inside the smallPodsContainer. | 3741 // Start positioning of the small pods inside the smallPodsContainer. |
| 3830 var topPadding = actualTopPadding; | 3742 var topPadding = actualTopPadding; |
| 3831 var lastPod = undefined; | 3743 var lastPod = undefined; |
| 3832 for (var pod of pods) { | 3744 for (var pod of pods) { |
| 3833 if (pod == this.mainPod_) { | 3745 if (pod == this.mainPod_) { |
| 3834 continue; | 3746 continue; |
| 3835 } | 3747 } |
| 3836 pod.left = SCROLL_LEFT_PADDING; | 3748 pod.left = SCROLL_LEFT_PADDING; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 3855 document.querySelector('.small-pod-container-mask').hidden = true; | 3767 document.querySelector('.small-pod-container-mask').hidden = true; |
| 3856 document.querySelector('.small-pod-container-mask.rotate').hidden = true; | 3768 document.querySelector('.small-pod-container-mask.rotate').hidden = true; |
| 3857 this.smallPodsContainer.classList.remove('scroll'); | 3769 this.smallPodsContainer.classList.remove('scroll'); |
| 3858 var pods = this.pods; | 3770 var pods = this.pods; |
| 3859 for (var pod of pods) { | 3771 for (var pod of pods) { |
| 3860 // There is a chance that one of the pods has a bottom padding, so | 3772 // There is a chance that one of the pods has a bottom padding, so |
| 3861 // reset all of them to be safe. This is because if the pod was at | 3773 // reset all of them to be safe. This is because if the pod was at |
| 3862 // the last position in the scrollable container, a bottom padding | 3774 // the last position in the scrollable container, a bottom padding |
| 3863 // was added to ensure a symmetric layout. | 3775 // was added to ensure a symmetric layout. |
| 3864 pod.style.paddingBottom = cr.ui.toCssPx(0); | 3776 pod.style.paddingBottom = cr.ui.toCssPx(0); |
| 3777 // Remove the switch animation that might be added earlier. | |
| 3778 pod.imageElement.classList.remove('switch-image-animation'); | |
| 3779 pod.smallPodImageElement.classList.remove('switch-image-animation'); | |
| 3865 } | 3780 } |
| 3866 }, | 3781 }, |
| 3867 | 3782 |
| 3868 /** | 3783 /** |
| 3869 * Check if the screen is in portrait mode. | 3784 * Checks if the screen is in portrait mode. |
| 3870 * @return {boolean} True if in portrait mode. | 3785 * @return {boolean} True if in portrait mode. |
| 3871 */ | 3786 */ |
| 3872 isPortraitMode: function() { | 3787 isPortraitMode_: function() { |
| 3873 return this.screenSize.width < | 3788 return this.screenSize.width < this.screenSize.height; |
| 3874 this.screenSize.height; | 3789 }, |
| 3790 | |
| 3791 /** | |
| 3792 * Checks if the screen is shrinked, e.g., when showing virtual keyboard. | |
| 3793 * @return {boolean} True if the screen is shrinked. | |
| 3794 */ | |
| 3795 isScreenShrinked_: function() { | |
| 3796 return this.screenSize.height <= Oobe.getInstance().clientAreaSize.height; | |
|
jdufault
2017/05/31 17:13:21
Why not use virtualKeyboardShown? Can you document
Wenzhao (Colin) Zang
2017/05/31 18:50:16
AFAIK there's no additional case, but based on my
jdufault
2017/05/31 19:02:36
Okay. Can you add a comment?
| |
| 3875 }, | 3797 }, |
| 3876 | 3798 |
| 3877 /** | 3799 /** |
| 3878 * Called when scroll bar is shown and we need a mask for the header bar. | 3800 * Called when scroll bar is shown and we need a mask for the header bar. |
| 3879 * @private | 3801 * @private |
| 3880 */ | 3802 */ |
| 3881 showScrollMask: function() { | 3803 showScrollMask_: function() { |
| 3882 var topMask = document.querySelector('.small-pod-container-mask'); | 3804 var topMask = document.querySelector('.small-pod-container-mask'); |
| 3883 topMask.hidden = false; | 3805 topMask.hidden = false; |
| 3884 topMask.style.left = this.smallPodsContainer.style.left; | 3806 topMask.style.left = this.smallPodsContainer.style.left; |
| 3885 topMask.style.width = this.smallPodsContainer.style.width; | 3807 topMask.style.width = this.smallPodsContainer.style.width; |
| 3886 // The bottom mask is a rotation of the top mask. | 3808 // The bottom mask is a rotation of the top mask. |
| 3887 var bottomMask = | 3809 var bottomMask = |
| 3888 document.querySelector('.small-pod-container-mask.rotate'); | 3810 document.querySelector('.small-pod-container-mask.rotate'); |
| 3889 bottomMask.hidden = false; | 3811 bottomMask.hidden = false; |
| 3890 bottomMask.style.left = this.smallPodsContainer.style.left; | 3812 bottomMask.style.left = this.smallPodsContainer.style.left; |
| 3891 bottomMask.style.width = this.smallPodsContainer.style.width; | 3813 bottomMask.style.width = this.smallPodsContainer.style.width; |
| 3892 // The bottom mask should overlap with the header bar, and its z-index | 3814 // The bottom mask should overlap with the header bar, and its z-index |
| 3893 // is chosen to ensure it does not block users from using the header bar. | 3815 // is chosen to ensure it does not block users from using the header bar. |
| 3894 bottomMask.style.top = cr.ui.toCssPx( | 3816 bottomMask.style.top = cr.ui.toCssPx(this.screenSize.height - SCROLL_MASK_ HEIGHT); |
| 3895 this.screenSize.height - | |
| 3896 SCROLL_MASK_HEIGHT); | |
| 3897 }, | 3817 }, |
| 3898 | 3818 |
| 3899 /** | 3819 /** |
| 3900 * Makes sure that user name on each large pod is centered and extra long | 3820 * Makes sure that: |
| 3901 * name does not exceed max width. Names on small pods do not need to be | 3821 * 1) User name on each large pod is centered. |
| 3902 * dynamically updated. | 3822 * 2) Extra long names don't exceed maximum pod width. |
| 3823 * 3) Action box menus are either left-aligned or right-aligned with | |
| 3824 * the drop down button. | |
| 3903 * @private | 3825 * @private |
| 3904 */ | 3826 */ |
| 3905 updatePodNameArea: function() { | 3827 updatePodNameArea_: function() { |
| 3906 this.querySelectorAll('.name-container').forEach(function(nameArea) { | 3828 var pods = this.pods; |
| 3907 var nameElement = nameArea.querySelector('.name'); | 3829 for (var pod of pods) { |
| 3908 var leftMargin = (CROS_POD_WIDTH - nameElement.offsetWidth) / 2; | 3830 if (pods.length > POD_ROW_LIMIT && pod != this.mainPod_) |
| 3831 continue; | |
| 3832 var nameArea = pod.querySelector('.name-container'); | |
| 3833 var leftMargin = (CROS_POD_WIDTH - pod.nameElement.offsetWidth) / 2; | |
| 3909 if (leftMargin > 0) | 3834 if (leftMargin > 0) |
| 3910 nameArea.style.left = cr.ui.toCssPx(leftMargin); | 3835 nameArea.style.left = cr.ui.toCssPx(leftMargin); |
| 3911 else | 3836 else { |
| 3912 nameElement.style.width = cr.ui.toCssPx(CROS_POD_WIDTH); | 3837 pod.nameElement.style.width = cr.ui.toCssPx(CROS_POD_WIDTH); |
| 3913 }); | 3838 nameArea.style.left = cr.ui.toCssPx(0); |
| 3839 } | |
| 3840 // Update action box menu position to ensure it doesn't overlap with | |
| 3841 // elements outside the pod. | |
| 3842 var actionBoxMenu = pod.querySelector('.action-box-menu'); | |
| 3843 var actionBoxButton = pod.querySelector('.action-box-button'); | |
| 3844 var MENU_TOP_PADDING = 7; | |
| 3845 actionBoxMenu.style.top = cr.ui.toCssPx(actionBoxButton.offsetHeight + M ENU_TOP_PADDING); | |
| 3846 if (this.isPortraitMode_() && pods.length > 1) { | |
| 3847 // Confine the menu inside the pod when it may overlap with outside | |
| 3848 // elements. | |
| 3849 actionBoxMenu.style.left = "auto"; | |
| 3850 actionBoxMenu.style.right = cr.ui.toCssPx(0); | |
| 3851 } else { | |
| 3852 actionBoxMenu.style.left = cr.ui.toCssPx(pod.nameElement.offsetWidth + actionBoxButton.style.marginLeft); | |
| 3853 actionBoxMenu.style.right = "auto"; | |
| 3854 } | |
| 3855 // Add ripple animation. | |
| 3856 var actionBoxRippleEffect = pod.querySelector('.action-box-button.ripple -circle'); | |
| 3857 actionBoxRippleEffect.style.left = actionBoxMenu.style.left; | |
| 3858 actionBoxRippleEffect.style.top = cr.ui.toCssPx(actionBoxButton.style.ma rginTop); | |
| 3859 } | |
| 3914 }, | 3860 }, |
| 3915 | 3861 |
| 3916 /** | 3862 /** |
| 3917 * Called when a small or extra small pod is clicked to trigger the switch | 3863 * Called when a small or extra small pod is clicked to trigger the switch |
| 3918 * with the main pod. | 3864 * with the main pod. |
| 3919 */ | 3865 */ |
| 3920 switchMainPod: function(pod) { | 3866 switchMainPod: function(pod) { |
| 3921 if (this.disabled) { | 3867 if (this.disabled) { |
| 3922 console.error('Cannot change main pod while sign-in UI is disabled.'); | 3868 console.error('Cannot change main pod while sign-in UI is disabled.'); |
| 3923 return; | 3869 return; |
| 3924 } | 3870 } |
| 3925 if (!this.mainPod_) { | 3871 if (!this.mainPod_) { |
| 3926 console.error('Attempt to switch a non-existing main pod.'); | 3872 console.error('Attempt to switch a non-existing main pod.'); |
| 3927 return; | 3873 return; |
| 3928 } | 3874 } |
| 3929 // Find the index of the small pod. | 3875 // Find the index of the small pod. |
| 3930 var insert = 0; | 3876 var insert = 0; |
| 3931 var children = pod.parentNode.children; | 3877 var children = pod.parentNode.children; |
| 3932 while (insert < children.length && children[insert] != pod) | 3878 while (insert < children.length && children[insert] != pod) |
| 3933 insert++; | 3879 insert++; |
| 3934 if (insert >= children.length) { | 3880 if (insert >= children.length) { |
| 3935 console.error('Attempt to switch a non-existing small pod.'); | 3881 console.error('Attempt to switch a non-existing small pod.'); |
| 3936 return; | 3882 return; |
| 3937 } | 3883 } |
| 3938 // Switch style of the two pods. | 3884 // Switch style of the two pods. |
| 3939 this.mainPod_.setPodStyle(pod.getPodStyle()); | 3885 this.mainPod_.setPodStyle(pod.getPodStyle()); |
| 3940 pod.setPodStyle(UserPod.Style.LARGE); | 3886 pod.setPodStyle(UserPod.Style.LARGE); |
| 3887 // Add switch animation. | |
| 3888 this.mainPod_.smallPodImageElement.classList.add('switch-image-animation') ; | |
| 3889 pod.imageElement.classList.add('switch-image-animation'); | |
| 3941 | 3890 |
| 3942 // Switch parent and position of the two pods. | 3891 // Switch parent and position of the two pods. |
| 3943 var left = pod.left; | 3892 var left = pod.left; |
| 3944 var top = pod.top; | 3893 var top = pod.top; |
| 3945 // Edge case: paddingBottom should be switched too because there's a | 3894 // Edge case: paddingBottom should be switched too because there's a |
| 3946 // chance that the small pod was at the end of the scrollable container | 3895 // chance that the small pod was at the end of the scrollable container |
| 3947 // and had a non-zero paddingBottom. | 3896 // and had a non-zero paddingBottom. |
| 3948 var paddingBottom = pod.style.paddingBottom; | 3897 var paddingBottom = pod.style.paddingBottom; |
| 3949 var parent = pod.parentNode; | 3898 var parent = pod.parentNode; |
| 3950 parent.removeChild(pod); | 3899 parent.removeChild(pod); |
| 3951 this.appendChild(pod); | 3900 this.appendChild(pod); |
| 3952 pod.left = this.mainPod_.left; | 3901 pod.left = this.mainPod_.left; |
| 3953 pod.top = this.mainPod_.top; | 3902 pod.top = this.mainPod_.top; |
| 3954 pod.style.paddingBottom = cr.ui.toCssPx(0); | 3903 pod.style.paddingBottom = cr.ui.toCssPx(0); |
| 3955 | 3904 |
| 3956 this.removeChild(this.mainPod_); | 3905 this.removeChild(this.mainPod_); |
| 3957 // It must have the same index with the original small pod, instead | 3906 // It must have the same index with the original small pod, instead |
| 3958 // of being appended as the last child, in order to maintain the 'Tab' | 3907 // of being appended as the last child, in order to maintain the 'Tab' |
| 3959 // order. | 3908 // order. |
| 3960 parent.insertBefore(this.mainPod_, children[insert]); | 3909 parent.insertBefore(this.mainPod_, children[insert]); |
| 3961 this.mainPod_.left = left; | 3910 this.mainPod_.left = left; |
| 3962 this.mainPod_.top = top; | 3911 this.mainPod_.top = top; |
| 3963 this.mainPod_.style.paddingBottom = paddingBottom; | 3912 this.mainPod_.style.paddingBottom = paddingBottom; |
| 3964 this.mainPod_ = pod; | 3913 this.mainPod_ = pod; |
| 3965 // Focus the new main pod. | 3914 // The new main pod should already be focused but we need a focus update |
| 3966 this.focusPod(this.mainPod_); | 3915 // in order to focus on the input box. |
| 3967 this.updatePodNameArea(); | 3916 this.focusPod(this.mainPod_, true /* force */); |
| 3917 this.updatePodNameArea_(); | |
| 3968 }, | 3918 }, |
| 3969 | 3919 |
| 3970 /** | 3920 /** |
| 3971 * Returns dimensions of screen including the header bar. | 3921 * Returns dimensions of screen including the header bar. |
| 3972 * @type {Object} | 3922 * @type {Object} |
| 3973 */ | 3923 */ |
| 3974 get screenSize() { | 3924 get screenSize() { |
| 3975 var container = $('scroll-container'); | 3925 var container = $('scroll-container'); |
| 3976 return {width: container.offsetWidth, height: container.offsetHeight}; | 3926 return {width: container.offsetWidth, height: container.offsetHeight}; |
| 3977 }, | 3927 }, |
| 3978 | 3928 |
| 3979 /** | 3929 /** |
| 3980 * Number of columns. | 3930 * Displays a banner containing |message|. If the banner is already present |
| 3981 * @type {?number} | 3931 * this function updates the message in the banner. |
| 3932 * @param {string} message Text to be displayed or empty to hide the banner. | |
| 3982 */ | 3933 */ |
| 3983 set columns(columns) { | 3934 showBannerMessage: function(message) { |
| 3984 // Cannot use 'columns' here. | 3935 var banner = $('signin-banner'); |
| 3985 this.setAttribute('ncolumns', columns); | 3936 banner.textContent = message; |
| 3986 }, | 3937 banner.classList.toggle('message-set', !!message); |
| 3987 get columns() { | 3938 var bannerContainer = $('signin-banner-container1'); |
| 3988 return parseInt(this.getAttribute('ncolumns')); | 3939 var BANNER_TOP_PADDING = this.isScreenShrinked_() ? 0 : 38; |
| 3940 bannerContainer.style.top = cr.ui.toCssPx(this.mainPod_.top + CROS_POD_HEI GHT + BANNER_TOP_PADDING); | |
| 3941 if (this.pods.length <= POD_ROW_LIMIT) | |
| 3942 bannerContainer.style.left = cr.ui.toCssPx((this.screenSize.width - BANN ER_MESSAGE_WIDTH) / 2); | |
| 3943 else { | |
| 3944 var leftPadding = this.mainPod_.left - (BANNER_MESSAGE_WIDTH - CROS_POD_ WIDTH) / 2; | |
| 3945 bannerContainer.style.left = cr.ui.toCssPx(Math.max(leftPadding, 0)); | |
| 3946 } | |
| 3989 }, | 3947 }, |
| 3990 | 3948 |
| 3991 /** | 3949 /** |
| 3992 * Number of rows. | |
| 3993 * @type {?number} | |
| 3994 */ | |
| 3995 set rows(rows) { | |
| 3996 // Cannot use 'rows' here. | |
| 3997 this.setAttribute('nrows', rows); | |
| 3998 }, | |
| 3999 get rows() { | |
| 4000 return parseInt(this.getAttribute('nrows')); | |
| 4001 }, | |
| 4002 | |
| 4003 /** | |
| 4004 * Whether the pod is currently focused. | 3950 * Whether the pod is currently focused. |
| 4005 * @param {UserPod} pod Pod to check for focus. | 3951 * @param {UserPod} pod Pod to check for focus. |
| 4006 * @return {boolean} Pod focus status. | 3952 * @return {boolean} Pod focus status. |
| 4007 */ | 3953 */ |
| 4008 isFocused: function(pod) { | 3954 isFocused: function(pod) { |
| 4009 return this.focusedPod_ == pod; | 3955 return this.focusedPod_ == pod; |
| 4010 }, | 3956 }, |
| 4011 | 3957 |
| 4012 /** | 3958 /** |
| 4013 * Focuses a given user pod or clear focus when given null. | 3959 * Focuses a given user pod or clear focus when given null. |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4072 // |opt_skipInputFocus| is true. When |multiProfilesPolicyApplied| | 4018 // |opt_skipInputFocus| is true. When |multiProfilesPolicyApplied| |
| 4073 // is false, it doesn't focus on the password input box by default. | 4019 // is false, it doesn't focus on the password input box by default. |
| 4074 podToFocus.focus(); | 4020 podToFocus.focus(); |
| 4075 } | 4021 } |
| 4076 | 4022 |
| 4077 // focusPod() automatically loads wallpaper | 4023 // focusPod() automatically loads wallpaper |
| 4078 if (!podToFocus.user.isApp) | 4024 if (!podToFocus.user.isApp) |
| 4079 chrome.send('focusPod', [podToFocus.user.username]); | 4025 chrome.send('focusPod', [podToFocus.user.username]); |
| 4080 this.firstShown_ = false; | 4026 this.firstShown_ = false; |
| 4081 this.lastFocusedPod_ = podToFocus; | 4027 this.lastFocusedPod_ = podToFocus; |
| 4082 this.scrollFocusedPodIntoView(); | |
| 4083 this.setUserPodFingerprintIcon( | 4028 this.setUserPodFingerprintIcon( |
| 4084 podToFocus.user.username, FINGERPRINT_STATES.DEFAULT); | 4029 podToFocus.user.username, FINGERPRINT_STATES.DEFAULT); |
| 4085 } else { | 4030 } else { |
| 4086 chrome.send('noPodFocused'); | 4031 chrome.send('noPodFocused'); |
| 4087 } | 4032 } |
| 4088 this.insideFocusPod_ = false; | 4033 this.insideFocusPod_ = false; |
| 4089 }, | 4034 }, |
| 4090 | 4035 |
| 4091 /** | 4036 /** |
| 4092 * Resets wallpaper to the last active user's wallpaper, if any. | 4037 * Resets wallpaper to the last active user's wallpaper, if any. |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 4107 /** | 4052 /** |
| 4108 * Sets currently activated pod. | 4053 * Sets currently activated pod. |
| 4109 * @param {UserPod} pod Pod to check for focus. | 4054 * @param {UserPod} pod Pod to check for focus. |
| 4110 * @param {Event} e Event object. | 4055 * @param {Event} e Event object. |
| 4111 */ | 4056 */ |
| 4112 setActivatedPod: function(pod, e) { | 4057 setActivatedPod: function(pod, e) { |
| 4113 if (this.disabled) { | 4058 if (this.disabled) { |
| 4114 console.error('Cannot activate pod while sign-in UI is disabled.'); | 4059 console.error('Cannot activate pod while sign-in UI is disabled.'); |
| 4115 return; | 4060 return; |
| 4116 } | 4061 } |
| 4062 // If testing mode is enabled and a positive integer was entered, abort | |
| 4063 // the activation process and start testing mode. | |
| 4064 if (pod && this.testingModeEnabled_) { | |
| 4065 var userCount = pod.passwordElement.value; | |
| 4066 if (parseInt(userCount) == userCount && userCount > 0) { | |
| 4067 this.showDummyUsersForTesting(userCount); | |
| 4068 return; | |
| 4069 } | |
| 4070 } | |
| 4117 if (pod && pod.activate(e)) | 4071 if (pod && pod.activate(e)) |
| 4118 this.activatedPod_ = pod; | 4072 this.activatedPod_ = pod; |
| 4119 }, | 4073 }, |
| 4120 | 4074 |
| 4121 /** | 4075 /** |
| 4076 * Used for testing only. Create the specified number of dummy users and | |
| 4077 * conveniently test the behaviors under different number of pods. | |
| 4078 * @param {number} count The number of users we want to test for. | |
| 4079 */ | |
| 4080 showDummyUsersForTesting: function(count) { | |
|
jdufault
2017/05/31 17:13:21
Nice!
| |
| 4081 if (!this.testingModeEnabled_) { | |
| 4082 console.error('Attempt to create dummy users when testing mode is disabl ed.'); | |
| 4083 return; | |
| 4084 } | |
| 4085 var pods = this.pods; | |
| 4086 for (var pod of pods) | |
| 4087 pod.parentNode.removeChild(pod); | |
| 4088 var sampleUser = this.users_[0]; | |
| 4089 var users = []; | |
| 4090 for (var i = 0; i < count; i++) | |
| 4091 users.push(sampleUser); | |
| 4092 | |
| 4093 this.loadPods(users); | |
| 4094 }, | |
| 4095 | |
| 4096 /** | |
| 4122 * The pod of the signed-in user, if any; null otherwise. | 4097 * The pod of the signed-in user, if any; null otherwise. |
| 4123 * @type {?UserPod} | 4098 * @type {?UserPod} |
| 4124 */ | 4099 */ |
| 4125 get lockedPod() { | 4100 get lockedPod() { |
| 4126 for (var i = 0, pod; pod = this.pods[i]; ++i) { | 4101 for (var i = 0, pod; pod = this.pods[i]; ++i) { |
| 4127 if (pod.user.signedIn) | 4102 if (pod.user.signedIn) |
| 4128 return pod; | 4103 return pod; |
| 4129 } | 4104 } |
| 4130 return null; | 4105 return null; |
| 4131 }, | 4106 }, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4228 for (var i = 0, pod; pod = this.pods[i]; ++i) | 4203 for (var i = 0, pod; pod = this.pods[i]; ++i) |
| 4229 pod.isActionBoxMenuActive = false; | 4204 pod.isActionBoxMenuActive = false; |
| 4230 } | 4205 } |
| 4231 | 4206 |
| 4232 // Clears focus if not clicked on a pod and if there's more than one pod. | 4207 // Clears focus if not clicked on a pod and if there's more than one pod. |
| 4233 var pod = findAncestorByClass(e.target, 'pod'); | 4208 var pod = findAncestorByClass(e.target, 'pod'); |
| 4234 if ((!pod || pod.parentNode != this) && !this.alwaysFocusSinglePod) { | 4209 if ((!pod || pod.parentNode != this) && !this.alwaysFocusSinglePod) { |
| 4235 this.focusPod(); | 4210 this.focusPod(); |
| 4236 } | 4211 } |
| 4237 | 4212 |
| 4238 if (pod) | 4213 if (pod && pod.getPodStyle() == UserPod.Style.LARGE) |
| 4239 pod.isActionBoxMenuHovered = true; | 4214 pod.isActionBoxMenuHovered = true; |
| 4240 | 4215 |
| 4241 // Return focus back to single pod. | 4216 // Return focus back to single pod. |
| 4242 if (this.alwaysFocusSinglePod && !pod) { | 4217 if (this.alwaysFocusSinglePod && !pod) { |
| 4243 if ($('login-header-bar').contains(e.target)) | 4218 if ($('login-header-bar').contains(e.target)) |
| 4244 return; | 4219 return; |
| 4245 this.focusPod(this.focusedPod_, true /* force */); | 4220 // If the click is outside the single pod, still focus on that pod |
| 4221 // but do not focus on input box any more. This makes virtual keyboard | |
| 4222 // (if present) disappear. | |
| 4223 this.focusPod(this.focusedPod_, true /* force */, true /* opt_skipInputF ocus */); | |
|
jdufault
2017/05/31 17:13:21
nit: line length
Wenzhao (Colin) Zang
2017/05/31 18:50:16
Done.
| |
| 4246 this.focusedPod_.userTypeBubbleElement.classList.remove('bubble-shown'); | 4224 this.focusedPod_.userTypeBubbleElement.classList.remove('bubble-shown'); |
| 4247 this.focusedPod_.isActionBoxMenuHovered = false; | 4225 this.focusedPod_.isActionBoxMenuHovered = false; |
| 4248 } | 4226 } |
| 4249 }, | 4227 }, |
| 4250 | 4228 |
| 4251 /** | 4229 /** |
| 4252 * Handler of mouse move event. | 4230 * Handler of mouse move event. |
| 4253 * @param {Event} e Click Event object. | 4231 * @param {Event} e Click Event object. |
| 4254 * @private | 4232 * @private |
| 4255 */ | 4233 */ |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 4279 | 4257 |
| 4280 /** | 4258 /** |
| 4281 * Handles focus event. | 4259 * Handles focus event. |
| 4282 * @param {Event} e Focus Event object. | 4260 * @param {Event} e Focus Event object. |
| 4283 * @private | 4261 * @private |
| 4284 */ | 4262 */ |
| 4285 handleFocus_: function(e) { | 4263 handleFocus_: function(e) { |
| 4286 if (this.disabled) | 4264 if (this.disabled) |
| 4287 return; | 4265 return; |
| 4288 if (e.target.parentNode == this) { | 4266 if (e.target.parentNode == this) { |
| 4289 // Focus on a pod | 4267 // Handles focus event on a large pod. |
| 4290 if (e.target.classList.contains('focused')) { | 4268 if (e.target.classList.contains('focused')) { |
| 4269 // Edge case: prevent input box from receiving unncessary focus | |
| 4270 // (thus hiding virtual keyboard) when remove user is clicked. | |
| 4271 if (e.target.isActionBoxMenuActive) | |
| 4272 return; | |
| 4291 if (!e.target.multiProfilesPolicyApplied) | 4273 if (!e.target.multiProfilesPolicyApplied) |
| 4292 e.target.focusInput(); | 4274 e.target.focusInput(); |
| 4293 else | 4275 else |
| 4294 e.target.userTypeBubbleElement.classList.add('bubble-shown'); | 4276 e.target.userTypeBubbleElement.classList.add('bubble-shown'); |
| 4295 } else | 4277 } else |
| 4296 this.focusPod(e.target); | 4278 this.focusPod(e.target); |
| 4297 return; | 4279 return; |
| 4298 } | 4280 } |
| 4299 | 4281 |
| 4300 // Small pods do not have input box. | 4282 // Small pods do not have input box. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4426 event, this.listeners_[event][0], this.listeners_[event][1]); | 4408 event, this.listeners_[event][0], this.listeners_[event][1]); |
| 4427 } | 4409 } |
| 4428 $('login-header-bar').buttonsTabIndex = UserPodTabOrder.HEADER_BAR; | 4410 $('login-header-bar').buttonsTabIndex = UserPodTabOrder.HEADER_BAR; |
| 4429 | 4411 |
| 4430 if (this.podPlacementPostponed_) { | 4412 if (this.podPlacementPostponed_) { |
| 4431 this.podPlacementPostponed_ = false; | 4413 this.podPlacementPostponed_ = false; |
| 4432 this.placePods_(); | 4414 this.placePods_(); |
| 4433 this.maybePreselectPod(); | 4415 this.maybePreselectPod(); |
| 4434 } | 4416 } |
| 4435 | 4417 |
| 4436 this.updatePodNameArea(); | 4418 this.updatePodNameArea_(); |
| 4437 }, | 4419 }, |
| 4438 | 4420 |
| 4439 /** | 4421 /** |
| 4440 * Called when the element is hidden. | 4422 * Called when the element is hidden. |
| 4441 */ | 4423 */ |
| 4442 handleHide: function() { | 4424 handleHide: function() { |
| 4443 for (var event in this.listeners_) { | 4425 for (var event in this.listeners_) { |
| 4444 this.ownerDocument.removeEventListener( | 4426 this.ownerDocument.removeEventListener( |
| 4445 event, this.listeners_[event][0], this.listeners_[event][1]); | 4427 event, this.listeners_[event][0], this.listeners_[event][1]); |
| 4446 } | 4428 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 4474 if (pod && pod.multiProfilesPolicyApplied) { | 4456 if (pod && pod.multiProfilesPolicyApplied) { |
| 4475 pod.userTypeBubbleElement.classList.remove('bubble-shown'); | 4457 pod.userTypeBubbleElement.classList.remove('bubble-shown'); |
| 4476 } | 4458 } |
| 4477 } | 4459 } |
| 4478 }; | 4460 }; |
| 4479 | 4461 |
| 4480 return { | 4462 return { |
| 4481 PodRow: PodRow | 4463 PodRow: PodRow |
| 4482 }; | 4464 }; |
| 4483 }); | 4465 }); |
| OLD | NEW |