OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * @fileoverview User pod row implementation. | 6 * @fileoverview User pod row implementation. |
7 */ | 7 */ |
8 | 8 |
9 cr.define('login', function() { | 9 cr.define('login', function() { |
10 /** | 10 /** |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 = 9; |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 * @param {UserPod.Style} style Style set to the pod. |
| 1192 */ |
| 1193 setPodStyle: function(style) { |
| 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 * @return {UserPod.Style} Pod style. |
| 1218 */ |
| 1219 getPodStyle: function() { |
| 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 Loading... |
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 Loading... |
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 // Only large pods have mouse down event. |
| 2076 if (this.getPodStyle() == 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 Loading... |
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.getPodStyle() != UserPod.Style.LARGE) { |
| 2135 $('pod-row').switchMainPod(this); |
| 2136 return; |
| 2137 } |
| 2138 |
2047 if (!this.isActionBoxMenuActive) { | 2139 if (!this.isActionBoxMenuActive) { |
2048 if (this.isAuthTypeOnlineSignIn) { | 2140 if (this.isAuthTypeOnlineSignIn) { |
2049 this.showSigninUI(); | 2141 this.showSigninUI(); |
2050 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { | 2142 } else if (this.isAuthTypeUserClick && this.userClickAuthAllowed_) { |
2051 // Note that this.userClickAuthAllowed_ is set in mouse down event | 2143 // Note that this.userClickAuthAllowed_ is set in mouse down event |
2052 // handler. | 2144 // handler. |
2053 this.parentNode.setActivatedPod(this); | 2145 this.parentNode.setActivatedPod(this); |
2054 } else if (this.pinKeyboard && | 2146 } else if (this.pinKeyboard && |
2055 e.target == this.pinKeyboard.submitButton) { | 2147 e.target == this.pinKeyboard.submitButton) { |
2056 // Sets the pod as activated if the submit button is clicked so that | 2148 // 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. | 2149 // it simulates what the enter button does for the password/pin. |
2058 this.parentNode.setActivatedPod(this); | 2150 this.parentNode.setActivatedPod(this); |
2059 } | 2151 } |
2060 | 2152 |
2061 if (this.multiProfilesPolicyApplied) | 2153 if (this.multiProfilesPolicyApplied) |
2062 this.userTypeBubbleElement.classList.add('bubble-shown'); | 2154 this.userTypeBubbleElement.classList.add('bubble-shown'); |
2063 | 2155 |
2064 // Prevent default so that we don't trigger 'focus' event and | 2156 // Prevent default so that we don't trigger 'focus' event and |
2065 // stop propagation so that the 'click' event does not bubble | 2157 // stop propagation so that the 'click' event does not bubble |
2066 // up and accidentally closes the bubble tooltip. | 2158 // up and accidentally closes the bubble tooltip. |
2067 stopEventPropagation(e); | 2159 stopEventPropagation(e); |
2068 } | 2160 } |
2069 }, | 2161 }, |
2070 | 2162 |
2071 /** | 2163 /** |
2072 * Handles keydown event for a user pod. | 2164 * Handles keydown event for a user pod. |
2073 * @param {Event} e Key event. | 2165 * @param {Event} e Key event. |
2074 */ | 2166 */ |
2075 handlePodKeyDown_: function(e) { | 2167 handlePodKeyDown_: function(e) { |
| 2168 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2169 this.handleNonLargePodKeyDown_(e); |
| 2170 return; |
| 2171 } |
2076 if (!this.isAuthTypeUserClick || this.disabled) | 2172 if (!this.isAuthTypeUserClick || this.disabled) |
2077 return; | 2173 return; |
2078 switch (e.key) { | 2174 switch (e.key) { |
2079 case 'Enter': | 2175 case 'Enter': |
2080 case ' ': | 2176 case ' ': |
2081 if (this.parentNode.isFocused(this)) | 2177 if (this.parentNode.isFocused(this)) |
2082 this.parentNode.setActivatedPod(this); | 2178 this.parentNode.setActivatedPod(this); |
2083 break; | 2179 break; |
2084 } | 2180 } |
| 2181 }, |
| 2182 |
| 2183 /** |
| 2184 * Handles keydown event for a small or extra small user pod. |
| 2185 * @param {Event} e Key event. |
| 2186 */ |
| 2187 handleNonLargePodKeyDown_: function(e) { |
| 2188 switch (e.key) { |
| 2189 case 'Enter': |
| 2190 case ' ': |
| 2191 if ($('pod-row').isFocused(this)) |
| 2192 $('pod-row').switchMainPod(this); |
| 2193 break; |
| 2194 } |
2085 } | 2195 } |
2086 }; | 2196 }; |
2087 | 2197 |
2088 /** | 2198 /** |
2089 * Creates a public account user pod. | 2199 * Creates a public account user pod. |
2090 * @constructor | 2200 * @constructor |
2091 * @extends {UserPod} | 2201 * @extends {UserPod} |
2092 */ | 2202 */ |
2093 var PublicAccountUserPod = cr.ui.define(function() { | 2203 var PublicAccountUserPod = cr.ui.define(function() { |
2094 var node = UserPod(); | 2204 var node = UserPod(); |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2286 this.focusInput(); | 2396 this.focusInput(); |
2287 } | 2397 } |
2288 return true; | 2398 return true; |
2289 }, | 2399 }, |
2290 | 2400 |
2291 /** @override */ | 2401 /** @override */ |
2292 handleClickOnPod_: function(e) { | 2402 handleClickOnPod_: function(e) { |
2293 if (this.parentNode.disabled) | 2403 if (this.parentNode.disabled) |
2294 return; | 2404 return; |
2295 | 2405 |
| 2406 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2407 $('pod-row').switchMainPod(this); |
| 2408 return; |
| 2409 } |
| 2410 |
2296 this.parentNode.focusPod(this); | 2411 this.parentNode.focusPod(this); |
2297 this.parentNode.setActivatedPod(this, e); | 2412 this.parentNode.setActivatedPod(this, e); |
2298 // Prevent default so that we don't trigger 'focus' event. | 2413 // Prevent default so that we don't trigger 'focus' event. |
2299 e.preventDefault(); | 2414 e.preventDefault(); |
2300 }, | 2415 }, |
2301 | 2416 |
2302 /** | 2417 /** |
2303 * Updates the display name shown on the pod. | 2418 * Updates the display name shown on the pod. |
2304 * @param {string} displayName The new display name | 2419 * @param {string} displayName The new display name |
2305 */ | 2420 */ |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2519 get mainInput() { | 2634 get mainInput() { |
2520 if (this.user.needsSignin) | 2635 if (this.user.needsSignin) |
2521 return this.passwordElement; | 2636 return this.passwordElement; |
2522 else | 2637 else |
2523 return this.nameElement; | 2638 return this.nameElement; |
2524 }, | 2639 }, |
2525 | 2640 |
2526 /** @override */ | 2641 /** @override */ |
2527 update: function() { | 2642 update: function() { |
2528 this.imageElement.src = this.user.userImage; | 2643 this.imageElement.src = this.user.userImage; |
| 2644 this.smallPodImageElement.src = this.user.userImage; |
2529 this.nameElement.textContent = this.user.displayName; | 2645 this.nameElement.textContent = this.user.displayName; |
| 2646 this.smallPodNameElement.textContent = this.user.displayName; |
2530 this.reauthNameHintElement.textContent = this.user.displayName; | 2647 this.reauthNameHintElement.textContent = this.user.displayName; |
2531 | 2648 |
2532 var isLockedUser = this.user.needsSignin; | 2649 var isLockedUser = this.user.needsSignin; |
2533 var isLegacySupervisedUser = this.user.legacySupervisedUser; | 2650 var isLegacySupervisedUser = this.user.legacySupervisedUser; |
2534 var isChildUser = this.user.childUser; | 2651 var isChildUser = this.user.childUser; |
2535 var isSyncedUser = this.user.emailAddress !== ""; | 2652 var isSyncedUser = this.user.emailAddress !== ""; |
2536 var isProfileLoaded = this.user.isProfileLoaded; | 2653 var isProfileLoaded = this.user.isProfileLoaded; |
2537 this.classList.toggle('locked', isLockedUser); | 2654 this.classList.toggle('locked', isLockedUser); |
2538 this.classList.toggle('legacy-supervised', isLegacySupervisedUser); | 2655 this.classList.toggle('legacy-supervised', isLegacySupervisedUser); |
2539 this.classList.toggle('child', isChildUser); | 2656 this.classList.toggle('child', isChildUser); |
(...skipping 24 matching lines...) Expand all Loading... |
2564 } | 2681 } |
2565 this.passwordElement.value = ''; | 2682 this.passwordElement.value = ''; |
2566 return true; | 2683 return true; |
2567 }, | 2684 }, |
2568 | 2685 |
2569 /** @override */ | 2686 /** @override */ |
2570 handleClickOnPod_: function(e) { | 2687 handleClickOnPod_: function(e) { |
2571 if (this.parentNode.disabled) | 2688 if (this.parentNode.disabled) |
2572 return; | 2689 return; |
2573 | 2690 |
| 2691 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2692 $('pod-row').switchMainPod(this); |
| 2693 return; |
| 2694 } |
| 2695 |
2574 Oobe.clearErrors(); | 2696 Oobe.clearErrors(); |
2575 this.parentNode.lastFocusedPod_ = this; | 2697 this.parentNode.lastFocusedPod_ = this; |
2576 | 2698 |
2577 // If this is a locked pod and there are local credentials, show the | 2699 // 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 | 2700 // password field. Otherwise call activate() which will open up a browser |
2579 // window or show the reauth dialog, as needed. | 2701 // window or show the reauth dialog, as needed. |
2580 if (!(this.user.needsSignin && this.user.hasLocalCreds) && | 2702 if (!(this.user.needsSignin && this.user.hasLocalCreds) && |
2581 !this.isActionBoxMenuActive) { | 2703 !this.isActionBoxMenuActive) { |
2582 this.activate(e); | 2704 this.activate(e); |
2583 } | 2705 } |
(...skipping 21 matching lines...) Expand all Loading... |
2605 UserPod.prototype.decorate.call(this); | 2727 UserPod.prototype.decorate.call(this); |
2606 this.launchAppButtonElement.addEventListener('click', | 2728 this.launchAppButtonElement.addEventListener('click', |
2607 this.activate.bind(this)); | 2729 this.activate.bind(this)); |
2608 }, | 2730 }, |
2609 | 2731 |
2610 /** @override */ | 2732 /** @override */ |
2611 update: function() { | 2733 update: function() { |
2612 this.imageElement.src = this.user.iconUrl; | 2734 this.imageElement.src = this.user.iconUrl; |
2613 this.imageElement.alt = this.user.label; | 2735 this.imageElement.alt = this.user.label; |
2614 this.imageElement.title = this.user.label; | 2736 this.imageElement.title = this.user.label; |
| 2737 this.smallPodImageElement.src = this.user.iconUrl; |
| 2738 this.smallPodImageElement.alt = this.user.label; |
| 2739 this.smallPodImageElement.title = this.user.label; |
2615 this.passwordEntryContainerElement.hidden = true; | 2740 this.passwordEntryContainerElement.hidden = true; |
2616 this.launchAppButtonContainerElement.hidden = false; | 2741 this.launchAppButtonContainerElement.hidden = false; |
2617 this.nameElement.textContent = this.user.label; | 2742 this.nameElement.textContent = this.user.label; |
| 2743 this.smallPodNameElement.textContent = this.user.label; |
2618 this.reauthNameHintElement.textContent = this.user.label; | 2744 this.reauthNameHintElement.textContent = this.user.label; |
2619 | 2745 |
2620 UserPod.prototype.updateActionBoxArea.call(this); | 2746 UserPod.prototype.updateActionBoxArea.call(this); |
2621 UserPod.prototype.customizeUserPodPerUserType.call(this); | 2747 UserPod.prototype.customizeUserPodPerUserType.call(this); |
2622 }, | 2748 }, |
2623 | 2749 |
2624 /** @override */ | 2750 /** @override */ |
2625 get mainInput() { | 2751 get mainInput() { |
2626 return this.launchAppButtonElement; | 2752 return this.launchAppButtonElement; |
2627 }, | 2753 }, |
(...skipping 16 matching lines...) Expand all Loading... |
2644 var diagnosticMode = e && e.ctrlKey; | 2770 var diagnosticMode = e && e.ctrlKey; |
2645 this.launchApp_(this.user, diagnosticMode); | 2771 this.launchApp_(this.user, diagnosticMode); |
2646 return true; | 2772 return true; |
2647 }, | 2773 }, |
2648 | 2774 |
2649 /** @override */ | 2775 /** @override */ |
2650 handleClickOnPod_: function(e) { | 2776 handleClickOnPod_: function(e) { |
2651 if (this.parentNode.disabled) | 2777 if (this.parentNode.disabled) |
2652 return; | 2778 return; |
2653 | 2779 |
| 2780 if (this.getPodStyle() != UserPod.Style.LARGE) { |
| 2781 $('pod-row').switchMainPod(this); |
| 2782 return; |
| 2783 } |
| 2784 |
2654 Oobe.clearErrors(); | 2785 Oobe.clearErrors(); |
2655 this.parentNode.lastFocusedPod_ = this; | 2786 this.parentNode.lastFocusedPod_ = this; |
2656 this.activate(e); | 2787 this.activate(e); |
2657 }, | 2788 }, |
2658 | 2789 |
2659 /** | 2790 /** |
2660 * Launch the app. If |diagnosticMode| is true, ask user to confirm. | 2791 * Launch the app. If |diagnosticMode| is true, ask user to confirm. |
2661 * @param {Object} app App data. | 2792 * @param {Object} app App data. |
2662 * @param {boolean} diagnosticMode Whether to run the app in diagnostic | 2793 * @param {boolean} diagnosticMode Whether to run the app in diagnostic |
2663 * mode. | 2794 * mode. |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2705 | 2836 |
2706 // Focused pod. | 2837 // Focused pod. |
2707 focusedPod_: undefined, | 2838 focusedPod_: undefined, |
2708 | 2839 |
2709 // Activated pod, i.e. the pod of current login attempt. | 2840 // Activated pod, i.e. the pod of current login attempt. |
2710 activatedPod_: undefined, | 2841 activatedPod_: undefined, |
2711 | 2842 |
2712 // Pod that was most recently focused, if any. | 2843 // Pod that was most recently focused, if any. |
2713 lastFocusedPod_: undefined, | 2844 lastFocusedPod_: undefined, |
2714 | 2845 |
| 2846 // Pod that occupies the main spot. |
| 2847 mainPod_: undefined, |
| 2848 |
2715 // Pods whose initial images haven't been loaded yet. | 2849 // Pods whose initial images haven't been loaded yet. |
2716 podsWithPendingImages_: [], | 2850 podsWithPendingImages_: [], |
2717 | 2851 |
2718 // Whether pod placement has been postponed. | 2852 // Whether pod placement has been postponed. |
2719 podPlacementPostponed_: false, | 2853 podPlacementPostponed_: false, |
2720 | 2854 |
2721 // Standard user pod height/width. | 2855 // Standard user pod height/width. |
2722 userPodHeight_: 0, | 2856 userPodHeight_: 0, |
2723 userPodWidth_: 0, | 2857 userPodWidth_: 0, |
2724 | 2858 |
(...skipping 27 matching lines...) Expand all Loading... |
2752 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT : | 2886 isNewDesktopUserManager ? MD_DESKTOP_POD_HEIGHT : |
2753 DESKTOP_POD_HEIGHT : | 2887 DESKTOP_POD_HEIGHT : |
2754 CROS_POD_HEIGHT; | 2888 CROS_POD_HEIGHT; |
2755 this.userPodWidth_ = isDesktopUserManager ? | 2889 this.userPodWidth_ = isDesktopUserManager ? |
2756 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH : | 2890 isNewDesktopUserManager ? MD_DESKTOP_POD_WIDTH : |
2757 DESKTOP_POD_WIDTH : | 2891 DESKTOP_POD_WIDTH : |
2758 CROS_POD_WIDTH; | 2892 CROS_POD_WIDTH; |
2759 }, | 2893 }, |
2760 | 2894 |
2761 /** | 2895 /** |
2762 * Returns all the pods in this pod row. | 2896 * Returns all the pods in this pod row. Some pods may not be its direct |
| 2897 * children, but the caller doesn't have to know this. |
2763 * @type {NodeList} | 2898 * @type {NodeList} |
2764 */ | 2899 */ |
2765 get pods() { | 2900 get pods() { |
2766 return Array.prototype.slice.call(this.children); | 2901 var powRowChildren = Array.prototype.slice.call(this.children); |
| 2902 var containerChildren = |
| 2903 Array.prototype.slice.call(this.smallPodsContainer.children); |
| 2904 return powRowChildren.concat(containerChildren); |
2767 }, | 2905 }, |
2768 | 2906 |
2769 /** | 2907 /** |
2770 * Return true if user pod row has only single user pod in it, which should | 2908 * 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. | 2909 * always be focused except desktop and touch view modes. |
2772 * @type {boolean} | 2910 * @type {boolean} |
2773 */ | 2911 */ |
2774 get alwaysFocusSinglePod() { | 2912 get alwaysFocusSinglePod() { |
2775 var isDesktopUserManager = Oobe.getInstance().displayType == | 2913 var isDesktopUserManager = Oobe.getInstance().displayType == |
2776 DISPLAY_TYPE.DESKTOP_USER_MANAGER; | 2914 DISPLAY_TYPE.DESKTOP_USER_MANAGER; |
2777 | 2915 |
2778 return (isDesktopUserManager || this.touchViewEnabled_) ? | 2916 return (isDesktopUserManager || this.touchViewEnabled_) ? |
2779 false : this.children.length == 1; | 2917 false : |
| 2918 this.pods.length == 1; |
2780 }, | 2919 }, |
2781 | 2920 |
2782 /** | 2921 /** |
2783 * Returns pod with the given app id. | 2922 * Returns pod with the given app id. |
2784 * @param {!string} app_id Application id to be matched. | 2923 * @param {!string} app_id Application id to be matched. |
2785 * @return {Object} Pod with the given app id. null if pod hasn't been | 2924 * @return {Object} Pod with the given app id. null if pod hasn't been |
2786 * found. | 2925 * found. |
2787 */ | 2926 */ |
2788 getPodWithAppId_: function(app_id) { | 2927 getPodWithAppId_: function(app_id) { |
2789 for (var i = 0, pod; pod = this.pods[i]; ++i) { | 2928 for (var i = 0, pod; pod = this.pods[i]; ++i) { |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2946 /** | 3085 /** |
2947 * Removes user pod from pod row. | 3086 * Removes user pod from pod row. |
2948 * @param {!user} username | 3087 * @param {!user} username |
2949 */ | 3088 */ |
2950 removeUserPod: function(username) { | 3089 removeUserPod: function(username) { |
2951 var podToRemove = this.getPodWithUsername_(username); | 3090 var podToRemove = this.getPodWithUsername_(username); |
2952 if (podToRemove == null) { | 3091 if (podToRemove == null) { |
2953 console.warn('Attempt to remove pod that does not exist'); | 3092 console.warn('Attempt to remove pod that does not exist'); |
2954 return; | 3093 return; |
2955 } | 3094 } |
2956 this.removeChild(podToRemove); | 3095 // Its parent is not necessarily this pod row. |
2957 if (this.pods.length > 0) | 3096 podToRemove.parentNode.removeChild(podToRemove); |
| 3097 this.mainPod_ = null; |
| 3098 if (this.pods.length > 0) { |
| 3099 // placePods_() will select a new main pod and re-append pods |
| 3100 // to different parents if necessary. |
2958 this.placePods_(); | 3101 this.placePods_(); |
| 3102 this.maybePreselectPod(); |
| 3103 } |
2959 }, | 3104 }, |
2960 | 3105 |
2961 /** | 3106 /** |
2962 * Returns index of given pod or -1 if not found. | 3107 * Returns index of given pod or -1 if not found. |
2963 * @param {UserPod} pod Pod to look up. | 3108 * @param {UserPod} pod Pod to look up. |
2964 * @private | 3109 * @private |
2965 */ | 3110 */ |
2966 indexOf_: function(pod) { | 3111 indexOf_: function(pod) { |
2967 for (var i = 0; i < this.pods.length; ++i) { | 3112 for (var i = 0; i < this.pods.length; ++i) { |
2968 if (pod == this.pods[i]) | 3113 if (pod == this.pods[i]) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3013 * updated. | 3158 * updated. |
3014 */ | 3159 */ |
3015 rebuildPods: function() { | 3160 rebuildPods: function() { |
3016 var emptyPodRow = this.pods.length == 0; | 3161 var emptyPodRow = this.pods.length == 0; |
3017 | 3162 |
3018 // Clear existing pods. | 3163 // Clear existing pods. |
3019 this.innerHTML = ''; | 3164 this.innerHTML = ''; |
3020 this.focusedPod_ = undefined; | 3165 this.focusedPod_ = undefined; |
3021 this.activatedPod_ = undefined; | 3166 this.activatedPod_ = undefined; |
3022 this.lastFocusedPod_ = undefined; | 3167 this.lastFocusedPod_ = undefined; |
| 3168 this.mainPod_ = undefined; |
3023 | 3169 |
3024 // Switch off animation | 3170 // Switch off animation |
3025 Oobe.getInstance().toggleClass('flying-pods', false); | 3171 Oobe.getInstance().toggleClass('flying-pods', false); |
3026 | 3172 |
3027 // Populate the pod row. | |
3028 for (var i = 0; i < this.users_.length; ++i) | 3173 for (var i = 0; i < this.users_.length; ++i) |
3029 this.addUserPod(this.users_[i]); | 3174 this.addUserPod(this.users_[i]); |
3030 | 3175 |
3031 for (var i = 0, pod; pod = this.pods[i]; ++i) | 3176 for (var i = 0, pod; pod = this.pods[i]; ++i) |
3032 this.podsWithPendingImages_.push(pod); | 3177 this.podsWithPendingImages_.push(pod); |
3033 | 3178 |
3034 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. | 3179 // TODO(nkostylev): Edge case handling when kiosk apps are not fitting. |
3035 if (this.shouldShowApps_) { | 3180 if (this.shouldShowApps_) { |
3036 for (var i = 0; i < this.apps_.length; ++i) | 3181 for (var i = 0; i < this.apps_.length; ++i) |
3037 this.addUserPod(this.apps_[i]); | 3182 this.addUserPod(this.apps_[i]); |
(...skipping 25 matching lines...) Expand all Loading... |
3063 if ($('login-header-bar').signinUIState == | 3208 if ($('login-header-bar').signinUIState == |
3064 SIGNIN_UI_STATE.GAIA_SIGNIN && | 3209 SIGNIN_UI_STATE.GAIA_SIGNIN && |
3065 emptyPodRow && | 3210 emptyPodRow && |
3066 this.pods.length > 0) { | 3211 this.pods.length > 0) { |
3067 login.GaiaSigninScreen.updateControlsState(); | 3212 login.GaiaSigninScreen.updateControlsState(); |
3068 } | 3213 } |
3069 } | 3214 } |
3070 }, | 3215 }, |
3071 | 3216 |
3072 /** | 3217 /** |
| 3218 * Gets the container of small pods. |
| 3219 * @type {!HTMLDivElement} |
| 3220 */ |
| 3221 get smallPodsContainer() { |
| 3222 return document.querySelector('.small-pod-container'); |
| 3223 }, |
| 3224 |
| 3225 /** |
3073 * Adds given apps to the pod row. | 3226 * Adds given apps to the pod row. |
3074 * @param {array} apps Array of apps. | 3227 * @param {array} apps Array of apps. |
3075 */ | 3228 */ |
3076 setApps: function(apps) { | 3229 setApps: function(apps) { |
3077 this.apps_ = apps; | 3230 this.apps_ = apps; |
3078 this.rebuildPods(); | 3231 this.rebuildPods(); |
3079 chrome.send('kioskAppsLoaded'); | 3232 chrome.send('kioskAppsLoaded'); |
3080 | 3233 |
3081 // Check whether there's a pending kiosk app error. | 3234 // Check whether there's a pending kiosk app error. |
3082 window.setTimeout(function() { | 3235 window.setTimeout(function() { |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3315 }, | 3468 }, |
3316 | 3469 |
3317 /** | 3470 /** |
3318 * Updates the list of locales available for a public session. | 3471 * Updates the list of locales available for a public session. |
3319 * @param {string} userID The user ID of the public session | 3472 * @param {string} userID The user ID of the public session |
3320 * @param {!Object} locales The list of available locales | 3473 * @param {!Object} locales The list of available locales |
3321 * @param {string} defaultLocale The locale to select by default | 3474 * @param {string} defaultLocale The locale to select by default |
3322 * @param {boolean} multipleRecommendedLocales Whether |locales| contains | 3475 * @param {boolean} multipleRecommendedLocales Whether |locales| contains |
3323 * two or more recommended locales | 3476 * two or more recommended locales |
3324 */ | 3477 */ |
3325 setPublicSessionLocales: function(userID, | 3478 setPublicSessionLocales: function( |
3326 locales, | 3479 userID, locales, defaultLocale, multipleRecommendedLocales) { |
3327 defaultLocale, | |
3328 multipleRecommendedLocales) { | |
3329 var pod = this.getPodWithUsername_(userID); | 3480 var pod = this.getPodWithUsername_(userID); |
3330 if (pod != null) { | 3481 if (pod != null) { |
3331 pod.populateLanguageSelect(locales, | 3482 pod.populateLanguageSelect(locales, |
3332 defaultLocale, | 3483 defaultLocale, |
3333 multipleRecommendedLocales); | 3484 multipleRecommendedLocales); |
3334 } | 3485 } |
3335 }, | 3486 }, |
3336 | 3487 |
3337 /** | 3488 /** |
3338 * Updates the list of available keyboard layouts for a public session pod. | 3489 * Updates the list of available keyboard layouts for a public session pod. |
3339 * @param {string} userID The user ID of the public session | 3490 * @param {string} userID The user ID of the public session |
3340 * @param {string} locale The locale to which this list of keyboard layouts | 3491 * @param {string} locale The locale to which this list of keyboard layouts |
3341 * applies | 3492 * applies |
3342 * @param {!Object} list List of available keyboard layouts | 3493 * @param {!Object} list List of available keyboard layouts |
3343 */ | 3494 */ |
3344 setPublicSessionKeyboardLayouts: function(userID, locale, list) { | 3495 setPublicSessionKeyboardLayouts: function(userID, locale, list) { |
3345 var pod = this.getPodWithUsername_(userID); | 3496 var pod = this.getPodWithUsername_(userID); |
3346 if (pod != null) | 3497 if (pod != null) |
3347 pod.populateKeyboardSelect(locale, list); | 3498 pod.populateKeyboardSelect(locale, list); |
3348 }, | 3499 }, |
3349 | 3500 |
3350 /** | 3501 /** |
3351 * Called when window was resized. | 3502 * Called when window was resized. The two common use cases are changing |
| 3503 * screen orientation and showing the virtual keyboard. |
3352 */ | 3504 */ |
3353 onWindowResize: function() { | 3505 onWindowResize: function() { |
3354 var layout = this.calculateLayout_(); | 3506 var screen = document.querySelector('#scroll-container'); |
3355 if (layout.columns != this.columns || layout.rows != this.rows) | 3507 var clientArea = document.querySelector('#inner-container'); |
3356 this.placePods_(); | 3508 if (Oobe.getInstance().virtualKeyboardShown) { |
3357 | 3509 // Edge case: when virtual keyboard is shown, although the screen size |
3358 // Wrap this in a set timeout so the function is called after the pod is | 3510 // is reduced properly, the size of the outer container remains the |
3359 // finished transitioning so that we work with the final pod dimensions. | 3511 // same because its min-height is applied. Users can scroll the screen |
3360 // If there is no focused pod that may be transitioning when this function | 3512 // upward and see empty areas beyond the pod row and the scroll bar, |
3361 // is called, we can call scrollFocusedPodIntoView() right away. | 3513 // which should be avoided. |
3362 var timeOut = 0; | 3514 // This is a hacky solution: we can make the scroll container hide |
3363 if (this.focusedPod_) { | 3515 // the overflow area and manully position the client area. |
3364 var style = getComputedStyle(this.focusedPod_); | 3516 screen.style.overflowY = "hidden"; |
3365 timeOut = parseFloat(style.transitionDuration) * 1000; | 3517 clientArea.style.position = "absolute"; |
| 3518 clientArea.style.left = cr.ui.toCssPx(0); |
| 3519 clientArea.style.top = cr.ui.toCssPx(0); |
| 3520 } else { |
| 3521 // Sets the values to default when virtual keyboard is not shown. |
| 3522 screen.style.overflowY = "auto"; |
| 3523 clientArea.style.position = "relative"; |
3366 } | 3524 } |
3367 | 3525 this.placePods_(); |
3368 setTimeout(function() { | |
3369 this.scrollFocusedPodIntoView(); | |
3370 }.bind(this), timeOut); | |
3371 }, | 3526 }, |
3372 | 3527 |
3373 /** | 3528 /** |
3374 * Returns width of podrow having |columns| number of columns. | 3529 * Returns width of podrow having |columns| number of columns. |
3375 * @private | 3530 * @private |
3376 */ | 3531 */ |
3377 columnsToWidth_: function(columns) { | 3532 columnsToWidth_: function(columns) { |
3378 var isDesktopUserManager = Oobe.getInstance().displayType == | 3533 var isDesktopUserManager = Oobe.getInstance().displayType == |
3379 DISPLAY_TYPE.DESKTOP_USER_MANAGER; | 3534 DISPLAY_TYPE.DESKTOP_USER_MANAGER; |
3380 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : | 3535 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : |
(...skipping 30 matching lines...) Expand all Loading... |
3411 while (maxWidth < this.columnsToWidth_(columns) && columns > 1) | 3566 while (maxWidth < this.columnsToWidth_(columns) && columns > 1) |
3412 --columns; | 3567 --columns; |
3413 var rows = Math.floor((this.pods.length - 1) / columns) + 1; | 3568 var rows = Math.floor((this.pods.length - 1) / columns) + 1; |
3414 if (getComputedStyle( | 3569 if (getComputedStyle( |
3415 $('signin-banner'), null).getPropertyValue('display') != 'none') { | 3570 $('signin-banner'), null).getPropertyValue('display') != 'none') { |
3416 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER); | 3571 rows = Math.min(rows, MAX_NUMBER_OF_ROWS_UNDER_SIGNIN_BANNER); |
3417 } | 3572 } |
3418 if (!Oobe.getInstance().newDesktopUserManager) { | 3573 if (!Oobe.getInstance().newDesktopUserManager) { |
3419 var maxHeigth = Oobe.getInstance().clientAreaSize.height; | 3574 var maxHeigth = Oobe.getInstance().clientAreaSize.height; |
3420 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1) | 3575 while (maxHeigth < this.rowsToHeight_(rows) && rows > 1) |
3421 --rows; | 3576 --rows; |
3422 } | 3577 } |
3423 // One more iteration if it's not enough cells to place all pods. | 3578 // One more iteration if it's not enough cells to place all pods. |
3424 while (maxWidth >= this.columnsToWidth_(columns + 1) && | 3579 while (maxWidth >= this.columnsToWidth_(columns + 1) && |
3425 columns * rows < this.pods.length && | 3580 columns * rows < this.pods.length && |
3426 columns < MAX_NUMBER_OF_COLUMNS) { | 3581 columns < MAX_NUMBER_OF_COLUMNS) { |
3427 ++columns; | 3582 ++columns; |
3428 } | 3583 } |
3429 return {columns: columns, rows: rows}; | 3584 return {columns: columns, rows: rows}; |
3430 }, | 3585 }, |
3431 | 3586 |
3432 /** | 3587 /** |
3433 * Places pods onto their positions onto pod grid. | 3588 * Places pods onto their positions in pod grid matching the new design. |
3434 * @private | 3589 * @private |
3435 */ | 3590 */ |
3436 placePods_: function() { | 3591 placePods_: function() { |
3437 var isDesktopUserManager = Oobe.getInstance().displayType == | 3592 var pods = this.pods; |
3438 DISPLAY_TYPE.DESKTOP_USER_MANAGER; | 3593 if (pods.length == 0) { |
3439 if (isDesktopUserManager && !Oobe.getInstance().userPodsPageVisible) | 3594 console.error('Attempt to place pods for an empty pod list.'); |
3440 return; | 3595 return; |
3441 | 3596 } |
3442 var layout = this.calculateLayout_(); | 3597 // Append all pods to their proper parents. Small pods have parent other |
3443 var columns = this.columns = layout.columns; | 3598 // than the pod row. The pods were all initialized with the pow row as a |
3444 var rows = this.rows = layout.rows; | 3599 // temporary parent, which is intended to ensure that all event listeners |
3445 var maxPodsNumber = columns * rows; | 3600 // work properly. If the main pod already exists, it means we are in the |
3446 var margin = isDesktopUserManager ? DESKTOP_MARGIN_BY_COLUMNS[columns] : | 3601 // process of resizing the window, then there is no need to change parents |
3447 MARGIN_BY_COLUMNS[columns]; | 3602 // of any pod. |
3448 this.parentNode.setPreferredSize( | 3603 if (!this.mainPod_) { |
3449 this.columnsToWidth_(columns), this.rowsToHeight_(rows)); | 3604 this.mainPod_ = this.preselectedPod; |
3450 var height = this.userPodHeight_; | 3605 this.appendPodsToParents(); |
3451 var width = this.userPodWidth_; | 3606 } |
3452 var pinPodLocation = { column: columns + 1, row: rows + 1 }; | 3607 this.restoreInitialStates_(); |
3453 if (this.focusedPod_ && this.focusedPod_.isPinShown()) | 3608 if (Oobe.getInstance().virtualKeyboardShown) { |
3454 pinPodLocation = this.findPodLocation_(this.focusedPod_, columns, rows); | 3609 // When virtual keyboard is shown, the account picker should occupy |
3455 | 3610 // all the remaining screen. Screen size was already updated to exclude |
3456 this.pods.forEach(function(pod, index) { | 3611 // the virtual keyboard. |
3457 if (index >= maxPodsNumber) { | 3612 this.parentNode.setPreferredSize( |
3458 pod.hidden = true; | 3613 this.screenSize.width, |
3459 return; | 3614 this.screenSize.height); |
3460 } | 3615 } else { |
3461 pod.hidden = false; | 3616 // Make sure not to block the header bar when virtual keyboard is absent
. |
3462 if (pod.offsetHeight != height && | 3617 this.parentNode.setPreferredSize( |
3463 pod.offsetHeight != CROS_PIN_POD_HEIGHT) { | 3618 Oobe.getInstance().clientAreaSize.width, |
3464 console.error('Pod offsetHeight (' + pod.offsetHeight + | 3619 Oobe.getInstance().clientAreaSize.height); |
3465 ') and POD_HEIGHT (' + height + ') are not equal.'); | 3620 } |
3466 } | 3621 |
3467 if (pod.offsetWidth != width) { | 3622 if (pods.length == 1) { |
3468 console.error('Pod offsetWidth (' + pod.offsetWidth + | 3623 this.placeSinglePod_(); |
3469 ') and POD_WIDTH (' + width + ') are not equal.'); | 3624 } else if (pods.length == POD_ROW_LIMIT) { |
3470 } | 3625 this.placePodsOnPodRow_(); |
3471 var column = index % columns; | 3626 } else { |
3472 var row = Math.floor(index / columns); | 3627 this.placePodsOnContainer_(); |
3473 | 3628 } |
3474 var rowPadding = isDesktopUserManager ? DESKTOP_ROW_PADDING : | 3629 Oobe.getInstance().updateScreenSize(this.parentNode); |
3475 POD_ROW_PADDING; | 3630 this.updatePodNameArea(); |
3476 pod.left = rowPadding + column * (width + margin); | 3631 }, |
3477 | 3632 |
3478 // On desktop, we want the rows to always be equally spaced. | 3633 /** |
3479 pod.top = isDesktopUserManager ? row * (height + rowPadding) : | 3634 * Append pods to proper parents. Called each time before pod placement. |
3480 row * height + rowPadding; | 3635 * @private |
| 3636 */ |
| 3637 appendPodsToParents: function() { |
| 3638 var pods = this.pods; |
| 3639 // Pod count may have changed, so the placement method may change |
| 3640 // accordingly. Therefore, always remove all pods from their current |
| 3641 // parents first. |
| 3642 for (var pod of pods) { |
| 3643 pod.parentNode.removeChild(pod); |
| 3644 } |
| 3645 if (pods.length <= POD_ROW_LIMIT) { |
| 3646 for (var pod of pods) { |
| 3647 this.appendChild(pod); |
| 3648 } |
| 3649 } else { |
| 3650 // When the user count exceeds the limit (currently set to 2), only the |
| 3651 // main pod still has pow row as parent, all other pods should be |
| 3652 // appended to the container with scroll bar. |
| 3653 for (var pod of pods) { |
| 3654 if (pod == this.mainPod_) { |
| 3655 this.appendChild(pod); |
| 3656 } else { |
| 3657 this.smallPodsContainer.appendChild(pod); |
| 3658 } |
| 3659 } |
| 3660 } |
| 3661 }, |
| 3662 |
| 3663 /** |
| 3664 * Called when there is one user pod. |
| 3665 * @private |
| 3666 */ |
| 3667 placeSinglePod_: function() { |
| 3668 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3669 this.mainPod_.left = (this.screenSize.width - CROS_POD_WIDTH) / 2; |
| 3670 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3671 }, |
| 3672 |
| 3673 /** |
| 3674 * Called when there are two users pods. |
| 3675 * @private |
| 3676 */ |
| 3677 placePodsOnPodRow_: function() { |
| 3678 // Both pods have large size and are placed adjacently. |
| 3679 var secondPod = |
| 3680 this.pods[0] == this.mainPod_ ? this.pods[1] : this.pods[0]; |
| 3681 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3682 secondPod.setPodStyle(UserPod.Style.LARGE); |
| 3683 |
| 3684 var DOUBLE_PODS_PADDING = this.isPortraitMode() ? 32 : 118; |
| 3685 var leftPadding = (this.screenSize.width - (CROS_POD_WIDTH * 2 + DOUBLE_PO
DS_PADDING)) / 2; |
| 3686 // Start actual positioning. |
| 3687 this.mainPod_.left = leftPadding; |
| 3688 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3689 secondPod.left = leftPadding + CROS_POD_WIDTH + DOUBLE_PODS_PADDING; |
| 3690 secondPod.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3691 }, |
| 3692 |
| 3693 /** |
| 3694 * Called when there are more than two user pods. |
| 3695 * @private |
| 3696 */ |
| 3697 placePodsOnContainer_: function() { |
| 3698 this.smallPodsContainer.hidden = false; |
| 3699 var pods = this.pods; |
| 3700 if ((pods.length > LANDSCAPE_MODE_LIMIT && !this.isPortraitMode()) || |
| 3701 (pods.length > PORTRAIT_MODE_LIMIT && this.isPortraitMode())) { |
| 3702 // If the pod count exceeds limits, they should be in extra small size |
| 3703 // and the container will become scrollable. |
| 3704 this.placePodsOnScrollableContainer_(); |
| 3705 return; |
| 3706 } |
| 3707 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3708 for (var pod of pods) { |
| 3709 if (pod != this.mainPod_) { |
| 3710 // All pods except the main one must be set to the small style. |
| 3711 pod.setPodStyle(UserPod.Style.SMALL); |
| 3712 } |
| 3713 } |
| 3714 // The size of the smallPodsContainer must be updated to avoid overflow, |
| 3715 // otherwise unnecessary scroll bar will show up. |
| 3716 this.smallPodsContainer.style.height = |
| 3717 cr.ui.toCssPx(this.screenSize.height); |
| 3718 this.smallPodsContainer.style.width = cr.ui.toCssPx(CROS_SMALL_POD_WIDTH); |
| 3719 |
| 3720 var LEFT_PADDING = this.isPortraitMode() ? 0 : 98; |
| 3721 var MIDDLE_PADDING = this.isPortraitMode() ? 84 : 220; |
| 3722 var contentsWidth = LEFT_PADDING + |
| 3723 CROS_POD_WIDTH + MIDDLE_PADDING + CROS_SMALL_POD_WIDTH; |
| 3724 var blankWidth = this.screenSize.width - contentsWidth; |
| 3725 var actualLeftPadding = LEFT_PADDING; |
| 3726 actualLeftPadding += this.isPortraitMode() ? blankWidth * 2 / 3: |
| 3727 blankWidth / 2; |
| 3728 var SMALL_POD_PADDING = 54; |
| 3729 var actualSmallPodPadding = SMALL_POD_PADDING; |
| 3730 var smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + |
| 3731 (pods.length - 2) * actualSmallPodPadding; |
| 3732 if (smallPodsTotalHeight > this.screenSize.height) { |
| 3733 // Edge case: when the virtual keyboard is present, the total height of |
| 3734 // the smallPodsContainer may exceed the screen height. Decrease the |
| 3735 // padding among small pods according to the design spec. |
| 3736 actualSmallPodPadding = 32; |
| 3737 smallPodsTotalHeight = (pods.length - 1) * CROS_SMALL_POD_HEIGHT + |
| 3738 (pods.length - 2) * actualSmallPodPadding; |
| 3739 } |
| 3740 |
| 3741 // Start positioning of the main pod and the smallPodsContainer. |
| 3742 this.mainPod_.left = actualLeftPadding; |
| 3743 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3744 this.smallPodsContainer.style.left = |
| 3745 cr.ui.toCssPx(actualLeftPadding + CROS_POD_WIDTH + MIDDLE_PADDING); |
| 3746 this.smallPodsContainer.style.top = cr.ui.toCssPx(0); |
| 3747 // Start positioning of the small pods inside the smallPodsContainer. |
| 3748 var smallPodsTopPadding = (this.screenSize.height - smallPodsTotalHeight)
/ 2; |
| 3749 for (var pod of pods) { |
| 3750 if (pod == this.mainPod_) { |
| 3751 continue; |
| 3752 } |
| 3753 pod.left = 0; |
| 3754 pod.top = smallPodsTopPadding; |
| 3755 smallPodsTopPadding += CROS_SMALL_POD_HEIGHT + actualSmallPodPadding; |
| 3756 } |
| 3757 }, |
| 3758 |
| 3759 /** |
| 3760 * Called when there are more than 6 user pods in landscape mode, or more |
| 3761 * than 10 user pods in portrait mode. |
| 3762 * @private |
| 3763 */ |
| 3764 placePodsOnScrollableContainer_: function() { |
| 3765 this.smallPodsContainer.hidden = false; |
| 3766 // Add a dark overlay. |
| 3767 this.smallPodsContainer.classList.add('scroll'); |
| 3768 var pods = this.pods; |
| 3769 this.mainPod_.setPodStyle(UserPod.Style.LARGE); |
| 3770 for (var pod of pods) { |
| 3771 if (pod != this.mainPod_) { |
| 3772 // All pods except the main one must be set to the extra small style. |
| 3773 pod.setPodStyle(UserPod.Style.EXTRA_SMALL); |
| 3774 } |
| 3775 } |
| 3776 |
| 3777 var SCROLL_LEFT_PADDING = this.isPortraitMode() ? 46 : 72; |
| 3778 var SCROLL_RIGHT_PADDING = this.isPortraitMode() ? 12 : 72; |
| 3779 // The offsetWidth of the smallPodsContainer. |
| 3780 var scrollAreaWidth = SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH + |
| 3781 SCROLL_RIGHT_PADDING; |
| 3782 var mainPodPadding = (this.screenSize.width - |
| 3783 scrollAreaWidth - CROS_POD_WIDTH) / 2; |
| 3784 var SCROLL_TOP_PADDING = this.isPortraitMode() ? 66 : 72; |
| 3785 var EXTRA_SMALL_POD_PADDING = 32; |
| 3786 // Start positioning of the main pod and the smallPodsContainer. |
| 3787 this.mainPod_.left = mainPodPadding; |
| 3788 this.mainPod_.top = (this.screenSize.height - CROS_POD_HEIGHT) / 2; |
| 3789 this.smallPodsContainer.style.left = |
| 3790 cr.ui.toCssPx(mainPodPadding * 2 + CROS_POD_WIDTH); |
| 3791 this.smallPodsContainer.style.top = cr.ui.toCssPx(0); |
| 3792 |
| 3793 // Precalculate the total height of the scrollable container and check if |
| 3794 // it indeed exceeds the screen height. |
| 3795 var scrollHeight = 0; |
| 3796 for (var pod of pods) { |
| 3797 if (pod == this.mainPod_) { |
| 3798 continue; |
| 3799 } |
| 3800 scrollHeight += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING; |
| 3801 } |
| 3802 scrollHeight -= EXTRA_SMALL_POD_PADDING; |
| 3803 // The smallPodsContainer should occupy the full screen vertically. |
| 3804 this.smallPodsContainer.style.height = cr.ui.toCssPx(this.screenSize.heigh
t); |
| 3805 this.smallPodsContainer.style.width = cr.ui.toCssPx( |
| 3806 SCROLL_LEFT_PADDING + CROS_EXTRA_SMALL_POD_WIDTH + |
| 3807 SCROLL_RIGHT_PADDING); |
| 3808 |
| 3809 // SCROLL_TOP_PADDING denotes the smallest top padding we can tolerate |
| 3810 // before allowing the container to overflow and show the scroll bar. |
| 3811 var actualTopPadding = SCROLL_TOP_PADDING; |
| 3812 if ((this.screenSize.height - scrollHeight) / 2 > actualTopPadding) { |
| 3813 // Edge case: the total height of the scrollable container does not |
| 3814 // exceed the screen height (minus the neceesary padding), so the |
| 3815 // scroll bar will not appear. |
| 3816 // In this case, we still want to keep the extra small pod size and |
| 3817 // the overlay, but the top and bottom padding should be adjusted |
| 3818 // to ensure a symmetric layout. |
| 3819 actualTopPadding = (this.screenSize.height - scrollHeight) / 2; |
| 3820 } else if (!Oobe.getInstance().virtualKeyboardShown) { |
| 3821 // The scroll bar will definitely be shown if we reach here. A gradient |
| 3822 // mask is applied to avoid blocking the header bar if the virtual |
| 3823 // keyboard is not shown. When the keyboard is shown, there's no need |
| 3824 // to add the mask and the original top padding value should be kept. |
| 3825 actualTopPadding = SCROLL_MASK_HEIGHT; |
| 3826 this.showScrollMask(); |
| 3827 } |
| 3828 |
| 3829 // Start positioning of the small pods inside the smallPodsContainer. |
| 3830 var topPadding = actualTopPadding; |
| 3831 var lastPod = undefined; |
| 3832 for (var pod of pods) { |
| 3833 if (pod == this.mainPod_) { |
| 3834 continue; |
| 3835 } |
| 3836 pod.left = SCROLL_LEFT_PADDING; |
| 3837 pod.top = topPadding; |
| 3838 topPadding += CROS_EXTRA_SMALL_POD_HEIGHT + EXTRA_SMALL_POD_PADDING; |
| 3839 lastPod = pod; |
| 3840 } |
| 3841 // Make sure the last pod has a proper bottom padding for a symmetric |
| 3842 // layout. |
| 3843 lastPod.style.paddingBottom = cr.ui.toCssPx(actualTopPadding); |
| 3844 }, |
| 3845 |
| 3846 /** |
| 3847 * Called each time before pod placement to ensure we start with the |
| 3848 * initial state, which is ready to place only one user pod. The styles |
| 3849 * of elements necessary for other placement methods must be set |
| 3850 * explicitly each time. |
| 3851 * @private |
| 3852 */ |
| 3853 restoreInitialStates_: function() { |
| 3854 this.smallPodsContainer.hidden = true; |
| 3855 document.querySelector('.small-pod-container-mask').hidden = true; |
| 3856 document.querySelector('.small-pod-container-mask.rotate').hidden = true; |
| 3857 this.smallPodsContainer.classList.remove('scroll'); |
| 3858 var pods = this.pods; |
| 3859 for (var pod of pods) { |
| 3860 // There is a chance that one of the pods has a bottom padding, so |
| 3861 // reset all of them to be safe. This is because if the pod was at |
| 3862 // the last position in the scrollable container, a bottom padding |
| 3863 // was added to ensure a symmetric layout. |
| 3864 pod.style.paddingBottom = cr.ui.toCssPx(0); |
| 3865 } |
| 3866 }, |
| 3867 |
| 3868 /** |
| 3869 * Check if the screen is in portrait mode. |
| 3870 * @return {boolean} True if in portrait mode. |
| 3871 */ |
| 3872 isPortraitMode: function() { |
| 3873 return this.screenSize.width < |
| 3874 this.screenSize.height; |
| 3875 }, |
| 3876 |
| 3877 /** |
| 3878 * Called when scroll bar is shown and we need a mask for the header bar. |
| 3879 * @private |
| 3880 */ |
| 3881 showScrollMask: function() { |
| 3882 var topMask = document.querySelector('.small-pod-container-mask'); |
| 3883 topMask.hidden = false; |
| 3884 topMask.style.left = this.smallPodsContainer.style.left; |
| 3885 topMask.style.width = this.smallPodsContainer.style.width; |
| 3886 // The bottom mask is a rotation of the top mask. |
| 3887 var bottomMask = |
| 3888 document.querySelector('.small-pod-container-mask.rotate'); |
| 3889 bottomMask.hidden = false; |
| 3890 bottomMask.style.left = this.smallPodsContainer.style.left; |
| 3891 bottomMask.style.width = this.smallPodsContainer.style.width; |
| 3892 // The bottom mask should overlap with the header bar, and its z-index |
| 3893 // is chosen to ensure it does not block users from using the header bar. |
| 3894 bottomMask.style.top = cr.ui.toCssPx( |
| 3895 this.screenSize.height - |
| 3896 SCROLL_MASK_HEIGHT); |
| 3897 }, |
| 3898 |
| 3899 /** |
| 3900 * Makes sure that user name on each large pod is centered and extra long |
| 3901 * name does not exceed max width. Names on small pods do not need to be |
| 3902 * dynamically updated. |
| 3903 * @private |
| 3904 */ |
| 3905 updatePodNameArea: function() { |
| 3906 this.querySelectorAll('.name-container').forEach(function(nameArea) { |
| 3907 var nameElement = nameArea.querySelector('.name'); |
| 3908 var leftMargin = (CROS_POD_WIDTH - nameElement.offsetWidth) / 2; |
| 3909 if (leftMargin > 0) |
| 3910 nameArea.style.left = cr.ui.toCssPx(leftMargin); |
| 3911 else |
| 3912 nameElement.style.width = cr.ui.toCssPx(CROS_POD_WIDTH); |
3481 }); | 3913 }); |
3482 Oobe.getInstance().updateScreenSize(this.parentNode); | 3914 }, |
3483 }, | 3915 |
3484 | 3916 /** |
3485 /** | 3917 * Called when a small or extra small pod is clicked to trigger the switch |
| 3918 * with the main pod. |
| 3919 */ |
| 3920 switchMainPod: function(pod) { |
| 3921 if (this.disabled) { |
| 3922 console.error('Cannot change main pod while sign-in UI is disabled.'); |
| 3923 return; |
| 3924 } |
| 3925 if (!this.mainPod_) { |
| 3926 console.error('Attempt to switch a non-existing main pod.'); |
| 3927 return; |
| 3928 } |
| 3929 // Find the index of the small pod. |
| 3930 var insert = 0; |
| 3931 var children = pod.parentNode.children; |
| 3932 while (insert < children.length && children[insert] != pod) |
| 3933 insert++; |
| 3934 if (insert >= children.length) { |
| 3935 console.error('Attempt to switch a non-existing small pod.'); |
| 3936 return; |
| 3937 } |
| 3938 // Switch style of the two pods. |
| 3939 this.mainPod_.setPodStyle(pod.getPodStyle()); |
| 3940 pod.setPodStyle(UserPod.Style.LARGE); |
| 3941 |
| 3942 // Switch parent and position of the two pods. |
| 3943 var left = pod.left; |
| 3944 var top = pod.top; |
| 3945 // Edge case: paddingBottom should be switched too because there's a |
| 3946 // chance that the small pod was at the end of the scrollable container |
| 3947 // and had a non-zero paddingBottom. |
| 3948 var paddingBottom = pod.style.paddingBottom; |
| 3949 var parent = pod.parentNode; |
| 3950 parent.removeChild(pod); |
| 3951 this.appendChild(pod); |
| 3952 pod.left = this.mainPod_.left; |
| 3953 pod.top = this.mainPod_.top; |
| 3954 pod.style.paddingBottom = cr.ui.toCssPx(0); |
| 3955 |
| 3956 this.removeChild(this.mainPod_); |
| 3957 // It must have the same index with the original small pod, instead |
| 3958 // of being appended as the last child, in order to maintain the 'Tab' |
| 3959 // order. |
| 3960 parent.insertBefore(this.mainPod_, children[insert]); |
| 3961 this.mainPod_.left = left; |
| 3962 this.mainPod_.top = top; |
| 3963 this.mainPod_.style.paddingBottom = paddingBottom; |
| 3964 this.mainPod_ = pod; |
| 3965 // Focus the new main pod. |
| 3966 this.focusPod(this.mainPod_); |
| 3967 this.updatePodNameArea(); |
| 3968 }, |
| 3969 |
| 3970 /** |
| 3971 * Returns dimensions of screen including the header bar. |
| 3972 * @type {Object} |
| 3973 */ |
| 3974 get screenSize() { |
| 3975 var container = $('scroll-container'); |
| 3976 return {width: container.offsetWidth, height: container.offsetHeight}; |
| 3977 }, |
| 3978 |
| 3979 /** |
3486 * Number of columns. | 3980 * Number of columns. |
3487 * @type {?number} | 3981 * @type {?number} |
3488 */ | 3982 */ |
3489 set columns(columns) { | 3983 set columns(columns) { |
3490 // Cannot use 'columns' here. | 3984 // Cannot use 'columns' here. |
3491 this.setAttribute('ncolumns', columns); | 3985 this.setAttribute('ncolumns', columns); |
3492 }, | 3986 }, |
3493 get columns() { | 3987 get columns() { |
3494 return parseInt(this.getAttribute('ncolumns')); | 3988 return parseInt(this.getAttribute('ncolumns')); |
3495 }, | 3989 }, |
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3796 if (e.target.classList.contains('focused')) { | 4290 if (e.target.classList.contains('focused')) { |
3797 if (!e.target.multiProfilesPolicyApplied) | 4291 if (!e.target.multiProfilesPolicyApplied) |
3798 e.target.focusInput(); | 4292 e.target.focusInput(); |
3799 else | 4293 else |
3800 e.target.userTypeBubbleElement.classList.add('bubble-shown'); | 4294 e.target.userTypeBubbleElement.classList.add('bubble-shown'); |
3801 } else | 4295 } else |
3802 this.focusPod(e.target); | 4296 this.focusPod(e.target); |
3803 return; | 4297 return; |
3804 } | 4298 } |
3805 | 4299 |
| 4300 // Small pods do not have input box. |
| 4301 if (e.target.parentNode == this.smallPodsContainer) { |
| 4302 this.focusPod(e.target, false, true /* opt_skipInputFocus */); |
| 4303 return; |
| 4304 } |
| 4305 |
3806 var pod = findAncestorByClass(e.target, 'pod'); | 4306 var pod = findAncestorByClass(e.target, 'pod'); |
3807 if (pod && pod.parentNode == this) { | 4307 if (pod && pod.parentNode == this) { |
3808 // Focus on a control of a pod but not on the action area button. | 4308 // Focus on a control of a pod but not on the action area button. |
3809 if (!pod.classList.contains('focused')) { | 4309 if (!pod.classList.contains('focused')) { |
3810 if (e.target.classList.contains('action-box-area') || | 4310 if (e.target.classList.contains('action-box-area') || |
3811 e.target.classList.contains('remove-warning-button')) { | 4311 e.target.classList.contains('remove-warning-button')) { |
3812 // focusPod usually moves focus on the password input box which | 4312 // focusPod usually moves focus on the password input box which |
3813 // triggers virtual keyboard to show up. But the focus may move to a | 4313 // 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 | 4314 // non text input element shortly by e.target.focus. Hence, a |
3815 // virtual keyboard flicking might be observed. We need to manually | 4315 // virtual keyboard flicking might be observed. We need to manually |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3956 return; | 4456 return; |
3957 } | 4457 } |
3958 | 4458 |
3959 this.podsWithPendingImages_.splice(index, 1); | 4459 this.podsWithPendingImages_.splice(index, 1); |
3960 if (this.podsWithPendingImages_.length == 0) { | 4460 if (this.podsWithPendingImages_.length == 0) { |
3961 this.classList.remove('images-loading'); | 4461 this.classList.remove('images-loading'); |
3962 } | 4462 } |
3963 }, | 4463 }, |
3964 | 4464 |
3965 /** | 4465 /** |
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. | 4466 * Preselects pod, if needed. |
3982 */ | 4467 */ |
3983 maybePreselectPod: function() { | 4468 maybePreselectPod: function() { |
3984 var pod = this.preselectedPod; | 4469 var pod = this.preselectedPod; |
3985 this.focusPod(pod); | 4470 this.focusPod(pod); |
3986 | 4471 |
3987 // Hide user-type-bubble in case all user pods are disabled and we focus | 4472 // Hide user-type-bubble in case all user pods are disabled and we focus |
3988 // first pod. | 4473 // first pod. |
3989 if (pod && pod.multiProfilesPolicyApplied) { | 4474 if (pod && pod.multiProfilesPolicyApplied) { |
3990 pod.userTypeBubbleElement.classList.remove('bubble-shown'); | 4475 pod.userTypeBubbleElement.classList.remove('bubble-shown'); |
3991 } | 4476 } |
3992 } | 4477 } |
3993 }; | 4478 }; |
3994 | 4479 |
3995 return { | 4480 return { |
3996 PodRow: PodRow | 4481 PodRow: PodRow |
3997 }; | 4482 }; |
3998 }); | 4483 }); |
OLD | NEW |