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

Side by Side Diff: ui/login/account_picker/md_user_pod_row.js

Issue 2898283002: Multiple user pods implementation for new login screen (Closed)
Patch Set: Created 3 years, 7 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
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 CROS_POD_WIDTH = 306; 51 var CROS_POD_WIDTH = 306;
52 var CROS_SMALL_POD_WIDTH = 304;
53 var CROS_EXTRA_SMALL_POD_WIDTH = 282;
52 var DESKTOP_POD_WIDTH = 180; 54 var DESKTOP_POD_WIDTH = 180;
53 var MD_DESKTOP_POD_WIDTH = 160; 55 var MD_DESKTOP_POD_WIDTH = 160;
54 var PUBLIC_EXPANDED_BASIC_WIDTH = 500; 56 var PUBLIC_EXPANDED_BASIC_WIDTH = 500;
55 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610; 57 var PUBLIC_EXPANDED_ADVANCED_WIDTH = 610;
56 var CROS_POD_HEIGHT = 346; 58 var CROS_POD_HEIGHT = 346;
59 var CROS_SMALL_POD_HEIGHT = 74;
60 var CROS_EXTRA_SMALL_POD_HEIGHT = 60;
57 var DESKTOP_POD_HEIGHT = 226; 61 var DESKTOP_POD_HEIGHT = 226;
58 var MD_DESKTOP_POD_HEIGHT = 200; 62 var MD_DESKTOP_POD_HEIGHT = 200;
59 var POD_ROW_PADDING = 10; 63 var POD_ROW_PADDING = 10;
60 var DESKTOP_ROW_PADDING = 32; 64 var DESKTOP_ROW_PADDING = 32;
61 var CUSTOM_ICON_CONTAINER_SIZE = 40; 65 var CUSTOM_ICON_CONTAINER_SIZE = 40;
62 var CROS_PIN_POD_HEIGHT = 417; 66 var CROS_PIN_POD_HEIGHT = 417;
67 var SCROLL_MASK_HEIGHT = 112;
63 68
64 /** 69 /**
65 * Minimal padding between user pod and virtual keyboard. 70 * Minimal padding between user pod and virtual keyboard.
66 * @type {number} 71 * @type {number}
67 * @const 72 * @const
68 */ 73 */
69 var USER_POD_KEYBOARD_MIN_PADDING = 20; 74 var USER_POD_KEYBOARD_MIN_PADDING = 20;
70 75
71 /** 76 /**
72 * Maximum time for which the pod row remains hidden until all user images 77 * Maximum time for which the pod row remains hidden until all user images
73 * have been loaded. 78 * have been loaded.
74 * @type {number} 79 * @type {number}
75 * @const 80 * @const
76 */ 81 */
77 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000; 82 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000;
78 83
79 /** 84 /**
80 * Public session help topic identifier. 85 * Public session help topic identifier.
81 * @type {number} 86 * @type {number}
82 * @const 87 * @const
83 */ 88 */
84 var HELP_TOPIC_PUBLIC_SESSION = 3041033; 89 var HELP_TOPIC_PUBLIC_SESSION = 3041033;
85 90
86 /** 91 /**
87 * Tab order for user pods. Update these when adding new controls. 92 * Tab order for user pods. Update these when adding new controls.
88 * @enum {number} 93 * @enum {number}
89 * @const 94 * @const
90 */ 95 */
91 var UserPodTabOrder = { 96 var UserPodTabOrder = {
92 POD_INPUT: 1, // Password input field, Action box menu button and 97 POD_INPUT: 1, // Password input field and the pod itself.
93 // the pod itself. 98 PIN_KEYBOARD: 2, // Pin keyboard below the password input field.
94 PIN_KEYBOARD: 2, // Pin keyboard below the password input field. 99 POD_CUSTOM_ICON: 3, // Pod custom icon next to password input field.
95 POD_CUSTOM_ICON: 3, // Pod custom icon next to password input field. 100 HEADER_BAR: 4, // Buttons on the header bar (Shutdown, Add User).
96 HEADER_BAR: 4, // Buttons on the header bar (Shutdown, Add User). 101 ACTION_BOX_BUTTON: 5, // Action box menu button.
97 POD_MENU_ITEM: 5 // User pad menu items (User info, Remove user). 102 POD_MENU_ITEM: 6 // User pod menu items (User info, Remove user).
98 }; 103 };
99 104
100 /** 105 /**
101 * Supported authentication types. Keep in sync with the enum in 106 * Supported authentication types. Keep in sync with the enum in
102 * chrome/browser/signin/screenlock_bridge.h 107 * chrome/browser/signin/screenlock_bridge.h
103 * @enum {number} 108 * @enum {number}
104 * @const 109 * @const
105 */ 110 */
106 var AUTH_TYPE = { 111 var AUTH_TYPE = {
107 OFFLINE_PASSWORD: 0, 112 OFFLINE_PASSWORD: 0,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 {state: FINGERPRINT_STATES.DEFAULT, class: 'default'}, 153 {state: FINGERPRINT_STATES.DEFAULT, class: 'default'},
149 {state: FINGERPRINT_STATES.SIGNIN, class: 'signin'}, 154 {state: FINGERPRINT_STATES.SIGNIN, class: 'signin'},
150 {state: FINGERPRINT_STATES.FAILED, class: 'failed'} 155 {state: FINGERPRINT_STATES.FAILED, class: 'failed'}
151 ]; 156 ];
152 157
153 // Focus and tab order are organized as follows: 158 // Focus and tab order are organized as follows:
154 // 159 //
155 // (1) all user pods have tab index 1 so they are traversed first; 160 // (1) all user pods have tab index 1 so they are traversed first;
156 // (2) when a user pod is activated, its tab index is set to -1 and its 161 // (2) when a user pod is activated, its tab index is set to -1 and its
157 // main input field gets focus and tab index 1; 162 // main input field gets focus and tab index 1;
158 // (3) if user pod custom icon is interactive, it has tab index 2 so it 163 // (3) if pin keyboard is present, it has tab index 2 so it follows the input;
159 // follows the input. 164 // (4) if user pod custom icon is interactive, it has tab index 3;
160 // (4) buttons on the header bar have tab index 3 so they follow the custom 165 // (5) buttons on the header bar have tab index 4;
161 // icon, or user pod if custom icon is not interactive; 166 // (6) Action box buttons have tab index 5 and follow the buttons on the
162 // (5) Action box buttons have tab index 4 and follow header bar buttons; 167 // header bar;
163 // (6) lastly, focus jumps to the Status Area and back to user pods. 168 // (7) User pod menu items (if present) have tab index 6;
169 // (8) lastly, focus jumps to the Status Area and back to user pods.
164 // 170 //
165 // 'Focus' event is handled by a capture handler for the whole document 171 // 'Focus' event is handled by a capture handler for the whole document
166 // and in some cases 'mousedown' event handlers are used instead of 'click' 172 // and in some cases 'mousedown' event handlers are used instead of 'click'
167 // handlers where it's necessary to prevent 'focus' event from being fired. 173 // handlers where it's necessary to prevent 'focus' event from being fired.
168 174
169 /** 175 /**
170 * Helper function to remove a class from given element. 176 * Helper function to remove a class from given element.
171 * @param {!HTMLElement} el Element whose class list to change. 177 * @param {!HTMLElement} el Element whose class list to change.
172 * @param {string} cl Class to remove. 178 * @param {string} cl Class to remove.
173 */ 179 */
(...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 /** 752 /**
747 * True iff the pod can display the pin keyboard. The pin keyboard may not 753 * True iff the pod can display the pin keyboard. The pin keyboard may not
748 * always be displayed even if this is true, ie, if the virtual keyboard is 754 * always be displayed even if this is true, ie, if the virtual keyboard is
749 * also being displayed. 755 * also being displayed.
750 */ 756 */
751 pinEnabled: false, 757 pinEnabled: false,
752 758
753 /** @override */ 759 /** @override */
754 decorate: function() { 760 decorate: function() {
755 this.tabIndex = UserPodTabOrder.POD_INPUT; 761 this.tabIndex = UserPodTabOrder.POD_INPUT;
756 this.actionBoxAreaElement.tabIndex = UserPodTabOrder.POD_INPUT; 762 this.actionBoxAreaElement.tabIndex = UserPodTabOrder.ACTION_BOX_BUTTON;
757 763
758 this.addEventListener('keydown', this.handlePodKeyDown_.bind(this)); 764 this.addEventListener('keydown', this.handlePodKeyDown_.bind(this));
759 this.addEventListener('click', this.handleClickOnPod_.bind(this)); 765 this.addEventListener('click', this.handleClickOnPod_.bind(this));
760 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this)); 766 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this));
761 767
762 if (this.pinKeyboard) { 768 if (this.pinKeyboard) {
763 this.pinKeyboard.passwordElement = this.passwordElement; 769 this.pinKeyboard.passwordElement = this.passwordElement;
764 this.pinKeyboard.addEventListener('pin-change', 770 this.pinKeyboard.addEventListener('pin-change',
765 this.handleInputChanged_.bind(this)); 771 this.handleInputChanged_.bind(this));
766 this.pinKeyboard.tabIndex = UserPodTabOrder.PIN_KEYBOARD; 772 this.pinKeyboard.tabIndex = UserPodTabOrder.PIN_KEYBOARD;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 this.handleInputMouseUp_.bind(this)); 822 this.handleInputMouseUp_.bind(this));
817 823
818 if (this.submitButton) { 824 if (this.submitButton) {
819 this.submitButton.addEventListener('click', 825 this.submitButton.addEventListener('click',
820 this.handleSubmitButtonClick_.bind(this)); 826 this.handleSubmitButtonClick_.bind(this));
821 } 827 }
822 828
823 this.imageElement.addEventListener('load', 829 this.imageElement.addEventListener('load',
824 this.parentNode.handlePodImageLoad.bind(this.parentNode, this)); 830 this.parentNode.handlePodImageLoad.bind(this.parentNode, this));
825 831
832 this.smallPodImageElement.addEventListener(
833 'load',
834 this.parentNode.handlePodImageLoad.bind(this.parentNode, this));
835
826 var initialAuthType = this.user.initialAuthType || 836 var initialAuthType = this.user.initialAuthType ||
827 AUTH_TYPE.OFFLINE_PASSWORD; 837 AUTH_TYPE.OFFLINE_PASSWORD;
828 this.setAuthType(initialAuthType, null); 838 this.setAuthType(initialAuthType, null);
829 839
830 if (this.user.isActiveDirectory) 840 if (this.user.isActiveDirectory)
831 this.setAttribute('is-active-directory', ''); 841 this.setAttribute('is-active-directory', '');
832 842
833 this.userClickAuthAllowed_ = false; 843 this.userClickAuthAllowed_ = false;
834 844
835 // Lazy load the assets needed for the polymer submit button. 845 // Lazy load the assets needed for the polymer submit button.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 955
946 /** 956 /**
947 * Gets name element. 957 * Gets name element.
948 * @type {!HTMLDivElement} 958 * @type {!HTMLDivElement}
949 */ 959 */
950 get nameElement() { 960 get nameElement() {
951 return this.querySelector('.name'); 961 return this.querySelector('.name');
952 }, 962 },
953 963
954 /** 964 /**
965 * Gets image element of the small pod.
966 * @type {!HTMLImageElement}
967 */
968 get smallPodImageElement() {
969 return this.querySelector('.small-pod-image');
970 },
971
972 /**
973 * Gets name element of the small pod.
974 * @type {!HTMLDivElement}
975 */
976 get smallPodNameElement() {
977 return this.querySelector('.small-pod-name');
978 },
979
980 /**
955 * Gets reauth name hint element. 981 * Gets reauth name hint element.
956 * @type {!HTMLDivElement} 982 * @type {!HTMLDivElement}
957 */ 983 */
958 get reauthNameHintElement() { 984 get reauthNameHintElement() {
959 return this.querySelector('.reauth-name-hint'); 985 return this.querySelector('.reauth-name-hint');
960 }, 986 },
961 987
962 /** 988 /**
963 * Gets the container holding the password field. 989 * Gets the container holding the password field.
964 * @type {!HTMLInputElement} 990 * @type {!HTMLInputElement}
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 get customIconElement() { 1142 get customIconElement() {
1117 return this.querySelector('.custom-icon-container'); 1143 return this.querySelector('.custom-icon-container');
1118 }, 1144 },
1119 1145
1120 /** 1146 /**
1121 * Gets the elements used for statistics display. 1147 * Gets the elements used for statistics display.
1122 * @type {Object.<string, !HTMLDivElement>} 1148 * @type {Object.<string, !HTMLDivElement>}
1123 */ 1149 */
1124 get statsMapElements() { 1150 get statsMapElements() {
1125 return { 1151 return {
1126 'BrowsingHistory': 1152 'BrowsingHistory':
1127 this.querySelector('.action-box-remove-user-warning-history'), 1153 this.querySelector('.action-box-remove-user-warning-history'),
jdufault 2017/05/23 20:34:32 revert?
Wenzhao (Colin) Zang 2017/05/24 00:29:21 Reverted. It's changed by style checker.
1128 'Passwords': 1154 'Passwords':
1129 this.querySelector('.action-box-remove-user-warning-passwords'), 1155 this.querySelector('.action-box-remove-user-warning-passwords'),
1130 'Bookmarks': 1156 'Bookmarks':
1131 this.querySelector('.action-box-remove-user-warning-bookmarks'), 1157 this.querySelector('.action-box-remove-user-warning-bookmarks'),
1132 'Settings': 1158 'Settings':
1133 this.querySelector('.action-box-remove-user-warning-settings') 1159 this.querySelector('.action-box-remove-user-warning-settings')
1134 } 1160 }
1135 }, 1161 },
1136 1162
1137 /** 1163 /**
1138 * Gets the fingerprint icon area. 1164 * Gets the fingerprint icon area.
1139 * @type {!HTMLDivElement} 1165 * @type {!HTMLDivElement}
1140 */ 1166 */
1141 get fingerprintIconElement() { 1167 get fingerprintIconElement() {
1142 return this.querySelector('.fingerprint-icon-container'); 1168 return this.querySelector('.fingerprint-icon-container');
1143 }, 1169 },
1144 1170
1171 changeToLargePod: function() {
1172 this.querySelector('.large-pod').hidden = false;
1173 this.querySelector('.small-pod').hidden = true;
1174 },
1175
1176 changeToSmallPod: function() {
1177 this.querySelector('.large-pod').hidden = true;
1178 this.querySelector('.small-pod').hidden = false;
1179 this.querySelector('.small-pod').classList.remove('extra-small');
1180 },
1181
1182 changeToExtraSmallPod: function() {
1183 this.querySelector('.large-pod').hidden = true;
1184 this.querySelector('.small-pod').hidden = false;
1185 this.querySelector('.small-pod').classList.add('extra-small');
1186 },
1187
1188 isInLargeForm: function() {
1189 return this.querySelector('.small-pod').hidden;
1190 },
1191
1192 isInExtraSmallForm: function() {
1193 return this.querySelector('.small-pod').classList.contains('extra-small');
1194 },
1195
1145 /** 1196 /**
1146 * Updates the user pod element. 1197 * Updates the user pod element.
1147 */ 1198 */
1148 update: function() { 1199 update: function() {
1149 this.imageElement.src = 'chrome://userimage/' + this.user.username + 1200 this.imageElement.src = 'chrome://userimage/' + this.user.username +
1150 '?id=' + UserPod.userImageSalt_[this.user.username]; 1201 '?id=' + UserPod.userImageSalt_[this.user.username];
1202 this.smallPodImageElement.src = 'chrome://userimage/' +
jdufault 2017/05/23 20:34:32 Try to avoid redefining (non-trivial) strings mult
Wenzhao (Colin) Zang 2017/05/24 00:29:21 Done.
1203 this.user.username +
1204 '?id=' + UserPod.userImageSalt_[this.user.username];
1151 1205
1152 this.nameElement.textContent = this.user_.displayName; 1206 this.nameElement.textContent = this.user_.displayName;
1207 this.smallPodNameElement.textContent = this.user_.displayName;
1153 this.reauthNameHintElement.textContent = this.user_.displayName; 1208 this.reauthNameHintElement.textContent = this.user_.displayName;
1154 this.classList.toggle('signed-in', this.user_.signedIn); 1209 this.classList.toggle('signed-in', this.user_.signedIn);
1155 1210
1156 if (this.isAuthTypeUserClick) 1211 if (this.isAuthTypeUserClick)
1157 this.passwordLabelElement.textContent = this.authValue; 1212 this.passwordLabelElement.textContent = this.authValue;
1158 1213
1159 this.updateActionBoxArea(); 1214 this.updateActionBoxArea();
1160 1215
1161 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF( 1216 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF(
1162 'passwordFieldAccessibleName', this.user_.emailAddress)); 1217 'passwordFieldAccessibleName', this.user_.emailAddress));
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 } 1850 }
1796 }, 1851 },
1797 1852
1798 /** 1853 /**
1799 * Refresh the message in the remove user warning dialog. 1854 * Refresh the message in the remove user warning dialog.
1800 * @param {string} profilePath The filepath of the URL (must be verified). 1855 * @param {string} profilePath The filepath of the URL (must be verified).
1801 * @param {string} message The message to be written. 1856 * @param {string} message The message to be written.
1802 * @param {number|string=} count The number or string to replace $1 in 1857 * @param {number|string=} count The number or string to replace $1 in
1803 * |message|. Can be omitted if $1 is not present in |message|. 1858 * |message|. Can be omitted if $1 is not present in |message|.
1804 */ 1859 */
1805 updateRemoveWarningDialogSetMessage_: function(profilePath, message, 1860 updateRemoveWarningDialogSetMessage_: function(
1806 count) { 1861 profilePath, message, count) {
1807 if (profilePath !== this.user.profilePath) 1862 if (profilePath !== this.user.profilePath)
1808 return; 1863 return;
1809 // Add localized messages where $1 will be replaced with 1864 // Add localized messages where $1 will be replaced with
1810 // <span class="total-count"></span> and $2 will be replaced with 1865 // <span class="total-count"></span> and $2 will be replaced with
1811 // <span class="email"></span>. 1866 // <span class="email"></span>.
1812 var element = this.querySelector('.action-box-remove-user-warning-text'); 1867 var element = this.querySelector('.action-box-remove-user-warning-text');
1813 element.textContent = ''; 1868 element.textContent = '';
1814 1869
1815 messageParts = message.split(/(\$[12])/); 1870 messageParts = message.split(/(\$[12])/);
1816 var numParts = messageParts.length; 1871 var numParts = messageParts.length;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 this.actionBoxMenuRemoveElement.tabIndex = -1; 2035 this.actionBoxMenuRemoveElement.tabIndex = -1;
1981 }, 2036 },
1982 2037
1983 /** 2038 /**
1984 * Handles mouse down event. It sets whether the user click auth will be 2039 * Handles mouse down event. It sets whether the user click auth will be
1985 * allowed on the next mouse click event. The auth is allowed iff the pod 2040 * allowed on the next mouse click event. The auth is allowed iff the pod
1986 * was focused on the mouse down event starting the click. 2041 * was focused on the mouse down event starting the click.
1987 * @param {Event} e The mouse down event. 2042 * @param {Event} e The mouse down event.
1988 */ 2043 */
1989 handlePodMouseDown_: function(e) { 2044 handlePodMouseDown_: function(e) {
1990 this.userClickAuthAllowed_ = this.parentNode.isFocused(this); 2045 if (this.isInLargeForm())
2046 this.userClickAuthAllowed_ = this.parentNode.isFocused(this);
1991 }, 2047 },
1992 2048
1993 /** 2049 /**
1994 * Called when the input of the password element changes. Updates the submit 2050 * Called when the input of the password element changes. Updates the submit
1995 * button color and state and hides the error popup bubble. 2051 * button color and state and hides the error popup bubble.
1996 */ 2052 */
1997 updateInput_: function() { 2053 updateInput_: function() {
1998 var isEmpty = this.passwordElement.value.length == 0; 2054 var isEmpty = this.passwordElement.value.length == 0;
1999 if (this.submitButton) { 2055 if (this.submitButton) {
2000 this.submitButton.disabled = isEmpty; 2056 this.submitButton.disabled = isEmpty;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 }, 2093 },
2038 2094
2039 /** 2095 /**
2040 * Handles click event on a user pod. 2096 * Handles click event on a user pod.
2041 * @param {Event} e Click event. 2097 * @param {Event} e Click event.
2042 */ 2098 */
2043 handleClickOnPod_: function(e) { 2099 handleClickOnPod_: function(e) {
2044 if (this.parentNode.disabled) 2100 if (this.parentNode.disabled)
2045 return; 2101 return;
2046 2102
2103 if (!this.isInLargeForm()) {
2104 // It should trigger the switch between the small pod and the main pod.
2105 $('pod-row').changeMainPod_(this);
2106 return;
2107 }
2108
2047 if (!this.isActionBoxMenuActive) { 2109 if (!this.isActionBoxMenuActive) {
2048 if (this.isAuthTypeOnlineSignIn) { 2110 if (this.isAuthTypeOnlineSignIn) {
2049 this.showSigninUI(); 2111 this.showSigninUI();
2050 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { 2112 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) {
2051 // Note that this.userClickAuthAllowed_ is set in mouse down event 2113 // Note that this.userClickAuthAllowed_ is set in mouse down event
2052 // handler. 2114 // handler.
2053 this.parentNode.setActivatedPod(this); 2115 this.parentNode.setActivatedPod(this);
2054 } else if (this.pinKeyboard && 2116 } else if (this.pinKeyboard &&
2055 e.target == this.pinKeyboard.submitButton) { 2117 e.target == this.pinKeyboard.submitButton) {
2056 // Sets the pod as activated if the submit button is clicked so that 2118 // Sets the pod as activated if the submit button is clicked so that
2057 // it simulates what the enter button does for the password/pin. 2119 // it simulates what the enter button does for the password/pin.
2058 this.parentNode.setActivatedPod(this); 2120 this.parentNode.setActivatedPod(this);
2059 } 2121 }
2060 2122
2061 if (this.multiProfilesPolicyApplied) 2123 if (this.multiProfilesPolicyApplied)
2062 this.userTypeBubbleElement.classList.add('bubble-shown'); 2124 this.userTypeBubbleElement.classList.add('bubble-shown');
2063 2125
2064 // Prevent default so that we don't trigger 'focus' event and 2126 // Prevent default so that we don't trigger 'focus' event and
2065 // stop propagation so that the 'click' event does not bubble 2127 // stop propagation so that the 'click' event does not bubble
2066 // up and accidentally closes the bubble tooltip. 2128 // up and accidentally closes the bubble tooltip.
2067 stopEventPropagation(e); 2129 stopEventPropagation(e);
2068 } 2130 }
2069 }, 2131 },
2070 2132
2071 /** 2133 /**
2072 * Handles keydown event for a user pod. 2134 * Handles keydown event for a user pod.
2073 * @param {Event} e Key event. 2135 * @param {Event} e Key event.
2074 */ 2136 */
2075 handlePodKeyDown_: function(e) { 2137 handlePodKeyDown_: function(e) {
2138 if (!this.isInLargeForm()) {
2139 this.handleSmallPodKeyDown_(e);
2140 return;
2141 }
2076 if (!this.isAuthTypeUserClick || this.disabled) 2142 if (!this.isAuthTypeUserClick || this.disabled)
2077 return; 2143 return;
2078 switch (e.key) { 2144 switch (e.key) {
2079 case 'Enter': 2145 case 'Enter':
2080 case ' ': 2146 case ' ':
2081 if (this.parentNode.isFocused(this)) 2147 if (this.parentNode.isFocused(this))
2082 this.parentNode.setActivatedPod(this); 2148 this.parentNode.setActivatedPod(this);
2083 break; 2149 break;
2084 } 2150 }
2151 },
2152
2153 /**
2154 * Handles keydown event for a small user pod.
2155 * @param {Event} e Key event.
2156 */
2157 handleSmallPodKeyDown_: function(e) {
2158 switch (e.key) {
2159 case 'Enter':
2160 case ' ':
2161 if ($('pod-row').isFocused(this))
2162 $('pod-row').changeMainPod_(this);
2163 break;
2164 }
2085 } 2165 }
2086 }; 2166 };
2087 2167
2088 /** 2168 /**
2089 * Creates a public account user pod. 2169 * Creates a public account user pod.
2090 * @constructor 2170 * @constructor
2091 * @extends {UserPod} 2171 * @extends {UserPod}
2092 */ 2172 */
2093 var PublicAccountUserPod = cr.ui.define(function() { 2173 var PublicAccountUserPod = cr.ui.define(function() {
2094 var node = UserPod(); 2174 var node = UserPod();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 this.focusInput(); 2366 this.focusInput();
2287 } 2367 }
2288 return true; 2368 return true;
2289 }, 2369 },
2290 2370
2291 /** @override */ 2371 /** @override */
2292 handleClickOnPod_: function(e) { 2372 handleClickOnPod_: function(e) {
2293 if (this.parentNode.disabled) 2373 if (this.parentNode.disabled)
2294 return; 2374 return;
2295 2375
2376 if (!this.isInLargeForm()) {
2377 // It should trigger the switch between the small pod and the main pod.
2378 $('pod-row').changeMainPod_(this);
jdufault 2017/05/23 20:34:32 changeMainPod_ seems like it should be a public (i
Wenzhao (Colin) Zang 2017/05/24 00:29:20 The underscore is removed. I'm open to rename it b
2379 return;
2380 }
2381
2296 this.parentNode.focusPod(this); 2382 this.parentNode.focusPod(this);
2297 this.parentNode.setActivatedPod(this, e); 2383 this.parentNode.setActivatedPod(this, e);
jdufault 2017/05/23 20:34:32 If you remove these two calls, does anything break
Wenzhao (Colin) Zang 2017/05/24 00:29:20 The two calls must be kept for 'large' pods. They
2298 // Prevent default so that we don't trigger 'focus' event. 2384 // Prevent default so that we don't trigger 'focus' event.
2299 e.preventDefault(); 2385 e.preventDefault();
2300 }, 2386 },
2301 2387
2302 /** 2388 /**
2303 * Updates the display name shown on the pod. 2389 * Updates the display name shown on the pod.
2304 * @param {string} displayName The new display name 2390 * @param {string} displayName The new display name
2305 */ 2391 */
2306 setDisplayName: function(displayName) { 2392 setDisplayName: function(displayName) {
2307 this.user_.displayName = displayName; 2393 this.user_.displayName = displayName;
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 get mainInput() { 2605 get mainInput() {
2520 if (this.user.needsSignin) 2606 if (this.user.needsSignin)
2521 return this.passwordElement; 2607 return this.passwordElement;
2522 else 2608 else
2523 return this.nameElement; 2609 return this.nameElement;
2524 }, 2610 },
2525 2611
2526 /** @override */ 2612 /** @override */
2527 update: function() { 2613 update: function() {
2528 this.imageElement.src = this.user.userImage; 2614 this.imageElement.src = this.user.userImage;
2615 this.smallPodImageElement.src = this.user.userImage;
2529 this.nameElement.textContent = this.user.displayName; 2616 this.nameElement.textContent = this.user.displayName;
2617 this.smallPodNameElement.textContent = this.user.displayName;
2530 this.reauthNameHintElement.textContent = this.user.displayName; 2618 this.reauthNameHintElement.textContent = this.user.displayName;
2531 2619
2532 var isLockedUser = this.user.needsSignin; 2620 var isLockedUser = this.user.needsSignin;
2533 var isLegacySupervisedUser = this.user.legacySupervisedUser; 2621 var isLegacySupervisedUser = this.user.legacySupervisedUser;
2534 var isChildUser = this.user.childUser; 2622 var isChildUser = this.user.childUser;
2535 var isSyncedUser = this.user.emailAddress !== ""; 2623 var isSyncedUser = this.user.emailAddress !== "";
2536 var isProfileLoaded = this.user.isProfileLoaded; 2624 var isProfileLoaded = this.user.isProfileLoaded;
2537 this.classList.toggle('locked', isLockedUser); 2625 this.classList.toggle('locked', isLockedUser);
2538 this.classList.toggle('legacy-supervised', isLegacySupervisedUser); 2626 this.classList.toggle('legacy-supervised', isLegacySupervisedUser);
2539 this.classList.toggle('child', isChildUser); 2627 this.classList.toggle('child', isChildUser);
(...skipping 24 matching lines...) Expand all
2564 } 2652 }
2565 this.passwordElement.value = ''; 2653 this.passwordElement.value = '';
2566 return true; 2654 return true;
2567 }, 2655 },
2568 2656
2569 /** @override */ 2657 /** @override */
2570 handleClickOnPod_: function(e) { 2658 handleClickOnPod_: function(e) {
2571 if (this.parentNode.disabled) 2659 if (this.parentNode.disabled)
2572 return; 2660 return;
2573 2661
2662 if (!this.isInLargeForm()) {
2663 // It should trigger the switch between the small pod and the main pod.
2664 $('pod-row').changeMainPod_(this);
2665 return;
2666 }
2667
2574 Oobe.clearErrors(); 2668 Oobe.clearErrors();
2575 this.parentNode.lastFocusedPod_ = this; 2669 this.parentNode.lastFocusedPod_ = this;
2576 2670
2577 // If this is a locked pod and there are local credentials, show the 2671 // If this is a locked pod and there are local credentials, show the
2578 // password field. Otherwise call activate() which will open up a browser 2672 // password field. Otherwise call activate() which will open up a browser
2579 // window or show the reauth dialog, as needed. 2673 // window or show the reauth dialog, as needed.
2580 if (!(this.user.needsSignin && this.user.hasLocalCreds) && 2674 if (!(this.user.needsSignin && this.user.hasLocalCreds) &&
2581 !this.isActionBoxMenuActive) { 2675 !this.isActionBoxMenuActive) {
2582 this.activate(e); 2676 this.activate(e);
2583 } 2677 }
(...skipping 21 matching lines...) Expand all
2605 UserPod.prototype.decorate.call(this); 2699 UserPod.prototype.decorate.call(this);
2606 this.launchAppButtonElement.addEventListener('click', 2700 this.launchAppButtonElement.addEventListener('click',
2607 this.activate.bind(this)); 2701 this.activate.bind(this));
2608 }, 2702 },
2609 2703
2610 /** @override */ 2704 /** @override */
2611 update: function() { 2705 update: function() {
2612 this.imageElement.src = this.user.iconUrl; 2706 this.imageElement.src = this.user.iconUrl;
2613 this.imageElement.alt = this.user.label; 2707 this.imageElement.alt = this.user.label;
2614 this.imageElement.title = this.user.label; 2708 this.imageElement.title = this.user.label;
2709 this.smallPodImageElement.src = this.user.iconUrl;
2710 this.smallPodImageElement.alt = this.user.label;
2711 this.smallPodImageElement.title = this.user.label;
2615 this.passwordEntryContainerElement.hidden = true; 2712 this.passwordEntryContainerElement.hidden = true;
2616 this.launchAppButtonContainerElement.hidden = false; 2713 this.launchAppButtonContainerElement.hidden = false;
2617 this.nameElement.textContent = this.user.label; 2714 this.nameElement.textContent = this.user.label;
2715 this.smallPodNameElement.textContent = this.user.label;
2618 this.reauthNameHintElement.textContent = this.user.label; 2716 this.reauthNameHintElement.textContent = this.user.label;
2619 2717
2620 UserPod.prototype.updateActionBoxArea.call(this); 2718 UserPod.prototype.updateActionBoxArea.call(this);
2621 UserPod.prototype.customizeUserPodPerUserType.call(this); 2719 UserPod.prototype.customizeUserPodPerUserType.call(this);
2622 }, 2720 },
2623 2721
2624 /** @override */ 2722 /** @override */
2625 get mainInput() { 2723 get mainInput() {
2626 return this.launchAppButtonElement; 2724 return this.launchAppButtonElement;
2627 }, 2725 },
(...skipping 16 matching lines...) Expand all
2644 var diagnosticMode = e && e.ctrlKey; 2742 var diagnosticMode = e && e.ctrlKey;
2645 this.launchApp_(this.user, diagnosticMode); 2743 this.launchApp_(this.user, diagnosticMode);
2646 return true; 2744 return true;
2647 }, 2745 },
2648 2746
2649 /** @override */ 2747 /** @override */
2650 handleClickOnPod_: function(e) { 2748 handleClickOnPod_: function(e) {
2651 if (this.parentNode.disabled) 2749 if (this.parentNode.disabled)
2652 return; 2750 return;
2653 2751
2752 if (!this.isInLargeForm()) {
2753 // It should trigger the switch between the small pod and the main pod.
2754 $('pod-row').changeMainPod_(this);
2755 return;
2756 }
2757
2654 Oobe.clearErrors(); 2758 Oobe.clearErrors();
2655 this.parentNode.lastFocusedPod_ = this; 2759 this.parentNode.lastFocusedPod_ = this;
2656 this.activate(e); 2760 this.activate(e);
2657 }, 2761 },
2658 2762
2659 /** 2763 /**
2660 * Launch the app. If |diagnosticMode| is true, ask user to confirm. 2764 * Launch the app. If |diagnosticMode| is true, ask user to confirm.
2661 * @param {Object} app App data. 2765 * @param {Object} app App data.
2662 * @param {boolean} diagnosticMode Whether to run the app in diagnostic 2766 * @param {boolean} diagnosticMode Whether to run the app in diagnostic
2663 * mode. 2767 * mode.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 2809
2706 // Focused pod. 2810 // Focused pod.
2707 focusedPod_: undefined, 2811 focusedPod_: undefined,
2708 2812
2709 // Activated pod, i.e. the pod of current login attempt. 2813 // Activated pod, i.e. the pod of current login attempt.
2710 activatedPod_: undefined, 2814 activatedPod_: undefined,
2711 2815
2712 // Pod that was most recently focused, if any. 2816 // Pod that was most recently focused, if any.
2713 lastFocusedPod_: undefined, 2817 lastFocusedPod_: undefined,
2714 2818
2819 // Pod that occupies the main spot.
2820 mainPod_: undefined,
2821
2715 // Pods whose initial images haven't been loaded yet. 2822 // Pods whose initial images haven't been loaded yet.
2716 podsWithPendingImages_: [], 2823 podsWithPendingImages_: [],
2717 2824
2718 // Whether pod placement has been postponed. 2825 // Whether pod placement has been postponed.
2719 podPlacementPostponed_: false, 2826 podPlacementPostponed_: false,
2720 2827
2721 // Standard user pod height/width. 2828 // Standard user pod height/width.
2722 userPodHeight_: 0, 2829 userPodHeight_: 0,
2723 userPodWidth_: 0, 2830 userPodWidth_: 0,
2724 2831
(...skipping 27 matching lines...) Expand all
2752 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT : 2859 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT :
2753 DESKTOP_POD_HEIGHT : 2860 DESKTOP_POD_HEIGHT :
2754 CROS_POD_HEIGHT; 2861 CROS_POD_HEIGHT;
2755 this.userPodWidth_ = isDesktopUserManager ? 2862 this.userPodWidth_ = isDesktopUserManager ?
2756 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH : 2863 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH :
2757 DESKTOP_POD_WIDTH : 2864 DESKTOP_POD_WIDTH :
2758 CROS_POD_WIDTH; 2865 CROS_POD_WIDTH;
2759 }, 2866 },
2760 2867
2761 /** 2868 /**
2762 * Returns all the pods in this pod row. 2869 * Returns all the pods in this pod row. Some pods may not be its direct
2870 * children, but the caller doesn't have to know this.
2763 * @type {NodeList} 2871 * @type {NodeList}
2764 */ 2872 */
2765 get pods() { 2873 get pods() {
2766 return Array.prototype.slice.call(this.children); 2874 var powRowChildren = Array.prototype.slice.call(this.children);
2875 var containerChildren =
2876 Array.prototype.slice.call(this.smallPodsContainer.children);
2877 return powRowChildren.concat(containerChildren);
2767 }, 2878 },
2768 2879
2769 /** 2880 /**
2770 * Return true if user pod row has only single user pod in it, which should 2881 * Return true if user pod row has only single user pod in it, which should
2771 * always be focused except desktop and touch view modes. 2882 * always be focused except desktop and touch view modes.
2772 * @type {boolean} 2883 * @type {boolean}
2773 */ 2884 */
2774 get alwaysFocusSinglePod() { 2885 get alwaysFocusSinglePod() {
2775 var isDesktopUserManager = Oobe.getInstance().displayType == 2886 var isDesktopUserManager = Oobe.getInstance().displayType ==
2776 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 2887 DISPLAY_TYPE.DESKTOP_USER_MANAGER;
2777 2888
2778 return (isDesktopUserManager || this.touchViewEnabled_) ? 2889 return (isDesktopUserManager || this.touchViewEnabled_) ?
2779 false : this.children.length == 1; 2890 false :
2891 this.pods.length == 1;
2780 }, 2892 },
2781 2893
2782 /** 2894 /**
2783 * Returns pod with the given app id. 2895 * Returns pod with the given app id.
2784 * @param {!string} app_id Application id to be matched. 2896 * @param {!string} app_id Application id to be matched.
2785 * @return {Object} Pod with the given app id. null if pod hasn't been 2897 * @return {Object} Pod with the given app id. null if pod hasn't been
2786 * found. 2898 * found.
2787 */ 2899 */
2788 getPodWithAppId_: function(app_id) { 2900 getPodWithAppId_: function(app_id) {
2789 for (var i = 0, pod; pod = this.pods[i]; ++i) { 2901 for (var i = 0, pod; pod = this.pods[i]; ++i) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 /** 3058 /**
2947 * Removes user pod from pod row. 3059 * Removes user pod from pod row.
2948 * @param {!user} username 3060 * @param {!user} username
2949 */ 3061 */
2950 removeUserPod: function(username) { 3062 removeUserPod: function(username) {
2951 var podToRemove = this.getPodWithUsername_(username); 3063 var podToRemove = this.getPodWithUsername_(username);
2952 if (podToRemove == null) { 3064 if (podToRemove == null) {
2953 console.warn('Attempt to remove pod that does not exist'); 3065 console.warn('Attempt to remove pod that does not exist');
2954 return; 3066 return;
2955 } 3067 }
2956 this.removeChild(podToRemove); 3068 podToRemove.parentNode.removeChild(podToRemove);
2957 if (this.pods.length > 0) 3069 this.mainPod_ = null;
3070 if (this.pods.length > 0) {
2958 this.placePods_(); 3071 this.placePods_();
3072 this.maybePreselectPod();
3073 }
2959 }, 3074 },
2960 3075
2961 /** 3076 /**
2962 * Returns index of given pod or -1 if not found. 3077 * Returns index of given pod or -1 if not found.
2963 * @param {UserPod} pod Pod to look up. 3078 * @param {UserPod} pod Pod to look up.
2964 * @private 3079 * @private
2965 */ 3080 */
2966 indexOf_: function(pod) { 3081 indexOf_: function(pod) {
2967 for (var i = 0; i < this.pods.length; ++i) { 3082 for (var i = 0; i < this.pods.length; ++i) {
2968 if (pod == this.pods[i]) 3083 if (pod == this.pods[i])
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3017 3132
3018 // Clear existing pods. 3133 // Clear existing pods.
3019 this.innerHTML = ''; 3134 this.innerHTML = '';
3020 this.focusedPod_ = undefined; 3135 this.focusedPod_ = undefined;
3021 this.activatedPod_ = undefined; 3136 this.activatedPod_ = undefined;
3022 this.lastFocusedPod_ = undefined; 3137 this.lastFocusedPod_ = undefined;
3023 3138
3024 // Switch off animation 3139 // Switch off animation
3025 Oobe.getInstance().toggleClass('flying-pods', false); 3140 Oobe.getInstance().toggleClass('flying-pods', false);
3026 3141
3027 // Populate the pod row.
3028 for (var i = 0; i < this.users_.length; ++i) 3142 for (var i = 0; i < this.users_.length; ++i)
3029 this.addUserPod(this.users_[i]); 3143 this.addUserPod(this.users_[i]);
3030 3144
3031 for (var i = 0, pod; pod = this.pods[i]; ++i) 3145 for (var i = 0, pod; pod = this.pods[i]; ++i)
3032 this.podsWithPendingImages_.push(pod); 3146 this.podsWithPendingImages_.push(pod);
3033 3147
3034 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. 3148 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting.
3035 if (this.shouldShowApps_) { 3149 if (this.shouldShowApps_) {
3036 for (var i = 0; i < this.apps_.length; ++i) 3150 for (var i = 0; i < this.apps_.length; ++i)
3037 this.addUserPod(this.apps_[i]); 3151 this.addUserPod(this.apps_[i]);
(...skipping 25 matching lines...) Expand all
3063 if ($('login-header-bar').signinUIState == 3177 if ($('login-header-bar').signinUIState ==
3064 SIGNIN_UI_STATE.GAIA_SIGNIN && 3178 SIGNIN_UI_STATE.GAIA_SIGNIN &&
3065 emptyPodRow && 3179 emptyPodRow &&
3066 this.pods.length > 0) { 3180 this.pods.length > 0) {
3067 login.GaiaSigninScreen.updateControlsState(); 3181 login.GaiaSigninScreen.updateControlsState();
3068 } 3182 }
3069 } 3183 }
3070 }, 3184 },
3071 3185
3072 /** 3186 /**
3187 * Gets the container of small pods.
3188 * @type {!HTMLDivElement}
3189 */
3190 get smallPodsContainer() {
3191 return document.querySelector('.small-pod-container');
3192 },
3193
3194 /**
3073 * Adds given apps to the pod row. 3195 * Adds given apps to the pod row.
3074 * @param {array} apps Array of apps. 3196 * @param {array} apps Array of apps.
3075 */ 3197 */
3076 setApps: function(apps) { 3198 setApps: function(apps) {
3077 this.apps_ = apps; 3199 this.apps_ = apps;
3078 this.rebuildPods(); 3200 this.rebuildPods();
3079 chrome.send('kioskAppsLoaded'); 3201 chrome.send('kioskAppsLoaded');
3080 3202
3081 // Check whether there's a pending kiosk app error. 3203 // Check whether there's a pending kiosk app error.
3082 window.setTimeout(function() { 3204 window.setTimeout(function() {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 }, 3437 },
3316 3438
3317 /** 3439 /**
3318 * Updates the list of locales available for a public session. 3440 * Updates the list of locales available for a public session.
3319 * @param {string} userID The user ID of the public session 3441 * @param {string} userID The user ID of the public session
3320 * @param {!Object} locales The list of available locales 3442 * @param {!Object} locales The list of available locales
3321 * @param {string} defaultLocale The locale to select by default 3443 * @param {string} defaultLocale The locale to select by default
3322 * @param {boolean} multipleRecommendedLocales Whether |locales| contains 3444 * @param {boolean} multipleRecommendedLocales Whether |locales| contains
3323 * two or more recommended locales 3445 * two or more recommended locales
3324 */ 3446 */
3325 setPublicSessionLocales: function(userID, 3447 setPublicSessionLocales: function(
3326 locales, 3448 userID, locales, defaultLocale, multipleRecommendedLocales) {
3327 defaultLocale,
3328 multipleRecommendedLocales) {
3329 var pod = this.getPodWithUsername_(userID); 3449 var pod = this.getPodWithUsername_(userID);
3330 if (pod != null) { 3450 if (pod != null) {
3331 pod.populateLanguageSelect(locales, 3451 pod.populateLanguageSelect(locales,
3332 defaultLocale, 3452 defaultLocale,
3333 multipleRecommendedLocales); 3453 multipleRecommendedLocales);
3334 } 3454 }
3335 }, 3455 },
3336 3456
3337 /** 3457 /**
3338 * Updates the list of available keyboard layouts for a public session pod. 3458 * Updates the list of available keyboard layouts for a public session pod.
3339 * @param {string} userID The user ID of the public session 3459 * @param {string} userID The user ID of the public session
3340 * @param {string} locale The locale to which this list of keyboard layouts 3460 * @param {string} locale The locale to which this list of keyboard layouts
3341 * applies 3461 * applies
3342 * @param {!Object} list List of available keyboard layouts 3462 * @param {!Object} list List of available keyboard layouts
3343 */ 3463 */
3344 setPublicSessionKeyboardLayouts: function(userID, locale, list) { 3464 setPublicSessionKeyboardLayouts: function(userID, locale, list) {
3345 var pod = this.getPodWithUsername_(userID); 3465 var pod = this.getPodWithUsername_(userID);
3346 if (pod != null) 3466 if (pod != null)
3347 pod.populateKeyboardSelect(locale, list); 3467 pod.populateKeyboardSelect(locale, list);
3348 }, 3468 },
3349 3469
3350 /** 3470 /**
3351 * Called when window was resized. 3471 * Called when window was resized.
3352 */ 3472 */
3353 onWindowResize: function() { 3473 onWindowResize: function() {
jdufault 2017/05/23 20:34:32 Did you test with virtual keyboard?
Wenzhao (Colin) Zang 2017/05/24 00:29:20 I did. It works, but has bugs related to the backg
3354 var layout = this.calculateLayout_(); 3474 this.placePods_();
3355 if (layout.columns != this.columns || layout.rows != this.rows)
3356 this.placePods_();
3357
3358 // Wrap this in a set timeout so the function is called after the pod is
3359 // finished transitioning so that we work with the final pod dimensions.
3360 // If there is no focused pod that may be transitioning when this function
3361 // is called, we can call scrollFocusedPodIntoView() right away.
3362 var timeOut = 0;
3363 if (this.focusedPod_) {
3364 var style = getComputedStyle(this.focusedPod_);
3365 timeOut = parseFloat(style.transitionDuration) * 1000;
3366 }
3367
3368 setTimeout(function() {
3369 this.scrollFocusedPodIntoView();
3370 }.bind(this), timeOut);
3371 }, 3475 },
3372 3476
3373 /** 3477 /**
3374 * Returns width of podrow having |columns| number of columns. 3478 * Returns width of podrow having |columns| number of columns.
3375 * @private 3479 * @private
3376 */ 3480 */
3377 columnsToWidth_: function(columns) { 3481 columnsToWidth_: function(columns) {
3378 var isDesktopUserManager = Oobe.getInstance().displayType == 3482 var isDesktopUserManager = Oobe.getInstance().displayType ==
3379 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 3483 DISPLAY_TYPE.DESKTOP_USER_MANAGER;
3380 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : 3484 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] :
(...skipping 30 matching lines...) Expand all
3411 while (maxWidth < this.columnsToWidth_(columns) && columns > 1) 3515 while (maxWidth < this.columnsToWidth_(columns) && columns > 1)
3412 --columns; 3516 --columns;
3413 var rows = Math.floor((this.pods.length - 1) / columns) + 1; 3517 var rows = Math.floor((this.pods.length - 1) / columns) + 1;
3414 if (getComputedStyle( 3518 if (getComputedStyle(
3415 $('signin-banner'), null).getPropertyValue('display') != 'none') { 3519 $('signin-banner'), null).getPropertyValue('display') != 'none') {
3416 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER); 3520 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER);
3417 } 3521 }
3418 if (!Oobe.getInstance().newDesktopUserManager) { 3522 if (!Oobe.getInstance().newDesktopUserManager) {
3419 var maxHeigth = Oobe.getInstance().clientAreaSize.height; 3523 var maxHeigth = Oobe.getInstance().clientAreaSize.height;
3420 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1) 3524 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1)
3421 --rows; 3525 --rows;
3422 } 3526 }
3423 // One more iteration if it's not enough cells to place all pods. 3527 // One more iteration if it's not enough cells to place all pods.
3424 while (maxWidth >= this.columnsToWidth_(columns + 1) && 3528 while (maxWidth >= this.columnsToWidth_(columns + 1) &&
3425 columns * rows < this.pods.length && 3529 columns * rows < this.pods.length &&
3426 columns < MAX_NUMBER_OF_COLUMNS) { 3530 columns < MAX_NUMBER_OF_COLUMNS) {
3427 ++columns; 3531 ++columns;
3428 } 3532 }
3429 return {columns: columns, rows: rows}; 3533 return {columns: columns, rows: rows};
3430 }, 3534 },
3431 3535
3432 /** 3536 /**
3433 * Places pods onto their positions onto pod grid. 3537 * Places pods onto their positions in pod grid matching the new design.
3434 * @private 3538 * @private
3435 */ 3539 */
3436 placePods_: function() { 3540 placePods_: function() {
3437 var isDesktopUserManager = Oobe.getInstance().displayType == 3541 var pods = this.pods;
3438 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 3542 if (pods.length == 0) {
3439 if (isDesktopUserManager && !Oobe.getInstance().userPodsPageVisible) 3543 console.error('Attempt to place pods for an empty pod list.');
3440 return; 3544 return;
3441 3545 }
3442 var layout = this.calculateLayout_(); 3546 // Append all pods to their proper parents. Small pods have parent other
3443 var columns = this.columns = layout.columns; 3547 // than the pod row. The pods were all initialized with the pow row as a
3444 var rows = this.rows = layout.rows; 3548 // temporary parent, which is intended to ensure that all event listeners
3445 var maxPodsNumber = columns * rows; 3549 // work properly. If the main pod already exists, it means we are in the
3446 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : 3550 // process of resizing the window, then there is no need to change parents
3447 MARGIN_BY_COLUMNS[columns]; 3551 // of any pod.
3552 if (!this.mainPod_) {
3553 this.mainPod_ = this.preselectedPod;
3554 this.appendPodsToParents();
3555 }
3556 this.restoreInitialStates_();
3557
3558 if (pods.length == 1) {
3559 this.placeSinglePod_();
3560 } else if (pods.length == 2) {
3561 this.placeDoublePods_();
3562 } else {
3563 this.placePodsOnContainer_();
3564 }
3565 Oobe.getInstance().updateScreenSize(this.parentNode);
3566 this.updatePodNameArea();
3567 },
3568
3569 /**
3570 * Append pods to proper parents. Called each time before pod placement.
3571 * @private
3572 */
3573 appendPodsToParents: function() {
3574 var pods = this.pods;
3575 // Pod count may have changed, remove all pods from their current parents
3576 // first.
3577 for (var i = 0, pod; pod = pods[i]; ++i) {
jdufault 2017/05/23 20:34:32 for (var pod of pods)?
Wenzhao (Colin) Zang 2017/05/24 00:29:20 Done.
3578 pod.parentNode.removeChild(pod);
3579 }
3580
3581 if (pods.length <= 2) {
jdufault 2017/05/23 20:34:32 Add comment on the 2 / make it a constant
Wenzhao (Colin) Zang 2017/05/24 00:29:20 Done.
3582 for (var i = 0, pod; pod = pods[i]; ++i) {
3583 this.appendChild(pod);
3584 }
3585 } else {
3586 for (var i = 0, pod; pod = pods[i]; ++i) {
3587 if (pod == this.mainPod_) {
3588 this.appendChild(pod);
3589 } else {
3590 this.smallPodsContainer.appendChild(pod);
3591 }
3592 }
3593 }
3594 },
3595
3596 /**
3597 * Called when there is one user.
3598 * @private
3599 */
3600 placeSinglePod_: function() {
3601 this.mainPod_.changeToLargePod();
3602 this.parentNode.setPreferredSize(CROS_POD_WIDTH, CROS_POD_HEIGHT);
3603 // The pod may have different positions before, so always set them
3604 // explicitly.
3605 this.mainPod_.left = 0;
3606 this.mainPod_.top = 0;
3607 },
3608
3609 /**
3610 * Called when there are two users.
3611 * @private
3612 */
3613 placeDoublePods_: function() {
3614 var secondPod =
3615 this.pods[0] == this.mainPod_ ? this.pods[1] : this.pods[0];
3616 this.mainPod_.changeToLargePod();
3617 secondPod.changeToLargePod();
3618
3619 var DOUBLE_PODS_PADDING = this.isPortraitMode() ? 32 : 118;
3620 var parentWidth = CROS_POD_WIDTH * 2 + DOUBLE_PODS_PADDING;
3621 this.parentNode.setPreferredSize(parentWidth, CROS_POD_HEIGHT);
3622
3623 this.mainPod_.left = 0;
3624 this.mainPod_.top = 0;
3625 secondPod.left = CROS_POD_WIDTH + DOUBLE_PODS_PADDING;
3626 secondPod.top = 0;
3627 },
3628
3629 /**
3630 * Called when there are more than two users.
3631 * @private
3632 */
3633 placePodsOnContainer_: function() {
3634 this.smallPodsContainer.hidden = false;
3635 var pods = this.pods;
3636 if ((pods.length > 6 && !this.isPortraitMode()) ||
jdufault 2017/05/23 20:34:32 constant for 6 and 10
Wenzhao (Colin) Zang 2017/05/24 00:29:21 Done.
3637 (pods.length > 10 && this.isPortraitMode())) {
3638 this.placePodsOnScrollableContainer_();
3639 return;
3640 }
3641
3642 var MIDDLE_PADDING = this.isPortraitMode() ? 84 : 220;
3643 var portraitWidth =
3644 CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH;
3645 var LEFT_PADDING = this.isPortraitMode() ?
3646 (Oobe.getInstance().clientAreaSize.width - portraitWidth) / 3 :
3647 98;
3648 var SMALL_POD_PADDING = 54;
3649 var smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT +
3650 (pods.length - 2) * SMALL_POD_PADDING;
3651 var parentHeight = Math.max(CROS_POD_HEIGHT, smallPodsTotalHeight);
3652 if (parentHeight > Oobe.getInstance().clientAreaSize.height) {
3653 // The current design spec assumes the screen height is large enough,
3654 // but if it's not, fall to the scrollable container case. We do not
3655 // have a backup solution yet if the screen width is exceeded.
3656 this.placePodsOnScrollableContainer_();
3657 return;
3658 }
3659 this.smallPodsContainer.style.height =
3660 cr.ui.toCssPx(Oobe.getInstance().clientAreaSize.height);
3661 this.smallPodsContainer.style.width = cr.ui.toCssPx(CROS_SMALL_POD_WIDTH);
3662 var parentWidth =
3663 LEFT_PADDING + CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH;
3664 this.parentNode.setPreferredSize(parentWidth, parentHeight);
3665
3666 this.mainPod_.changeToLargePod();
3667 for (var i = 0, pod; pod = pods[i]; ++i) {
3668 if (pod != this.mainPod_) {
3669 pod.changeToSmallPod();
3670 }
3671 }
3672 this.mainPod_.left = LEFT_PADDING;
3673 this.mainPod_.top =
3674 Math.max((smallPodsTotalHeight - CROS_POD_HEIGHT) / 2, 0);
3675 this.smallPodsContainer.style.left =
3676 cr.ui.toCssPx(LEFT_PADDING + CROS_POD_WIDTH + MIDDLE_PADDING);
3677 this.smallPodsContainer.style.top = cr.ui.toCssPx(
3678 Math.max((CROS_POD_HEIGHT - smallPodsTotalHeight) / 2, 0));
3679 var topPadding = 0;
3680 for (var i = 0, pod; pod = pods[i]; ++i) {
3681 if (pod == this.mainPod_) {
3682 continue;
3683 }
3684 pod.left = 0;
3685 pod.top = topPadding;
3686 topPadding += CROS_SMALL_POD_HEIGHT + SMALL_POD_PADDING;
3687 }
3688 },
3689
3690 /**
3691 * Called when there are more than 6 users in landscape mode, or more than
3692 * 10 users in portrait mode.
3693 * @private
3694 */
3695 placePodsOnScrollableContainer_: function() {
3696 this.smallPodsContainer.hidden = false;
3697 this.smallPodsContainer.classList.add('scroll');
3698 var pods = this.pods;
3699 this.mainPod_.changeToLargePod();
3700 for (var i = 0, pod; pod = pods[i]; ++i) {
3701 if (pod != this.mainPod_) {
3702 pod.changeToExtraSmallPod();
3703 }
3704 }
3705
3706 var SCROLL_LEFT_PADDING = this.isPortraitMode() ? 46 : 72;
3707 var SCROLL_RIGHT_PADDING = this.isPortraitMode() ? 12 : 72;
3708 var scrollAreaWidth = SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH +
3709 SCROLL_RIGHT_PADDING;
3710 var mainPodPadding = (Oobe.getInstance().clientAreaSize.width -
3711 scrollAreaWidth - CROS_POD_WIDTH) /
3712 2;
3713 var SCROLL_TOP_PADDING = this.isPortraitMode() ? 66 : 72;
3714 var EXTRA_SMALL_POD_PADDING = 32;
3715 this.smallPodsContainer.style.left =
3716 cr.ui.toCssPx(mainPodPadding * 2 + CROS_POD_WIDTH);
3717 this.smallPodsContainer.style.top = cr.ui.toCssPx(0);
3718
3719 var scrollHeight = 0;
3720 for (var i = 0, pod; pod = pods[i]; ++i) {
3721 if (pod == this.mainPod_) {
3722 continue;
3723 }
3724 scrollHeight += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING;
3725 }
3726 scrollHeight -= EXTRA_SMALL_POD_PADDING;
3727 var screenHeight =
3728 document.querySelector('#scroll-container').offsetHeight;
3729 var actualTopPadding = SCROLL_TOP_PADDING;
3730 this.smallPodsContainer.style.width = cr.ui.toCssPx(
3731 SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH +
3732 SCROLL_RIGHT_PADDING);
3733 this.smallPodsContainer.style.height = cr.ui.toCssPx(screenHeight);
3734 if ((screenHeight - scrollHeight) / 2 > actualTopPadding) {
3735 // Edge case: the contents don't overflow because the pods were
3736 // shrinked. In this case the top padding should be adjusted to have a
3737 // symmetric layout.
3738 actualTopPadding = (screenHeight - scrollHeight) / 2;
3739 } else {
3740 // The scrollable container should occupy the full screen (including the
3741 // header bar) and a gradient mask is applied to avoid blocking the
3742 // header bar.
3743 actualTopPadding = SCROLL_MASK_HEIGHT;
3744 this.showScrollMask();
3745 }
3448 this.parentNode.setPreferredSize( 3746 this.parentNode.setPreferredSize(
3449 this.columnsToWidth_(columns), this.rowsToHeight_(rows)); 3747 Oobe.getInstance().clientAreaSize.width,
3450 var height = this.userPodHeight_; 3748 Oobe.getInstance().clientAreaSize.height);
3451 var width = this.userPodWidth_; 3749 this.mainPod_.left = mainPodPadding;
3452 var pinPodLocation = { column: columns + 1, row: rows + 1 }; 3750 this.mainPod_.top = (screenHeight - CROS_POD_HEIGHT) / 2;
3453 if (this.focusedPod_ && this.focusedPod_.isPinShown()) 3751
3454 pinPodLocation = this.findPodLocation_(this.focusedPod_, columns, rows); 3752 var topPadding = actualTopPadding;
3455 3753 var lastPod = undefined;
3456 this.pods.forEach(function(pod, index) { 3754 for (var i = 0, pod; pod = pods[i]; ++i) {
3457 if (index >= maxPodsNumber) { 3755 if (pod == this.mainPod_) {
3458 pod.hidden = true; 3756 continue;
3459 return; 3757 }
3460 } 3758 pod.left = SCROLL_LEFT_PADDING;
3461 pod.hidden = false; 3759 pod.top = topPadding;
3462 if (pod.offsetHeight != height && 3760 topPadding += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING;
3463 pod.offsetHeight != CROS_PIN_POD_HEIGHT) { 3761 lastPod = pod;
3464 console.error('Pod offsetHeight (' + pod.offsetHeight + 3762 }
3465 ') and POD_HEIGHT (' + height + ') are not equal.'); 3763 if (!document.querySelector('.small-pod-container-mask').hidden) {
3466 } 3764 // Make sure the last pod isn't blocked by the mask.
3467 if (pod.offsetWidth != width) { 3765 lastPod.style.paddingBottom = cr.ui.toCssPx(SCROLL_MASK_HEIGHT);
3468 console.error('Pod offsetWidth (' + pod.offsetWidth + 3766 }
3469 ') and POD_WIDTH (' + width + ') are not equal.'); 3767 },
3470 } 3768
3471 var column = index % columns; 3769 /**
3472 var row = Math.floor(index / columns); 3770 * Called each time before pod placement to ensure we start with a clean
3473 3771 * state.
3474 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : 3772 * @private
3475 POD_ROW_PADDING; 3773 */
3476 pod.left = rowPadding + column * (width + margin); 3774 restoreInitialStates_: function() {
3477 3775 this.smallPodsContainer.hidden = true;
3478 // On desktop, we want the rows to always be equally spaced. 3776 document.querySelector('.small-pod-container-mask').hidden = true;
3479 pod.top = isDesktopUserManager ? row * (height + rowPadding) : 3777 document.querySelector('.small-pod-container-mask.rotate').hidden = true;
3480 row * height + rowPadding; 3778 this.smallPodsContainer.classList.remove('scroll');
3779 var pods = this.pods;
3780 for (var i = 0, pod; pod = pods[i]; ++i) {
3781 pod.style.paddingBottom = cr.ui.toCssPx(0);
3782 }
3783 },
3784
3785 /**
3786 * Check if it's in portrait mode.
3787 * @return {boolean} True if in portrait mode.
3788 */
3789 isPortraitMode: function() {
3790 return Oobe.getInstance().clientAreaSize.width <
3791 Oobe.getInstance().clientAreaSize.height;
3792 },
3793
3794 /**
3795 * Called when scroll bar is shown and we need a mask for the header bar.
3796 * @private
3797 */
3798 showScrollMask: function() {
3799 var topMask = document.querySelector('.small-pod-container-mask');
3800 topMask.hidden = false;
3801 topMask.style.left = this.smallPodsContainer.style.left;
3802 topMask.style.width = this.smallPodsContainer.style.width;
3803 var bottomMask =
3804 document.querySelector('.small-pod-container-mask.rotate');
3805 bottomMask.hidden = false;
3806 bottomMask.style.left = this.smallPodsContainer.style.left;
3807 bottomMask.style.width = this.smallPodsContainer.style.width;
3808 // The bottom mask should overlap with the header bar.
3809 bottomMask.style.top = cr.ui.toCssPx(
3810 document.querySelector('#scroll-container').offsetHeight -
3811 SCROLL_MASK_HEIGHT);
3812 },
3813
3814 /**
3815 * Makes sure that user name on each large pod is centered and extra long
3816 * name does not exceed max width.
3817 * @private
3818 */
3819 updatePodNameArea: function() {
3820 this.querySelectorAll('.name-container').forEach(function(nameArea) {
3821 var nameElement = nameArea.querySelector('.name');
3822 var leftMargin = (CROS_POD_WIDTH - nameElement.offsetWidth) / 2;
3823 if (leftMargin > 0)
3824 nameArea.style.left = cr.ui.toCssPx(leftMargin);
3825 else
3826 nameElement.style.width = cr.ui.toCssPx(CROS_POD_WIDTH);
3481 }); 3827 });
3482 Oobe.getInstance().updateScreenSize(this.parentNode); 3828 },
3483 }, 3829
3484 3830 /**
3485 /** 3831 * Called when a small pod is clicked to trigger the switch between the
3832 * small pod and the main pod.
3833 */
3834 changeMainPod_: function(pod) {
3835 if (this.disabled) {
3836 console.error('Cannot change main pod while sign-in UI is disabled.');
3837 return;
3838 }
3839 if (!this.mainPod_) {
3840 console.error('Attempt to switch a non-existing main pod.');
3841 return;
3842 }
3843 var insert = 0;
3844 var children = pod.parentNode.children;
3845 while (insert < children.length && children[insert] != pod)
3846 insert++;
3847 if (insert >= children.length) {
3848 console.error('Attempt to switch a non-existing small pod.');
3849 return;
3850 }
3851 if (pod.isInExtraSmallForm()) {
jdufault 2017/05/23 20:34:32 Instead of having separate functions for isExtraSm
Wenzhao (Colin) Zang 2017/05/24 00:29:20 Done.
3852 this.mainPod_.changeToExtraSmallPod();
3853 } else {
3854 this.mainPod_.changeToSmallPod();
3855 }
3856 pod.changeToLargePod();
3857
3858 var left = pod.left;
3859 var top = pod.top;
3860 var paddingBottom = pod.style.paddingBottom;
3861 var parent = pod.parentNode;
3862 parent.removeChild(pod);
3863 this.appendChild(pod);
3864 pod.left = this.mainPod_.left;
3865 pod.top = this.mainPod_.top;
3866 pod.style.paddingBottom = cr.ui.toCssPx(0);
3867
3868 this.removeChild(this.mainPod_);
3869 parent.insertBefore(this.mainPod_, children[insert]);
3870 this.mainPod_.left = left;
3871 this.mainPod_.top = top;
3872 this.mainPod_.style.paddingBottom = paddingBottom;
3873 this.mainPod_ = pod;
3874 this.focusPod(this.mainPod_);
3875 this.updatePodNameArea();
3876 },
3877
3878 /**
3486 * Number of columns. 3879 * Number of columns.
3487 * @type {?number} 3880 * @type {?number}
3488 */ 3881 */
3489 set columns(columns) { 3882 set columns(columns) {
3490 // Cannot use 'columns' here. 3883 // Cannot use 'columns' here.
3491 this.setAttribute('ncolumns', columns); 3884 this.setAttribute('ncolumns', columns);
3492 }, 3885 },
3493 get columns() { 3886 get columns() {
3494 return parseInt(this.getAttribute('ncolumns')); 3887 return parseInt(this.getAttribute('ncolumns'));
3495 }, 3888 },
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
3796 if (e.target.classList.contains('focused')) { 4189 if (e.target.classList.contains('focused')) {
3797 if (!e.target.multiProfilesPolicyApplied) 4190 if (!e.target.multiProfilesPolicyApplied)
3798 e.target.focusInput(); 4191 e.target.focusInput();
3799 else 4192 else
3800 e.target.userTypeBubbleElement.classList.add('bubble-shown'); 4193 e.target.userTypeBubbleElement.classList.add('bubble-shown');
3801 } else 4194 } else
3802 this.focusPod(e.target); 4195 this.focusPod(e.target);
3803 return; 4196 return;
3804 } 4197 }
3805 4198
4199 // Small pods do not have input box.
4200 if (e.target.parentNode == this.smallPodsContainer) {
4201 this.focusPod(e.target, false, true /* opt_skipInputFocus */);
4202 return;
4203 }
4204
3806 var pod = findAncestorByClass(e.target, 'pod'); 4205 var pod = findAncestorByClass(e.target, 'pod');
3807 if (pod && pod.parentNode == this) { 4206 if (pod && pod.parentNode == this) {
3808 // Focus on a control of a pod but not on the action area button. 4207 // Focus on a control of a pod but not on the action area button.
3809 if (!pod.classList.contains('focused')) { 4208 if (!pod.classList.contains('focused')) {
3810 if (e.target.classList.contains('action-box-area') || 4209 if (e.target.classList.contains('action-box-area') ||
3811 e.target.classList.contains('remove-warning-button')) { 4210 e.target.classList.contains('remove-warning-button')) {
3812 // focusPod usually moves focus on the password input box which 4211 // focusPod usually moves focus on the password input box which
3813 // triggers virtual keyboard to show up. But the focus may move to a 4212 // triggers virtual keyboard to show up. But the focus may move to a
3814 // non text input element shortly by e.target.focus. Hence, a 4213 // non text input element shortly by e.target.focus. Hence, a
3815 // virtual keyboard flicking might be observed. We need to manually 4214 // virtual keyboard flicking might be observed. We need to manually
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 return; 4355 return;
3957 } 4356 }
3958 4357
3959 this.podsWithPendingImages_.splice(index, 1); 4358 this.podsWithPendingImages_.splice(index, 1);
3960 if (this.podsWithPendingImages_.length == 0) { 4359 if (this.podsWithPendingImages_.length == 0) {
3961 this.classList.remove('images-loading'); 4360 this.classList.remove('images-loading');
3962 } 4361 }
3963 }, 4362 },
3964 4363
3965 /** 4364 /**
3966 * Makes sure user name is centered in each pod and extra long name
3967 * does not exceed max width.
3968 */
3969 updatePodNameArea: function() {
3970 this.querySelectorAll('.name-container').forEach(function(nameArea) {
3971 var nameElement = nameArea.querySelector('.name');
3972 var leftMargin = (CROS_POD_WIDTH - nameElement.offsetWidth) / 2;
3973 if (leftMargin > 0)
3974 nameArea.style.left = leftMargin + 'px';
3975 else
3976 nameElement.style.width = CROS_POD_WIDTH + 'px';
3977 });
3978 },
3979
3980 /**
3981 * Preselects pod, if needed. 4365 * Preselects pod, if needed.
3982 */ 4366 */
3983 maybePreselectPod: function() { 4367 maybePreselectPod: function() {
3984 var pod = this.preselectedPod; 4368 var pod = this.preselectedPod;
3985 this.focusPod(pod); 4369 this.focusPod(pod);
3986 4370
3987 // Hide user-type-bubble in case all user pods are disabled and we focus 4371 // Hide user-type-bubble in case all user pods are disabled and we focus
3988 // first pod. 4372 // first pod.
3989 if (pod && pod.multiProfilesPolicyApplied) { 4373 if (pod && pod.multiProfilesPolicyApplied) {
3990 pod.userTypeBubbleElement.classList.remove('bubble-shown'); 4374 pod.userTypeBubbleElement.classList.remove('bubble-shown');
3991 } 4375 }
3992 } 4376 }
3993 }; 4377 };
3994 4378
3995 return { 4379 return {
3996 PodRow: PodRow 4380 PodRow: PodRow
3997 }; 4381 };
3998 }); 4382 });
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698