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

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: Simplify the pod placement process and make it adaptive to the virtual keyboard 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;
68
69 /**
70 * The maximum number of users that each pod placement method can handle.
71 */
72 var POD_ROW_LIMIT = 2;
73 var LANDSCAPE_MODE_LIMIT = 6;
74 var PORTRAIT_MODE_LIMIT = 10;
63 75
64 /** 76 /**
65 * Minimal padding between user pod and virtual keyboard. 77 * Minimal padding between user pod and virtual keyboard.
66 * @type {number} 78 * @type {number}
67 * @const 79 * @const
68 */ 80 */
69 var USER_POD_KEYBOARD_MIN_PADDING = 20; 81 var USER_POD_KEYBOARD_MIN_PADDING = 20;
70 82
71 /** 83 /**
72 * Maximum time for which the pod row remains hidden until all user images 84 * Maximum time for which the pod row remains hidden until all user images
73 * have been loaded. 85 * have been loaded.
74 * @type {number} 86 * @type {number}
75 * @const 87 * @const
76 */ 88 */
77 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000; 89 var POD_ROW_IMAGES_LOAD_TIMEOUT_MS = 3000;
78 90
79 /** 91 /**
80 * Public session help topic identifier. 92 * Public session help topic identifier.
81 * @type {number} 93 * @type {number}
82 * @const 94 * @const
83 */ 95 */
84 var HELP_TOPIC_PUBLIC_SESSION = 3041033; 96 var HELP_TOPIC_PUBLIC_SESSION = 3041033;
85 97
86 /** 98 /**
87 * Tab order for user pods. Update these when adding new controls. 99 * Tab order for user pods. Update these when adding new controls.
88 * @enum {number} 100 * @enum {number}
89 * @const 101 * @const
90 */ 102 */
91 var UserPodTabOrder = { 103 var UserPodTabOrder = {
92 POD_INPUT: 1, // Password input field, Action box menu button and 104 POD_INPUT: 1, // Password input field and the pod itself.
93 // the pod itself. 105 PIN_KEYBOARD: 2, // Pin keyboard below the password input field.
94 PIN_KEYBOARD: 2, // Pin keyboard below the password input field. 106 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. 107 HEADER_BAR: 4, // Buttons on the header bar (Shutdown, Add User).
96 HEADER_BAR: 4, // Buttons on the header bar (Shutdown, Add User). 108 ACTION_BOX_BUTTON: 5, // Action box menu button.
97 POD_MENU_ITEM: 5 // User pad menu items (User info, Remove user). 109 POD_MENU_ITEM: 6 // User pod menu items (User info, Remove user).
98 }; 110 };
99 111
100 /** 112 /**
101 * Supported authentication types. Keep in sync with the enum in 113 * Supported authentication types. Keep in sync with the enum in
102 * chrome/browser/signin/screenlock_bridge.h 114 * chrome/browser/signin/screenlock_bridge.h
103 * @enum {number} 115 * @enum {number}
104 * @const 116 * @const
105 */ 117 */
106 var AUTH_TYPE = { 118 var AUTH_TYPE = {
107 OFFLINE_PASSWORD: 0, 119 OFFLINE_PASSWORD: 0,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
148 {state: FINGERPRINT_STATES.DEFAULT, class: 'default'}, 160 {state: FINGERPRINT_STATES.DEFAULT, class: 'default'},
149 {state: FINGERPRINT_STATES.SIGNIN, class: 'signin'}, 161 {state: FINGERPRINT_STATES.SIGNIN, class: 'signin'},
150 {state: FINGERPRINT_STATES.FAILED, class: 'failed'} 162 {state: FINGERPRINT_STATES.FAILED, class: 'failed'}
151 ]; 163 ];
152 164
153 // Focus and tab order are organized as follows: 165 // Focus and tab order are organized as follows:
154 // 166 //
155 // (1) all user pods have tab index 1 so they are traversed first; 167 // (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 168 // (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; 169 // 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 170 // (3) if pin keyboard is present, it has tab index 2 so it follows the input;
159 // follows the input. 171 // (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 172 // (5) buttons on the header bar have tab index 4;
161 // icon, or user pod if custom icon is not interactive; 173 // (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; 174 // header bar;
163 // (6) lastly, focus jumps to the Status Area and back to user pods. 175 // (7) User pod menu items (if present) have tab index 6;
176 // (8) lastly, focus jumps to the Status Area and back to user pods.
164 // 177 //
165 // 'Focus' event is handled by a capture handler for the whole document 178 // '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' 179 // 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. 180 // handlers where it's necessary to prevent 'focus' event from being fired.
168 181
169 /** 182 /**
170 * Helper function to remove a class from given element. 183 * Helper function to remove a class from given element.
171 * @param {!HTMLElement} el Element whose class list to change. 184 * @param {!HTMLElement} el Element whose class list to change.
172 * @param {string} cl Class to remove. 185 * @param {string} cl Class to remove.
173 */ 186 */
174 function removeClass(el, cl) { 187 function removeClass(el, cl) {
175 el.classList.remove(cl); 188 el.classList.remove(cl);
176 } 189 }
177 190
178 /** 191 /**
179 * Creates a user pod. 192 * Creates a user pod.
180 * @constructor 193 * @constructor
181 * @extends {HTMLDivElement} 194 * @extends {HTMLDivElement}
182 */ 195 */
183 var UserPod = cr.ui.define(function() { 196 var UserPod = cr.ui.define(function() {
184 var node = $('user-pod-template').cloneNode(true); 197 var node = $('user-pod-template').cloneNode(true);
185 node.removeAttribute('id'); 198 node.removeAttribute('id');
186 return node; 199 return node;
187 }); 200 });
188 201
189 /** 202 /**
203 * The display style of user pods.
204 * @enum {number}
205 * @const
206 */
207 UserPod.Style = {
208 LARGE: 0,
209 SMALL: 1,
210 EXTRA_SMALL: 2
211 };
212
213 /**
190 * Stops event propagation from the any user pod child element. 214 * Stops event propagation from the any user pod child element.
191 * @param {Event} e Event to handle. 215 * @param {Event} e Event to handle.
192 */ 216 */
193 function stopEventPropagation(e) { 217 function stopEventPropagation(e) {
194 // Prevent default so that we don't trigger a 'focus' event. 218 // Prevent default so that we don't trigger a 'focus' event.
195 e.preventDefault(); 219 e.preventDefault();
196 e.stopPropagation(); 220 e.stopPropagation();
197 } 221 }
198 222
199 /** 223 /**
(...skipping 546 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 /** 770 /**
747 * True iff the pod can display the pin keyboard. The pin keyboard may not 771 * 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 772 * always be displayed even if this is true, ie, if the virtual keyboard is
749 * also being displayed. 773 * also being displayed.
750 */ 774 */
751 pinEnabled: false, 775 pinEnabled: false,
752 776
753 /** @override */ 777 /** @override */
754 decorate: function() { 778 decorate: function() {
755 this.tabIndex = UserPodTabOrder.POD_INPUT; 779 this.tabIndex = UserPodTabOrder.POD_INPUT;
756 this.actionBoxAreaElement.tabIndex = UserPodTabOrder.POD_INPUT; 780 this.actionBoxAreaElement.tabIndex = UserPodTabOrder.ACTION_BOX_BUTTON;
757 781
758 this.addEventListener('keydown', this.handlePodKeyDown_.bind(this)); 782 this.addEventListener('keydown', this.handlePodKeyDown_.bind(this));
759 this.addEventListener('click', this.handleClickOnPod_.bind(this)); 783 this.addEventListener('click', this.handleClickOnPod_.bind(this));
760 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this)); 784 this.addEventListener('mousedown', this.handlePodMouseDown_.bind(this));
761 785
762 if (this.pinKeyboard) { 786 if (this.pinKeyboard) {
763 this.pinKeyboard.passwordElement = this.passwordElement; 787 this.pinKeyboard.passwordElement = this.passwordElement;
764 this.pinKeyboard.addEventListener('pin-change', 788 this.pinKeyboard.addEventListener('pin-change',
765 this.handleInputChanged_.bind(this)); 789 this.handleInputChanged_.bind(this));
766 this.pinKeyboard.tabIndex = UserPodTabOrder.PIN_KEYBOARD; 790 this.pinKeyboard.tabIndex = UserPodTabOrder.PIN_KEYBOARD;
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 this.handleInputMouseUp_.bind(this)); 840 this.handleInputMouseUp_.bind(this));
817 841
818 if (this.submitButton) { 842 if (this.submitButton) {
819 this.submitButton.addEventListener('click', 843 this.submitButton.addEventListener('click',
820 this.handleSubmitButtonClick_.bind(this)); 844 this.handleSubmitButtonClick_.bind(this));
821 } 845 }
822 846
823 this.imageElement.addEventListener('load', 847 this.imageElement.addEventListener('load',
824 this.parentNode.handlePodImageLoad.bind(this.parentNode, this)); 848 this.parentNode.handlePodImageLoad.bind(this.parentNode, this));
825 849
850 this.smallPodImageElement.addEventListener(
851 'load',
852 this.parentNode.handlePodImageLoad.bind(this.parentNode, this));
853
826 var initialAuthType = this.user.initialAuthType || 854 var initialAuthType = this.user.initialAuthType ||
827 AUTH_TYPE.OFFLINE_PASSWORD; 855 AUTH_TYPE.OFFLINE_PASSWORD;
828 this.setAuthType(initialAuthType, null); 856 this.setAuthType(initialAuthType, null);
829 857
830 if (this.user.isActiveDirectory) 858 if (this.user.isActiveDirectory)
831 this.setAttribute('is-active-directory', ''); 859 this.setAttribute('is-active-directory', '');
832 860
833 this.userClickAuthAllowed_ = false; 861 this.userClickAuthAllowed_ = false;
834 862
835 // Lazy load the assets needed for the polymer submit button. 863 // Lazy load the assets needed for the polymer submit button.
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 973
946 /** 974 /**
947 * Gets name element. 975 * Gets name element.
948 * @type {!HTMLDivElement} 976 * @type {!HTMLDivElement}
949 */ 977 */
950 get nameElement() { 978 get nameElement() {
951 return this.querySelector('.name'); 979 return this.querySelector('.name');
952 }, 980 },
953 981
954 /** 982 /**
983 * Gets image element of the small pod.
984 * @type {!HTMLImageElement}
985 */
986 get smallPodImageElement() {
987 return this.querySelector('.small-pod-image');
988 },
989
990 /**
991 * Gets name element of the small pod.
992 * @type {!HTMLDivElement}
993 */
994 get smallPodNameElement() {
995 return this.querySelector('.small-pod-name');
996 },
997
998 /**
955 * Gets reauth name hint element. 999 * Gets reauth name hint element.
956 * @type {!HTMLDivElement} 1000 * @type {!HTMLDivElement}
957 */ 1001 */
958 get reauthNameHintElement() { 1002 get reauthNameHintElement() {
959 return this.querySelector('.reauth-name-hint'); 1003 return this.querySelector('.reauth-name-hint');
960 }, 1004 },
961 1005
962 /** 1006 /**
963 * Gets the container holding the password field. 1007 * Gets the container holding the password field.
964 * @type {!HTMLInputElement} 1008 * @type {!HTMLInputElement}
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
1136 1180
1137 /** 1181 /**
1138 * Gets the fingerprint icon area. 1182 * Gets the fingerprint icon area.
1139 * @type {!HTMLDivElement} 1183 * @type {!HTMLDivElement}
1140 */ 1184 */
1141 get fingerprintIconElement() { 1185 get fingerprintIconElement() {
1142 return this.querySelector('.fingerprint-icon-container'); 1186 return this.querySelector('.fingerprint-icon-container');
1143 }, 1187 },
1144 1188
1145 /** 1189 /**
1190 * Sets the pod style.
1191 * @type {number}
jdufault 2017/05/24 17:11:15 This doesn't return anything so there shouldn't be
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Done.
jdufault 2017/05/24 20:44:52 Needs @param type annotation
Wenzhao (Colin) Zang 2017/05/24 21:36:37 Done.
1192 */
1193 set podStyle(style) {
jdufault 2017/05/24 17:11:15 FYI: In the future I recommend making any non-triv
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Done.
jdufault 2017/05/24 20:44:52 The idea here is to have it clear at the call site
Wenzhao (Colin) Zang 2017/05/24 21:36:37 Oh I see. I misunderstood earlier.
Wenzhao (Colin) Zang 2017/05/24 21:36:37 Done.
1194 switch (style) {
1195 case UserPod.Style.LARGE:
1196 this.querySelector('.large-pod').hidden = false;
1197 this.querySelector('.small-pod').hidden = true;
1198 break;
1199 case UserPod.Style.SMALL:
1200 this.querySelector('.large-pod').hidden = true;
1201 this.querySelector('.small-pod').hidden = false;
1202 this.querySelector('.small-pod').classList.remove('extra-small');
1203 break;
1204 case UserPod.Style.EXTRA_SMALL:
1205 this.querySelector('.large-pod').hidden = true;
1206 this.querySelector('.small-pod').hidden = false;
1207 this.querySelector('.small-pod').classList.add('extra-small');
1208 break;
1209 default:
1210 console.error("Attempt to set an invalid pod style.");
1211 break;
1212 }
1213 },
1214
1215 /**
1216 * Gets the pod style.
1217 * @type {number}
jdufault 2017/05/24 17:11:14 @type {UserPod.Style}
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Done.
1218 */
1219 get podStyle() {
1220 if (this.querySelector('.small-pod').hidden)
1221 return UserPod.Style.LARGE;
1222 if (this.querySelector('.small-pod').classList.contains('extra-small'))
1223 return UserPod.Style.EXTRA_SMALL;
1224 return UserPod.Style.SMALL;
1225 },
1226
1227 /**
1146 * Updates the user pod element. 1228 * Updates the user pod element.
1147 */ 1229 */
1148 update: function() { 1230 update: function() {
1149 this.imageElement.src = 'chrome://userimage/' + this.user.username + 1231 var imageSrc = 'chrome://userimage/' + this.user.username +
1150 '?id=' + UserPod.userImageSalt_[this.user.username]; 1232 '?id=' + UserPod.userImageSalt_[this.user.username];
1233 this.imageElement.src = imageSrc;
1234 this.smallPodImageElement.src = imageSrc;
1151 1235
1152 this.nameElement.textContent = this.user_.displayName; 1236 this.nameElement.textContent = this.user_.displayName;
1237 this.smallPodNameElement.textContent = this.user_.displayName;
1153 this.reauthNameHintElement.textContent = this.user_.displayName; 1238 this.reauthNameHintElement.textContent = this.user_.displayName;
1154 this.classList.toggle('signed-in', this.user_.signedIn); 1239 this.classList.toggle('signed-in', this.user_.signedIn);
1155 1240
1156 if (this.isAuthTypeUserClick) 1241 if (this.isAuthTypeUserClick)
1157 this.passwordLabelElement.textContent = this.authValue; 1242 this.passwordLabelElement.textContent = this.authValue;
1158 1243
1159 this.updateActionBoxArea(); 1244 this.updateActionBoxArea();
1160 1245
1161 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF( 1246 this.passwordElement.setAttribute('aria-label', loadTimeData.getStringF(
1162 'passwordFieldAccessibleName', this.user_.emailAddress)); 1247 'passwordFieldAccessibleName', this.user_.emailAddress));
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after
1795 } 1880 }
1796 }, 1881 },
1797 1882
1798 /** 1883 /**
1799 * Refresh the message in the remove user warning dialog. 1884 * Refresh the message in the remove user warning dialog.
1800 * @param {string} profilePath The filepath of the URL (must be verified). 1885 * @param {string} profilePath The filepath of the URL (must be verified).
1801 * @param {string} message The message to be written. 1886 * @param {string} message The message to be written.
1802 * @param {number|string=} count The number or string to replace $1 in 1887 * @param {number|string=} count The number or string to replace $1 in
1803 * |message|. Can be omitted if $1 is not present in |message|. 1888 * |message|. Can be omitted if $1 is not present in |message|.
1804 */ 1889 */
1805 updateRemoveWarningDialogSetMessage_: function(profilePath, message, 1890 updateRemoveWarningDialogSetMessage_: function(
1806 count) { 1891 profilePath, message, count) {
1807 if (profilePath !== this.user.profilePath) 1892 if (profilePath !== this.user.profilePath)
1808 return; 1893 return;
1809 // Add localized messages where $1 will be replaced with 1894 // Add localized messages where $1 will be replaced with
1810 // <span class="total-count"></span> and $2 will be replaced with 1895 // <span class="total-count"></span> and $2 will be replaced with
1811 // <span class="email"></span>. 1896 // <span class="email"></span>.
1812 var element = this.querySelector('.action-box-remove-user-warning-text'); 1897 var element = this.querySelector('.action-box-remove-user-warning-text');
1813 element.textContent = ''; 1898 element.textContent = '';
1814 1899
1815 messageParts = message.split(/(\$[12])/); 1900 messageParts = message.split(/(\$[12])/);
1816 var numParts = messageParts.length; 1901 var numParts = messageParts.length;
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 this.actionBoxMenuRemoveElement.tabIndex = -1; 2065 this.actionBoxMenuRemoveElement.tabIndex = -1;
1981 }, 2066 },
1982 2067
1983 /** 2068 /**
1984 * Handles mouse down event. It sets whether the user click auth will be 2069 * 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 2070 * 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. 2071 * was focused on the mouse down event starting the click.
1987 * @param {Event} e The mouse down event. 2072 * @param {Event} e The mouse down event.
1988 */ 2073 */
1989 handlePodMouseDown_: function(e) { 2074 handlePodMouseDown_: function(e) {
1990 this.userClickAuthAllowed_ = this.parentNode.isFocused(this); 2075 // Small pods do not have mouse down event.
jdufault 2017/05/24 17:11:15 The comment is a little confusing - I'd recommend
2076 if (this.podStyle == UserPod.Style.LARGE)
2077 this.userClickAuthAllowed_ = this.parentNode.isFocused(this);
1991 }, 2078 },
1992 2079
1993 /** 2080 /**
1994 * Called when the input of the password element changes. Updates the submit 2081 * Called when the input of the password element changes. Updates the submit
1995 * button color and state and hides the error popup bubble. 2082 * button color and state and hides the error popup bubble.
1996 */ 2083 */
1997 updateInput_: function() { 2084 updateInput_: function() {
1998 var isEmpty = this.passwordElement.value.length == 0; 2085 var isEmpty = this.passwordElement.value.length == 0;
1999 if (this.submitButton) { 2086 if (this.submitButton) {
2000 this.submitButton.disabled = isEmpty; 2087 this.submitButton.disabled = isEmpty;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 }, 2124 },
2038 2125
2039 /** 2126 /**
2040 * Handles click event on a user pod. 2127 * Handles click event on a user pod.
2041 * @param {Event} e Click event. 2128 * @param {Event} e Click event.
2042 */ 2129 */
2043 handleClickOnPod_: function(e) { 2130 handleClickOnPod_: function(e) {
2044 if (this.parentNode.disabled) 2131 if (this.parentNode.disabled)
2045 return; 2132 return;
2046 2133
2134 if (this.podStyle != UserPod.Style.LARGE) {
2135 // It should trigger the switch between the small pod and the main pod.
2136 $('pod-row').changeMainPod(this);
2137 return;
2138 }
2139
2047 if (!this.isActionBoxMenuActive) { 2140 if (!this.isActionBoxMenuActive) {
2048 if (this.isAuthTypeOnlineSignIn) { 2141 if (this.isAuthTypeOnlineSignIn) {
2049 this.showSigninUI(); 2142 this.showSigninUI();
2050 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { 2143 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) {
2051 // Note that this.userClickAuthAllowed_ is set in mouse down event 2144 // Note that this.userClickAuthAllowed_ is set in mouse down event
2052 // handler. 2145 // handler.
2053 this.parentNode.setActivatedPod(this); 2146 this.parentNode.setActivatedPod(this);
2054 } else if (this.pinKeyboard && 2147 } else if (this.pinKeyboard &&
2055 e.target == this.pinKeyboard.submitButton) { 2148 e.target == this.pinKeyboard.submitButton) {
2056 // Sets the pod as activated if the submit button is clicked so that 2149 // 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. 2150 // it simulates what the enter button does for the password/pin.
2058 this.parentNode.setActivatedPod(this); 2151 this.parentNode.setActivatedPod(this);
2059 } 2152 }
2060 2153
2061 if (this.multiProfilesPolicyApplied) 2154 if (this.multiProfilesPolicyApplied)
2062 this.userTypeBubbleElement.classList.add('bubble-shown'); 2155 this.userTypeBubbleElement.classList.add('bubble-shown');
2063 2156
2064 // Prevent default so that we don't trigger 'focus' event and 2157 // Prevent default so that we don't trigger 'focus' event and
2065 // stop propagation so that the 'click' event does not bubble 2158 // stop propagation so that the 'click' event does not bubble
2066 // up and accidentally closes the bubble tooltip. 2159 // up and accidentally closes the bubble tooltip.
2067 stopEventPropagation(e); 2160 stopEventPropagation(e);
2068 } 2161 }
2069 }, 2162 },
2070 2163
2071 /** 2164 /**
2072 * Handles keydown event for a user pod. 2165 * Handles keydown event for a user pod.
2073 * @param {Event} e Key event. 2166 * @param {Event} e Key event.
2074 */ 2167 */
2075 handlePodKeyDown_: function(e) { 2168 handlePodKeyDown_: function(e) {
2169 if (this.podStyle != UserPod.Style.LARGE) {
2170 this.handleSmallPodKeyDown_(e);
jdufault 2017/05/24 17:11:14 handleNonLargePodKeyDown?
Wenzhao (Colin) Zang 2017/05/24 19:23:44 Done.
2171 return;
2172 }
2076 if (!this.isAuthTypeUserClick || this.disabled) 2173 if (!this.isAuthTypeUserClick || this.disabled)
2077 return; 2174 return;
2078 switch (e.key) { 2175 switch (e.key) {
2079 case 'Enter': 2176 case 'Enter':
2080 case ' ': 2177 case ' ':
2081 if (this.parentNode.isFocused(this)) 2178 if (this.parentNode.isFocused(this))
2082 this.parentNode.setActivatedPod(this); 2179 this.parentNode.setActivatedPod(this);
2083 break; 2180 break;
2084 } 2181 }
2182 },
2183
2184 /**
2185 * Handles keydown event for a small user pod.
2186 * @param {Event} e Key event.
2187 */
2188 handleSmallPodKeyDown_: function(e) {
2189 switch (e.key) {
2190 case 'Enter':
2191 case ' ':
2192 if ($('pod-row').isFocused(this))
2193 $('pod-row').changeMainPod(this);
2194 break;
2195 }
2085 } 2196 }
2086 }; 2197 };
2087 2198
2088 /** 2199 /**
2089 * Creates a public account user pod. 2200 * Creates a public account user pod.
2090 * @constructor 2201 * @constructor
2091 * @extends {UserPod} 2202 * @extends {UserPod}
2092 */ 2203 */
2093 var PublicAccountUserPod = cr.ui.define(function() { 2204 var PublicAccountUserPod = cr.ui.define(function() {
2094 var node = UserPod(); 2205 var node = UserPod();
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
2286 this.focusInput(); 2397 this.focusInput();
2287 } 2398 }
2288 return true; 2399 return true;
2289 }, 2400 },
2290 2401
2291 /** @override */ 2402 /** @override */
2292 handleClickOnPod_: function(e) { 2403 handleClickOnPod_: function(e) {
2293 if (this.parentNode.disabled) 2404 if (this.parentNode.disabled)
2294 return; 2405 return;
2295 2406
2407 if (this.podStyle != UserPod.Style.LARGE) {
2408 // It should trigger the switch between the small pod and the main pod.
2409 $('pod-row').changeMainPod(this);
2410 return;
2411 }
2412
2296 this.parentNode.focusPod(this); 2413 this.parentNode.focusPod(this);
2297 this.parentNode.setActivatedPod(this, e); 2414 this.parentNode.setActivatedPod(this, e);
2298 // Prevent default so that we don't trigger 'focus' event. 2415 // Prevent default so that we don't trigger 'focus' event.
2299 e.preventDefault(); 2416 e.preventDefault();
2300 }, 2417 },
2301 2418
2302 /** 2419 /**
2303 * Updates the display name shown on the pod. 2420 * Updates the display name shown on the pod.
2304 * @param {string} displayName The new display name 2421 * @param {string} displayName The new display name
2305 */ 2422 */
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
2519 get mainInput() { 2636 get mainInput() {
2520 if (this.user.needsSignin) 2637 if (this.user.needsSignin)
2521 return this.passwordElement; 2638 return this.passwordElement;
2522 else 2639 else
2523 return this.nameElement; 2640 return this.nameElement;
2524 }, 2641 },
2525 2642
2526 /** @override */ 2643 /** @override */
2527 update: function() { 2644 update: function() {
2528 this.imageElement.src = this.user.userImage; 2645 this.imageElement.src = this.user.userImage;
2646 this.smallPodImageElement.src = this.user.userImage;
2529 this.nameElement.textContent = this.user.displayName; 2647 this.nameElement.textContent = this.user.displayName;
2648 this.smallPodNameElement.textContent = this.user.displayName;
2530 this.reauthNameHintElement.textContent = this.user.displayName; 2649 this.reauthNameHintElement.textContent = this.user.displayName;
2531 2650
2532 var isLockedUser = this.user.needsSignin; 2651 var isLockedUser = this.user.needsSignin;
2533 var isLegacySupervisedUser = this.user.legacySupervisedUser; 2652 var isLegacySupervisedUser = this.user.legacySupervisedUser;
2534 var isChildUser = this.user.childUser; 2653 var isChildUser = this.user.childUser;
2535 var isSyncedUser = this.user.emailAddress !== ""; 2654 var isSyncedUser = this.user.emailAddress !== "";
2536 var isProfileLoaded = this.user.isProfileLoaded; 2655 var isProfileLoaded = this.user.isProfileLoaded;
2537 this.classList.toggle('locked', isLockedUser); 2656 this.classList.toggle('locked', isLockedUser);
2538 this.classList.toggle('legacy-supervised', isLegacySupervisedUser); 2657 this.classList.toggle('legacy-supervised', isLegacySupervisedUser);
2539 this.classList.toggle('child', isChildUser); 2658 this.classList.toggle('child', isChildUser);
(...skipping 24 matching lines...) Expand all
2564 } 2683 }
2565 this.passwordElement.value = ''; 2684 this.passwordElement.value = '';
2566 return true; 2685 return true;
2567 }, 2686 },
2568 2687
2569 /** @override */ 2688 /** @override */
2570 handleClickOnPod_: function(e) { 2689 handleClickOnPod_: function(e) {
2571 if (this.parentNode.disabled) 2690 if (this.parentNode.disabled)
2572 return; 2691 return;
2573 2692
2693 if (this.podStyle != UserPod.Style.LARGE) {
2694 // It should trigger the switch between the small pod and the main pod.
jdufault 2017/05/24 17:11:15 This comment is a restatement of relatively obviou
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Acknowledged.
Wenzhao (Colin) Zang 2017/05/24 21:36:37 Done.
2695 $('pod-row').changeMainPod(this);
2696 return;
2697 }
2698
2574 Oobe.clearErrors(); 2699 Oobe.clearErrors();
2575 this.parentNode.lastFocusedPod_ = this; 2700 this.parentNode.lastFocusedPod_ = this;
2576 2701
2577 // If this is a locked pod and there are local credentials, show the 2702 // 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 2703 // password field. Otherwise call activate() which will open up a browser
2579 // window or show the reauth dialog, as needed. 2704 // window or show the reauth dialog, as needed.
2580 if (!(this.user.needsSignin && this.user.hasLocalCreds) && 2705 if (!(this.user.needsSignin && this.user.hasLocalCreds) &&
2581 !this.isActionBoxMenuActive) { 2706 !this.isActionBoxMenuActive) {
2582 this.activate(e); 2707 this.activate(e);
2583 } 2708 }
(...skipping 21 matching lines...) Expand all
2605 UserPod.prototype.decorate.call(this); 2730 UserPod.prototype.decorate.call(this);
2606 this.launchAppButtonElement.addEventListener('click', 2731 this.launchAppButtonElement.addEventListener('click',
2607 this.activate.bind(this)); 2732 this.activate.bind(this));
2608 }, 2733 },
2609 2734
2610 /** @override */ 2735 /** @override */
2611 update: function() { 2736 update: function() {
2612 this.imageElement.src = this.user.iconUrl; 2737 this.imageElement.src = this.user.iconUrl;
2613 this.imageElement.alt = this.user.label; 2738 this.imageElement.alt = this.user.label;
2614 this.imageElement.title = this.user.label; 2739 this.imageElement.title = this.user.label;
2740 this.smallPodImageElement.src = this.user.iconUrl;
2741 this.smallPodImageElement.alt = this.user.label;
2742 this.smallPodImageElement.title = this.user.label;
2615 this.passwordEntryContainerElement.hidden = true; 2743 this.passwordEntryContainerElement.hidden = true;
2616 this.launchAppButtonContainerElement.hidden = false; 2744 this.launchAppButtonContainerElement.hidden = false;
2617 this.nameElement.textContent = this.user.label; 2745 this.nameElement.textContent = this.user.label;
2746 this.smallPodNameElement.textContent = this.user.label;
2618 this.reauthNameHintElement.textContent = this.user.label; 2747 this.reauthNameHintElement.textContent = this.user.label;
2619 2748
2620 UserPod.prototype.updateActionBoxArea.call(this); 2749 UserPod.prototype.updateActionBoxArea.call(this);
2621 UserPod.prototype.customizeUserPodPerUserType.call(this); 2750 UserPod.prototype.customizeUserPodPerUserType.call(this);
2622 }, 2751 },
2623 2752
2624 /** @override */ 2753 /** @override */
2625 get mainInput() { 2754 get mainInput() {
2626 return this.launchAppButtonElement; 2755 return this.launchAppButtonElement;
2627 }, 2756 },
(...skipping 16 matching lines...) Expand all
2644 var diagnosticMode = e && e.ctrlKey; 2773 var diagnosticMode = e && e.ctrlKey;
2645 this.launchApp_(this.user, diagnosticMode); 2774 this.launchApp_(this.user, diagnosticMode);
2646 return true; 2775 return true;
2647 }, 2776 },
2648 2777
2649 /** @override */ 2778 /** @override */
2650 handleClickOnPod_: function(e) { 2779 handleClickOnPod_: function(e) {
2651 if (this.parentNode.disabled) 2780 if (this.parentNode.disabled)
2652 return; 2781 return;
2653 2782
2783 if (this.podStyle != UserPod.Style.LARGE) {
2784 // It should trigger the switch between the small pod and the main pod.
2785 $('pod-row').changeMainPod(this);
jdufault 2017/05/24 17:11:15 FYI: 'change' is an unusual word, typically 'set'
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Done.
2786 return;
2787 }
2788
2654 Oobe.clearErrors(); 2789 Oobe.clearErrors();
2655 this.parentNode.lastFocusedPod_ = this; 2790 this.parentNode.lastFocusedPod_ = this;
2656 this.activate(e); 2791 this.activate(e);
2657 }, 2792 },
2658 2793
2659 /** 2794 /**
2660 * Launch the app. If |diagnosticMode| is true, ask user to confirm. 2795 * Launch the app. If |diagnosticMode| is true, ask user to confirm.
2661 * @param {Object} app App data. 2796 * @param {Object} app App data.
2662 * @param {boolean} diagnosticMode Whether to run the app in diagnostic 2797 * @param {boolean} diagnosticMode Whether to run the app in diagnostic
2663 * mode. 2798 * mode.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2705 2840
2706 // Focused pod. 2841 // Focused pod.
2707 focusedPod_: undefined, 2842 focusedPod_: undefined,
2708 2843
2709 // Activated pod, i.e. the pod of current login attempt. 2844 // Activated pod, i.e. the pod of current login attempt.
2710 activatedPod_: undefined, 2845 activatedPod_: undefined,
2711 2846
2712 // Pod that was most recently focused, if any. 2847 // Pod that was most recently focused, if any.
2713 lastFocusedPod_: undefined, 2848 lastFocusedPod_: undefined,
2714 2849
2850 // Pod that occupies the main spot.
2851 mainPod_: undefined,
2852
2715 // Pods whose initial images haven't been loaded yet. 2853 // Pods whose initial images haven't been loaded yet.
2716 podsWithPendingImages_: [], 2854 podsWithPendingImages_: [],
2717 2855
2718 // Whether pod placement has been postponed. 2856 // Whether pod placement has been postponed.
2719 podPlacementPostponed_: false, 2857 podPlacementPostponed_: false,
2720 2858
2721 // Standard user pod height/width. 2859 // Standard user pod height/width.
2722 userPodHeight_: 0, 2860 userPodHeight_: 0,
2723 userPodWidth_: 0, 2861 userPodWidth_: 0,
2724 2862
(...skipping 27 matching lines...) Expand all
2752 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT : 2890 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT :
2753 DESKTOP_POD_HEIGHT : 2891 DESKTOP_POD_HEIGHT :
2754 CROS_POD_HEIGHT; 2892 CROS_POD_HEIGHT;
2755 this.userPodWidth_ = isDesktopUserManager ? 2893 this.userPodWidth_ = isDesktopUserManager ?
2756 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH : 2894 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH :
2757 DESKTOP_POD_WIDTH : 2895 DESKTOP_POD_WIDTH :
2758 CROS_POD_WIDTH; 2896 CROS_POD_WIDTH;
2759 }, 2897 },
2760 2898
2761 /** 2899 /**
2762 * Returns all the pods in this pod row. 2900 * Returns all the pods in this pod row. Some pods may not be its direct
2901 * children, but the caller doesn't have to know this.
2763 * @type {NodeList} 2902 * @type {NodeList}
2764 */ 2903 */
2765 get pods() { 2904 get pods() {
2766 return Array.prototype.slice.call(this.children); 2905 var powRowChildren = Array.prototype.slice.call(this.children);
2906 var containerChildren =
2907 Array.prototype.slice.call(this.smallPodsContainer.children);
2908 return powRowChildren.concat(containerChildren);
2767 }, 2909 },
2768 2910
2769 /** 2911 /**
2770 * Return true if user pod row has only single user pod in it, which should 2912 * 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. 2913 * always be focused except desktop and touch view modes.
2772 * @type {boolean} 2914 * @type {boolean}
2773 */ 2915 */
2774 get alwaysFocusSinglePod() { 2916 get alwaysFocusSinglePod() {
2775 var isDesktopUserManager = Oobe.getInstance().displayType == 2917 var isDesktopUserManager = Oobe.getInstance().displayType ==
2776 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 2918 DISPLAY_TYPE.DESKTOP_USER_MANAGER;
2777 2919
2778 return (isDesktopUserManager || this.touchViewEnabled_) ? 2920 return (isDesktopUserManager || this.touchViewEnabled_) ?
2779 false : this.children.length == 1; 2921 false :
2922 this.pods.length == 1;
2780 }, 2923 },
2781 2924
2782 /** 2925 /**
2783 * Returns pod with the given app id. 2926 * Returns pod with the given app id.
2784 * @param {!string} app_id Application id to be matched. 2927 * @param {!string} app_id Application id to be matched.
2785 * @return {Object} Pod with the given app id. null if pod hasn't been 2928 * @return {Object} Pod with the given app id. null if pod hasn't been
2786 * found. 2929 * found.
2787 */ 2930 */
2788 getPodWithAppId_: function(app_id) { 2931 getPodWithAppId_: function(app_id) {
2789 for (var i = 0, pod; pod = this.pods[i]; ++i) { 2932 for (var i = 0, pod; pod = this.pods[i]; ++i) {
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
2946 /** 3089 /**
2947 * Removes user pod from pod row. 3090 * Removes user pod from pod row.
2948 * @param {!user} username 3091 * @param {!user} username
2949 */ 3092 */
2950 removeUserPod: function(username) { 3093 removeUserPod: function(username) {
2951 var podToRemove = this.getPodWithUsername_(username); 3094 var podToRemove = this.getPodWithUsername_(username);
2952 if (podToRemove == null) { 3095 if (podToRemove == null) {
2953 console.warn('Attempt to remove pod that does not exist'); 3096 console.warn('Attempt to remove pod that does not exist');
2954 return; 3097 return;
2955 } 3098 }
2956 this.removeChild(podToRemove); 3099 // Its parent is not necessarily this pod row.
2957 if (this.pods.length > 0) 3100 podToRemove.parentNode.removeChild(podToRemove);
3101 this.mainPod_ = null;
3102 if (this.pods.length > 0) {
3103 // placePods_() will select a new main pod and re-append pods
3104 // to different parents if necessary.
2958 this.placePods_(); 3105 this.placePods_();
3106 this.maybePreselectPod();
3107 }
2959 }, 3108 },
2960 3109
2961 /** 3110 /**
2962 * Returns index of given pod or -1 if not found. 3111 * Returns index of given pod or -1 if not found.
2963 * @param {UserPod} pod Pod to look up. 3112 * @param {UserPod} pod Pod to look up.
2964 * @private 3113 * @private
2965 */ 3114 */
2966 indexOf_: function(pod) { 3115 indexOf_: function(pod) {
2967 for (var i = 0; i < this.pods.length; ++i) { 3116 for (var i = 0; i < this.pods.length; ++i) {
2968 if (pod == this.pods[i]) 3117 if (pod == this.pods[i])
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3013 * updated. 3162 * updated.
3014 */ 3163 */
3015 rebuildPods: function() { 3164 rebuildPods: function() {
3016 var emptyPodRow = this.pods.length == 0; 3165 var emptyPodRow = this.pods.length == 0;
3017 3166
3018 // Clear existing pods. 3167 // Clear existing pods.
3019 this.innerHTML = ''; 3168 this.innerHTML = '';
3020 this.focusedPod_ = undefined; 3169 this.focusedPod_ = undefined;
3021 this.activatedPod_ = undefined; 3170 this.activatedPod_ = undefined;
3022 this.lastFocusedPod_ = undefined; 3171 this.lastFocusedPod_ = undefined;
3172 this.mainPod_ = undefined;
3023 3173
3024 // Switch off animation 3174 // Switch off animation
3025 Oobe.getInstance().toggleClass('flying-pods', false); 3175 Oobe.getInstance().toggleClass('flying-pods', false);
3026 3176
3027 // Populate the pod row.
3028 for (var i = 0; i < this.users_.length; ++i) 3177 for (var i = 0; i < this.users_.length; ++i)
3029 this.addUserPod(this.users_[i]); 3178 this.addUserPod(this.users_[i]);
3030 3179
3031 for (var i = 0, pod; pod = this.pods[i]; ++i) 3180 for (var i = 0, pod; pod = this.pods[i]; ++i)
3032 this.podsWithPendingImages_.push(pod); 3181 this.podsWithPendingImages_.push(pod);
3033 3182
3034 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. 3183 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting.
3035 if (this.shouldShowApps_) { 3184 if (this.shouldShowApps_) {
3036 for (var i = 0; i < this.apps_.length; ++i) 3185 for (var i = 0; i < this.apps_.length; ++i)
3037 this.addUserPod(this.apps_[i]); 3186 this.addUserPod(this.apps_[i]);
(...skipping 25 matching lines...) Expand all
3063 if ($('login-header-bar').signinUIState == 3212 if ($('login-header-bar').signinUIState ==
3064 SIGNIN_UI_STATE.GAIA_SIGNIN && 3213 SIGNIN_UI_STATE.GAIA_SIGNIN &&
3065 emptyPodRow && 3214 emptyPodRow &&
3066 this.pods.length > 0) { 3215 this.pods.length > 0) {
3067 login.GaiaSigninScreen.updateControlsState(); 3216 login.GaiaSigninScreen.updateControlsState();
3068 } 3217 }
3069 } 3218 }
3070 }, 3219 },
3071 3220
3072 /** 3221 /**
3222 * Gets the container of small pods.
3223 * @type {!HTMLDivElement}
3224 */
3225 get smallPodsContainer() {
3226 return document.querySelector('.small-pod-container');
3227 },
3228
3229 /**
3073 * Adds given apps to the pod row. 3230 * Adds given apps to the pod row.
3074 * @param {array} apps Array of apps. 3231 * @param {array} apps Array of apps.
3075 */ 3232 */
3076 setApps: function(apps) { 3233 setApps: function(apps) {
3077 this.apps_ = apps; 3234 this.apps_ = apps;
3078 this.rebuildPods(); 3235 this.rebuildPods();
3079 chrome.send('kioskAppsLoaded'); 3236 chrome.send('kioskAppsLoaded');
3080 3237
3081 // Check whether there's a pending kiosk app error. 3238 // Check whether there's a pending kiosk app error.
3082 window.setTimeout(function() { 3239 window.setTimeout(function() {
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after
3315 }, 3472 },
3316 3473
3317 /** 3474 /**
3318 * Updates the list of locales available for a public session. 3475 * Updates the list of locales available for a public session.
3319 * @param {string} userID The user ID of the public session 3476 * @param {string} userID The user ID of the public session
3320 * @param {!Object} locales The list of available locales 3477 * @param {!Object} locales The list of available locales
3321 * @param {string} defaultLocale The locale to select by default 3478 * @param {string} defaultLocale The locale to select by default
3322 * @param {boolean} multipleRecommendedLocales Whether |locales| contains 3479 * @param {boolean} multipleRecommendedLocales Whether |locales| contains
3323 * two or more recommended locales 3480 * two or more recommended locales
3324 */ 3481 */
3325 setPublicSessionLocales: function(userID, 3482 setPublicSessionLocales: function(
3326 locales, 3483 userID, locales, defaultLocale, multipleRecommendedLocales) {
3327 defaultLocale,
3328 multipleRecommendedLocales) {
3329 var pod = this.getPodWithUsername_(userID); 3484 var pod = this.getPodWithUsername_(userID);
3330 if (pod != null) { 3485 if (pod != null) {
3331 pod.populateLanguageSelect(locales, 3486 pod.populateLanguageSelect(locales,
3332 defaultLocale, 3487 defaultLocale,
3333 multipleRecommendedLocales); 3488 multipleRecommendedLocales);
3334 } 3489 }
3335 }, 3490 },
3336 3491
3337 /** 3492 /**
3338 * Updates the list of available keyboard layouts for a public session pod. 3493 * Updates the list of available keyboard layouts for a public session pod.
3339 * @param {string} userID The user ID of the public session 3494 * @param {string} userID The user ID of the public session
3340 * @param {string} locale The locale to which this list of keyboard layouts 3495 * @param {string} locale The locale to which this list of keyboard layouts
3341 * applies 3496 * applies
3342 * @param {!Object} list List of available keyboard layouts 3497 * @param {!Object} list List of available keyboard layouts
3343 */ 3498 */
3344 setPublicSessionKeyboardLayouts: function(userID, locale, list) { 3499 setPublicSessionKeyboardLayouts: function(userID, locale, list) {
3345 var pod = this.getPodWithUsername_(userID); 3500 var pod = this.getPodWithUsername_(userID);
3346 if (pod != null) 3501 if (pod != null)
3347 pod.populateKeyboardSelect(locale, list); 3502 pod.populateKeyboardSelect(locale, list);
3348 }, 3503 },
3349 3504
3350 /** 3505 /**
3351 * Called when window was resized. 3506 * Called when window was resized.
3352 */ 3507 */
3353 onWindowResize: function() { 3508 onWindowResize: function() {
3354 var layout = this.calculateLayout_(); 3509 this.placePods_();
jdufault 2017/05/24 17:11:14 Does this happen on orientation change?
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Yes. onWindowResize is called when changing the sc
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 }, 3510 },
3372 3511
3373 /** 3512 /**
3374 * Returns width of podrow having |columns| number of columns. 3513 * Returns width of podrow having |columns| number of columns.
3375 * @private 3514 * @private
3376 */ 3515 */
3377 columnsToWidth_: function(columns) { 3516 columnsToWidth_: function(columns) {
3378 var isDesktopUserManager = Oobe.getInstance().displayType == 3517 var isDesktopUserManager = Oobe.getInstance().displayType ==
3379 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 3518 DISPLAY_TYPE.DESKTOP_USER_MANAGER;
3380 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : 3519 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] :
(...skipping 30 matching lines...) Expand all
3411 while (maxWidth < this.columnsToWidth_(columns) && columns > 1) 3550 while (maxWidth < this.columnsToWidth_(columns) && columns > 1)
3412 --columns; 3551 --columns;
3413 var rows = Math.floor((this.pods.length - 1) / columns) + 1; 3552 var rows = Math.floor((this.pods.length - 1) / columns) + 1;
3414 if (getComputedStyle( 3553 if (getComputedStyle(
3415 $('signin-banner'), null).getPropertyValue('display') != 'none') { 3554 $('signin-banner'), null).getPropertyValue('display') != 'none') {
3416 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER); 3555 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER);
3417 } 3556 }
3418 if (!Oobe.getInstance().newDesktopUserManager) { 3557 if (!Oobe.getInstance().newDesktopUserManager) {
3419 var maxHeigth = Oobe.getInstance().clientAreaSize.height; 3558 var maxHeigth = Oobe.getInstance().clientAreaSize.height;
3420 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1) 3559 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1)
3421 --rows; 3560 --rows;
3422 } 3561 }
3423 // One more iteration if it's not enough cells to place all pods. 3562 // One more iteration if it's not enough cells to place all pods.
3424 while (maxWidth >= this.columnsToWidth_(columns + 1) && 3563 while (maxWidth >= this.columnsToWidth_(columns + 1) &&
3425 columns * rows < this.pods.length && 3564 columns * rows < this.pods.length &&
3426 columns < MAX_NUMBER_OF_COLUMNS) { 3565 columns < MAX_NUMBER_OF_COLUMNS) {
3427 ++columns; 3566 ++columns;
3428 } 3567 }
3429 return {columns: columns, rows: rows}; 3568 return {columns: columns, rows: rows};
3430 }, 3569 },
3431 3570
3432 /** 3571 /**
3433 * Places pods onto their positions onto pod grid. 3572 * Places pods onto their positions in pod grid matching the new design.
3434 * @private 3573 * @private
3435 */ 3574 */
3436 placePods_: function() { 3575 placePods_: function() {
3437 var isDesktopUserManager = Oobe.getInstance().displayType == 3576 var pods = this.pods;
3438 DISPLAY_TYPE.DESKTOP_USER_MANAGER; 3577 if (pods.length == 0) {
3439 if (isDesktopUserManager && !Oobe.getInstance().userPodsPageVisible) 3578 console.error('Attempt to place pods for an empty pod list.');
3440 return; 3579 return;
3441 3580 }
3442 var layout = this.calculateLayout_(); 3581 // Append all pods to their proper parents. Small pods have parent other
3443 var columns = this.columns = layout.columns; 3582 // than the pod row. The pods were all initialized with the pow row as a
3444 var rows = this.rows = layout.rows; 3583 // temporary parent, which is intended to ensure that all event listeners
3445 var maxPodsNumber = columns * rows; 3584 // work properly. If the main pod already exists, it means we are in the
3446 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : 3585 // process of resizing the window, then there is no need to change parents
3447 MARGIN_BY_COLUMNS[columns]; 3586 // of any pod.
3587 if (!this.mainPod_) {
3588 this.mainPod_ = this.preselectedPod;
3589 this.appendPodsToParents();
3590 }
3591 this.restoreInitialStates_();
3592 // Make sure not to block the header bar.
3448 this.parentNode.setPreferredSize( 3593 this.parentNode.setPreferredSize(
3449 this.columnsToWidth_(columns), this.rowsToHeight_(rows)); 3594 Oobe.getInstance().clientAreaSize.width,
3450 var height = this.userPodHeight_; 3595 Oobe.getInstance().clientAreaSize.height);
3451 var width = this.userPodWidth_; 3596
3452 var pinPodLocation = { column: columns + 1, row: rows + 1 }; 3597 if (pods.length == 1) {
3453 if (this.focusedPod_ && this.focusedPod_.isPinShown()) 3598 this.placeSinglePod_();
3454 pinPodLocation = this.findPodLocation_(this.focusedPod_, columns, rows); 3599 } else if (pods.length == POD_ROW_LIMIT) {
3455 3600 this.placePodsOnPodRow_();
3456 this.pods.forEach(function(pod, index) { 3601 } else {
3457 if (index >= maxPodsNumber) { 3602 this.placePodsOnContainer_();
3458 pod.hidden = true; 3603 }
3459 return; 3604 Oobe.getInstance().updateScreenSize(this.parentNode);
3460 } 3605 this.updatePodNameArea();
3461 pod.hidden = false; 3606 },
3462 if (pod.offsetHeight != height && 3607
3463 pod.offsetHeight != CROS_PIN_POD_HEIGHT) { 3608 /**
3464 console.error('Pod offsetHeight (' + pod.offsetHeight + 3609 * Append pods to proper parents. Called each time before pod placement.
3465 ') and POD_HEIGHT (' + height + ') are not equal.'); 3610 * @private
3466 } 3611 */
3467 if (pod.offsetWidth != width) { 3612 appendPodsToParents: function() {
3468 console.error('Pod offsetWidth (' + pod.offsetWidth + 3613 var pods = this.pods;
3469 ') and POD_WIDTH (' + width + ') are not equal.'); 3614 // Pod count may have changed, so the placement method may change
3470 } 3615 // accordingly. Therefore, always remove all pods from their current
3471 var column = index % columns; 3616 // parents first.
3472 var row = Math.floor(index / columns); 3617 for (var pod of pods) {
3473 3618 pod.parentNode.removeChild(pod);
3474 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : 3619 }
3475 POD_ROW_PADDING; 3620 if (pods.length <= POD_ROW_LIMIT) {
3476 pod.left = rowPadding + column * (width + margin); 3621 for (var pod of pods) {
3477 3622 this.appendChild(pod);
3478 // On desktop, we want the rows to always be equally spaced. 3623 }
3479 pod.top = isDesktopUserManager ? row * (height + rowPadding) : 3624 } else {
3480 row * height + rowPadding; 3625 // When the user count exceeds the limit (currently set to 2), only the
3626 // main pod still has pow row as parent, all other pods should be
3627 // appended to the container with scroll bar.
3628 for (var pod of pods) {
3629 if (pod == this.mainPod_) {
3630 this.appendChild(pod);
3631 } else {
3632 this.smallPodsContainer.appendChild(pod);
3633 }
3634 }
3635 }
3636 },
3637
3638 /**
3639 * Called when there is one user pod.
3640 * @private
3641 */
3642 placeSinglePod_: function() {
3643 this.mainPod_.podStyle = UserPod.Style.LARGE;
3644 this.mainPod_.left = (this.screenSize.width - CROS_POD_WIDTH) / 2;
3645 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2;
3646 },
3647
3648 /**
3649 * Called when there are two users pods.
3650 * @private
3651 */
3652 placePodsOnPodRow_: function() {
3653 // Both pods have large size and are placed adjacently.
3654 var secondPod =
3655 this.pods[0] == this.mainPod_ ? this.pods[1] : this.pods[0];
3656 this.mainPod_.podStyle = UserPod.Style.LARGE;
3657 secondPod.podStyle = UserPod.Style.LARGE;
3658
3659 var DOUBLE_PODS_PADDING = this.isPortraitMode() ? 32 : 118;
3660 var leftPadding = (this.screenSize.width - (CROS_POD_WIDTH * 2 + DOUBLE_PO DS_PADDING)) / 2;
3661 // Start actual positioning.
3662 this.mainPod_.left = leftPadding;
3663 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2;
3664 secondPod.left = leftPadding + CROS_POD_WIDTH + DOUBLE_PODS_PADDING;
3665 secondPod.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2;
3666 },
3667
3668 /**
3669 * Called when there are more than two user pods.
3670 * @private
3671 */
3672 placePodsOnContainer_: function() {
3673 this.smallPodsContainer.hidden = false;
3674 var pods = this.pods;
3675 if ((pods.length > LANDSCAPE_MODE_LIMIT && !this.isPortraitMode()) ||
3676 (pods.length > PORTRAIT_MODE_LIMIT && this.isPortraitMode())) {
3677 // If the pod count exceeds limits, they should be in extra small size
3678 // and the container will become scrollable.
3679 this.placePodsOnScrollableContainer_();
3680 return;
3681 }
3682 this.mainPod_.podStyle = UserPod.Style.LARGE;
3683 for (var pod of pods) {
3684 if (pod != this.mainPod_) {
3685 // All pods except the main one must be set to the small style.
3686 pod.podStyle = UserPod.Style.SMALL;
3687 }
3688 }
3689 // The size of the smallPodsContainer must be updated to avoid overflow,
3690 // otherwise unnecessary scroll bar will show up.
3691 this.smallPodsContainer.style.height =
3692 cr.ui.toCssPx(this.screenSize.height);
3693 this.smallPodsContainer.style.width = cr.ui.toCssPx(CROS_SMALL_POD_WIDTH);
3694
3695 var LEFT_PADDING = this.isPortraitMode() ? 0 : 98;
3696 var MIDDLE_PADDING = this.isPortraitMode() ? 84 : 220;
3697 var contentsWidth = LEFT_PADDING +
3698 CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH;
3699 var blankWidth = this.screenSize.width - contentsWidth;
3700 var actualLeftPadding = LEFT_PADDING;
3701 actualLeftPadding += this.isPortraitMode() ? blankWidth * 2 / 3:
3702 blankWidth / 2;
3703 var SMALL_POD_PADDING = 54;
3704 var actualSmallPodPadding = SMALL_POD_PADDING;
3705 var smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT +
3706 (pods.length - 2) * actualSmallPodPadding;
3707 if (smallPodsTotalHeight > this.screenSize.height) {
3708 // Edge case: when the virtual keyboard is present, the total height of
3709 // the smallPodsContainer may exceed the screen height. Decrease the
3710 // padding among small pods according to the design spec.
3711 actualSmallPodPadding = 32;
3712 smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT +
3713 (pods.length - 2) * actualSmallPodPadding;
3714 }
3715
3716 // Start positioning of the main pod and the smallPodsContainer.
3717 this.mainPod_.left = actualLeftPadding;
3718 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2;
3719 this.smallPodsContainer.style.left =
3720 cr.ui.toCssPx(actualLeftPadding + CROS_POD_WIDTH + MIDDLE_PADDING);
3721 this.smallPodsContainer.style.top = cr.ui.toCssPx(0);
3722 // Start positioning of the small pods inside the smallPodsContainer.
3723 var smallPodsTopPadding = (this.screenSize.height - smallPodsTotalHeight) / 2;
3724 for (var pod of pods) {
3725 if (pod == this.mainPod_) {
jdufault 2017/05/24 17:11:14 FYI: style guide says to drop the {} on single-lin
Wenzhao (Colin) Zang 2017/05/24 19:23:44 I will pay attention to it.
3726 continue;
3727 }
3728 pod.left = 0;
3729 pod.top = smallPodsTopPadding;
3730 smallPodsTopPadding += CROS_SMALL_POD_HEIGHT + actualSmallPodPadding;
3731 }
3732 },
3733
3734 /**
3735 * Called when there are more than 6 user pods in landscape mode, or more
3736 * than 10 user pods in portrait mode.
3737 * @private
3738 */
3739 placePodsOnScrollableContainer_: function() {
3740 this.smallPodsContainer.hidden = false;
3741 // Add a dark overlay.
3742 this.smallPodsContainer.classList.add('scroll');
3743 var pods = this.pods;
3744 this.mainPod_.podStyle = UserPod.Style.LARGE;
3745 for (var pod of pods) {
3746 if (pod != this.mainPod_) {
3747 // All pods except the main one must be set to the extra small style.
3748 pod.podStyle = UserPod.Style.EXTRA_SMALL;
3749 }
3750 }
3751
3752 var SCROLL_LEFT_PADDING = this.isPortraitMode() ? 46 : 72;
3753 var SCROLL_RIGHT_PADDING = this.isPortraitMode() ? 12 : 72;
3754 // The offsetWidth of the smallPodsContainer.
3755 var scrollAreaWidth = SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH +
3756 SCROLL_RIGHT_PADDING;
3757 var mainPodPadding = (this.screenSize.width -
3758 scrollAreaWidth - CROS_POD_WIDTH) / 2;
3759 var SCROLL_TOP_PADDING = this.isPortraitMode() ? 66 : 72;
3760 var EXTRA_SMALL_POD_PADDING = 32;
3761
3762 // Precalculate the total height of the scrollable container and check if
3763 // it indeed exceeds the screen height.
3764 var scrollHeight = 0;
3765 for (var pod of pods) {
3766 if (pod == this.mainPod_) {
3767 continue;
3768 }
3769 scrollHeight += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING;
3770 }
3771 scrollHeight -= EXTRA_SMALL_POD_PADDING;
3772 // The smallPodsContainer should occupy the full screen vertically.
3773 this.smallPodsContainer.style.height = cr.ui.toCssPx(this.screenSize.heigh t);
3774 this.smallPodsContainer.style.width = cr.ui.toCssPx(
3775 SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH +
3776 SCROLL_RIGHT_PADDING);
3777
3778 // SCROLL_TOP_PADDING denotes the smallest top padding we can tolerate
3779 // before allowing the container to overflow and show the scroll bar.
3780 var actualTopPadding = SCROLL_TOP_PADDING;
3781 if ((this.screenSize.height - scrollHeight) / 2 > actualTopPadding) {
3782 // Edge case: the total height of the scrollable container does not
3783 // exceed the screen height (minus the neceesary padding), so the
3784 // scroll bar will not appear.
3785 // In this case, we still want to keep the extra small pod size and
3786 // the overlay, but the top and bottom padding should be adjusted
3787 // to ensure a symmetric layout.
3788 actualTopPadding = (this.screenSize.height - scrollHeight) / 2;
3789 } else {
3790 // The scroll bar will definitely be shown if we reach here. A gradient
3791 // mask is applied to avoid blocking the header bar.
3792 actualTopPadding = SCROLL_MASK_HEIGHT;
3793 this.showScrollMask();
3794 }
3795 // Start positioning of the main pod and the smallPodsContainer.
3796 this.mainPod_.left = mainPodPadding;
3797 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2;
3798 this.smallPodsContainer.style.left =
3799 cr.ui.toCssPx(mainPodPadding * 2 + CROS_POD_WIDTH);
3800 this.smallPodsContainer.style.top = cr.ui.toCssPx(0);
3801 // Start positioning of the small pods inside the smallPodsContainer.
3802 var topPadding = actualTopPadding;
3803 var lastPod = undefined;
3804 for (var pod of pods) {
3805 if (pod == this.mainPod_) {
3806 continue;
3807 }
3808 pod.left = SCROLL_LEFT_PADDING;
3809 pod.top = topPadding;
3810 topPadding += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING;
3811 lastPod = pod;
3812 }
3813 // If the scroll bar and the gradient mask are shown, make sure the last
3814 // pod isn't blocked by the mask.
3815 if (!document.querySelector('.small-pod-container-mask').hidden) {
3816 lastPod.style.paddingBottom = cr.ui.toCssPx(SCROLL_MASK_HEIGHT);
3817 }
3818 },
3819
3820 /**
3821 * Called each time before pod placement to ensure we start with the
3822 * initial state, which is ready to place only one user pod. The styles
3823 * of elements necessary for other placement methods must be set
3824 * explicitly each time.
3825 * @private
3826 */
3827 restoreInitialStates_: function() {
3828 this.smallPodsContainer.hidden = true;
3829 document.querySelector('.small-pod-container-mask').hidden = true;
3830 document.querySelector('.small-pod-container-mask.rotate').hidden = true;
3831 this.smallPodsContainer.classList.remove('scroll');
3832 var pods = this.pods;
3833 for (var pod of pods) {
3834 // There is a chance that one of the pods have a bottom padding, so
3835 // reset all of them to be safe.
jdufault 2017/05/24 17:11:15 Any idea why? It'd be good to include that in the
Wenzhao (Colin) Zang 2017/05/24 19:23:44 Done.
3836 pod.style.paddingBottom = cr.ui.toCssPx(0);
3837 }
3838 },
3839
3840 /**
3841 * Check if it's in portrait mode.
jdufault 2017/05/24 17:11:15 Please clarify "it"
Wenzhao (Colin) Zang 2017/05/24 19:23:43 Done.
3842 * @return {boolean} True if in portrait mode.
3843 */
3844 isPortraitMode: function() {
3845 return this.screenSize.width <
3846 this.screenSize.height;
3847 },
3848
3849 /**
3850 * Called when scroll bar is shown and we need a mask for the header bar.
3851 * @private
3852 */
3853 showScrollMask: function() {
3854 var topMask = document.querySelector('.small-pod-container-mask');
3855 topMask.hidden = false;
3856 topMask.style.left = this.smallPodsContainer.style.left;
3857 topMask.style.width = this.smallPodsContainer.style.width;
3858 // The bottom mask is a rotation of the top mask.
3859 var bottomMask =
3860 document.querySelector('.small-pod-container-mask.rotate');
3861 bottomMask.hidden = false;
3862 bottomMask.style.left = this.smallPodsContainer.style.left;
3863 bottomMask.style.width = this.smallPodsContainer.style.width;
3864 // The bottom mask should overlap with the header bar, and its z-index
3865 // is chosen to ensure it does not block users from using the header bar.
3866 bottomMask.style.top = cr.ui.toCssPx(
3867 document.querySelector('#scroll-container').offsetHeight -
3868 SCROLL_MASK_HEIGHT);
3869 },
3870
3871 /**
3872 * Makes sure that user name on each large pod is centered and extra long
3873 * name does not exceed max width. Names on small pods do not need to be
3874 * dynamically updated.
3875 * @private
3876 */
3877 updatePodNameArea: function() {
3878 this.querySelectorAll('.name-container').forEach(function(nameArea) {
3879 var nameElement = nameArea.querySelector('.name');
3880 var leftMargin = (CROS_POD_WIDTH - nameElement.offsetWidth) / 2;
3881 if (leftMargin > 0)
3882 nameArea.style.left = cr.ui.toCssPx(leftMargin);
3883 else
3884 nameElement.style.width = cr.ui.toCssPx(CROS_POD_WIDTH);
3481 }); 3885 });
3482 Oobe.getInstance().updateScreenSize(this.parentNode); 3886 },
3483 }, 3887
3484 3888 /**
3485 /** 3889 * Called when a small pod is clicked to trigger the switch between the
3890 * small pod and the main pod.
3891 */
3892 changeMainPod: function(pod) {
3893 if (this.disabled) {
3894 console.error('Cannot change main pod while sign-in UI is disabled.');
3895 return;
3896 }
3897 if (!this.mainPod_) {
3898 console.error('Attempt to switch a non-existing main pod.');
3899 return;
3900 }
3901 // Find the index of the small pod.
3902 var insert = 0;
3903 var children = pod.parentNode.children;
3904 while (insert < children.length && children[insert] != pod)
3905 insert++;
3906 if (insert >= children.length) {
3907 console.error('Attempt to switch a non-existing small pod.');
3908 return;
3909 }
3910 // Switch style of the two pods.
3911 if (pod.podStyle == UserPod.Style.EXTRA_SMALL) {
jdufault 2017/05/24 17:11:14 this.mainPod_.podStyle = pod.podStyle? Then you c
Wenzhao (Colin) Zang 2017/05/24 19:23:44 Done.
3912 this.mainPod_.podStyle = UserPod.Style.EXTRA_SMALL;
3913 } else {
3914 this.mainPod_.podStyle = UserPod.Style.SMALL;
3915 }
3916 pod.podStyle = UserPod.Style.LARGE;
3917
3918 // Switch parent and position of the two pods.
3919 var left = pod.left;
3920 var top = pod.top;
3921 // Edge case: paddingBottom should be switched too because there's a
3922 // chance that the small pod was at the end of the scrollable container
3923 // and had a non-zero paddingBottom.
3924 var paddingBottom = pod.style.paddingBottom;
3925 var parent = pod.parentNode;
3926 parent.removeChild(pod);
3927 this.appendChild(pod);
3928 pod.left = this.mainPod_.left;
3929 pod.top = this.mainPod_.top;
3930 pod.style.paddingBottom = cr.ui.toCssPx(0);
3931
3932 this.removeChild(this.mainPod_);
3933 // It must have the same index with the original small pod, instead
3934 // of being appended as the last child, in order to maintain the 'Tab'
3935 // order.
3936 parent.insertBefore(this.mainPod_, children[insert]);
3937 this.mainPod_.left = left;
3938 this.mainPod_.top = top;
3939 this.mainPod_.style.paddingBottom = paddingBottom;
3940 this.mainPod_ = pod;
3941 // Focus the new main pod.
3942 this.focusPod(this.mainPod_);
3943 this.updatePodNameArea();
3944 },
3945
3946 /**
3947 * Returns dimensions of screen including the header bar.
3948 * @type {Object}
3949 */
3950 get screenSize() {
3951 var container = $('scroll-container');
3952 return {width: container.offsetWidth, height: container.offsetHeight};
3953 },
3954
3955 /**
3486 * Number of columns. 3956 * Number of columns.
3487 * @type {?number} 3957 * @type {?number}
3488 */ 3958 */
3489 set columns(columns) { 3959 set columns(columns) {
3490 // Cannot use 'columns' here. 3960 // Cannot use 'columns' here.
3491 this.setAttribute('ncolumns', columns); 3961 this.setAttribute('ncolumns', columns);
3492 }, 3962 },
3493 get columns() { 3963 get columns() {
3494 return parseInt(this.getAttribute('ncolumns')); 3964 return parseInt(this.getAttribute('ncolumns'));
3495 }, 3965 },
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
3796 if (e.target.classList.contains('focused')) { 4266 if (e.target.classList.contains('focused')) {
3797 if (!e.target.multiProfilesPolicyApplied) 4267 if (!e.target.multiProfilesPolicyApplied)
3798 e.target.focusInput(); 4268 e.target.focusInput();
3799 else 4269 else
3800 e.target.userTypeBubbleElement.classList.add('bubble-shown'); 4270 e.target.userTypeBubbleElement.classList.add('bubble-shown');
3801 } else 4271 } else
3802 this.focusPod(e.target); 4272 this.focusPod(e.target);
3803 return; 4273 return;
3804 } 4274 }
3805 4275
4276 // Small pods do not have input box.
4277 if (e.target.parentNode == this.smallPodsContainer) {
4278 this.focusPod(e.target, false, true /* opt_skipInputFocus */);
4279 return;
4280 }
4281
3806 var pod = findAncestorByClass(e.target, 'pod'); 4282 var pod = findAncestorByClass(e.target, 'pod');
3807 if (pod && pod.parentNode == this) { 4283 if (pod && pod.parentNode == this) {
3808 // Focus on a control of a pod but not on the action area button. 4284 // Focus on a control of a pod but not on the action area button.
3809 if (!pod.classList.contains('focused')) { 4285 if (!pod.classList.contains('focused')) {
3810 if (e.target.classList.contains('action-box-area') || 4286 if (e.target.classList.contains('action-box-area') ||
3811 e.target.classList.contains('remove-warning-button')) { 4287 e.target.classList.contains('remove-warning-button')) {
3812 // focusPod usually moves focus on the password input box which 4288 // focusPod usually moves focus on the password input box which
3813 // triggers virtual keyboard to show up. But the focus may move to a 4289 // 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 4290 // non text input element shortly by e.target.focus. Hence, a
3815 // virtual keyboard flicking might be observed. We need to manually 4291 // virtual keyboard flicking might be observed. We need to manually
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
3956 return; 4432 return;
3957 } 4433 }
3958 4434
3959 this.podsWithPendingImages_.splice(index, 1); 4435 this.podsWithPendingImages_.splice(index, 1);
3960 if (this.podsWithPendingImages_.length == 0) { 4436 if (this.podsWithPendingImages_.length == 0) {
3961 this.classList.remove('images-loading'); 4437 this.classList.remove('images-loading');
3962 } 4438 }
3963 }, 4439 },
3964 4440
3965 /** 4441 /**
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. 4442 * Preselects pod, if needed.
3982 */ 4443 */
3983 maybePreselectPod: function() { 4444 maybePreselectPod: function() {
3984 var pod = this.preselectedPod; 4445 var pod = this.preselectedPod;
3985 this.focusPod(pod); 4446 this.focusPod(pod);
3986 4447
3987 // Hide user-type-bubble in case all user pods are disabled and we focus 4448 // Hide user-type-bubble in case all user pods are disabled and we focus
3988 // first pod. 4449 // first pod.
3989 if (pod && pod.multiProfilesPolicyApplied) { 4450 if (pod && pod.multiProfilesPolicyApplied) {
3990 pod.userTypeBubbleElement.classList.remove('bubble-shown'); 4451 pod.userTypeBubbleElement.classList.remove('bubble-shown');
3991 } 4452 }
3992 } 4453 }
3993 }; 4454 };
3994 4455
3995 return { 4456 return {
3996 PodRow: PodRow 4457 PodRow: PodRow
3997 }; 4458 };
3998 }); 4459 });
OLDNEW
« no previous file with comments | « ui/login/account_picker/md_user_pod_row.css ('k') | ui/login/account_picker/md_user_pod_template.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698